Added new Option "Wrap PHPdocs and comments at print margin"
[phpeclipse.git] / net.sourceforge.phpeclipse / src / net / sourceforge / phpeclipse / actions / PHPOpenDeclarationEditorAction.java
1 /***********************************************************************************************************************************
2  * Copyright (c) 2000, 2002 IBM Corp. and others. All rights reserved. This program and the accompanying materials are made
3  * available under the terms of the Common Public License v1.0 which accompanies this distribution, and is available at
4  * http://www.eclipse.org/legal/cpl-v10.html
5  * 
6  * Contributors: www.phpeclipse.de
7  **********************************************************************************************************************************/
8 package net.sourceforge.phpeclipse.actions;
9
10 import java.util.Collections;
11 import java.util.List;
12 import java.util.Set;
13
14 import net.sourceforge.phpdt.internal.ui.util.PHPFileUtil;
15 import net.sourceforge.phpeclipse.PHPeclipsePlugin;
16 import net.sourceforge.phpeclipse.builder.IdentifierIndexManager;
17 import net.sourceforge.phpeclipse.builder.PHPIdentifierLocation;
18 import net.sourceforge.phpeclipse.phpeditor.PHPEditor;
19 import net.sourceforge.phpeclipse.phpeditor.php.PHPWordExtractor;
20
21 import org.eclipse.core.resources.IContainer;
22 import org.eclipse.core.resources.IFile;
23 import org.eclipse.core.resources.IProject;
24 import org.eclipse.core.internal.resources.File;
25 import org.eclipse.core.runtime.CoreException;
26 import org.eclipse.core.runtime.IPath;
27 import org.eclipse.jface.action.IAction;
28 import org.eclipse.jface.text.BadLocationException;
29 import org.eclipse.jface.text.IDocument;
30 import org.eclipse.jface.text.ITextSelection;
31 import org.eclipse.jface.text.TextSelection;
32 import org.eclipse.jface.viewers.ISelection;
33 import org.eclipse.jface.viewers.LabelProvider;
34 import org.eclipse.jface.window.Window;
35 import org.eclipse.swt.graphics.Point;
36 import org.eclipse.ui.IEditorActionDelegate;
37 import org.eclipse.ui.IEditorPart;
38 import org.eclipse.ui.IFileEditorInput;
39 import org.eclipse.ui.IWorkbenchWindow;
40 import org.eclipse.ui.actions.ActionDelegate;
41 import org.eclipse.ui.dialogs.ListSelectionDialog;
42 import org.eclipse.ui.internal.dialogs.ListContentProvider;
43
44 public class PHPOpenDeclarationEditorAction extends ActionDelegate implements IEditorActionDelegate {
45
46   private IWorkbenchWindow fWindow;
47
48   private PHPEditor fEditor;
49
50   private IProject fProject;
51
52   private boolean isIncludeString;
53
54   public void dispose() {
55   }
56
57   public void init(IWorkbenchWindow window) {
58     this.fWindow = window;
59   }
60
61   public void selectionChanged(IAction action, ISelection selection) {
62     if (!selection.isEmpty()) {
63       if (selection instanceof TextSelection) {
64         action.setEnabled(true);
65       } else if (fWindow.getActivePage() != null && fWindow.getActivePage().getActivePart() != null) {
66         //
67       }
68     }
69   }
70
71   public void run(IAction action) {
72     if (fEditor == null) {
73       IEditorPart targetEditor = fWindow.getActivePage().getActiveEditor();
74       if (targetEditor != null && (targetEditor instanceof PHPEditor)) {
75         fEditor = (PHPEditor) targetEditor;
76       }
77     }
78     if (fEditor != null) {
79       // determine the current Project from a (file-based) Editor
80       IFile f = ((IFileEditorInput) fEditor.getEditorInput()).getFile();
81       fProject = f.getProject();
82       //      System.out.println(fProject.toString());
83
84       ITextSelection selection = (ITextSelection) fEditor.getSelectionProvider().getSelection();
85       IDocument doc = fEditor.getDocumentProvider().getDocument(fEditor.getEditorInput());
86       int pos = selection.getOffset();
87       //  System.out.println(selection.getText());
88       String identifierOrInclude = getIdentifierOrInclude(doc, pos);
89       //      System.out.println(word);
90       if (identifierOrInclude != null && !identifierOrInclude.equals("")) {
91         if (isIncludeString) {
92           openIncludeFile(identifierOrInclude);
93         } else {
94           openIdentifierDeclaration(f, identifierOrInclude);
95         }
96       }
97     }
98   }
99
100   /**
101    * @param filename
102    */
103   private void openIncludeFile(String filename) {
104     if (filename != null && !filename.equals("")) {
105       try {
106         IFile currentFile = ((IFileEditorInput) fEditor.getEditorInput()).getFile();
107         IPath path = PHPFileUtil.determineFilePath(filename, currentFile, fProject);
108         if (path != null) { 
109 //          String projectPath = fProject.getLocation().toString();
110 //          String filePath = path.toString().substring(projectPath.length()+1);
111 //          IFile file = fProject.getFile(filePath);
112           IFile file = PHPFileUtil.createFile(path, fProject);
113           //        IFile file = getIncludeFile(fProject, (IFileEditorInput) fEditor.getEditorInput(), filename);
114           if (file != null && file.exists()) {
115             PHPeclipsePlugin.getDefault().openFileInTextEditor(file.getLocation().toString());
116             return;
117           }
118         }
119       } catch (Exception e) {
120         // ignore
121       }
122
123       try {
124
125         IdentifierIndexManager indexManager = PHPeclipsePlugin.getDefault().getIndexManager(fProject);
126         //            filename = StringUtil.replaceRegExChars(filename);
127         List list = indexManager.getFileList(filename);
128         if (list != null && list.size() > 0) {
129           //String workspaceLocation = PHPeclipsePlugin.getWorkspace().getRoot().getLocation().toString();
130           String workspaceLocation = fProject.getLocation().toString() + java.io.File.separatorChar;
131
132           ListSelectionDialog listSelectionDialog = new ListSelectionDialog(PHPeclipsePlugin.getDefault().getWorkbench()
133               .getActiveWorkbenchWindow().getShell(), list, new ListContentProvider(), new LabelProvider(),
134               "Select the includes to open.");
135           listSelectionDialog.setTitle("Multiple includes found");
136           if (listSelectionDialog.open() == Window.OK) {
137             Object[] locations = listSelectionDialog.getResult();
138             if (locations != null) {
139               try {
140                 for (int i = 0; i < locations.length; i++) {
141                   //                    PHPIdentifierLocation location = (PHPIdentifierLocation)
142                   // locations[i];
143                   String openFilename = workspaceLocation + ((String) locations[i]);
144                   PHPeclipsePlugin.getDefault().openFileInTextEditor(openFilename);
145                 }
146               } catch (CoreException e) {
147                 // TODO Auto-generated catch block
148                 e.printStackTrace();
149               }
150             }
151           }
152
153         }
154       } catch (Exception e) {
155       }
156
157     }
158     return;
159   }
160
161   /**
162    * @param f
163    * @param identiifer
164    */
165   private void openIdentifierDeclaration(IFile f, String identiifer) {
166     if (identiifer != null && !identiifer.equals("")) {
167       IdentifierIndexManager indexManager = PHPeclipsePlugin.getDefault().getIndexManager(fProject);
168       List locationsList = indexManager.getLocations(identiifer);
169       if (locationsList != null && locationsList.size() > 0) {
170
171         //          String workspaceLocation = PHPeclipsePlugin.getWorkspace().getRoot()
172         //              .getLocation().toString();
173
174         String workspaceLocation = fProject.getLocation().toString() + java.io.File.separatorChar;
175         // TODO show all entries of the list in a dialog box
176         // at the moment always the first entry will be opened
177         if (locationsList.size() > 1) {
178           // determine all includes:
179           IncludesScanner includesScanner = new IncludesScanner(fProject, (IFileEditorInput) fEditor.getEditorInput());
180           includesScanner.addFile(f);
181           Set exactIncludeSet = includesScanner.getSet();
182
183           PHPIdentifierLocation includeName;
184           for (int i = 0; i < locationsList.size(); i++) {
185             includeName = (PHPIdentifierLocation) locationsList.get(i);
186             if (exactIncludeSet.contains(includeName.getFilename())) {
187               includeName.setMatch(PHPIdentifierLocation.EXACT_MATCH);
188             } else {
189               includeName.setMatch(PHPIdentifierLocation.UNDEFINED_MATCH);
190             }
191           }
192           Collections.sort(locationsList);
193
194           ListSelectionDialog listSelectionDialog = new ListSelectionDialog(PHPeclipsePlugin.getDefault().getWorkbench()
195               .getActiveWorkbenchWindow().getShell(), locationsList, new ListContentProvider(), new LabelProvider(),
196               "Select the resources to open.");
197           listSelectionDialog.setTitle("Multiple declarations found");
198           if (listSelectionDialog.open() == Window.OK) {
199             Object[] locations = listSelectionDialog.getResult();
200             if (locations != null) {
201               try {
202                 for (int i = 0; i < locations.length; i++) {
203                   PHPIdentifierLocation location = (PHPIdentifierLocation) locations[i];
204                   String filename = workspaceLocation + location.getFilename();
205                   //                                    System.out.println(filename);
206                   if (location.getOffset() >= 0) {
207                     PHPeclipsePlugin.getDefault().openFileAndGotoOffset(filename, location.getOffset(), identiifer.length());
208                   } else {
209                     PHPeclipsePlugin.getDefault().openFileAndFindString(filename, identiifer);
210                   }
211                 }
212               } catch (CoreException e) {
213                 // TODO Auto-generated catch block
214                 e.printStackTrace();
215               }
216             }
217           }
218         } else {
219           try {
220             PHPIdentifierLocation location = (PHPIdentifierLocation) locationsList.get(0);
221             String filename = workspaceLocation + location.getFilename();
222             //                                  System.out.println(filename);
223             if (location.getOffset() >= 0) {
224               PHPeclipsePlugin.getDefault().openFileAndGotoOffset(filename, location.getOffset(), identiifer.length());
225             } else {
226               PHPeclipsePlugin.getDefault().openFileAndFindString(filename, identiifer);
227             }
228           } catch (CoreException e) {
229             // TODO Auto-generated catch block
230             e.printStackTrace();
231           }
232         }
233       }
234     }
235   }
236
237   public void setActiveEditor(IAction action, IEditorPart targetEditor) {
238     if (targetEditor != null && (targetEditor instanceof PHPEditor)) {
239       fEditor = (PHPEditor) targetEditor;
240     }
241   }
242
243   private String getIdentifierOrInclude(IDocument doc, int pos) {
244     //    private String getPHPIncludeText(IDocument doc, int pos) {
245     Point word = null;
246     int start = -1;
247     int end = -1;
248     isIncludeString = false;
249     try {
250       //    try to find an include string
251       int position = pos;
252       char character = ' ';
253
254       while (position >= 0) {
255         character = doc.getChar(position);
256         if ((character == '\"') || (character == '\'') || (character == '\r') || (character == '\n'))
257           break;
258         --position;
259       }
260       if ((character == '\"') || (character == '\'')) {
261         start = position;
262
263         position = pos;
264         int length = doc.getLength();
265         character = ' ';
266         while (position < length) {
267           character = doc.getChar(position);
268           if ((character == '\"') || (character == '\'') || (character == '\r') || (character == '\n'))
269             break;
270           ++position;
271         }
272         if ((character == '\"') || (character == '\'')) {
273           start++;
274           end = position;
275
276           if (end > start) {
277             word = new Point(start, end - start); // include name found
278             isIncludeString = true;
279           }
280         }
281       }
282
283       // try to find an identifier
284       if (word == null) {
285         word = PHPWordExtractor.findWord(doc, pos); // identifier found
286         isIncludeString = false;
287       }
288     } catch (BadLocationException x) {
289     }
290
291     if (word != null) {
292       try {
293         return doc.get(word.x, word.y);
294       } catch (BadLocationException e) {
295       }
296     }
297     return "";
298   }
299
300   //    
301   //    
302   //    Point word = PHPWordExtractor.findWord(doc, pos);
303   //    if (word != null) {
304   //      try {
305   //        return doc.get(word.x, word.y);
306   //      } catch (BadLocationException e) {
307   //      }
308   //    }
309   //    return "";
310   //  }
311   private IContainer getWorkingLocation(IFileEditorInput editorInput) {
312     if (editorInput == null || editorInput.getFile() == null) {
313       return null;
314     }
315     return editorInput.getFile().getParent();
316   }
317
318   //  private IFile getIncludeFile(IProject project, IFileEditorInput editorInput, String relativeFilename) {
319   //    IContainer container = getWorkingLocation(editorInput);
320   //    String fullPath = project.getLocation().toString();
321   //    IFile file = null;
322   //    if (relativeFilename.startsWith("../")) {
323   //      Path path = new Path(relativeFilename);
324   //      file = container.getFile(path);
325   //      return file;
326   //    }
327   //    int index = relativeFilename.lastIndexOf('/');
328   //
329   //    if (index >= 0) {
330   //      Path path = new Path(relativeFilename);
331   //      file = project.getFile(path);
332   //      if (file.exists()) {
333   //        return file;
334   //      }
335   //    }
336   //
337   //    Path path = new Path(relativeFilename);
338   //    file = container.getFile(path);
339   //
340   //    return file;
341   //  }
342 }