041a5d582931f07804516626d541fc0c54fbea76
[phpeclipse.git] /
1 package net.sourceforge.phpdt.internal.debug.ui.launcher;
2
3 import java.util.ArrayList;
4 import java.util.Iterator;
5 import java.util.List;
6 import java.util.HashMap;
7 import java.util.Map;
8
9 import net.sourceforge.phpdt.internal.debug.ui.PHPDebugUiMessages;
10 import net.sourceforge.phpdt.internal.debug.ui.PHPDebugUiPlugin;
11 import net.sourceforge.phpdt.internal.debug.ui.preferences.EditInterpreterDialog;
12 import net.sourceforge.phpdt.internal.launching.PHPInterpreter;
13 import net.sourceforge.phpdt.internal.launching.PHPLaunchConfigurationAttribute;
14 import net.sourceforge.phpdt.internal.launching.PHPRuntime;
15 import net.sourceforge.phpdt.internal.ui.PHPUiImages;
16 import net.sourceforge.phpeclipse.LoadPathEntry;
17 import net.sourceforge.phpeclipse.PHPCore;
18 import net.sourceforge.phpeclipse.resourcesview.PHPProject;
19
20 import org.eclipse.core.runtime.CoreException;
21 import org.eclipse.debug.core.ILaunchConfiguration;
22 import org.eclipse.debug.core.ILaunchConfigurationWorkingCopy;
23 import org.eclipse.debug.ui.AbstractLaunchConfigurationTab;
24 import org.eclipse.jface.viewers.ListViewer;
25 import org.eclipse.jface.viewers.TableLayout;
26 import org.eclipse.jface.viewers.ColumnWeightData;
27 import org.eclipse.swt.SWT;
28 import org.eclipse.swt.events.ModifyEvent;
29 import org.eclipse.swt.events.ModifyListener;
30 import org.eclipse.swt.events.SelectionAdapter;
31 import org.eclipse.swt.events.SelectionEvent;
32 import org.eclipse.swt.events.SelectionListener;
33 import org.eclipse.swt.graphics.Image;
34 import org.eclipse.swt.layout.GridData;
35 import org.eclipse.swt.layout.GridLayout;
36 import org.eclipse.swt.widgets.Button;
37 import org.eclipse.swt.widgets.Combo;
38 import org.eclipse.swt.widgets.Composite;
39 import org.eclipse.swt.widgets.Label;
40 import org.eclipse.swt.widgets.TabFolder;
41 import org.eclipse.swt.widgets.TabItem;
42 import org.eclipse.swt.widgets.Table;
43 import org.eclipse.swt.widgets.TableItem;
44 import org.eclipse.swt.widgets.Text;
45 import org.eclipse.swt.widgets.TableColumn;
46 import org.eclipse.ui.internal.dialogs.ListContentProvider;
47
48 public class PHPEnvironmentTab extends AbstractLaunchConfigurationTab {
49         protected ListViewer loadPathListViewer;
50         protected java.util.List installedInterpretersWorkingCopy;
51         protected Combo interpreterCombo;
52         protected Button loadPathDefaultButton;
53         protected Button fRemoteDebugCheckBox;
54         protected Button fFileMapRemoveButton;
55         protected Button fFileMapAddButton;
56         protected Button fFileMapEditButton;
57         protected Text fRemoteSourcePath;
58         protected Table fRemoteDebugFileMapTable;
59         protected TabFolder tabFolder;
60         
61         private class RemoteDebugTabListener extends SelectionAdapter implements ModifyListener {
62
63                 /* (non-Javadoc)
64                  * @see org.eclipse.swt.events.ModifyListener#modifyText(org.eclipse.swt.events.ModifyEvent)
65                  */
66                 public void modifyText(ModifyEvent e) {
67                         updateLaunchConfigurationDialog();
68                 }
69                 
70                 /* (non-Javadoc)
71                  * @see org.eclipse.swt.events.SelectionListener#widgetSelected(org.eclipse.swt.events.SelectionEvent)
72                  */
73                 public void widgetSelected(SelectionEvent e) {
74                         Object source= e.getSource();
75                         if (source == fRemoteDebugFileMapTable) {
76                                 setFileMapButtonsEnableState();
77                         } else if (source == fFileMapAddButton) {
78                                 handleFileMapAddButtonSelected();
79                         } else if (source == fFileMapEditButton) {
80                                 handleFileMapEditButtonSelected();
81                         } else if (source == fFileMapRemoveButton) {
82                                 handleFileMapRemoveButtonSelected();
83                         } else if (source == fRemoteDebugCheckBox) {
84                                 setRemoteTabEnableState();              
85                         } else {
86                                 updateLaunchConfigurationDialog();;
87                 }
88                         
89                 }
90
91         }
92         
93         private RemoteDebugTabListener fListener= new RemoteDebugTabListener();
94         
95         private static final boolean DEFAULT_REMOTE_DEBUG= false;
96         static String [] columnTitles   = { PHPDebugUiMessages.getString("LaunchConfigurationTab.PHPEnvironment.remoteDebugTab.FileMapTableTitle.local"),
97                                                                                                                                                 PHPDebugUiMessages.getString("LaunchConfigurationTab.PHPEnvironment.remoteDebugTab.FileMapTableTitle.remote")
98                                                                                                                                         };
99         public PHPEnvironmentTab() {
100                 super();
101         }
102
103         public void createControl(Composite parent) {
104                 Composite composite = createPageRoot(parent);
105
106                 tabFolder = new TabFolder(composite, SWT.NONE);
107                 GridData gridData = new GridData(GridData.FILL_BOTH);
108                 tabFolder.setLayoutData(gridData);
109
110                 addLoadPathTab(tabFolder);
111                 addInterpreterTab(tabFolder);
112                 addRemoteDebugTab(tabFolder);
113         }
114         
115         protected void addRemoteDebugTab(TabFolder tabFolder)
116         {
117                 Label label;
118                                 
119                 TabItem remoteDebugTab = new TabItem(tabFolder, SWT.NONE, 0);
120                 remoteDebugTab.setText(PHPDebugUiMessages.getString("LaunchConfigurationTab.PHPEnvironment.remoteDebugTab.label"));
121                 
122                 Composite comp = new Composite(tabFolder, SWT.NONE);
123                 comp.setLayout(new GridLayout());       
124                 remoteDebugTab.setControl(comp);                
125                 GridData gd;
126                 
127                 fRemoteDebugCheckBox = new Button(comp, SWT.CHECK);
128                 fRemoteDebugCheckBox.setText(PHPDebugUiMessages.getString("LaunchConfigurationTab.PHPEnvironment.remoteDebugTab.RemoteCheckBox.label"));
129                 fRemoteDebugCheckBox.setLayoutData(new GridData(GridData.HORIZONTAL_ALIGN_BEGINNING));
130                 fRemoteDebugCheckBox.addSelectionListener(fListener);
131                 
132                 label = new Label(comp, SWT.NONE);
133                 label.setText(PHPDebugUiMessages.getString("LaunchConfigurationTab.PHPEnvironment.remoteDebugTab.RemoteSourcePath.label"));
134                 fRemoteSourcePath = new Text(comp, SWT.BORDER | SWT.SINGLE);
135                 gd = new GridData(GridData.FILL_HORIZONTAL);
136                 fRemoteSourcePath.setLayoutData(gd);            
137                 fRemoteSourcePath.addModifyListener(fListener);
138                 
139                 createVerticalSpacer(comp,1);
140                 
141                 Composite fileMapComp = new Composite(comp, SWT.NONE);
142                 gd = new GridData(GridData.FILL_BOTH);
143                 fileMapComp.setLayoutData(gd);
144                 GridLayout parametersLayout = new GridLayout();
145                 parametersLayout.numColumns = 2;
146                 parametersLayout.marginHeight = 0;
147                 parametersLayout.marginWidth = 0;
148                 fileMapComp.setLayout(parametersLayout);
149
150                 
151                 Label fileMapLabel = new Label(fileMapComp, SWT.NONE);
152                 fileMapLabel.setText(PHPDebugUiMessages.getString("LaunchConfigurationTab.PHPEnvironment.remoteDebugTab.FileMap.label"));
153                 gd = new GridData();
154                 gd.horizontalSpan = 2;
155                 fileMapLabel.setLayoutData(gd);
156
157                 
158                 fRemoteDebugFileMapTable = new Table(fileMapComp, SWT.BORDER | SWT.MULTI);
159                 TableLayout tableLayout = new TableLayout();
160                 fRemoteDebugFileMapTable.setLayout(tableLayout);
161
162                 gd = new GridData(GridData.FILL_BOTH);
163                 fRemoteDebugFileMapTable.setLayoutData(gd);
164                 TableColumn column1 = new TableColumn(this.fRemoteDebugFileMapTable, SWT.NONE);
165                 column1.setText(PHPDebugUiMessages.getString("LaunchConfigurationTab.PHPEnvironment.remoteDebugTab.FileMap.Table.Title.local")); //$NON-NLS-1$
166                 TableColumn column2 = new TableColumn(this.fRemoteDebugFileMapTable, SWT.NONE);
167                 column2.setText(PHPDebugUiMessages.getString("LaunchConfigurationTab.PHPEnvironment.remoteDebugTab.FileMap.Table.Title.remote"));                //$NON-NLS-1$
168                 tableLayout.addColumnData(new ColumnWeightData(100));
169                 tableLayout.addColumnData(new ColumnWeightData(100));
170                 fRemoteDebugFileMapTable.setHeaderVisible(true);
171                 fRemoteDebugFileMapTable.setLinesVisible(true);
172                 fRemoteDebugFileMapTable.addSelectionListener(fListener);
173                 fRemoteDebugFileMapTable.setEnabled(false);             
174         
175                 Composite envButtonComp = new Composite(fileMapComp, SWT.NONE);
176                 GridLayout envButtonLayout = new GridLayout();
177                 envButtonLayout.marginHeight = 0;
178                 envButtonLayout.marginWidth = 0;
179                 envButtonComp.setLayout(envButtonLayout);
180                 gd = new GridData(GridData.VERTICAL_ALIGN_BEGINNING | GridData.HORIZONTAL_ALIGN_FILL);
181                 envButtonComp.setLayoutData(gd);
182
183                 
184                 fFileMapAddButton = createPushButton(envButtonComp ,PHPDebugUiMessages.getString("LaunchConfigurationTab.PHPEnvironment.remoteDebugTab.FileMap.Button.Add.label"), null); //$NON-NLS-1$
185                 fFileMapAddButton.addSelectionListener(fListener);
186                 fFileMapAddButton.setEnabled(false);
187                 
188                 fFileMapEditButton = createPushButton(envButtonComp,PHPDebugUiMessages.getString("LaunchConfigurationTab.PHPEnvironment.remoteDebugTab.FileMap.Button.Edit.label"), null); //$NON-NLS-1$
189                 fFileMapEditButton.addSelectionListener(fListener);
190                 fFileMapEditButton.setEnabled(false);
191                 
192                 fFileMapRemoveButton = createPushButton(envButtonComp,PHPDebugUiMessages.getString("LaunchConfigurationTab.PHPEnvironment.remoteDebugTab.FileMap.Button.Remove.label"), null); //$NON-NLS-1$
193                 fFileMapRemoveButton.addSelectionListener(fListener);
194                 fFileMapRemoveButton.setEnabled(false);
195         
196
197         }
198         
199         void handleFileMapAddButtonSelected()
200         {
201                 TableItem item = new TableItem (fRemoteDebugFileMapTable, SWT.NONE);
202                 updateLaunchConfigurationDialog();
203         }
204         
205         void handleFileMapRemoveButtonSelected()
206         {
207                 int idx=fRemoteDebugFileMapTable.getSelectionIndex();
208                 if (idx !=-1)
209                 fRemoteDebugFileMapTable.remove(idx);
210                 updateLaunchConfigurationDialog();
211         }
212         
213         void handleFileMapEditButtonSelected()
214         {
215         }
216
217
218         /**
219          * Set the enabled state of whole tab.
220          */
221         private void setRemoteTabEnableState() {
222                 boolean state=fRemoteDebugCheckBox.getSelection();
223                 fRemoteSourcePath.setEnabled(state);
224                 
225 //      TODO: (cperkonig)       not implemented yet             
226 //              fRemoteDebugFileMapTable.setEnabled(state);
227 //              if (!state)
228 //              {
229 //                      fFileMapEditButton.setEnabled(false);
230 //                      fFileMapRemoveButton.setEnabled(false);         
231 //                      fFileMapAddButton.setEnabled(false);
232 //              } else {
233 //                      setFileMapButtonsEnableState();
234 //              }
235
236                 updateLaunchConfigurationDialog();
237         }
238         
239         
240         /**
241          * Set the enabled state of the three environment variable-related buttons based on the
242          * selection in the FileMapTable widget.
243          */
244         private void setFileMapButtonsEnableState() {
245 //      just do nothing for now
246 //
247                 if(fRemoteDebugCheckBox.getSelection())
248                 {
249                         int selectCount = this.fRemoteDebugFileMapTable.getSelectionIndices().length;
250                         if (selectCount < 1) {
251                                 fFileMapEditButton.setEnabled(false);
252                                 fFileMapRemoveButton.setEnabled(false);
253                         } else {
254                                 fFileMapRemoveButton.setEnabled(true);
255                                 if (selectCount == 1) {
256                                         fFileMapEditButton.setEnabled(true);
257                                 } else {
258                                         fFileMapEditButton.setEnabled(false);
259                                 }
260                         }               
261                         fFileMapAddButton.setEnabled(true);
262                 }
263         }
264         
265         
266
267         protected void addLoadPathTab(TabFolder tabFolder) {
268                 Composite loadPathComposite = new Composite(tabFolder, SWT.NONE);
269                 loadPathComposite.setLayout(new GridLayout());
270
271                 loadPathListViewer = new ListViewer(loadPathComposite, SWT.BORDER | SWT.MULTI | SWT.V_SCROLL | SWT.H_SCROLL);
272                 loadPathListViewer.setContentProvider(new ListContentProvider());
273                 loadPathListViewer.setLabelProvider(new LoadPathEntryLabelProvider());
274                 loadPathListViewer.getList().setLayoutData(new GridData(GridData.FILL_BOTH));
275
276                 TabItem loadPathTab = new TabItem(tabFolder, SWT.NONE, 0);
277                 loadPathTab.setText(PHPDebugUiMessages.getString("LaunchConfigurationTab.PHPEnvironment.loadPathTab.label"));
278                 loadPathTab.setControl(loadPathComposite);
279                 loadPathTab.setData(loadPathListViewer);
280
281                 loadPathDefaultButton = new Button(loadPathComposite, SWT.CHECK);
282                 loadPathDefaultButton.setText(PHPDebugUiMessages.getString("LaunchConfigurationTab.PHPEnvironment.loadPathDefaultButton.label"));
283                 loadPathDefaultButton.setLayoutData(new GridData(GridData.HORIZONTAL_ALIGN_BEGINNING));
284                 loadPathDefaultButton.addSelectionListener(getLoadPathDefaultButtonSelectionListener());
285                 
286                 loadPathDefaultButton.setEnabled(false); //for now, until the load path is customizable on the configuration
287         }
288
289         protected SelectionListener getLoadPathSelectionListener() {
290                 return new SelectionAdapter() {
291                         public void widgetSelected(SelectionEvent e) {
292                                 System.out.println("Loadpath list selection occurred: " + e.getSource());
293                         }
294                 };
295         }
296         
297         
298
299         protected SelectionListener getLoadPathDefaultButtonSelectionListener() {
300                 return new SelectionAdapter() {
301                         public void widgetSelected(SelectionEvent e) {
302                                 setUseLoadPathDefaults(((Button) e.getSource()).getSelection());
303                         }
304                 };
305         }
306
307         protected void addInterpreterTab(TabFolder tabFolder) {
308                 Composite interpreterComposite = new Composite(tabFolder, SWT.NONE);
309                 GridLayout layout = new GridLayout();
310                 layout.numColumns = 2;
311                 layout.marginHeight = 0;
312                 layout.marginWidth = 0;
313                 interpreterComposite.setLayout(layout);
314                 interpreterComposite.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
315
316                 createVerticalSpacer(interpreterComposite, 2);
317
318                 interpreterCombo = new Combo(interpreterComposite, SWT.READ_ONLY);
319                 interpreterCombo.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
320                 initializeInterpreterCombo(interpreterCombo);
321                 interpreterCombo.addModifyListener(getInterpreterComboModifyListener());
322
323                 Button interpreterAddButton = new Button(interpreterComposite, SWT.PUSH);
324                 interpreterAddButton.setText(PHPDebugUiMessages.getString("LaunchConfigurationTab.PHPEnvironment.interpreterAddButton.label"));
325                 interpreterAddButton.addSelectionListener(new SelectionAdapter() {
326                         public void widgetSelected(SelectionEvent evt) {
327                                 PHPInterpreter newInterpreter = new PHPInterpreter(null, null);
328                                 EditInterpreterDialog editor = new EditInterpreterDialog(getShell(), PHPDebugUiMessages.getString("LaunchConfigurationTab.PHPEnvironment.editInterpreterDialog.title"));
329                                 editor.create();
330                                 editor.setInterpreterToEdit(newInterpreter);
331                                 if (EditInterpreterDialog.OK == editor.open()) {
332                                         PHPRuntime.getDefault().addInstalledInterpreter(newInterpreter);
333                                         interpreterCombo.add(newInterpreter.getName());
334                                         interpreterCombo.select(interpreterCombo.indexOf(newInterpreter.getName()));
335                                 }
336                         }
337                 });
338
339                 TabItem interpreterTab = new TabItem(tabFolder, SWT.NONE);
340                 interpreterTab.setText(PHPDebugUiMessages.getString("LaunchConfigurationTab.PHPEnvironment.interpreterTab.label"));
341                 interpreterTab.setControl(interpreterComposite);
342         }
343
344         protected ModifyListener getInterpreterComboModifyListener() {
345                 return new ModifyListener() {
346                         public void modifyText(ModifyEvent evt) {
347                                 updateLaunchConfigurationDialog();
348                         }
349                 };
350         }
351
352         protected void createVerticalSpacer(Composite comp, int colSpan) {
353                 Label label = new Label(comp, SWT.NONE);
354                 GridData gd = new GridData();
355                 gd.horizontalSpan = colSpan;
356                 label.setLayoutData(gd);
357         }
358
359         public void setDefaults(ILaunchConfigurationWorkingCopy configuration) {
360         }
361
362         public void initializeFrom(ILaunchConfiguration configuration) {
363                 initializeLoadPath(configuration);
364                 initializeInterpreterSelection(configuration);
365                 initializeRemoteDebug(configuration);
366         }
367         
368         protected void initializeRemoteDebug(ILaunchConfiguration configuration)
369         {
370                 String s[];
371                 int startIdx =0;
372                 int idx;
373                 try{
374                         fRemoteDebugCheckBox.setSelection(
375                                 configuration.getAttribute(PHPLaunchConfigurationAttribute.REMOTE_DEBUG,DEFAULT_REMOTE_DEBUG));
376                 } catch(CoreException ce) {
377                         fRemoteDebugCheckBox.setSelection(DEFAULT_REMOTE_DEBUG);
378                 }
379                 setRemoteTabEnableState();
380                 try{
381                         fRemoteSourcePath.setText(
382                                         configuration.getAttribute(PHPLaunchConfigurationAttribute.REMOTE_PATH,""));
383                 } catch(CoreException ce) {
384                         fRemoteSourcePath.setText("");
385                 }
386                         
387                 updateFileMapFromConfig(configuration);
388                  
389         }
390         
391         private void updateFileMapFromConfig(ILaunchConfiguration config) {
392                         Map envVars = null;
393                         try {
394                                 if (config != null) {
395                                         envVars = config.getAttribute(PHPLaunchConfigurationAttribute.FILE_MAP, (Map)null);
396                                 }
397                                 updateFileMapTable(envVars, this.fRemoteDebugFileMapTable);
398                                 setFileMapButtonsEnableState();
399                         } catch (CoreException ce) {
400                                 log(ce);
401                         }
402                 }
403
404                 private void updateFileMapTable(Map map, Table tableWidget) {
405                         tableWidget.removeAll();
406                         if (map == null) {
407                                 return;
408                         }
409                         Iterator iterator = map.keySet().iterator();
410                         while (iterator.hasNext()) {
411                                 String key = (String) iterator.next();
412                                 String value = (String) map.get(key);
413                                 TableItem tableItem = new TableItem(tableWidget, SWT.NONE);
414                                 tableItem.setText(new String[] {key, value});                   
415                         }
416                 }
417
418         protected void initializeLoadPath(ILaunchConfiguration configuration) {
419                 boolean useDefaultLoadPath = true;
420                 try {
421                         useDefaultLoadPath = configuration.getAttribute(PHPLaunchConfigurationAttribute.USE_DEFAULT_LOAD_PATH, true);
422                         setUseLoadPathDefaults(useDefaultLoadPath);
423                         if (useDefaultLoadPath) {
424                                 String projectName = configuration.getAttribute(PHPLaunchConfigurationAttribute.PROJECT_NAME, "");
425                                 if (projectName != "") {
426                                         PHPProject project = PHPCore.getPHPProject(projectName);
427                                         if (project != null) {
428                                                 List loadPathEntries = project.getLoadPathEntries();
429                                                 loadPathListViewer.setInput(loadPathEntries);
430                                         }
431                                 }
432                         }
433                 } catch (CoreException e) {
434                         log(e);
435                 }
436         }
437
438         protected void setUseLoadPathDefaults(boolean useDefaults) {
439                 loadPathListViewer.getList().setEnabled(!useDefaults);
440                 loadPathDefaultButton.setSelection(useDefaults);
441         }
442
443         protected void initializeInterpreterSelection(ILaunchConfiguration configuration) {
444                 String interpreterName = null;
445                 try {
446                         interpreterName = configuration.getAttribute(PHPLaunchConfigurationAttribute.SELECTED_INTERPRETER, "");
447                 } catch (CoreException e) {
448                         log(e);
449                 }
450                 if (interpreterName != null && !interpreterName.equals(""))
451                         interpreterCombo.select(interpreterCombo.indexOf(interpreterName));
452         }
453
454         protected void initializeInterpreterCombo(Combo interpreterCombo) {
455                 installedInterpretersWorkingCopy = new ArrayList();
456                 installedInterpretersWorkingCopy.addAll(PHPRuntime.getDefault().getInstalledInterpreters());
457
458                 String[] interpreterNames = new String[installedInterpretersWorkingCopy.size()];
459                 for (int interpreterIndex = 0; interpreterIndex < installedInterpretersWorkingCopy.size(); interpreterIndex++) {
460                         PHPInterpreter interpreter = (PHPInterpreter) installedInterpretersWorkingCopy.get(interpreterIndex);
461                         interpreterNames[interpreterIndex] = interpreter.getName();
462                 }
463                 interpreterCombo.setItems(interpreterNames);
464
465                 PHPInterpreter selectedInterpreter = PHPRuntime.getDefault().getSelectedInterpreter();
466                 if (selectedInterpreter != null)
467                         interpreterCombo.select(interpreterCombo.indexOf(selectedInterpreter.getName()));
468         }
469
470         public void performApply(ILaunchConfigurationWorkingCopy configuration) {
471                 int selectionIndex = interpreterCombo.getSelectionIndex();
472                 if (selectionIndex >= 0)
473                         configuration.setAttribute(PHPLaunchConfigurationAttribute.SELECTED_INTERPRETER, interpreterCombo.getItem(selectionIndex));
474
475                 configuration.setAttribute(PHPLaunchConfigurationAttribute.USE_DEFAULT_LOAD_PATH, loadPathDefaultButton.getSelection());
476
477                 if (!loadPathDefaultButton.getSelection()) {
478                         List loadPathEntries = (List) loadPathListViewer.getInput();
479                         List loadPathStrings = new ArrayList();
480                         for (Iterator iterator = loadPathEntries.iterator(); iterator.hasNext();) {
481                                 LoadPathEntry entry = (LoadPathEntry) iterator.next();
482                                 loadPathStrings.add(entry.getPath().toString());
483                         }
484                         configuration.setAttribute(PHPLaunchConfigurationAttribute.CUSTOM_LOAD_PATH, loadPathStrings);
485                 }
486                 
487                 configuration.setAttribute(PHPLaunchConfigurationAttribute.REMOTE_DEBUG, fRemoteDebugCheckBox.getSelection());
488                 configuration.setAttribute(PHPLaunchConfigurationAttribute.FILE_MAP, getMapFromFileMapTable());         
489                 configuration.setAttribute(PHPLaunchConfigurationAttribute.REMOTE_PATH, fRemoteSourcePath.getText());
490         }
491
492         protected Composite createPageRoot(Composite parent) {
493                 Composite composite = new Composite(parent, SWT.NULL);
494                 GridLayout layout = new GridLayout();
495                 layout.numColumns = 2;
496                 composite.setLayout(layout);
497                 createVerticalSpacer(composite, 2);
498                 setControl(composite);
499
500                 return composite;
501         }
502         
503         private Map getMapFromFileMapTable() {
504                 TableItem[] items = fRemoteDebugFileMapTable.getItems();
505                 if (items.length == 0) {
506                         return null;
507                 }
508                 Map map = new HashMap(items.length);
509                 for (int i = 0; i < items.length; i++) {
510                         TableItem item = items[i];
511                         String key = item.getText(0);
512                         String value = item.getText(1);
513                         map.put(key, value);
514                 }               
515                 return map;
516         }
517
518         public String getName() {
519                 return PHPDebugUiMessages.getString("LaunchConfigurationTab.PHPEnvironment.name");
520         }
521
522         public boolean isValid(ILaunchConfiguration launchConfig) {
523                 try {
524                         String selectedInterpreter = launchConfig.getAttribute(PHPLaunchConfigurationAttribute.SELECTED_INTERPRETER, "");
525                         if (selectedInterpreter.length() == 0) {
526                                 setErrorMessage(PHPDebugUiMessages.getString("LaunchConfigurationTab.PHPEnvironment.interpreter_not_selected_error_message"));
527                                 return false;
528                         }
529                 } catch (CoreException e) {
530                         log(e);
531                 }
532                 
533                 setErrorMessage(null);
534                 return true;
535         }
536         
537         protected void log(Throwable t) {
538                 PHPDebugUiPlugin.log(t);
539         }
540
541         public Image getImage() {
542                 return PHPUiImages.get(PHPUiImages.IMG_CTOOLS_PHP);
543         }
544
545 }