View Javadoc

1   /*
2    * Copyright 1999-2006 Faculty of Mathematics, Physics and Informatics, Comenius
3    * University, Bratislava. This file is protected by the Mozilla Public License
4    * version 1.1 (the License); you may not use this file except in compliance
5    * with the License. You may obtain a copy of the License at
6    * http://euromath2.sourceforge.net/license.html Unless required by applicable
7    * law or agreed to in writing, software distributed under the License is
8    * distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
9    * KIND, either express or implied. See the License for the specific language
10   * governing permissions and limitations under the License.
11   */
12  package sk.uniba.euromath.editor.textEditor.commands;
13  
14  import java.util.List;
15  import org.eclipse.core.runtime.IStatus;
16  import org.eclipse.gef.commands.Command;
17  import sk.baka.ikslibs.levelmapper.NodeListID;
18  import sk.baka.xml.gene.ExportException;
19  import sk.uniba.euromath.EuroMath;
20  import sk.uniba.euromath.document.XMLAccess;
21  import sk.uniba.euromath.editor.textEditor.ITextPieceKeeper;
22  import sk.uniba.euromath.editor.textEditor.TextPieceInfoImpl;
23  import sk.uniba.euromath.editor.textEditor.tools.TextTool;
24  import sk.uniba.euromath.editor.xmlEditor.commands.DocumentModifyCompoundCommand;
25  
26  /***
27   * Command to delete text from xml. Only to delete. Use canExecute to test if
28   * delete can be performed. Text to delete is specified exactly in constructor,
29   * but some additional white spaces are deleted at end of deletion:
30   * {@link #treatWhiteSpaces()}.
31   * 
32   * @author Tomáš Studva, Martin Kollar 1.10.2005
33   */
34  public class DeleteTextCommand extends Command {
35  
36      /***
37       * Textual node holding text where deletion will be done.
38       */
39      private final NodeListID textNode;
40  
41      /***
42       * Position in textual node's text where deletion starts.
43       */
44      private int nodeTextPosition;
45  
46      /***
47       * Length of deletion.
48       */
49      private int length;
50  
51      /***
52       * XMLAccess instance.
53       */
54      private final XMLAccess xmlAccess;
55  
56      /***
57       * Creates command to delete text. Text to delete is specified by ids of
58       * text pieces, i.e. ids have form: id of textual node < start of
59       * deletion in node's text, length of deletion in node's text >. Ids must
60       * be tided up first by {@link TextPieceInfoImpl#tidyUpIds(List)} if needed.
61       * 
62       * @param ids
63       *            identifies what to delete, text piece style ids: id of textual
64       *            node &lt; start of deletion in <b>node's text</b>, length of
65       *            deletion in <b>node's text</b> &gt;
66       * @param xmlAccess
67       *            instance
68       * @return DocumentModifyCompoundCommand compound of DeleteTextCommands.
69       */
70      public static DocumentModifyCompoundCommand createCommandToDeleteText(
71              List<String> ids, XMLAccess xmlAccess) {
72          DocumentModifyCompoundCommand command = new DocumentModifyCompoundCommand(
73                  xmlAccess);
74          for (String id : ids) {
75              command.add(new DeleteTextCommand(TextPieceInfoImpl.getNodeID(id),
76                      TextPieceInfoImpl.getOffset(id), TextPieceInfoImpl
77                              .getLength(id), xmlAccess));
78          }
79          return command;
80  
81      }
82  
83      /***
84       * Constructor.
85       * 
86       * @param pieceKeeper
87       *            pieceKeeper holding text where deletion will be done
88       * @param position
89       *            position of start of deletion in <b>pieceKeeper's text</b>,
90       * @param length
91       *            of text to delete
92       * @param xmlAccess
93       *            XMLAccess instance
94       */
95      public DeleteTextCommand(ITextPieceKeeper pieceKeeper, int position,
96              int length, XMLAccess xmlAccess) {
97          if ((position < 0) || (position > pieceKeeper.getText().length()))
98              throw new IllegalArgumentException("Illegal position"); //$NON-NLS-1$
99          this.length = length;
100         this.xmlAccess = xmlAccess;
101         String id = pieceKeeper.getTextPieceInfo().getNodeID();
102         // get XML text node(s)
103         this.textNode = this.xmlAccess.getIdManager().getNodeNull(id);
104         assert this.textNode != null;
105         assert this.textNode.isTextual();
106 
107         // resolve position to the XML text(s) position
108         String prevText = pieceKeeper.getWholeTextToPosition(position);
109         this.nodeTextPosition = this.textNode.resolveIndex(prevText, prevText
110                 .length());
111     }
112 
113     /***
114      * Constructor.
115      * 
116      * @param id
117      *            of textual node holding text where deletion will be done
118      * @param position
119      *            position of start of deletion in <b>textual node's text</b>,
120      * @param length
121      *            of <b>textual node's text</b> to delete
122      * @param xmlAccess
123      *            XMLAccess instance
124      */
125     public DeleteTextCommand(String id, int position, int length,
126             XMLAccess xmlAccess) {
127         this.nodeTextPosition = position;
128         this.length = length;
129         this.xmlAccess = xmlAccess;
130         // get XML text node(s)
131         this.textNode = this.xmlAccess.getIdManager().getNodeNull(id);
132         assert this.textNode != null;
133         assert this.textNode.isTextual();
134     }
135 
136     /***
137      * Treats white spaces at end of deletion. Some additional white spaces if
138      * exitst at end, are deleted. //TODO GUI pouzivat ju, zatial sa nepouziva
139      */
140     private void treatWhiteSpaces() {
141         // TODO Kollar podla mna toto robi: ak posledny char ktory mam zmazat je
142         // medzera, tak zmazem este jednu. A malo by to toto? : ak posledny char
143         // ktory mam zmazat je medzera, tak zmaz vsetky nasledujuce medzery,
144         // prekonzultuj so mnou. A preco je v prvom riadku ta podmienka? T.S
145         if (this.nodeTextPosition > 0) {
146             if (this.nodeTextPosition + this.length < this.textNode
147                     .getTextValue().length())
148                 if ((TextTool.isWhiteSpace(this.textNode.getTextValue().charAt(
149                         this.nodeTextPosition + this.length)))
150                         && (TextTool.isWhiteSpace(this.textNode.getTextValue()
151                                 .charAt(this.nodeTextPosition - 1))))
152                     this.length++;
153         }
154     }
155 
156     @Override
157     public void execute() {
158         if (!canExecute())
159             throw new IllegalArgumentException(
160                     "Illegal call of execute method. Command cannot be executed."); //$NON-NLS-1$
161         // modify the document
162         this.xmlAccess.getModifier().startModify();
163         this.xmlAccess.getModifier().delete(this.textNode,
164                 this.nodeTextPosition, this.nodeTextPosition + this.length);
165         // transform the document
166         try {
167             this.xmlAccess.getModifier().endModify();
168         } catch (ExportException ex) {
169             EuroMath.log(IStatus.ERROR, 0, "Error during transformation", ex); //$NON-NLS-1$
170         }
171     }
172 
173     @Override
174     public boolean canExecute() {
175         return this.textNode.isDeletable(this.nodeTextPosition,
176                 this.nodeTextPosition + this.length);
177     }
178 }