first veron of external tools
[phpeclipse.git] / net.sourceforge.phpeclipse / src / net / sourceforge / phpeclipse / views / PHPConsole.java
1 package net.sourceforge.phpeclipse.views;
2
3 /**********************************************************************
4 Copyright (c) 2000, 2002 IBM Corp. and others.
5 All rights reserved. This program and the accompanying materials
6 are made available under the terms of the Common Public License v1.0
7 which accompanies this distribution, and is available at
8 http://www.eclipse.org/legal/cpl-v10.html
9
10 Contributors:
11     IBM Corporation - Initial implementation
12     Klaus Hartlage - www.eclipseproject.de
13 **********************************************************************/
14
15 import java.io.File;
16 import java.io.IOException;
17 import java.io.InputStream;
18 import java.io.StreamTokenizer;
19 import java.io.StringReader;
20 import java.util.ArrayList;
21
22 import net.sourceforge.phpdt.internal.ui.PHPUiImages;
23 import net.sourceforge.phpeclipse.PHPeclipsePlugin;
24 import net.sourceforge.phpeclipse.actions.PHPActionMessages;
25
26 import org.eclipse.core.resources.IFile;
27 import org.eclipse.core.runtime.IStatus;
28 import org.eclipse.core.runtime.Status;
29 import org.eclipse.jface.action.Action;
30 import org.eclipse.jface.action.IMenuListener;
31 import org.eclipse.jface.action.IMenuManager;
32 import org.eclipse.jface.action.IToolBarManager;
33 import org.eclipse.jface.action.MenuManager;
34 import org.eclipse.jface.action.Separator;
35 import org.eclipse.jface.preference.IPreferenceStore;
36 import org.eclipse.jface.resource.JFaceResources;
37 import org.eclipse.jface.text.BadLocationException;
38 import org.eclipse.jface.text.Document;
39 import org.eclipse.jface.text.TextViewer;
40 import org.eclipse.swt.SWT;
41 import org.eclipse.swt.custom.StyledText;
42 import org.eclipse.swt.events.ModifyEvent;
43 import org.eclipse.swt.events.ModifyListener;
44 import org.eclipse.swt.events.SelectionEvent;
45 import org.eclipse.swt.events.SelectionListener;
46 import org.eclipse.swt.layout.GridData;
47 import org.eclipse.swt.layout.GridLayout;
48 import org.eclipse.swt.widgets.Combo;
49 import org.eclipse.swt.widgets.Composite;
50 import org.eclipse.swt.widgets.Label;
51 import org.eclipse.swt.widgets.Menu;
52 import org.eclipse.ui.IActionBars;
53 import org.eclipse.ui.IEditorInput;
54 import org.eclipse.ui.IFileEditorInput;
55 import org.eclipse.ui.IWorkbenchActionConstants;
56 import org.eclipse.ui.IWorkbenchPage;
57 import org.eclipse.ui.PartInitException;
58 import org.eclipse.ui.PlatformUI;
59 import org.eclipse.ui.part.ViewPart;
60 import org.eclipse.ui.texteditor.ITextEditor;
61
62 /**
63  * The PHPConsole is used to display the output if you start MySQL/Apache
64  * @see ViewPart
65  */
66 public class PHPConsole extends ViewPart {
67
68   public static final String CONSOLE_ID = "net.sourceforge.phpeclipse.views.phpconsoleview";
69   private int COMMAND_COMBO_SIZE = 10;
70
71   private TextViewer fViewer = null;
72   private Document fDocument = null;
73   private StyledText fStyledText;
74   private Combo fCommandCombo;
75   // private Action goAction;
76
77   private Action cutAction = new Action() {
78     public void run() {
79       fViewer.getTextWidget().cut();
80     }
81   };
82   private Action copyAction = new Action() {
83     public void run() {
84       fStyledText.copy();
85     }
86   };
87   //  private Action pasteAction = new Action() {
88   //    public void run() {
89   //      fViewer.getTextWidget().paste();
90   //    }
91   //  };
92   private Action selectAllAction = new Action() {
93     public void run() {
94       fStyledText.selectAll();
95     }
96   };
97   private Action clearAction = new Action() {
98     public void run() {
99       fStyledText.setText("");
100     }
101   };
102   /**
103    * The constructor.
104    */
105   public PHPConsole() {
106   }
107
108   /**
109    * Insert the method's description here.
110    * @see ViewPart#createPartControl
111    */
112   public void createPartControl(Composite parent) {
113     Composite container = new Composite(parent, SWT.NULL);
114     //   control = container;
115     GridLayout layout = new GridLayout();
116     layout.marginWidth = 0;
117     layout.marginHeight = 0;
118     layout.verticalSpacing = 0;
119     container.setLayout(layout);
120     Composite navContainer = new Composite(container, SWT.NONE);
121     layout = new GridLayout();
122     layout.numColumns = 2;
123     layout.marginHeight = 1;
124     navContainer.setLayout(layout);
125     createCommandBar(navContainer);
126     navContainer.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
127
128     fViewer = new TextViewer(container, SWT.WRAP | SWT.V_SCROLL | SWT.H_SCROLL);
129     GridData viewerData = new GridData(GridData.FILL_BOTH);
130     fViewer.getControl().setLayoutData(viewerData);
131     fViewer.setEditable(false);
132
133     fStyledText = fViewer.getTextWidget();
134     fStyledText.setFont(JFaceResources.getFontRegistry().get(JFaceResources.TEXT_FONT));
135
136     cutAction.setText("Cut");
137     copyAction.setText("Copy");
138     //   pasteAction.setText("Paste");
139     selectAllAction.setText("Select All");
140     clearAction.setText("Clear PHP Console");
141     clearAction.setImageDescriptor(PHPUiImages.DESC_CLEAR);
142     clearAction.setToolTipText("Clear PHP Console");
143
144     IActionBars bars = this.getViewSite().getActionBars();
145     bars.setGlobalActionHandler(IWorkbenchActionConstants.CUT, cutAction);
146     bars.setGlobalActionHandler(IWorkbenchActionConstants.COPY, copyAction);
147     //  bars.setGlobalActionHandler(IWorkbenchActionConstants.PASTE, pasteAction);
148
149     hookContextMenu();
150     //  hookDoubleClickAction();
151     contributeToActionBars();
152
153     appendOutputText("This is the PHP console.\n");
154     appendOutputText("Type: \"php $f\" to run the current editor file.\n");
155
156   }
157
158   private void createCommandBar(Composite parent) {
159     Label addressLabel = new Label(parent, SWT.NONE);
160     addressLabel.setText("Command:");
161
162     fCommandCombo = new Combo(parent, SWT.DROP_DOWN | SWT.BORDER);
163     fCommandCombo.addModifyListener(new ModifyListener() {
164       public void modifyText(ModifyEvent e) {
165         String text = fCommandCombo.getText();
166         //       goAction.setEnabled(text.length() > 0);
167       }
168     });
169     fCommandCombo.addSelectionListener(new SelectionListener() {
170       public void widgetSelected(SelectionEvent e) {
171         String text = fCommandCombo.getItem(fCommandCombo.getSelectionIndex());
172         if (text.length() > 0) {
173           fCommandCombo.setText(text);
174           //    executeCommand(text);
175         }
176       }
177       public void widgetDefaultSelected(SelectionEvent e) {
178         executeCommand(fCommandCombo.getText());
179       }
180     });
181     GridData gd = new GridData(GridData.FILL_HORIZONTAL);
182     fCommandCombo.setLayoutData(gd);
183     //    ToolBar toolbar = new ToolBar(parent, SWT.FLAT | SWT.HORIZONTAL);
184     //    toolBarManager = new ToolBarManager(toolbar);
185     //    makeActions();
186     //    IToolBarManager localBar =
187     //      getViewSite().getActionBars().getToolBarManager();
188     //    localBar.add(backwardAction);
189     //    localBar.add(forwardAction);
190   }
191
192   private void executeCommand(String command) {
193     command.trim();
194     if (command.equals("")) {
195       fCommandCombo.forceFocus();
196       return;
197     }
198     execute(command);
199
200     fCommandCombo.forceFocus();
201     // add to Combo history
202     String[] items = fCommandCombo.getItems();
203     int loc = -1;
204     String normURL = command;
205     for (int i = 0; i < items.length; i++) {
206       String normItem = items[i];
207       if (normURL.equals(normItem)) {
208         // match 
209         loc = i;
210         break;
211       }
212     }
213     if (loc != -1) {
214       fCommandCombo.remove(loc);
215     }
216     fCommandCombo.add(command, 0);
217     if (fCommandCombo.getItemCount() > COMMAND_COMBO_SIZE) {
218       fCommandCombo.remove(fCommandCombo.getItemCount() - 1);
219     }
220     fCommandCombo.getParent().layout(true);
221   }
222
223   private void execute(String command) {
224     ArrayList args = new ArrayList();
225
226     command = command.replace('\\', '§');
227
228     StreamTokenizer tokenizer = new StreamTokenizer(new StringReader(command));
229     tokenizer.resetSyntax();
230
231     tokenizer.whitespaceChars(0, ' ');
232     tokenizer.wordChars('!', 255);
233
234     tokenizer.quoteChar('"');
235     tokenizer.quoteChar('\'');
236
237     int token;
238     try {
239       while ((token = tokenizer.nextToken()) != StreamTokenizer.TT_EOF) {
240         if (token == StreamTokenizer.TT_WORD) {
241           args.add(tokenizer.sval);
242         }
243       }
244     } catch (IOException e) {
245       // 
246     }
247     String arg = "";
248     // replace variables in arguments
249
250     IFile file = getFile();
251     if (file != null) {
252       String fileLocation = file.getLocation().toString();
253       for (int i = 0; i < args.size(); i++) {
254         arg = args.get(i).toString();
255         if (arg.equals("$f")) {
256           //current php editor file
257           if (File.separatorChar == '\\') {
258             fileLocation = fileLocation.replace('/', '\\');
259           }
260           args.set(i, fileLocation);
261         }
262       }
263     }
264
265     final IPreferenceStore store = PHPeclipsePlugin.getDefault().getPreferenceStore();
266
267     String arg0 = "";
268     String temp;
269     StringBuffer commandBuffer = new StringBuffer(1024);
270     //    Program.launch(command);
271     if (args.size() > 0) {
272       arg0 = (String) args.get(0);
273       arg0 = arg0.replace('§', '\\');
274       args.remove(0);
275       if (arg0.equals("php")) {
276         temp = store.getString(PHPeclipsePlugin.PHP_RUN_PREF);
277         if (temp != null) {
278           arg0 = temp;
279         }
280       }
281       commandBuffer.append(arg0 + " ");
282     }
283     String[] stringArgs = new String[args.size()];
284     for (int i = 0; i < args.size(); i++) {
285       arg = (String) args.get(i);
286       arg = arg.replace('§', '\\');
287       stringArgs[i] = arg;
288       commandBuffer.append(arg + " ");
289     }
290     commandBuffer.append("\n");
291
292     try {
293       command = commandBuffer.toString();
294       write(command);
295       Runtime runtime = Runtime.getRuntime();
296
297       // runs the command
298       Process process = runtime.exec(command);
299       
300       //process.waitFor();
301       InputStream in = process.getInputStream();
302       String output = getStringFromStream(in);
303       write(output);
304       in.close();
305 //    } catch (InterruptedException e) {
306 //      write(e.toString());
307     } catch (IOException e) {
308       write(e.toString());
309     }
310   }
311
312   private void hookContextMenu() {
313     MenuManager menuMgr = new MenuManager("#PopupMenu");
314     menuMgr.setRemoveAllWhenShown(true);
315     menuMgr.addMenuListener(new IMenuListener() {
316       public void menuAboutToShow(IMenuManager manager) {
317         PHPConsole.this.fillContextMenu(manager);
318       }
319     });
320     Menu menu = menuMgr.createContextMenu(fViewer.getControl());
321     fViewer.getControl().setMenu(menu);
322     getSite().registerContextMenu(menuMgr, fViewer);
323   }
324
325   private void contributeToActionBars() {
326     IActionBars bars = getViewSite().getActionBars();
327     fillLocalPullDown(bars.getMenuManager());
328     fillLocalToolBar(bars.getToolBarManager());
329   }
330
331   private void fillLocalPullDown(IMenuManager manager) {
332     manager.add(cutAction);
333     manager.add(copyAction);
334     //   manager.add(pasteAction);
335     manager.add(selectAllAction);
336   }
337
338   private void fillContextMenu(IMenuManager manager) {
339     manager.add(cutAction);
340     manager.add(copyAction);
341     //  manager.add(pasteAction);
342     manager.add(selectAllAction);
343     // Other plug-ins can contribute there actions here
344     manager.add(new Separator("Additions"));
345   }
346
347   private void fillLocalToolBar(IToolBarManager manager) {
348     manager.add(clearAction);
349   }
350   /**
351    * Insert the method's description here.
352    * @see ViewPart#setFocus
353    */
354   public void setFocus() {
355     fCommandCombo.forceFocus();
356   }
357
358   /**
359    * Set the text for the viewer
360    */
361   public void setOutputText(String text) {
362     fDocument = new Document(text);
363     fViewer.setDocument(fDocument);
364   }
365
366   public void appendOutputText(String text) {
367     try {
368       if (fDocument == null) {
369         fDocument = new Document(text);
370         fViewer.setDocument(fDocument);
371       } else {
372         fDocument.replace(fDocument.getLength(), 0, text);
373       }
374     } catch (BadLocationException e) {
375     }
376     //  viewer.setDocument(document);
377   }
378
379   public static PHPConsole getInstance() {
380     IWorkbenchPage page = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage();
381     PHPConsole console = (PHPConsole) page.findView(PHPConsole.CONSOLE_ID);
382
383     if (PHPeclipsePlugin.getDefault().getPreferenceStore().getBoolean(PHPeclipsePlugin.SHOW_OUTPUT_IN_CONSOLE) == true) {
384       try {
385         page.showView(PHPConsole.CONSOLE_ID);
386         if (console == null) {
387           console = (PHPConsole) page.findView(PHPConsole.CONSOLE_ID);
388         }
389       } catch (PartInitException e) {
390         PHPeclipsePlugin.getDefault().getLog().log(
391           new Status(
392             IStatus.ERROR,
393             PHPeclipsePlugin.getPluginId(),
394             0,
395             PHPActionMessages.getString("PHPStartApacheAction.consoleViewOpeningProblem"),
396             e));
397       }
398     }
399     return console;
400   }
401
402   /**
403    * Prints out the string represented by the string 
404    */
405   public synchronized void write(String output) {
406     appendOutputText(output);
407   }
408
409   /**
410    * Creates a string buffer from the given input stream
411    */
412   public static String getStringFromStream(InputStream stream) throws IOException {
413     StringBuffer buffer = new StringBuffer();
414     byte[] b = new byte[100];
415     int finished = 0;
416     while (finished != -1) {
417       finished = stream.read(b);
418       if (finished != -1) {
419         String current = new String(b, 0, finished);
420         buffer.append(current);
421       }
422     }
423     return buffer.toString();
424   }
425
426   /**
427    * Finds the file that's currently opened in the PHP Text Editor
428    */
429   protected IFile getFile() {
430     ITextEditor editor = PHPeclipsePlugin.getDefault().getTextEditor();
431
432     IEditorInput editorInput = null;
433     if (editor != null) {
434       editorInput = editor.getEditorInput();
435     }
436
437     if (editorInput instanceof IFileEditorInput)
438       return ((IFileEditorInput) editorInput).getFile();
439
440     // if nothing was found, which should never happen
441     return null;
442   }
443 }