Source Code Cross Referenced for MoveLinesAction.java in  » IDE-Eclipse » ui-workbench » org » eclipse » ui » texteditor » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » IDE Eclipse » ui workbench » org.eclipse.ui.texteditor 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        /*******************************************************************************
002:         * Copyright (c) 2000, 2006 IBM Corporation and others.
003:         * All rights reserved. This program and the accompanying materials
004:         * are made available under the terms of the Eclipse Public License v1.0
005:         * which accompanies this distribution, and is available at
006:         * http://www.eclipse.org/legal/epl-v10.html
007:         *
008:         * Contributors:
009:         *     IBM Corporation - initial API and implementation
010:         *******************************************************************************/package org.eclipse.ui.texteditor;
011:
012:        import java.util.ResourceBundle;
013:
014:        import org.eclipse.swt.custom.StyledText;
015:        import org.eclipse.swt.graphics.Point;
016:        import org.eclipse.swt.widgets.Event;
017:
018:        import org.eclipse.core.runtime.Assert;
019:
020:        import org.eclipse.jface.text.BadLocationException;
021:        import org.eclipse.jface.text.IDocument;
022:        import org.eclipse.jface.text.IRegion;
023:        import org.eclipse.jface.text.IRewriteTarget;
024:        import org.eclipse.jface.text.ITextSelection;
025:        import org.eclipse.jface.text.ITextViewer;
026:        import org.eclipse.jface.text.ITextViewerExtension5;
027:        import org.eclipse.jface.text.TextSelection;
028:        import org.eclipse.jface.text.TextUtilities;
029:        import org.eclipse.jface.text.source.ISourceViewer;
030:
031:        import org.eclipse.ui.internal.texteditor.CompoundEditExitStrategy;
032:        import org.eclipse.ui.internal.texteditor.ICompoundEditListener;
033:
034:        /**
035:         * Action for moving selected lines in an editor.
036:         * @since 3.0
037:         */
038:        public class MoveLinesAction extends TextEditorAction {
039:
040:            /* configuration variables - define what this action does */
041:
042:            /** <code>true</code> if lines are shifted upwards, <code>false</code> otherwise. */
043:            private final boolean fUpwards;
044:            /** <code>true</code> if lines are to be copied instead of moved. */
045:            private final boolean fCopy;
046:            /** The editor we are working on. */
047:            private final AbstractTextEditor fEditor;
048:
049:            /* compound members of this action */
050:
051:            /**
052:             * The exit strategy that will detect the ending of a compound edit.
053:             * @since 3.1
054:             */
055:            private final CompoundEditExitStrategy fStrategy;
056:
057:            /* process variables - may change in every run() */
058:
059:            /**
060:             * Set to <code>true</code> by <code>getMovingSelection</code> if the resulting selection
061:             * should include the last delimiter.
062:             */
063:            private boolean fAddDelimiter;
064:            /** <code>true</code> if a compound move / copy is going on. */
065:            private boolean fEditInProgress = false;
066:
067:            /**
068:             * Creates and initializes the action for the given text editor.
069:             * The action configures its visual representation from the given resource
070:             * bundle.
071:             *
072:             * @param bundle the resource bundle
073:             * @param prefix a prefix to be prepended to the various resource keys
074:             *   (described in <code>ResourceAction</code> constructor), or  <code>null</code> if none
075:             * @param editor the text editor
076:             * @param upwards <code>true</code>if the selected lines should be moved upwards,
077:             * <code>false</code> if downwards
078:             * @param copy if <code>true</code>, the action will copy lines instead of moving them
079:             * @see TextEditorAction#TextEditorAction(ResourceBundle, String, ITextEditor)
080:             */
081:            public MoveLinesAction(ResourceBundle bundle, String prefix,
082:                    AbstractTextEditor editor, boolean upwards, boolean copy) {
083:                super (bundle, prefix, editor);
084:                fEditor = editor;
085:                fUpwards = upwards;
086:                fCopy = copy;
087:                String[] commandIds = copy ? new String[] {
088:                        ITextEditorActionDefinitionIds.COPY_LINES_UP,
089:                        ITextEditorActionDefinitionIds.COPY_LINES_DOWN }
090:                        : new String[] {
091:                                ITextEditorActionDefinitionIds.MOVE_LINES_UP,
092:                                ITextEditorActionDefinitionIds.MOVE_LINES_DOWN };
093:                fStrategy = new CompoundEditExitStrategy(commandIds);
094:                fStrategy.addCompoundListener(new ICompoundEditListener() {
095:                    public void endCompoundEdit() {
096:                        MoveLinesAction.this .endCompoundEdit();
097:                    }
098:                });
099:                update();
100:            }
101:
102:            /**
103:             * Ends the compound change.
104:             */
105:            private void beginCompoundEdit() {
106:                if (fEditInProgress || fEditor == null)
107:                    return;
108:
109:                fEditInProgress = true;
110:
111:                fStrategy.arm(fEditor.getSourceViewer());
112:
113:                IRewriteTarget target = (IRewriteTarget) fEditor
114:                        .getAdapter(IRewriteTarget.class);
115:                if (target != null) {
116:                    target.beginCompoundChange();
117:                }
118:            }
119:
120:            /**
121:             * Checks if <code>selection</code> is contained by the visible region of <code>viewer</code>.
122:             * As a special case, a selection is considered contained even if it extends over the visible
123:             * region, but the extension stays on a partially contained line and contains only white space.
124:             *
125:             * @param selection the selection to be checked
126:             * @param viewer the viewer displaying a visible region of <code>selection</code>'s document.
127:             * @return <code>true</code>, if <code>selection</code> is contained, <code>false</code> otherwise.
128:             */
129:            private boolean containedByVisibleRegion(ITextSelection selection,
130:                    ISourceViewer viewer) {
131:                int min = selection.getOffset();
132:                int max = min + selection.getLength();
133:                IDocument document = viewer.getDocument();
134:
135:                IRegion visible;
136:                if (viewer instanceof  ITextViewerExtension5)
137:                    visible = ((ITextViewerExtension5) viewer)
138:                            .getModelCoverage();
139:                else
140:                    visible = viewer.getVisibleRegion();
141:
142:                int visOffset = visible.getOffset();
143:                try {
144:                    if (visOffset > min) {
145:                        if (document.getLineOfOffset(visOffset) != selection
146:                                .getStartLine())
147:                            return false;
148:                        if (!isWhitespace(document.get(min, visOffset - min))) {
149:                            showStatus();
150:                            return false;
151:                        }
152:                    }
153:                    int visEnd = visOffset + visible.getLength();
154:                    if (visEnd < max) {
155:                        if (document.getLineOfOffset(visEnd) != selection
156:                                .getEndLine())
157:                            return false;
158:                        if (!isWhitespace(document.get(visEnd, max - visEnd))) {
159:                            showStatus();
160:                            return false;
161:                        }
162:                    }
163:                    return true;
164:                } catch (BadLocationException e) {
165:                }
166:                return false;
167:            }
168:
169:            /**
170:             * Ends the compound change.
171:             */
172:            private void endCompoundEdit() {
173:                if (!fEditInProgress || fEditor == null)
174:                    return;
175:
176:                IRewriteTarget target = (IRewriteTarget) fEditor
177:                        .getAdapter(IRewriteTarget.class);
178:                if (target != null) {
179:                    target.endCompoundChange();
180:                }
181:
182:                fEditInProgress = false;
183:            }
184:
185:            /**
186:             * Given a selection on a document, computes the lines fully or partially covered by
187:             * <code>selection</code>. A line in the document is considered covered if
188:             * <code>selection</code> comprises any characters on it, including the terminating delimiter.
189:             * <p>Note that the last line in a selection is not considered covered if the selection only
190:             * comprises the line delimiter at its beginning (that is considered part of the second last
191:             * line).
192:             * As a special case, if the selection is empty, a line is considered covered if the caret is
193:             * at any position in the line, including between the delimiter and the start of the line. The
194:             * line containing the delimiter is not considered covered in that case.
195:             * </p>
196:             *
197:             * @param document the document <code>selection</code> refers to
198:             * @param selection a selection on <code>document</code>
199:             * @param viewer the <code>ISourceViewer</code> displaying <code>document</code>
200:             * @return a selection describing the range of lines (partially) covered by
201:             * <code>selection</code>, without any terminating line delimiters
202:             * @throws BadLocationException if the selection is out of bounds (when the underlying document has changed during the call)
203:             */
204:            private ITextSelection getMovingSelection(IDocument document,
205:                    ITextSelection selection, ISourceViewer viewer)
206:                    throws BadLocationException {
207:                int low = document.getLineOffset(selection.getStartLine());
208:                int endLine = selection.getEndLine();
209:                int high = document.getLineOffset(endLine)
210:                        + document.getLineLength(endLine);
211:
212:                // get everything up to last line without its delimiter
213:                String delim = document.getLineDelimiter(endLine);
214:                if (delim != null)
215:                    high -= delim.length();
216:
217:                // the new selection will cover the entire lines being moved, except for the last line's
218:                // delimiter. The exception to this rule is an empty last line, which will stay covered
219:                // including its delimiter
220:                if (delim != null
221:                        && document.getLineLength(endLine) == delim.length())
222:                    fAddDelimiter = true;
223:                else
224:                    fAddDelimiter = false;
225:
226:                return new TextSelection(document, low, high - low);
227:            }
228:
229:            /**
230:             * Computes the region of the skipped line given the text block to be moved. If
231:             * <code>fUpwards</code> is <code>true</code>, the line above <code>selection</code>
232:             * is selected, otherwise the line below.
233:             *
234:             * @param document the document <code>selection</code> refers to
235:             * @param selection the selection on <code>document</code> that will be moved.
236:             * @return the region comprising the line that <code>selection</code> will be moved over, without its terminating delimiter.
237:             */
238:            private ITextSelection getSkippedLine(IDocument document,
239:                    ITextSelection selection) {
240:                int skippedLineN = (fUpwards ? selection.getStartLine() - 1
241:                        : selection.getEndLine() + 1);
242:                if (skippedLineN > document.getNumberOfLines()
243:                        || (!fCopy && (skippedLineN < 0 || skippedLineN == document
244:                                .getNumberOfLines())))
245:                    return null;
246:                try {
247:                    if (fCopy && skippedLineN == -1)
248:                        skippedLineN = 0;
249:                    IRegion line = document.getLineInformation(skippedLineN);
250:                    return new TextSelection(document, line.getOffset(), line
251:                            .getLength());
252:                } catch (BadLocationException e) {
253:                    // only happens on concurrent modifications
254:                    return null;
255:                }
256:            }
257:
258:            /**
259:             * Checks for white space in a string.
260:             *
261:             * @param string the string to be checked or <code>null</code>
262:             * @return <code>true</code> if <code>string</code> contains only white space or is
263:             * <code>null</code>, <code>false</code> otherwise
264:             */
265:            private boolean isWhitespace(String string) {
266:                return string == null ? true : string.trim().length() == 0;
267:            }
268:
269:            /*
270:             * @see org.eclipse.jface.action.IAction#run()
271:             */
272:            public void runWithEvent(Event event) {
273:
274:                // get involved objects
275:                if (fEditor == null)
276:                    return;
277:
278:                if (!validateEditorInputState())
279:                    return;
280:
281:                ISourceViewer viewer = fEditor.getSourceViewer();
282:                if (viewer == null)
283:                    return;
284:
285:                IDocument document = viewer.getDocument();
286:                if (document == null)
287:                    return;
288:
289:                StyledText widget = viewer.getTextWidget();
290:                if (widget == null)
291:                    return;
292:
293:                // get selection
294:                Point p = viewer.getSelectedRange();
295:                if (p == null)
296:                    return;
297:
298:                ITextSelection sel = new TextSelection(document, p.x, p.y);
299:
300:                ITextSelection skippedLine = getSkippedLine(document, sel);
301:                if (skippedLine == null)
302:                    return;
303:
304:                try {
305:
306:                    ITextSelection movingArea = getMovingSelection(document,
307:                            sel, viewer);
308:
309:                    // if either the skipped line or the moving lines are outside the widget's
310:                    // visible area, bail out
311:                    if (!containedByVisibleRegion(movingArea, viewer)
312:                            || !containedByVisibleRegion(skippedLine, viewer))
313:                        return;
314:
315:                    // get the content to be moved around: the moving (selected) area and the skipped line
316:                    String moving = movingArea.getText();
317:                    String skipped = skippedLine.getText();
318:                    if (moving == null || skipped == null
319:                            || document.getLength() == 0)
320:                        return;
321:
322:                    String delim;
323:                    String insertion;
324:                    int offset, deviation;
325:                    if (fUpwards) {
326:                        delim = document.getLineDelimiter(skippedLine
327:                                .getEndLine());
328:                        if (fCopy) {
329:                            delim = TextUtilities
330:                                    .getDefaultLineDelimiter(document);
331:                            insertion = moving + delim;
332:                            offset = movingArea.getOffset();
333:                            deviation = 0;
334:                        } else {
335:                            Assert.isNotNull(delim);
336:                            insertion = moving + delim + skipped;
337:                            offset = skippedLine.getOffset();
338:                            deviation = -skippedLine.getLength()
339:                                    - delim.length();
340:                        }
341:                    } else {
342:                        delim = document.getLineDelimiter(movingArea
343:                                .getEndLine());
344:                        if (fCopy) {
345:                            if (delim == null) {
346:                                delim = TextUtilities
347:                                        .getDefaultLineDelimiter(document);
348:                                insertion = delim + moving;
349:                            } else {
350:                                insertion = moving + delim;
351:                            }
352:                            offset = skippedLine.getOffset();
353:                            deviation = movingArea.getLength() + delim.length();
354:                        } else {
355:                            Assert.isNotNull(delim);
356:                            insertion = skipped + delim + moving;
357:                            offset = movingArea.getOffset();
358:                            deviation = skipped.length() + delim.length();
359:                        }
360:                    }
361:
362:                    // modify the document
363:                    beginCompoundEdit();
364:                    if (fCopy) {
365:                        //				fDescription= new EditDescription(offset, 0, insertion.length());
366:                        document.replace(offset, 0, insertion);
367:                    } else {
368:                        //				fDescription= new EditDescription(offset, insertion.length(), insertion.length());
369:                        document.replace(offset, insertion.length(), insertion);
370:                    }
371:
372:                    // move the selection along
373:                    int selOffset = movingArea.getOffset() + deviation;
374:                    int selLength = movingArea.getLength()
375:                            + (fAddDelimiter ? delim.length() : 0);
376:                    if (!(viewer instanceof  ITextViewerExtension5))
377:                        selLength = Math.min(selLength, viewer
378:                                .getVisibleRegion().getOffset()
379:                                + viewer.getVisibleRegion().getLength()
380:                                - selOffset);
381:                    else {
382:                        // TODO need to check what is necessary in the projection case
383:                    }
384:                    selectAndReveal(viewer, selOffset, selLength);
385:                } catch (BadLocationException x) {
386:                    // won't happen without concurrent modification - bail out
387:                    return;
388:                }
389:            }
390:
391:            /**
392:             * Performs similar to AbstractTextEditor.selectAndReveal, but does not update
393:             * the viewers highlight area.
394:             *
395:             * @param viewer the viewer that we want to select on
396:             * @param offset the offset of the selection
397:             * @param length the length of the selection
398:             */
399:            private void selectAndReveal(ITextViewer viewer, int offset,
400:                    int length) {
401:                // invert selection to avoid jumping to the end of the selection in st.showSelection()
402:                viewer.setSelectedRange(offset + length, -length);
403:                //viewer.revealRange(offset, length); // will trigger jumping
404:                StyledText st = viewer.getTextWidget();
405:                if (st != null)
406:                    st.showSelection(); // only minimal scrolling
407:            }
408:
409:            /**
410:             * Displays information in the status line why a line move is not possible
411:             */
412:            private void showStatus() {
413:                IEditorStatusLine status = (IEditorStatusLine) fEditor
414:                        .getAdapter(IEditorStatusLine.class);
415:                if (status == null)
416:                    return;
417:                status.setMessage(false,
418:                        EditorMessages.Editor_MoveLines_IllegalMove_status,
419:                        null);
420:            }
421:
422:            /*
423:             * @see org.eclipse.ui.texteditor.IUpdate#update()
424:             */
425:            public void update() {
426:                super.update();
427:
428:                if (isEnabled())
429:                    setEnabled(canModifyEditor());
430:
431:            }
432:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.