d8b4537e3ff2bbe60bac0d00e463e3529afe0e6a
[phpeclipse.git] /
1 package net.sourceforge.phpeclipse.wiki.actions;
2
3 import java.io.ByteArrayInputStream;
4
5 import net.sourceforge.phpeclipse.wiki.editor.WikiEditor;
6 import net.sourceforge.phpeclipse.wiki.editor.WikiEditorPlugin;
7 import net.sourceforge.phpeclipse.wiki.preferences.Util;
8
9 import org.eclipse.core.resources.IContainer;
10 import org.eclipse.core.resources.IFile;
11 import org.eclipse.core.resources.IFolder;
12 import org.eclipse.core.resources.IProject;
13 import org.eclipse.core.resources.IResource;
14 import org.eclipse.core.resources.IResourceStatus;
15 import org.eclipse.core.resources.ResourcesPlugin;
16 import org.eclipse.core.runtime.CoreException;
17 import org.eclipse.core.runtime.IPath;
18 import org.eclipse.core.runtime.IProgressMonitor;
19 import org.eclipse.core.runtime.Path;
20 import org.eclipse.core.runtime.SubProgressMonitor;
21 import org.eclipse.jface.action.IAction;
22 import org.eclipse.jface.text.BadLocationException;
23 import org.eclipse.jface.text.IDocument;
24 import org.eclipse.jface.text.ITextSelection;
25 import org.eclipse.jface.text.TextSelection;
26 import org.eclipse.jface.viewers.ISelection;
27 import org.eclipse.ui.IEditorActionDelegate;
28 import org.eclipse.ui.IEditorPart;
29 import org.eclipse.ui.IFileEditorInput;
30 import org.eclipse.ui.IWorkbenchWindow;
31 import org.eclipse.ui.ide.IDE;
32 import org.eclipse.ui.internal.ide.IDEWorkbenchPlugin;
33 import org.eclipse.ui.texteditor.AbstractTextEditor;
34
35 public final class OpenWikiLinkEditorAction implements IEditorActionDelegate {
36
37   private IWorkbenchWindow window;
38
39   private AbstractTextEditor editor;
40
41   public void dispose() {
42   }
43
44   public void init(IWorkbenchWindow window) {
45     this.window = window;
46   }
47
48   public void selectionChanged(IAction action, ISelection selection) {
49     if (selection.isEmpty()) {
50       return;
51     }
52     if (selection instanceof TextSelection) {
53       action.setEnabled(true);
54       return;
55     }
56     if (window.getActivePage() != null && window.getActivePage().getActivePart() != null) {
57       action.setEnabled(window.getActivePage().getActivePart().getClass().equals(WikiEditor.class));
58     }
59   }
60
61   public void run(IAction action) {
62     if (editor == null) {
63       IEditorPart targetEditor = window.getActivePage().getActiveEditor();
64       if (targetEditor != null && (targetEditor instanceof AbstractTextEditor)) {
65         editor = (AbstractTextEditor) targetEditor;
66       }
67     }
68     if (editor != null) {
69       openWikiLinkOnSelection();
70     }
71   }
72
73   public void setActiveEditor(IAction action, IEditorPart targetEditor) {
74     if (targetEditor != null && (targetEditor instanceof AbstractTextEditor)) {
75       editor = (AbstractTextEditor) targetEditor;
76     }
77   }
78
79   public static String getWikiString(AbstractTextEditor editor, IDocument document, int initialPos) {
80     try {
81       int pos = initialPos;
82       int line = document.getLineOfOffset(pos);
83       int start = document.getLineOffset(line);
84       int end = start + document.getLineInformation(line).getLength();
85
86       /*
87        * The line does not include \n or \r so pos can be > end. Making pos = end in this case is safe for the purposes of
88        * determining the TextRegion at the cursor position
89        */
90       if (pos > end) {
91         pos = end;
92       }
93
94       int offsetInLine = pos - start;
95       String word = document.get(start, end - start);
96       int wordlen = word.length();
97       int wikiLinkStart = -1;
98       int wikiLinkEnd = -1;
99
100       for (int i = offsetInLine; i < wordlen; i++) {
101         if (word.charAt(i) == ']' && i < wordlen - 1 && word.charAt(i + 1) == ']') {
102           wikiLinkEnd = i;
103           break;
104         }
105         if (word.charAt(i) == '|') {
106           wikiLinkEnd = i;
107           break;
108         }
109         if (word.charAt(i) == '#') {
110           wikiLinkEnd = i;
111           break;
112         }
113       }
114       for (int i = offsetInLine; i >= 0; i--) {
115         if (word.charAt(i) == '[' && i > 0 && word.charAt(i - 1) == '[') {
116           wikiLinkStart = i + 1;
117           break;
118         }
119         if (word.charAt(i) == '|') { // links wih different description
120           wikiLinkEnd = i;
121         }
122         if (word.charAt(i) == '#') { // for links with anchors
123           wikiLinkEnd = i;
124         }
125       }
126       if (wikiLinkStart != (-1) && wikiLinkEnd != (-1) && wikiLinkStart < wikiLinkEnd) {
127         return new String(word.toCharArray(), wikiLinkStart, wikiLinkEnd - wikiLinkStart);
128       }
129     } catch (BadLocationException e) {
130
131     }
132     return "";
133   }
134
135   public IDocument getDocument() {
136     IDocument doc = editor.getDocumentProvider().getDocument(editor.getEditorInput());
137     return doc;
138   }
139
140   public void openWikiLinkOnSelection() {
141     IDocument doc = getDocument();
142     ITextSelection selection = (ITextSelection) editor.getSelectionProvider().getSelection();
143     int pos = selection.getOffset();
144     
145     String textRegion = getWikiString(editor, doc, pos);
146     IFileEditorInput ei = (IFileEditorInput) editor.getEditorInput();
147     openWikiFile(ei.getFile(), textRegion);
148   }
149
150   public static void openWikiUrl(IProject project, String word) {
151     if (word != null && !word.equals("")) {
152       IFile cfile = project.getFile("dummy.wp");
153       IFile file = getWikiFile(cfile, word);
154       try {
155         createNewFileIfNeeded(file, word);
156         //                              if (WikiEditorPlugin.getDefault().getPreferenceStore().getBoolean(WikiConstants.REUSE_EDITOR)) {
157         //                                      saveIfNeeded();
158         //                                      getActivePage().reuseEditor(reusableEditor, new FileEditorInput(file));
159         //                              } else {
160         IDE.openEditor(WikiEditorPlugin.getDefault().getActivePage(), file, true);
161         //                                      redrawText();
162         //                              }
163       } catch (Exception e) {
164         //                        WikiEditorPlugin.getDefault().logAndReport(WikiEditorPlugin.getResourceString(WikiConstants.RESOURCE_WIKI_ERROR_DIALOGUE_OPEN_WIKI_FILE_TITLE),
165         // WikiPlugin.getResourceString(WikiConstants.RESOURCE_WIKI_ERROR_DIALOGUE_OPEN_WIKI_FILE_TEXT), e);
166       }
167     } 
168   } 
169   
170   public static void openWikiFile(IFile cfile, String word) {
171     if (word != null && !word.equals("")) {
172       IFile file = getWikiFile(cfile, word);
173       try {
174         createNewFileIfNeeded(file, word);
175         //                              if (WikiEditorPlugin.getDefault().getPreferenceStore().getBoolean(WikiConstants.REUSE_EDITOR)) {
176         //                                      saveIfNeeded();
177         //                                      getActivePage().reuseEditor(reusableEditor, new FileEditorInput(file));
178         //                              } else {
179         IDE.openEditor(WikiEditorPlugin.getDefault().getActivePage(), file, true);
180         //                                      redrawText();
181         //                              }
182       } catch (Exception e) {
183         //                        WikiEditorPlugin.getDefault().logAndReport(WikiEditorPlugin.getResourceString(WikiConstants.RESOURCE_WIKI_ERROR_DIALOGUE_OPEN_WIKI_FILE_TITLE),
184         // WikiPlugin.getResourceString(WikiConstants.RESOURCE_WIKI_ERROR_DIALOGUE_OPEN_WIKI_FILE_TEXT), e);
185       }
186     } 
187   }
188
189   private static void createNewFileIfNeeded(IFile file, String word) throws CoreException {
190     if (!file.exists()) {
191       createWikiFile(file, word);
192     }
193   }
194
195   private static IFile getWikiFile(IFile file, String word) {
196     String wikiFileName = Util.getWikiFileName(word, file, WikiEditorPlugin.HTML_OUTPUT_PATH);
197     IPath path = new Path(wikiFileName);
198     return ResourcesPlugin.getWorkspace().getRoot().getFileForLocation(path);
199   }
200
201   /**
202    * Creates a folder resource handle for the folder with the given workspace path. This method does not create the folder resource;
203    * this is the responsibility of <code>createFolder</code>.
204    * 
205    * @param folderPath
206    *          the path of the folder resource to create a handle for
207    * @return the new folder resource handle
208    * @see #createFolder
209    */
210   private static IFolder createFolderHandle(IPath folderPath) {
211     return IDEWorkbenchPlugin.getPluginWorkspace().getRoot().getFolder(folderPath);
212   }
213
214   private static void createFolder(IFolder folderHandle, IProgressMonitor monitor) throws CoreException {
215     try {
216       // Create the folder resource in the workspace
217       // Recursive to create any folders which do not exist already
218       if (!folderHandle.exists()) {
219         IContainer parent = folderHandle.getParent();
220         if (parent instanceof IFolder && (!((IFolder) parent).exists())) {
221           createFolder((IFolder) parent, monitor);
222         }
223         //                  if (linkTargetPath != null)
224         //                              folderHandle.createLink(linkTargetPath, IResource.ALLOW_MISSING_LOCAL, monitor);
225         //                  else
226         folderHandle.create(false, true, monitor);
227       }
228     } catch (CoreException e) {
229       // If the folder already existed locally, just refresh to get contents
230       if (e.getStatus().getCode() == IResourceStatus.PATH_OCCUPIED)
231         folderHandle.refreshLocal(IResource.DEPTH_INFINITE, new SubProgressMonitor(monitor, 500));
232       else
233         throw e;
234     }
235   }
236
237   private static void createWikiFile(IFile file, String word) throws CoreException {
238     IContainer parent = file.getParent();
239     if (parent instanceof IFolder && (!((IFolder) parent).exists())) {
240       createFolder((IFolder) parent, null);
241     }
242     String newText = "<!--" + word + "-->";
243     byte[] buffer = newText.getBytes();
244     ByteArrayInputStream source = new ByteArrayInputStream(buffer);
245     file.create(source, true, null);
246   }
247
248 }