KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > eclipse > jdt > internal > ui > preferences > formatter > LineWrappingTabPage


1 /*******************************************************************************
2  * Copyright (c) 2000, 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 package org.eclipse.jdt.internal.ui.preferences.formatter;
12
13 import java.util.ArrayList JavaDoc;
14 import java.util.Collection JavaDoc;
15 import java.util.HashMap JavaDoc;
16 import java.util.Iterator JavaDoc;
17 import java.util.List JavaDoc;
18 import java.util.Map JavaDoc;
19 import java.util.Observable JavaDoc;
20 import java.util.Observer JavaDoc;
21
22 import org.eclipse.core.runtime.IStatus;
23 import org.eclipse.core.runtime.Status;
24
25 import org.eclipse.swt.SWT;
26 import org.eclipse.swt.events.SelectionAdapter;
27 import org.eclipse.swt.events.SelectionEvent;
28 import org.eclipse.swt.layout.GridData;
29 import org.eclipse.swt.widgets.Button;
30 import org.eclipse.swt.widgets.Combo;
31 import org.eclipse.swt.widgets.Composite;
32 import org.eclipse.swt.widgets.Control;
33 import org.eclipse.swt.widgets.Group;
34 import org.eclipse.swt.widgets.Label;
35
36 import org.eclipse.jface.dialogs.IDialogSettings;
37 import org.eclipse.jface.viewers.DoubleClickEvent;
38 import org.eclipse.jface.viewers.IDoubleClickListener;
39 import org.eclipse.jface.viewers.ISelection;
40 import org.eclipse.jface.viewers.ISelectionChangedListener;
41 import org.eclipse.jface.viewers.IStructuredSelection;
42 import org.eclipse.jface.viewers.ITreeContentProvider;
43 import org.eclipse.jface.viewers.LabelProvider;
44 import org.eclipse.jface.viewers.SelectionChangedEvent;
45 import org.eclipse.jface.viewers.StructuredSelection;
46 import org.eclipse.jface.viewers.TreeViewer;
47 import org.eclipse.jface.viewers.Viewer;
48
49 import org.eclipse.jdt.core.formatter.DefaultCodeFormatterConstants;
50
51 import org.eclipse.jdt.internal.corext.util.Messages;
52
53 import org.eclipse.jdt.ui.JavaUI;
54
55 import org.eclipse.jdt.internal.ui.JavaPlugin;
56
57
58 /**
59  * The line wrapping tab page.
60  */

