KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > eclipse > pde > internal > ui > editor > cheatsheet > comp > details > CompCSTaskDetails


1 /*******************************************************************************
2  * Copyright (c) 2006, 2007 IBM Corporation and others.
3  * All rights reserved. This program and the accompanying materials
4  * are made available under the terms of the Eclipse Public License v1.0
5  * which accompanies this distribution, and is available at
6  * http://www.eclipse.org/legal/epl-v10.html
7  *
8  * Contributors:
9  * IBM Corporation - initial API and implementation
10  *******************************************************************************/

11
12 package org.eclipse.pde.internal.ui.editor.cheatsheet.comp.details;
13
14 import java.util.StringTokenizer JavaDoc;
15
16 import org.eclipse.core.resources.IFile;
17 import org.eclipse.core.resources.IResource;
18 import org.eclipse.core.resources.IWorkspaceRoot;
19 import org.eclipse.core.runtime.Path;
20 import org.eclipse.jface.viewers.ISelection;
21 import org.eclipse.jface.viewers.StructuredSelection;
22 import org.eclipse.jface.window.Window;
23 import org.eclipse.jface.wizard.IWizardPage;
24 import org.eclipse.jface.wizard.WizardDialog;
25 import org.eclipse.pde.internal.core.icheatsheet.comp.ICompCSConstants;
26 import org.eclipse.pde.internal.core.icheatsheet.comp.ICompCSModelFactory;
27 import org.eclipse.pde.internal.core.icheatsheet.comp.ICompCSParam;
28 import org.eclipse.pde.internal.core.icheatsheet.comp.ICompCSTask;
29 import org.eclipse.pde.internal.ui.PDEPlugin;
30 import org.eclipse.pde.internal.ui.PDEUIMessages;
31 import org.eclipse.pde.internal.ui.editor.FormEntryAdapter;
32 import org.eclipse.pde.internal.ui.editor.cheatsheet.CSAbstractDetails;
33 import org.eclipse.pde.internal.ui.editor.cheatsheet.ICSMaster;
34 import org.eclipse.pde.internal.ui.editor.cheatsheet.comp.CompCSFileValidator;
35 import org.eclipse.pde.internal.ui.editor.cheatsheet.comp.CompCSInputContext;
36 import org.eclipse.pde.internal.ui.parts.FormEntry;
37 import org.eclipse.pde.internal.ui.util.FileExtensionFilter;
38 import org.eclipse.pde.internal.ui.wizards.cheatsheet.NewSimpleCSFileWizard;
39 import org.eclipse.pde.internal.ui.wizards.cheatsheet.SimpleCSFileWizardPage;
40 import org.eclipse.swt.SWT;
41 import org.eclipse.swt.events.SelectionAdapter;
42 import org.eclipse.swt.events.SelectionEvent;
43 import org.eclipse.swt.graphics.Color;
44 import org.eclipse.swt.layout.GridData;
45 import org.eclipse.swt.widgets.Button;
46 import org.eclipse.swt.widgets.Composite;
47 import org.eclipse.ui.PartInitException;
48 import org.eclipse.ui.PlatformUI;
49 import org.eclipse.ui.dialogs.ElementTreeSelectionDialog;
50 import org.eclipse.ui.forms.IFormColors;
51 import org.eclipse.ui.forms.IFormPart;
52 import org.eclipse.ui.forms.IManagedForm;
53 import org.eclipse.ui.forms.events.HyperlinkEvent;
54 import org.eclipse.ui.forms.widgets.ExpandableComposite;
55 import org.eclipse.ui.forms.widgets.Section;
56 import org.eclipse.ui.ide.IDE;
57 import org.eclipse.ui.model.WorkbenchContentProvider;
58 import org.eclipse.ui.model.WorkbenchLabelProvider;
59
60 /**
61  * CompCSTaskDetails
62  *
63  */

