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