61 public class LineWrappingTabPage extends FormatterTabPage {
62     /**
63      * Constant array for boolean selection
64      */

65     private static String JavaDoc[] FALSE_TRUE = {
66         DefaultCodeFormatterConstants.FALSE,
67         DefaultCodeFormatterConstants.TRUE
68     };
69
70     /**
71      * Represents a line wrapping category. All members are final.
72      */

73     private final static class Category {
74         public final String JavaDoc key;
75         public final String JavaDoc name;
76         public final String JavaDoc previewText;
77         public final List JavaDoc children;
78         public final List JavaDoc preferences;
79         
80         public int index;
81
82         public Category(String JavaDoc _key, String JavaDoc _previewText, String JavaDoc _name) {
83             this.key= _key;
84             this.name= _name;
85             this.previewText= _previewText != null ? createPreviewHeader(_name) + _previewText : null;
86             children= new ArrayList JavaDoc();
87             preferences= new ArrayList JavaDoc();
88         }
89         
90         /**
91          * @param _name Category name
92          */

93         public Category(String JavaDoc _name) {
94             this(null, null, _name);
95         }
96         
97         public String JavaDoc toString() {
98             return name;
99         }
100
101         public void addPreference(Preference specificPreference) {
102             preferences.add(specificPreference);
103         }
104
105         public Preference[] getSpecificPreferences() {
106             return (Preference[])preferences.toArray(new Preference[preferences.size()]);
107         }
108     }
109     
110
111     private final static String JavaDoc PREF_CATEGORY_INDEX= JavaUI.ID_PLUGIN + "formatter_page.line_wrapping_tab_page.last_category_index"; //$NON-NLS-1$
112

113     
114     private final class CategoryListener implements ISelectionChangedListener, IDoubleClickListener {
115         
116         private final List JavaDoc fCategoriesList;
117         
118         private int fIndex= 0;
119         
120         public CategoryListener(List JavaDoc categoriesTree) {
121             fCategoriesList= new ArrayList JavaDoc();
122             flatten(fCategoriesList, categoriesTree);
123         }
124         
125         private void flatten(List JavaDoc categoriesList, List JavaDoc categoriesTree) {
126             for (final Iterator JavaDoc iter= categoriesTree.iterator(); iter.hasNext(); ) {
127                 final Category category= (Category) iter.next();
128                 category.index= fIndex++;
129                 categoriesList.add(category);
130                 flatten(categoriesList, category.children);
131             }
132         }
133
134         public void add(Category category) {
135             category.index= fIndex++;
136             fCategoriesList.add(category);
137         }
138
139         public void selectionChanged(SelectionChangedEvent event) {
140             if (event != null)
141                 fSelection= (IStructuredSelection)event.getSelection();
142             
143             if (fSelection.size() == 0) {
144                 disableAll();
145                 return;
146             }
147             
148             if (!fOptionsGroup.isEnabled())
149                 enableDefaultComponents(true);
150             
151             fSelectionState.refreshState(fSelection);
152             
153             final Category category= (Category)fSelection.getFirstElement();
154             fDialogSettings.put(PREF_CATEGORY_INDEX, category.index);
155             
156             fOptionsGroup.setText(getGroupLabel(category));
157         }
158         
159         private String JavaDoc getGroupLabel(Category category) {
160             if (fSelection.size() == 1) {
161                 if (fSelectionState.getElements().size() == 1)
162                     return Messages.format(FormatterMessages.LineWrappingTabPage_group, category.name.toLowerCase());
163                 return Messages.format(FormatterMessages.LineWrappingTabPage_multi_group, new String JavaDoc[] {category.name.toLowerCase(), Integer.toString(fSelectionState.getElements().size())});
164             }
165             return Messages.format(FormatterMessages.LineWrappingTabPage_multiple_selections, new String JavaDoc[] {Integer.toString(fSelectionState.getElements().size())});
166         }
167         
168         private void disableAll() {
169             enableDefaultComponents(false);
170             fIndentStyleCombo.setEnabled(false);
171             fForceSplit.setEnabled(false);
172         }
173         
174         private void enableDefaultComponents(boolean enabled) {
175             fOptionsGroup.setEnabled(enabled);
176             fWrappingStyleCombo.setEnabled(enabled);
177             fWrappingStylePolicy.setEnabled(enabled);
178         }
179
180         public void restoreSelection() {
181             int index;
182             try {
183                 index= fDialogSettings.getInt(PREF_CATEGORY_INDEX);
184             } catch (NumberFormatException JavaDoc ex) {
185                 index= -1;
186             }
187             if (index < 0 || index > fCategoriesList.size() - 1) {
188                 index= 1; // In order to select a category with preview initially
189
}
190             final Category category= (Category)fCategoriesList.get(index);
191             fCategoriesViewer.setSelection(new StructuredSelection(new Category[] {category}));
192         }
193
194         public void doubleClick(DoubleClickEvent event) {
195             final ISelection selection= event.getSelection();
196             if (selection instanceof IStructuredSelection) {
197                 final Category node= (Category)((IStructuredSelection)selection).getFirstElement();
198                 fCategoriesViewer.setExpandedState(node, !fCategoriesViewer.getExpandedState(node));
199             }
200         }
201     }
202     
203     private class SelectionState {
204         private List JavaDoc fElements= new ArrayList JavaDoc();
205         private boolean fRequiresRelayout;
206         
207         public void refreshState(IStructuredSelection selection) {
208             Map JavaDoc wrappingStyleMap= new HashMap JavaDoc();
209             Map JavaDoc indentStyleMap= new HashMap JavaDoc();
210             Map JavaDoc forceWrappingMap= new HashMap JavaDoc();
211             fRequiresRelayout= false;
212             showSpecificControls(false);
213             fElements.clear();
214             evaluateElements(selection.iterator());
215             evaluateMaps(wrappingStyleMap, indentStyleMap, forceWrappingMap);
216             setPreviewText(getPreviewText(wrappingStyleMap, indentStyleMap, forceWrappingMap));
217             refreshControls(wrappingStyleMap, indentStyleMap, forceWrappingMap);
218         }
219         
220         public List JavaDoc getElements() {
221             return fElements;
222         }
223         
224         private void evaluateElements(Iterator JavaDoc iterator) {
225             Category category;
226             String JavaDoc value;
227             while (iterator.hasNext()) {
228                 category= (Category) iterator.next();
229                 value= (String JavaDoc)fWorkingValues.get(category.key);
230                 if (value != null) {
231                     if (!fElements.contains(category))
232                         fElements.add(category);
233                 }
234                 else {
235                     evaluateElements(category.children.iterator());
236                 }
237             }
238         }
239         
240         private void evaluateMaps(Map JavaDoc wrappingStyleMap, Map JavaDoc indentStyleMap, Map JavaDoc forceWrappingMap) {
241             Iterator JavaDoc iterator= fElements.iterator();
242             while (iterator.hasNext()) {
243                 insertIntoMap(wrappingStyleMap, indentStyleMap, forceWrappingMap, (Category)iterator.next());
244             }
245         }
246   
247         private String JavaDoc getPreviewText(Map JavaDoc wrappingMap, Map JavaDoc indentMap, Map JavaDoc forceMap) {
248             Iterator JavaDoc iterator= fElements.iterator();
249             String JavaDoc previewText= ""; //$NON-NLS-1$
250
while (iterator.hasNext()) {
251                 Category category= (Category)iterator.next();
252                 previewText= previewText + category.previewText + "\n\n"; //$NON-NLS-1$
253
}
254             return previewText;
255         }
256         
257         private void insertIntoMap(Map JavaDoc wrappingMap, Map JavaDoc indentMap, Map JavaDoc forceMap, Category category) {
258             final String JavaDoc value= (String JavaDoc)fWorkingValues.get(category.key);
259             Integer JavaDoc wrappingStyle;
260             Integer JavaDoc indentStyle;
261             Boolean JavaDoc forceWrapping;
262             
263             try {
264                 wrappingStyle= new Integer JavaDoc(DefaultCodeFormatterConstants.getWrappingStyle(value));
265                 indentStyle= new Integer JavaDoc(DefaultCodeFormatterConstants.getIndentStyle(value));
266                 forceWrapping= new Boolean JavaDoc(DefaultCodeFormatterConstants.getForceWrapping(value));
267             } catch (IllegalArgumentException JavaDoc e) {
268                 forceWrapping= new Boolean JavaDoc(false);
269                 indentStyle= new Integer JavaDoc(DefaultCodeFormatterConstants.INDENT_DEFAULT);
270                 wrappingStyle= new Integer JavaDoc(DefaultCodeFormatterConstants.WRAP_NO_SPLIT);
271             }
272             
273             increaseMapEntry(wrappingMap, wrappingStyle);
274             increaseMapEntry(indentMap, indentStyle);
275             increaseMapEntry(forceMap, forceWrapping);
276         }
277         
278         private void increaseMapEntry(Map JavaDoc map, Object JavaDoc type) {
279             Integer JavaDoc count= (Integer JavaDoc)map.get(type);
280             if (count == null) // not in map yet -> count == 0
281
map.put(type, new Integer JavaDoc(1));
282             else
283                 map.put(type, new Integer JavaDoc(count.intValue() + 1));
284         }
285                 
286         private void refreshControls(Map JavaDoc wrappingStyleMap, Map JavaDoc indentStyleMap, Map JavaDoc forceWrappingMap) {
287             updateCombos(wrappingStyleMap, indentStyleMap);
288             updateButton(forceWrappingMap);
289             Integer JavaDoc wrappingStyleMax= getWrappingStyleMax(wrappingStyleMap);
290             boolean isInhomogeneous= (fElements.size() != ((Integer JavaDoc)wrappingStyleMap.get(wrappingStyleMax)).intValue());
291             updateControlEnablement(isInhomogeneous, wrappingStyleMax.intValue());
292             showSpecificControls(true);
293             if (fRequiresRelayout) {
294                 fOptionsComposite.layout(true, true);
295             }
296             doUpdatePreview();
297             notifyValuesModified();
298         }
299         
300         private void showSpecificControls(boolean show) {
301             if (fElements.size() != 1)
302                 return;
303             
304             Preference[] preferences= ((Category)fElements.get(0)).getSpecificPreferences();
305             if (preferences.length == 0)
306                 return;
307             
308             fRequiresRelayout= true;
309             for (int i= 0; i < preferences.length; i++) {
310                 Preference preference= preferences[i];
311                 Control control= preference.getControl();
312                 control.setVisible(show);
313                 ((GridData)control.getLayoutData()).exclude= !show;
314             }
315         }
316
317         private Integer JavaDoc getWrappingStyleMax(Map JavaDoc wrappingStyleMap) {
318             int maxCount= 0, maxStyle= 0;
319             for (int i=0; i<WRAPPING_NAMES.length; i++) {
320                 Integer JavaDoc count= (Integer JavaDoc)wrappingStyleMap.get(new Integer JavaDoc(i));
321                 if (count == null)
322                     continue;
323                 if (count.intValue() > maxCount) {
324                     maxCount= count.intValue();
325                     maxStyle= i;
326                 }
327             }
328             return new Integer JavaDoc(maxStyle);
329         }
330         
331         private void updateButton(Map JavaDoc forceWrappingMap) {
332             Integer JavaDoc nrOfTrue= (Integer JavaDoc)forceWrappingMap.get(Boolean.TRUE);
333             Integer JavaDoc nrOfFalse= (Integer JavaDoc)forceWrappingMap.get(Boolean.FALSE);
334             
335             if (nrOfTrue == null || nrOfFalse == null)
336                 fForceSplit.setSelection(nrOfTrue != null);
337             else
338                 fForceSplit.setSelection(nrOfTrue.intValue() > nrOfFalse.intValue());
339             
340             int max= getMax(nrOfTrue, nrOfFalse);
341             String JavaDoc label= FormatterMessages.LineWrappingTabPage_force_split_checkbox_multi_text;
342             fForceSplit.setText(getLabelText(label, max, fElements.size()));
343         }
344         
345         private String JavaDoc getLabelText(String JavaDoc label, int count, int nElements) {
346             if (nElements == 1 || count == 0)
347                 return label;
348             return Messages.format(FormatterMessages.LineWrappingTabPage_occurences, new String JavaDoc[] {label, Integer.toString(count), Integer.toString(nElements)});
349         }
350         
351         private int getMax(Integer JavaDoc nrOfTrue, Integer JavaDoc nrOfFalse) {
352             if (nrOfTrue == null)
353                 return nrOfFalse.intValue();
354             if (nrOfFalse == null)
355                 return nrOfTrue.intValue();
356             if (nrOfTrue.compareTo(nrOfFalse) >= 0)
357                 return nrOfTrue.intValue();
358             return nrOfFalse.intValue();
359         }
360         
361         private void updateCombos(Map JavaDoc wrappingStyleMap, Map JavaDoc indentStyleMap) {
362             updateCombo(fWrappingStyleCombo, wrappingStyleMap, WRAPPING_NAMES);
363             updateCombo(fIndentStyleCombo, indentStyleMap, INDENT_NAMES);
364         }
365         
366         private void updateCombo(Combo combo, Map JavaDoc map, final String JavaDoc[] items) {
367             String JavaDoc[] newItems= new String JavaDoc[items.length];
368             int maxCount= 0, maxStyle= 0;
369                         
370             for(int i = 0; i < items.length; i++) {
371                 Integer JavaDoc count= (Integer JavaDoc) map.get(new Integer JavaDoc(i));
372                 int val= (count == null) ? 0 : count.intValue();
373                 if (val > maxCount) {
374                     maxCount= val;
375                     maxStyle= i;
376                 }
377                 newItems[i]= getLabelText(items[i], val, fElements.size());
378             }
379             combo.setItems(newItems);
380             combo.setText(newItems[maxStyle]);
381         }
382     }
383     
384     protected static final String JavaDoc[] INDENT_NAMES = {
385         FormatterMessages.LineWrappingTabPage_indentation_default,
386         FormatterMessages.LineWrappingTabPage_indentation_on_column,
387         FormatterMessages.LineWrappingTabPage_indentation_by_one
388     };
389     
390     
391     protected static final String JavaDoc[] WRAPPING_NAMES = {
392         FormatterMessages.LineWrappingTabPage_splitting_do_not_split,
393         FormatterMessages.LineWrappingTabPage_splitting_wrap_when_necessary, // COMPACT_SPLIT
394
FormatterMessages.LineWrappingTabPage_splitting_always_wrap_first_others_when_necessary, // COMPACT_FIRST_BREAK_SPLIT
395
FormatterMessages.LineWrappingTabPage_splitting_wrap_always, // ONE_PER_LINE_SPLIT
396
FormatterMessages.LineWrappingTabPage_splitting_wrap_always_indent_all_but_first, // NEXT_SHIFTED_SPLIT
397
FormatterMessages.LineWrappingTabPage_splitting_wrap_always_except_first_only_if_necessary
398     };
399     
400
401     private final Category fCompactIfCategory= new Category(
402         DefaultCodeFormatterConstants.FORMATTER_ALIGNMENT_FOR_COMPACT_IF,
403         "class Example {" + //$NON-NLS-1$
404
"int foo(int argument) {" + //$NON-NLS-1$
405
" if (argument==0) return 0;" + //$NON-NLS-1$
406
" if (argument==1) return 42; else return 43;" + //$NON-NLS-1$
407
"}}", //$NON-NLS-1$
408
FormatterMessages.LineWrappingTabPage_compact_if_else
409     );
410     
411
412     private final Category fTypeDeclarationSuperclassCategory= new Category(
413         DefaultCodeFormatterConstants.FORMATTER_ALIGNMENT_FOR_SUPERCLASS_IN_TYPE_DECLARATION,
414         "class Example extends OtherClass {}", //$NON-NLS-1$
415
FormatterMessages.LineWrappingTabPage_extends_clause
416     );
417     
418
419     private final Category fTypeDeclarationSuperinterfacesCategory= new Category(
420         DefaultCodeFormatterConstants.FORMATTER_ALIGNMENT_FOR_SUPERINTERFACES_IN_TYPE_DECLARATION,
421         "class Example implements I1, I2, I3 {}", //$NON-NLS-1$
422
FormatterMessages.LineWrappingTabPage_implements_clause
423     );
424     
425     
426     private final Category fConstructorDeclarationsParametersCategory= new Category(
427         DefaultCodeFormatterConstants.FORMATTER_ALIGNMENT_FOR_PARAMETERS_IN_CONSTRUCTOR_DECLARATION,
428         "class Example {Example(int arg1, int arg2, int arg3, int arg4, int arg5, int arg6) { this();}" + //$NON-NLS-1$
429
"Example() {}}", //$NON-NLS-1$
430
FormatterMessages.LineWrappingTabPage_parameters
431     );
432
433     private final Category fMethodDeclarationsParametersCategory= new Category(
434         DefaultCodeFormatterConstants.FORMATTER_ALIGNMENT_FOR_PARAMETERS_IN_METHOD_DECLARATION,
435         "class Example {void foo(int arg1, int arg2, int arg3, int arg4, int arg5, int arg6) {}}", //$NON-NLS-1$
436
FormatterMessages.LineWrappingTabPage_parameters
437     );
438     
439     private final Category fMessageSendArgumentsCategory= new Category(
440         DefaultCodeFormatterConstants.FORMATTER_ALIGNMENT_FOR_ARGUMENTS_IN_METHOD_INVOCATION,
441         "class Example {void foo() {Other.bar( 100, 200, 300, 400, 500, 600, 700, 800, 900 );}}", //$NON-NLS-1$
442
FormatterMessages.LineWrappingTabPage_arguments
443     );
444
445     private final Category fMessageSendSelectorCategory= new Category(
446         DefaultCodeFormatterConstants.FORMATTER_ALIGNMENT_FOR_SELECTOR_IN_METHOD_INVOCATION,
447         "class Example {int foo(Some a) {return a.getFirst();}}", //$NON-NLS-1$
448
FormatterMessages.LineWrappingTabPage_qualified_invocations
449     );
450     
451     private final Category fMethodThrowsClauseCategory= new Category(
452         DefaultCodeFormatterConstants.FORMATTER_ALIGNMENT_FOR_THROWS_CLAUSE_IN_METHOD_DECLARATION,
453         "class Example {" + //$NON-NLS-1$
454
"int foo() throws FirstException, SecondException, ThirdException {" + //$NON-NLS-1$
455
" return Other.doSomething();}}", //$NON-NLS-1$
456
FormatterMessages.LineWrappingTabPage_throws_clause
457     );
458
459     private final Category fConstructorThrowsClauseCategory= new Category(
460         DefaultCodeFormatterConstants.FORMATTER_ALIGNMENT_FOR_THROWS_CLAUSE_IN_CONSTRUCTOR_DECLARATION,
461         "class Example {" + //$NON-NLS-1$
462
"Example() throws FirstException, SecondException, ThirdException {" + //$NON-NLS-1$
463
" return Other.doSomething();}}", //$NON-NLS-1$
464
FormatterMessages.LineWrappingTabPage_throws_clause
465     );
466
467     
468     private final Category fAllocationExpressionArgumentsCategory= new Category(
469         DefaultCodeFormatterConstants.FORMATTER_ALIGNMENT_FOR_ARGUMENTS_IN_ALLOCATION_EXPRESSION,
470         "class Example {SomeClass foo() {return new SomeClass(100, 200, 300, 400, 500, 600, 700, 800, 900 );}}", //$NON-NLS-1$
471
FormatterMessages.LineWrappingTabPage_object_allocation
472     );
473     
474     private final Category fQualifiedAllocationExpressionCategory= new Category (
475         DefaultCodeFormatterConstants.FORMATTER_ALIGNMENT_FOR_ARGUMENTS_IN_QUALIFIED_ALLOCATION_EXPRESSION,
476         "class Example {SomeClass foo() {return SomeOtherClass.new SomeClass(100, 200, 300, 400, 500 );}}", //$NON-NLS-1$
477
FormatterMessages.LineWrappingTabPage_qualified_object_allocation
478     );
479     
480     private final Category fArrayInitializerExpressionsCategory= new Category(
481         DefaultCodeFormatterConstants.FORMATTER_ALIGNMENT_FOR_EXPRESSIONS_IN_ARRAY_INITIALIZER,
482         "class Example {int [] fArray= {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12};}", //$NON-NLS-1$
483
FormatterMessages.LineWrappingTabPage_array_init
484     );
485     
486     private final Category fExplicitConstructorArgumentsCategory= new Category(
487         DefaultCodeFormatterConstants.FORMATTER_ALIGNMENT_FOR_ARGUMENTS_IN_EXPLICIT_CONSTRUCTOR_CALL,
488         "class Example extends AnotherClass {Example() {super(100, 200, 300, 400, 500, 600, 700);}}", //$NON-NLS-1$
489
FormatterMessages.LineWrappingTabPage_explicit_constructor_invocations
490     );
491
492     private final Category fConditionalExpressionCategory= new Category(
493         DefaultCodeFormatterConstants.FORMATTER_ALIGNMENT_FOR_CONDITIONAL_EXPRESSION,
494         "class Example extends AnotherClass {int Example(boolean Argument) {return argument ? 100000 : 200000;}}", //$NON-NLS-1$
495
FormatterMessages.LineWrappingTabPage_conditionals
496     );
497
498     private final Category fBinaryExpressionCategory= new Category(
499         DefaultCodeFormatterConstants.FORMATTER_ALIGNMENT_FOR_BINARY_EXPRESSION,
500         "class Example extends AnotherClass {" + //$NON-NLS-1$
501
"int foo() {" + //$NON-NLS-1$
502
" int sum= 100 + 200 + 300 + 400 + 500 + 600 + 700 + 800;" + //$NON-NLS-1$
503
" int product= 1 * 2 * 3 * 4 * 5 * 6 * 7 * 8 * 9 * 10;" + //$NON-NLS-1$
504
" boolean val= true && false && true && false && true;" + //$NON-NLS-1$
505
" return product / sum;}}", //$NON-NLS-1$
506
FormatterMessages.LineWrappingTabPage_binary_exprs
507     );
508     
509     private final Category fEnumConstArgumentsCategory= new Category(
510         DefaultCodeFormatterConstants.FORMATTER_ALIGNMENT_FOR_ARGUMENTS_IN_ENUM_CONSTANT,
511         "enum Example {" + //$NON-NLS-1$
512
"GREEN(0, 255, 0), RED(255, 0, 0) }", //$NON-NLS-1$
513
FormatterMessages.LineWrappingTabPage_enum_constant_arguments
514     );
515     
516     private final Category fEnumDeclInterfacesCategory= new Category(
517         DefaultCodeFormatterConstants.FORMATTER_ALIGNMENT_FOR_SUPERINTERFACES_IN_ENUM_DECLARATION,
518         "enum Example implements A, B, C {" + //$NON-NLS-1$
519
"}", //$NON-NLS-1$
520
FormatterMessages.LineWrappingTabPage_enum_superinterfaces
521     );
522     
523     private final Category fEnumConstantsCategory= new Category(
524         DefaultCodeFormatterConstants.FORMATTER_ALIGNMENT_FOR_ENUM_CONSTANTS,
525         "enum Example {" + //$NON-NLS-1$
526
"CANCELLED, RUNNING, WAITING, FINISHED }" + //$NON-NLS-1$
527
"enum Example {" + //$NON-NLS-1$
528
"GREEN(0, 255, 0), RED(255, 0, 0) }", //$NON-NLS-1$
529
FormatterMessages.LineWrappingTabPage_enum_constants
530     );
531     
532     private final Category fAssignmentCategory= new Category(
533             DefaultCodeFormatterConstants.FORMATTER_ALIGNMENT_FOR_ASSIGNMENT,
534             "class Example {" + //$NON-NLS-1$
535
"private static final String string = \"TextTextText\";" + //$NON-NLS-1$
536
"void foo() {" + //$NON-NLS-1$
537
"for (int i = 0; i < 10; i++) {}" + //$NON-NLS-1$
538
"String s;" + //$NON-NLS-1$
539
"s = \"TextTextText\";}}", //$NON-NLS-1$
540
FormatterMessages.LineWrappingTabPage_assignment_alignment
541         );
542     
543     /**
544      * The default preview line width.
545      */

546     private static int DEFAULT_PREVIEW_WINDOW_LINE_WIDTH= 40;
547     
548     /**
549      * The key to save the user's preview window width in the dialog settings.
550      */

551     private static final String JavaDoc PREF_PREVIEW_LINE_WIDTH= JavaUI.ID_PLUGIN + ".codeformatter.line_wrapping_tab_page.preview_line_width"; //$NON-NLS-1$
552

553     /**
554      * The dialog settings.
555      */

556     protected final IDialogSettings fDialogSettings;
557     
558     protected TreeViewer fCategoriesViewer;
559     protected Label fWrappingStylePolicy;
560     protected Combo fWrappingStyleCombo;
561     protected Label fIndentStylePolicy;
562     protected Combo fIndentStyleCombo;
563     protected Button fForceSplit;
564
565     protected CompilationUnitPreview fPreview;
566
567     protected Group fOptionsGroup;
568
569     /**
570      * A collection containing the categories tree. This is used as model for the tree viewer.
571      * @see TreeViewer
572      */

573     private final List JavaDoc fCategories;
574     
575     /**
576      * The category listener which makes the selection persistent.
577      */

578     protected final CategoryListener fCategoryListener;
579     
580     /**
581      * The current selection of elements.
582      */

583     protected IStructuredSelection fSelection;
584     
585     /**
586      * An object containing the state for the UI.
587      */

588     SelectionState fSelectionState;
589     
590     /**
591      * A special options store wherein the preview line width is kept.
592      */

593     protected final Map JavaDoc fPreviewPreferences;
594     
595     /**
596      * The key for the preview line width.
597      */

598     private final String JavaDoc LINE_SPLIT= DefaultCodeFormatterConstants.FORMATTER_LINE_SPLIT;
599
600
601     private Composite fOptionsComposite;
602     
603     /**
604      * Create a new line wrapping tab page.
605      * @param modifyDialog
606      * @param workingValues
607      */

608     public LineWrappingTabPage(ModifyDialog modifyDialog, Map JavaDoc workingValues) {
609         super(modifyDialog, workingValues);
610
611         fDialogSettings= JavaPlugin.getDefault().getDialogSettings();
612         
613         final String JavaDoc previewLineWidth= fDialogSettings.get(PREF_PREVIEW_LINE_WIDTH);
614         
615         fPreviewPreferences= new HashMap JavaDoc();
616         fPreviewPreferences.put(LINE_SPLIT, previewLineWidth != null ? previewLineWidth : Integer.toString(DEFAULT_PREVIEW_WINDOW_LINE_WIDTH));
617         
618         fCategories= createCategories();
619         fCategoryListener= new CategoryListener(fCategories);
620     }
621     
622     /**
623      * @return Create the categories tree.
624      */

625     protected List JavaDoc createCategories() {
626
627         final Category classDeclarations= new Category(FormatterMessages.LineWrappingTabPage_class_decls);
628         classDeclarations.children.add(fTypeDeclarationSuperclassCategory);
629         classDeclarations.children.add(fTypeDeclarationSuperinterfacesCategory);
630         
631         final Category constructorDeclarations= new Category(null, null, FormatterMessages.LineWrappingTabPage_constructor_decls);
632         constructorDeclarations.children.add(fConstructorDeclarationsParametersCategory);
633         constructorDeclarations.children.add(fConstructorThrowsClauseCategory);
634
635         final Category methodDeclarations= new Category(null, null, FormatterMessages.LineWrappingTabPage_method_decls);
636         methodDeclarations.children.add(fMethodDeclarationsParametersCategory);
637         methodDeclarations.children.add(fMethodThrowsClauseCategory);
638
639         final Category enumDeclarations= new Category(FormatterMessages.LineWrappingTabPage_enum_decls);
640         enumDeclarations.children.add(fEnumConstantsCategory);
641         enumDeclarations.children.add(fEnumDeclInterfacesCategory);
642         enumDeclarations.children.add(fEnumConstArgumentsCategory);
643         
644         final Category functionCalls= new Category(FormatterMessages.LineWrappingTabPage_function_calls);
645         functionCalls.children.add(fMessageSendArgumentsCategory);
646         functionCalls.children.add(fMessageSendSelectorCategory);
647         functionCalls.children.add(fExplicitConstructorArgumentsCategory);
648         functionCalls.children.add(fAllocationExpressionArgumentsCategory);
649         functionCalls.children.add(fQualifiedAllocationExpressionCategory);
650         
651         final Category expressions= new Category(FormatterMessages.LineWrappingTabPage_expressions);
652         expressions.children.add(fBinaryExpressionCategory);
653         expressions.children.add(fConditionalExpressionCategory);
654         expressions.children.add(fArrayInitializerExpressionsCategory);
655         expressions.children.add(fAssignmentCategory);
656         
657         final Category statements= new Category(FormatterMessages.LineWrappingTabPage_statements);
658         statements.children.add(fCompactIfCategory);
659         
660         final List JavaDoc root= new ArrayList JavaDoc();
661         root.add(classDeclarations);
662         root.add(constructorDeclarations);
663         root.add(methodDeclarations);
664         root.add(enumDeclarations);
665         root.add(functionCalls);
666         root.add(expressions);
667         root.add(statements);
668         
669         return root;
670     }
671     
672     protected void doCreatePreferences(Composite composite, int numColumns) {
673     
674         fOptionsComposite= composite;
675         
676         final Group lineWidthGroup= createGroup(numColumns, composite, FormatterMessages.LineWrappingTabPage_width_indent);
677
678         createNumberPref(lineWidthGroup, numColumns, FormatterMessages.LineWrappingTabPage_width_indent_option_max_line_width, DefaultCodeFormatterConstants.FORMATTER_LINE_SPLIT, 0, 9999);
679         createNumberPref(lineWidthGroup, numColumns, FormatterMessages.LineWrappingTabPage_width_indent_option_default_indent_wrapped, DefaultCodeFormatterConstants.FORMATTER_CONTINUATION_INDENTATION, 0, 9999);
680         createNumberPref(lineWidthGroup, numColumns, FormatterMessages.LineWrappingTabPage_width_indent_option_default_indent_array, DefaultCodeFormatterConstants.FORMATTER_CONTINUATION_INDENTATION_FOR_ARRAY_INITIALIZER, 0, 9999);
681         
682         fCategoriesViewer= new TreeViewer(composite /*categoryGroup*/, SWT.MULTI | SWT.BORDER | SWT.READ_ONLY | SWT.V_SCROLL );
683         fCategoriesViewer.setContentProvider(new ITreeContentProvider() {
684             public Object JavaDoc[] getElements(Object JavaDoc inputElement) {
685                 return ((Collection JavaDoc)inputElement).toArray();
686             }
687             public Object JavaDoc[] getChildren(Object JavaDoc parentElement) {
688                 return ((Category)parentElement).children.toArray();
689             }
690             public Object JavaDoc getParent(Object JavaDoc element) { return null; }
691             public boolean hasChildren(Object JavaDoc element) {
692                 return !((Category)element).children.isEmpty();
693             }
694             public void inputChanged(Viewer viewer, Object JavaDoc oldInput, Object JavaDoc newInput) {}
695             public void dispose() {}
696         });
697         fCategoriesViewer.setLabelProvider(new LabelProvider());
698         fCategoriesViewer.setInput(fCategories);
699         
700         fCategoriesViewer.setExpandedElements(fCategories.toArray());
701
702         final GridData gd= createGridData(numColumns, GridData.FILL_BOTH, SWT.DEFAULT);
703         gd.heightHint= fPixelConverter.convertHeightInCharsToPixels(5);
704         fCategoriesViewer.getControl().setLayoutData(gd);
705
706         fOptionsGroup = createGroup(numColumns, composite, ""); //$NON-NLS-1$
707

708         // label "Select split style:"
709
fWrappingStylePolicy= createLabel(numColumns, fOptionsGroup, FormatterMessages.LineWrappingTabPage_wrapping_policy_label_text);
710     
711         // combo SplitStyleCombo
712
fWrappingStyleCombo= new Combo(fOptionsGroup, SWT.SINGLE | SWT.READ_ONLY);
713         fWrappingStyleCombo.setItems(WRAPPING_NAMES);
714         fWrappingStyleCombo.setLayoutData(createGridData(numColumns, GridData.HORIZONTAL_ALIGN_FILL, 0));
715         
716         // label "Select indentation style:"
717
fIndentStylePolicy= createLabel(numColumns, fOptionsGroup, FormatterMessages.LineWrappingTabPage_indentation_policy_label_text);
718         
719         // combo SplitStyleCombo
720
fIndentStyleCombo= new Combo(fOptionsGroup, SWT.SINGLE | SWT.READ_ONLY);
721         fIndentStyleCombo.setItems(INDENT_NAMES);
722         fIndentStyleCombo.setLayoutData(createGridData(numColumns, GridData.HORIZONTAL_ALIGN_FILL, 0));
723         
724         // button "Force split"
725
fForceSplit= new Button(fOptionsGroup, SWT.CHECK);
726         fForceSplit.setLayoutData(createGridData(numColumns - 1, GridData.HORIZONTAL_ALIGN_BEGINNING, SWT.DEFAULT));
727         fForceSplit.setText(FormatterMessages.LineWrappingTabPage_force_split_checkbox_text);
728         
729         Preference expressionWrapPositionPreference= createCheckboxPref(fOptionsGroup, 1, FormatterMessages.LineWrappingTabPage_binary_expression_wrap_operator, DefaultCodeFormatterConstants.FORMATTER_WRAP_BEFORE_BINARY_OPERATOR, FALSE_TRUE);
730         Control control= expressionWrapPositionPreference.getControl();
731         control.setVisible(false);
732         ((GridData)control.getLayoutData()).exclude= true;
733         fBinaryExpressionCategory.addPreference(expressionWrapPositionPreference);
734         
735         // selection state object
736
fSelectionState= new SelectionState();
737         
738     }
739     
740         
741     protected Composite doCreatePreviewPane(Composite composite, int numColumns) {
742         
743         super.doCreatePreviewPane(composite, numColumns);
744         
745         final NumberPreference previewLineWidth= new NumberPreference(composite, numColumns / 2, fPreviewPreferences, LINE_SPLIT,
746             0, 9999, FormatterMessages.LineWrappingTabPage_line_width_for_preview_label_text);
747         fDefaultFocusManager.add(previewLineWidth);
748         previewLineWidth.addObserver(fUpdater);
749         previewLineWidth.addObserver(new Observer JavaDoc() {
750             public void update(Observable JavaDoc o, Object JavaDoc arg) {
751                 fDialogSettings.put(PREF_PREVIEW_LINE_WIDTH, (String JavaDoc)fPreviewPreferences.get(LINE_SPLIT));
752             }
753         });
754         
755         return composite;
756     }
757     
758     /* (non-Javadoc)
759      * @see org.eclipse.jdt.internal.ui.preferences.formatter.ModifyDialogTabPage#doCreateJavaPreview(org.eclipse.swt.widgets.Composite)
760      */

761     protected JavaPreview doCreateJavaPreview(Composite parent) {
762         fPreview= new CompilationUnitPreview(fWorkingValues, parent);
763         return fPreview;
764     }
765
766     
767     protected void initializePage() {
768         
769         fCategoriesViewer.addSelectionChangedListener(fCategoryListener);
770         fCategoriesViewer.addDoubleClickListener(fCategoryListener);
771         
772         fForceSplit.addSelectionListener(new SelectionAdapter() {
773             public void widgetSelected(SelectionEvent e) {
774                 forceSplitChanged(fForceSplit.getSelection());
775             }
776         });
777         fIndentStyleCombo.addSelectionListener( new SelectionAdapter() {
778             public void widgetSelected(SelectionEvent e) {
779                 indentStyleChanged(((Combo)e.widget).getSelectionIndex());
780             }
781         });
782         fWrappingStyleCombo.addSelectionListener( new SelectionAdapter() {
783             public void widgetSelected(SelectionEvent e) {
784                 wrappingStyleChanged(((Combo)e.widget).getSelectionIndex());
785             }
786         });
787         
788         fCategoryListener.restoreSelection();
789         
790         fDefaultFocusManager.add(fCategoriesViewer.getControl());
791         fDefaultFocusManager.add(fWrappingStyleCombo);
792         fDefaultFocusManager.add(fIndentStyleCombo);
793         fDefaultFocusManager.add(fForceSplit);
794     }
795     
796     protected void doUpdatePreview() {
797         super.doUpdatePreview();
798         final Object JavaDoc normalSetting= fWorkingValues.get(LINE_SPLIT);
799         fWorkingValues.put(LINE_SPLIT, fPreviewPreferences.get(LINE_SPLIT));
800         fPreview.update();
801         fWorkingValues.put(LINE_SPLIT, normalSetting);
802     }
803     
804     protected void setPreviewText(String JavaDoc text) {
805         final Object JavaDoc normalSetting= fWorkingValues.get(LINE_SPLIT);
806         fWorkingValues.put(LINE_SPLIT, fPreviewPreferences.get(LINE_SPLIT));
807         fPreview.setPreviewText(text);
808         fWorkingValues.put(LINE_SPLIT, normalSetting);
809     }
810     
811     protected void forceSplitChanged(boolean forceSplit) {
812         Iterator JavaDoc iterator= fSelectionState.fElements.iterator();
813         String JavaDoc currentKey;
814         while (iterator.hasNext()) {
815             currentKey= ((Category)iterator.next()).key;
816             try {
817                 changeForceSplit(currentKey, forceSplit);
818             } catch (IllegalArgumentException JavaDoc e) {
819                 fWorkingValues.put(currentKey, DefaultCodeFormatterConstants.createAlignmentValue(forceSplit, DefaultCodeFormatterConstants.WRAP_NO_SPLIT, DefaultCodeFormatterConstants.INDENT_DEFAULT));
820                 JavaPlugin.log(new Status(IStatus.ERROR, JavaPlugin.getPluginId(), IStatus.OK,
821                         Messages.format(FormatterMessages.LineWrappingTabPage_error_invalid_value, currentKey), e));
822             }
823         }
824         fSelectionState.refreshState(fSelection);
825     }
826     
827     private void changeForceSplit(String JavaDoc currentKey, boolean forceSplit) throws IllegalArgumentException JavaDoc{
828         String JavaDoc value= (String JavaDoc)fWorkingValues.get(currentKey);
829         value= DefaultCodeFormatterConstants.setForceWrapping(value, forceSplit);
830         if (value == null)
831             throw new IllegalArgumentException JavaDoc();
832         fWorkingValues.put(currentKey, value);
833     }
834     
835     protected void wrappingStyleChanged(int wrappingStyle) {
836            Iterator JavaDoc iterator= fSelectionState.fElements.iterator();
837            String JavaDoc currentKey;
838             while (iterator.hasNext()) {
839                 currentKey= ((Category)iterator.next()).key;
840                 try {
841                     changeWrappingStyle(currentKey, wrappingStyle);
842                 } catch (IllegalArgumentException JavaDoc e) {
843                     fWorkingValues.put(currentKey, DefaultCodeFormatterConstants.createAlignmentValue(false, wrappingStyle, DefaultCodeFormatterConstants.INDENT_DEFAULT));
844                     JavaPlugin.log(new Status(IStatus.ERROR, JavaPlugin.getPluginId(), IStatus.OK,
845                             Messages.format(FormatterMessages.LineWrappingTabPage_error_invalid_value, currentKey), e));
846                 }
847             }
848             fSelectionState.refreshState(fSelection);
849     }
850     
851     private void changeWrappingStyle(String JavaDoc currentKey, int wrappingStyle) throws IllegalArgumentException JavaDoc {
852         String JavaDoc value= (String JavaDoc)fWorkingValues.get(currentKey);
853         value= DefaultCodeFormatterConstants.setWrappingStyle(value, wrappingStyle);
854         if (value == null)
855             throw new IllegalArgumentException JavaDoc();
856         fWorkingValues.put(currentKey, value);
857     }
858     
859     protected void indentStyleChanged(int indentStyle) {
860         Iterator JavaDoc iterator= fSelectionState.fElements.iterator();
861         String JavaDoc currentKey;
862         while (iterator.hasNext()) {
863             currentKey= ((Category)iterator.next()).key;
864             try {
865                 changeIndentStyle(currentKey, indentStyle);
866             } catch (IllegalArgumentException JavaDoc e) {
867                 fWorkingValues.put(currentKey, DefaultCodeFormatterConstants.createAlignmentValue(false, DefaultCodeFormatterConstants.WRAP_NO_SPLIT, indentStyle));
868                 JavaPlugin.log(new Status(IStatus.ERROR, JavaPlugin.getPluginId(), IStatus.OK,
869                         Messages.format(FormatterMessages.LineWrappingTabPage_error_invalid_value, currentKey), e));
870             }
871         }
872         fSelectionState.refreshState(fSelection);
873     }
874     
875     private void changeIndentStyle(String JavaDoc currentKey, int indentStyle) throws IllegalArgumentException JavaDoc{
876         String JavaDoc value= (String JavaDoc)fWorkingValues.get(currentKey);
877         value= DefaultCodeFormatterConstants.setIndentStyle(value, indentStyle);
878         if (value == null)
879             throw new IllegalArgumentException JavaDoc();
880         fWorkingValues.put(currentKey, value);
881     }
882     
883     protected void updateControlEnablement(boolean inhomogenous, int wrappingStyle) {
884         boolean doSplit= wrappingStyle != DefaultCodeFormatterConstants.WRAP_NO_SPLIT;
885         fIndentStylePolicy.setEnabled(true);
886         fIndentStyleCombo.setEnabled(inhomogenous || doSplit);
887         fForceSplit.setEnabled(inhomogenous || doSplit);
888     }
889 }
890
Popular Tags