64 public class CompCSTaskDetails extends CSAbstractDetails {
65
66     private Section fDefinitionSection;
67     
68     private FormEntry fNameEntry;
69
70     private FormEntry fPathEntry;
71     
72     private Button fSkip;
73     
74     private ICompCSTask fDataTask;
75     
76     private CompCSEnclosingTextDetails fEnclosingTextSection;
77     
78     private final static String JavaDoc F_PATH_SEPARATOR = "/"; //$NON-NLS-1$
79

80     private final static String JavaDoc F_DOT_DOT = ".."; //$NON-NLS-1$
81

82     /**
83      * @param section
84      */

85     public CompCSTaskDetails(ICSMaster section) {
86         super(section, CompCSInputContext.CONTEXT_ID);
87         fDataTask = null;
88
89         fNameEntry = null;
90         fPathEntry = null;
91         fSkip = null;
92
93         fDefinitionSection = null;
94         fEnclosingTextSection =
95             new CompCSEnclosingTextDetails(ICompCSConstants.TYPE_TASK, section);
96     }
97     
98     /**
99      * @param object
100      */

101     public void setData(ICompCSTask object) {
102         // Set data
103
fDataTask = object;
104         // Set data on the enclosing text section
105
fEnclosingTextSection.setData(object);
106     }
107     
108     /* (non-Javadoc)
109      * @see org.eclipse.ui.forms.AbstractFormPart#initialize(org.eclipse.ui.forms.IManagedForm)
110      */

111     public void initialize(IManagedForm form) {
112         super.initialize(form);
113         // Unfortunately this has to be explicitly called for sub detail
114
// sections through its main section parent; since, it never is
115
// registered directly.
116
// Initialize managed form for enclosing text section
117
fEnclosingTextSection.initialize(form);
118     }
119     
120     /* (non-Javadoc)
121      * @see org.eclipse.pde.internal.ui.editor.cheatsheet.CSAbstractDetails#createDetails(org.eclipse.swt.widgets.Composite)
122      */

123     public void createDetails(Composite parent) {
124
125         // Create the main section
126
int style = Section.DESCRIPTION | ExpandableComposite.TITLE_BAR;
127         fDefinitionSection = getPage().createUISection(parent, PDEUIMessages.SimpleCSDetails_3,
128             PDEUIMessages.CompCSTaskDetails_SectionDescription, style);
129         // Align the master and details section headers (misalignment caused
130
// by section toolbar icons)
131
getPage().alignSectionHeaders(getMasterSection().getSection(),
132                 fDefinitionSection);
133         // Create the container for the main section
134
Composite sectionClient = getPage().createUISectionContainer(fDefinitionSection, 3);
135         // Create the name entry
136
createUINameEntry(sectionClient);
137         // Create the kind combo
138
createUIPathEntry(sectionClient);
139         // Create the skip button
140
createUISkipButton(sectionClient);
141         // Create the enclosing text section
142
fEnclosingTextSection.createDetails(parent);
143         // Bind widgets
144
getManagedForm().getToolkit().paintBordersFor(sectionClient);
145         fDefinitionSection.setClient(sectionClient);
146         markDetailsPart(fDefinitionSection);
147     }
148
149     /**
150      * @param parent
151      */

152     private void createUINameEntry(Composite parent) {
153         fNameEntry = new FormEntry(parent, getManagedForm().getToolkit(),
154                 PDEUIMessages.CompCSTaskDetails_Name, SWT.NONE);
155     }
156
157     /**
158      * @param parent
159      */

160     private void createUIPathEntry(Composite parent) {
161         fPathEntry = new FormEntry(parent, getManagedForm().getToolkit(),
162                 PDEUIMessages.CompCSTaskDetails_Path, PDEUIMessages.GeneralInfoSection_browse, isEditable());
163     }
164     
165     /**
166      * @param parent
167      */

168     private void createUISkipButton(Composite parent) {
169         Color foreground = getToolkit().getColors().getColor(IFormColors.TITLE);
170         fSkip = getToolkit().createButton(parent, PDEUIMessages.CompCSTaskDetails_SkipLabel, SWT.CHECK);
171         GridData data = new GridData(GridData.FILL_HORIZONTAL);
172         data.horizontalSpan = 3;
173         fSkip.setLayoutData(data);
174         fSkip.setForeground(foreground);
175     }
176     
177     /* (non-Javadoc)
178      * @see org.eclipse.pde.internal.ui.editor.cheatsheet.CSAbstractDetails#hookListeners()
179      */

180     public void hookListeners() {
181         // Create listeners for the name entry
182
createListenersNameEntry();
183         // Create listeners for the path entry
184
createListenersPathEntry();
185         // Create listeners for the skip button
186
createListenersSkipButton();
187         // Create listeners within the enclosing text section
188
fEnclosingTextSection.hookListeners();
189     }
190
191     /**
192      *
193      */

194     private void createListenersNameEntry() {
195         fNameEntry.setFormEntryListener(new FormEntryAdapter(this) {
196             public void textValueChanged(FormEntry entry) {
197                 // Ensure data object is defined
198
if (fDataTask == null) {
199                     return;
200                 }
201                 fDataTask.setFieldName(fNameEntry.getValue());
202             }
203         });
204     }
205
206     /**
207      *
208      */

209     private void createListenersPathEntry() {
210         fPathEntry.setFormEntryListener(new FormEntryAdapter(this) {
211             public void browseButtonSelected(FormEntry entry) {
212                 // Ensure data object is defined
213
if (fDataTask == null) {
214                     return;
215                 }
216                 handleButtonEventPathEntry(entry);
217             }
218             public void linkActivated(HyperlinkEvent e) {
219                 // Ensure data object is defined
220
if (fDataTask == null) {
221                     return;
222                 }
223                 handleLinkEventPathEntry(convertPathRelativeToAbs(fPathEntry
224                         .getValue(), fDataTask.getModel()
225                         .getUnderlyingResource().getFullPath()
226                         .toPortableString()));
227             }
228             public void textValueChanged(FormEntry entry) {
229                 // Ensure data object is defined
230
if (fDataTask == null) {
231                     return;
232                 }
233                 // TODO: MP: LOW: CompCS: Could validate manual input
234
handleTextEventPathEntry(entry.getValue());
235             }
236         });
237     }
238     
239     /**
240      * @param entry
241      */

242     private void handleButtonEventPathEntry(FormEntry entry) {
243         // Create the dialog
244
ElementTreeSelectionDialog dialog =
245             new ElementTreeSelectionDialog(
246                 getManagedForm().getForm().getShell(),
247                 new WorkbenchLabelProvider(),
248                 new WorkbenchContentProvider());
249                 
250         dialog.setValidator(new CompCSFileValidator());
251         dialog.setAllowMultiple(false);
252         dialog.setTitle(PDEUIMessages.CompCSTaskDetails_simpleCSWizardTitle);
253         dialog.setMessage(PDEUIMessages.CompCSTaskDetails_simpleCSWizardDescription);
254         dialog.addFilter(new FileExtensionFilter("xml")); //$NON-NLS-1$
255
dialog.setInput(PDEPlugin.getWorkspace().getRoot().getProject(
256             fDataTask.getModel().getUnderlyingResource().getProject().getName()));
257
258         if (dialog.open() == Window.OK) {
259             IFile file = (IFile)dialog.getFirstResult();
260             String JavaDoc newValue = convertPathAbsToRelative(file.getFullPath()
261                     .toPortableString(), fDataTask.getModel()
262                     .getUnderlyingResource().getFullPath().toPortableString());
263             entry.setValue(newValue);
264             handleTextEventPathEntry(newValue);
265         }
266     }
267     
268     /**
269      * @param path
270      * @return
271      */

272     private String JavaDoc extractFileName(String JavaDoc path) {
273         StringTokenizer JavaDoc tokenizer = new StringTokenizer JavaDoc(path, F_PATH_SEPARATOR);
274         while (tokenizer.countTokens() > 1) {
275             tokenizer.nextToken();
276         }
277         return tokenizer.nextToken();
278     }
279     
280     /**
281      * @param path
282      * @return
283      */

284     private String JavaDoc convertPathAbsToRelative(String JavaDoc relativePath, String JavaDoc basePath) {
285         StringTokenizer JavaDoc convertPathTokenizer
286             = new StringTokenizer JavaDoc(relativePath, F_PATH_SEPARATOR);
287         StringTokenizer JavaDoc basePathTokenizer
288             = new StringTokenizer JavaDoc(basePath, F_PATH_SEPARATOR);
289         // First entry is the project name
290
String JavaDoc convertPathToken = convertPathTokenizer.nextToken();
291         String JavaDoc basePathToken = basePathTokenizer.nextToken();
292         // If the project names don't match, then we cannot make a relative
293
// path
294
if (convertPathToken.equals(basePathToken) == false) {
295             return ""; //$NON-NLS-1$
296
}
297         // Process base and convert path segments to make a relative path
298
while (basePathTokenizer.hasMoreTokens() &&
299                 convertPathTokenizer.hasMoreTokens()) {
300             
301             if (basePathTokenizer.countTokens() == 1) {
302                 // Only the base file name is left
303
// No ".." required
304
// No last base path segment is required since we did not
305
// get the next base path segment token
306
return createRelativePath(0, null, convertPathTokenizer);
307             } else if (convertPathTokenizer.countTokens() == 1) {
308                 // Only the convert file name is left
309
// Calculate required ".."
310
// No last base path segment is required since we did not
311
// get the next base path segment token
312
return createRelativePath(basePathTokenizer.countTokens() - 1,
313                         null, convertPathTokenizer);
314             } else {
315                 // Compare the next path segment
316
convertPathToken = convertPathTokenizer.nextToken();
317                 basePathToken = basePathTokenizer.nextToken();
318                 if (convertPathToken.equals(basePathToken) == false) {
319                     // The path segments are not equal
320
// Calculate required ".."
321
// Last base path segment needs to be included in the
322
// relative path
323
return createRelativePath(basePathTokenizer.countTokens(),
324                             convertPathToken, convertPathTokenizer);
325                 }
326             }
327         }
328         // This should never happen
329
return ""; //$NON-NLS-1$
330
}
331     
332     
333     /**
334      * @param dotDotCount
335      * @param tokenizer
336      * @return
337      */

338     private String JavaDoc createRelativePath(int dotDotCount, String JavaDoc lastToken,
339             StringTokenizer JavaDoc tokenizer) {
340         StringBuffer JavaDoc relativePath = new StringBuffer JavaDoc();
341         // Prepend with the number of specified ".."
342
for (int i = 0; i < dotDotCount; i++) {
343             relativePath.append(F_DOT_DOT);
344             relativePath.append(F_PATH_SEPARATOR);
345         }
346         // Append the last token if specified
347
if (lastToken != null) {
348             relativePath.append(lastToken);
349             relativePath.append(F_PATH_SEPARATOR);
350         }
351         // Append all the path segments excluding the file itself
352
for (int i = 0; i < (tokenizer.countTokens() - 1); i++) {
353             relativePath.append(tokenizer.nextToken());
354             relativePath.append(F_PATH_SEPARATOR);
355         }
356         // Append the file itself
357
relativePath.append(tokenizer.nextToken());
358         
359         return relativePath.toString();
360     }
361
362     /**
363      * @param absolutePath
364      */

365     private void handleLinkEventPathEntry(String JavaDoc absolutePath) {
366         IWorkspaceRoot root = PDEPlugin.getWorkspace().getRoot();
367         Path path = new Path(absolutePath);
368         // If the path is empty open the new simple cheat sheet wizard
369
if (path.isEmpty()) {
370             handleLinkWizardPathEntry();
371             return;
372         }
373         // Try to find the simple cheat sheet in the workspace
374
IResource resource = root.findMember(path);
375         // If the simple cheat sheet is found open the simple cheat sheet
376
// editor using it as input; otherwise, opne the simple cheat sheet
377
// wizard
378
if ((resource != null) &&
379                 (resource instanceof IFile)) {
380             try {
381                 IDE.openEditor(PDEPlugin.getActivePage(), (IFile) resource, true);
382             } catch (PartInitException e) {
383                 // Ignore
384
}
385         } else {
386             handleLinkWizardPathEntry();
387         }
388     }
389
390     /**
391      *
392      */

393     private void handleLinkWizardPathEntry() {
394         NewSimpleCSFileWizard wizard =
395             new NewSimpleCSFileWizard();
396         // Select in the tree view the directory this composite cheat sheet is
397
// stored in
398
wizard.init(PlatformUI.getWorkbench(), new StructuredSelection(
399                 fDataTask.getModel().getUnderlyingResource()));
400         // Create the dialog for the wizard
401
WizardDialog dialog =
402             new WizardDialog(PDEPlugin.getActiveWorkbenchShell(), wizard);
403         dialog.create();
404         // Get the wizard page
405
IWizardPage wizardPage = wizard.getPage(SimpleCSFileWizardPage.F_PAGE_NAME);
406         if ((wizardPage instanceof SimpleCSFileWizardPage) == false) {
407             return;
408         }
409         SimpleCSFileWizardPage page = (SimpleCSFileWizardPage)wizardPage;
410         // Set the initial file name
411
String JavaDoc initialValue = fPathEntry.getValue().trim();
412         if (initialValue.length() > 0) {
413             // It is a relative file name
414
page.setFileName(extractFileName(initialValue));
415         }
416         // Restrict user choices of where to store the new simple cheat sheet
417
// to only the project name this composite cheat sheet is stored in
418
page.setProjectName(fDataTask.getModel().getUnderlyingResource()
419                 .getProject().getName());
420         // Check the result
421
if (dialog.open() == Window.OK) {
422             String JavaDoc newValue = convertPathAbsToRelative(page
423                     .getAbsoluteFileName(), fDataTask.getModel()
424                     .getUnderlyingResource().getFullPath().toPortableString());
425             fPathEntry.setValue(newValue, true);
426             handleTextEventPathEntry(newValue);
427         }
428     }
429     
430     /**
431      * @param relativePath
432      * @return
433      */

434     private String JavaDoc convertPathRelativeToAbs(String JavaDoc relativePath, String JavaDoc basePath) {
435         StringTokenizer JavaDoc convertPathTokenizer
436             = new StringTokenizer JavaDoc(relativePath, F_PATH_SEPARATOR);
437         StringTokenizer JavaDoc basePathTokenizer
438             = new StringTokenizer JavaDoc(basePath, F_PATH_SEPARATOR);
439         // Accumulate the non ".." path segments excluding the file name
440
// and count the number of ".." path segments
441
StringBuffer JavaDoc endPath = new StringBuffer JavaDoc();
442         int dotDotCount = 0;
443         if (convertPathTokenizer.hasMoreTokens()) {
444             while (convertPathTokenizer.countTokens() > 1) {
445                 String JavaDoc token = convertPathTokenizer.nextToken();
446                 if (token.equals(F_DOT_DOT)) {
447                     dotDotCount++;
448                 } else {
449                     endPath.append(token);
450                     endPath.append(F_PATH_SEPARATOR);
451                 }
452             }
453             // Append the file name
454
endPath.append(convertPathTokenizer.nextToken());
455         }
456         // Calculate the number of base path segments to accumulate
457
int baseSegementCount = basePathTokenizer.countTokens() - dotDotCount -
458             1;
459         // Check to see if the relative path is bogus
460
if (baseSegementCount < 0) {
461             return ""; //$NON-NLS-1$
462
}
463         // Accumulate the initial path segments making up the absolute path
464
StringBuffer JavaDoc startPath = new StringBuffer JavaDoc(F_PATH_SEPARATOR);
465         for (int i = 0; i < baseSegementCount; i++) {
466             startPath.append(basePathTokenizer.nextToken());
467             startPath.append(F_PATH_SEPARATOR);
468         }
469         // Concatenate the start and end paths together to get the absolute
470
// paths
471
return startPath.toString() + endPath.toString();
472     }
473     
474     /**
475      * @param newValue
476      */

477     private void handleTextEventPathEntry(String JavaDoc newValue) {
478         // Check for existing parameters
479
if (fDataTask.hasFieldParams()) {
480             // There are existing parameters
481
// Check for an existing "path" parameter
482
ICompCSParam parameter =
483                 fDataTask.getFieldParam(ICompCSConstants.ATTRIBUTE_VALUE_PATH);
484             if (parameter != null) {
485                 parameter.setFieldValue(newValue);
486             } else {
487                 // No suitable parameter found
488
// Create a new "path" parameter
489
createTaskParamPathEntry(newValue);
490             }
491         } else {
492             // No existing parameters
493
// Create a new "path" parameter
494
createTaskParamPathEntry(newValue);
495         }
496     }
497
498     /**
499      * @param newValue
500      */

501     private void createTaskParamPathEntry(String JavaDoc newValue) {
502         ICompCSModelFactory factory = fDataTask.getModel().getFactory();
503         // Create parameter
504
ICompCSParam parameter = factory.createCompCSParam(fDataTask);
505         // Configure parameter
506
parameter.setFieldName(ICompCSConstants.ATTRIBUTE_VALUE_PATH);
507         parameter.setFieldValue(newValue);
508         // Add parameter to the task
509
fDataTask.addFieldParam(parameter);
510     }
511     
512     /**
513      *
514      */

515     private void createListenersSkipButton() {
516         fSkip.addSelectionListener(new SelectionAdapter() {
517             public void widgetSelected(SelectionEvent e) {
518                 // Ensure data object is defined
519
if (fDataTask == null) {
520                     return;
521                 }
522                 fDataTask.setFieldSkip(fSkip.getSelection());
523             }
524         });
525     }
526     
527     /* (non-Javadoc)
528      * @see org.eclipse.pde.internal.ui.editor.cheatsheet.CSAbstractDetails#updateFields()
529      */

530     public void updateFields() {
531         // Ensure data object is defined
532
if (fDataTask == null) {
533             return;
534         }
535         boolean editable = isEditableElement();
536         // Update name entry
537
updateNameEntry(editable);
538         // Update kind combo
539
updatePathEntry(editable);
540         // Update skip button
541
updateSkipButton(editable);
542         // Update fields within enclosing text section
543
fEnclosingTextSection.updateFields();
544     }
545
546     /**
547      * @param editable
548      */

549     private void updateNameEntry(boolean editable) {
550         fNameEntry.setValue(fDataTask.getFieldName(), true);
551         fNameEntry.setEditable(editable);
552     }
553
554     /**
555      * @param editable
556      */

557     private void updatePathEntry(boolean editable) {
558         ICompCSParam parameter =
559             fDataTask.getFieldParam(ICompCSConstants.ATTRIBUTE_VALUE_PATH);
560         if (parameter != null) {
561             fPathEntry.setValue(parameter.getFieldValue(), true);
562         } else {
563             fPathEntry.setValue("", true); //$NON-NLS-1$
564
}
565     }
566
567     /**
568      * @param editable
569      */

570     private void updateSkipButton(boolean editable) {
571         fSkip.setSelection(fDataTask.getFieldSkip());
572         fSkip.setEnabled(editable);
573     }
574     
575     /* (non-Javadoc)
576      * @see org.eclipse.ui.forms.AbstractFormPart#commit(boolean)
577      */

578     public void commit(boolean onSave) {
579         super.commit(onSave);
580         // Only required for form entries
581
fNameEntry.commit();
582         fPathEntry.commit();
583         // No need to call for sub details, because they contain no form entries
584
}
585
586     /* (non-Javadoc)
587      * @see org.eclipse.ui.forms.IPartSelectionListener#selectionChanged(org.eclipse.ui.forms.IFormPart, org.eclipse.jface.viewers.ISelection)
588      */

589     public void selectionChanged(IFormPart part, ISelection selection) {
590         // Get the first selected object
591
Object JavaDoc object = getFirstSelectedObject(selection);
592         // Ensure we have the right type
593
if ((object == null) ||
594                 (object instanceof ICompCSTask) == false) {
595             return;
596         }
597         // Set data
598
setData((ICompCSTask)object);
599         // Update the UI given the new data
600
updateFields();
601     }
602     
603     /* (non-Javadoc)
604      * @see org.eclipse.ui.forms.AbstractFormPart#dispose()
605      */

606     public void dispose() {
607         // Dispose of the enclosing text section
608
if (fEnclosingTextSection != null) {
609             fEnclosingTextSection.dispose();
610             fEnclosingTextSection = null;
611         }
612         super.dispose();
613     }
614
615 }
616
Popular Tags