View | Details | Raw Unified | Return to bug 201998 | Differences between
and this patch

Collapse All | Expand All

(-)plugin.properties (-1 / +3 lines)
Lines 250-255 Link Here
250
pluginsearch.action.name = Open Plug-in Artifact
250
pluginsearch.action.name = Open Plug-in Artifact
251
pluginsearch.action.menu.name = Open &Plug-in Artifact...
251
pluginsearch.action.menu.name = Open &Plug-in Artifact...
252
pluginsearch.action.desc = Open a plug-in artifact in the manifest editor
252
pluginsearch.action.desc = Open a plug-in artifact in the manifest editor
253
254
Internationalize.label = Internationalize...
253
markerGroupingEntry.label = Plug-in Development
255
markerGroupingEntry.label = Plug-in Development
254
showErrorInStackTraceConsoleAction.label = Show in Stack Trace Console View
256
showErrorInStackTraceConsoleAction.label = Show in Stack Trace Console View
255
showErrorInStackTraceConsoleAction.tooltip = Display the stack trace from the currently selected error in the java stack trace console
257
showErrorInStackTraceConsoleAction.tooltip = Display the stack trace from the currently selected error in the java stack trace console>>>>>>> 1.215
(-)plugin.xml (-1 / +23 lines)
Lines 578-583 Link Here
578
                  name="group1">
578
                  name="group1">
579
            </separator>
579
            </separator>
580
         </menu>
580
         </menu>
581
          <action
582
			   label="%Internationalize.label"
583
			   helpContextId="org.eclipse.pde.doc.user.internationalize_plugins"
584
			   class="org.eclipse.pde.internal.ui.nls.InternationalizeAction"
585
			   menubarPath="org.eclipse.pde.ui.plugin.tools/group0"
586
               enablesFor="+"
587
               id="org.eclipse.pde.ui.Internationalize">
588
         </action>
581
         <action
589
         <action
582
               label="%ExternalizeStrings.label"
590
               label="%ExternalizeStrings.label"
583
               helpContextId="org.eclipse.pde.doc.user.externalize_strings"
591
               helpContextId="org.eclipse.pde.doc.user.externalize_strings"
Lines 618-623 Link Here
618
                  name="group1">
626
                  name="group1">
619
            </separator>
627
            </separator>
620
         </menu>
628
         </menu>
629
          <action
630
			   label="%Internationalize.label"
631
			   class="org.eclipse.pde.internal.ui.nls.InternationalizeAction"
632
			   menubarPath="org.eclipse.pde.ui.manifest.tools/group0"
633
               enablesFor="+"
634
               id="org.eclipse.pde.ui.Internationalize">
635
         </action>
621
         <action
636
         <action
622
               label="%ExternalizeStrings.label"
637
               label="%ExternalizeStrings.label"
623
               helpContextId="org.eclipse.pde.doc.user.externalize_strings"
638
               helpContextId="org.eclipse.pde.doc.user.externalize_strings"
Lines 625-631 Link Here
625
               menubarPath="org.eclipse.pde.ui.manifest.tools/group0"
640
               menubarPath="org.eclipse.pde.ui.manifest.tools/group0"
626
               enablesFor="+"
641
               enablesFor="+"
627
               id="org.eclipse.pde.ui.ExternalizeStrings">
642
               id="org.eclipse.pde.ui.ExternalizeStrings">
628
         </action> 
643
         </action>
629
         <action
644
         <action
630
               label="%OrganizeManifest.label"
645
               label="%OrganizeManifest.label"
631
               helpContextId="org.eclipse.pde.doc.user.organize_manifest"
646
               helpContextId="org.eclipse.pde.doc.user.organize_manifest"
Lines 844-849 Link Here
844
               enablesFor="*"
859
               enablesFor="*"
845
               id="org.eclipse.pde.ui.UpdateClasspathAction3">
860
               id="org.eclipse.pde.ui.UpdateClasspathAction3">
846
         </action>
861
         </action>
862
          <action
863
			   label="%Internationalize.label"
864
			   class="org.eclipse.pde.internal.ui.nls.InternationalizeAction"
865
			   menubarPath="org.eclipse.pde.ui.project.tools/group1"
866
               enablesFor="+"
867
               id="org.eclipse.pde.ui.Internationalize">
868
         </action>
847
         <action
869
         <action
848
               label="%ExternalizeStrings.label"
870
               label="%ExternalizeStrings.label"
849
               helpContextId="org.eclipse.pde.doc.user.externalize_strings"
871
               helpContextId="org.eclipse.pde.doc.user.externalize_strings"
(-)src/org/eclipse/pde/internal/ui/pderesources.properties (+25 lines)
Lines 2050-2055 Link Here
2050
IntroSection_sectionDescription=The welcome page appears the first time the product is launched.  It is intended to introduce the features of the product to new users.
2050
IntroSection_sectionDescription=The welcome page appears the first time the product is launched.  It is intended to introduce the features of the product to new users.
2051
IntroSection_undefinedProductId=Undefined Product ID
2051
IntroSection_undefinedProductId=Undefined Product ID
2052
2052
2053
InternationalizeAction_internationalizeTitle=Internationalize Plug-ins
2054
InternationalizeAction_internationalizeMessage=All plug-ins have been internationalized
2055
InternationalizeWizard_title=Internationalize Plug-ins
2056
InternationalizeWizard_PluginPage_internationalizeList = Plug-ins to internationalize:
2057
InternationalizeWizard_PluginPage_availableList = Plug-ins found:
2058
InternationalizeWizard_PluginPage_filter = Filter available plug-ins
2059
InternationalizeWizard_PluginPage_templateLabel = Fragment project name template:
2060
InternationalizeWizard_PluginPage_pageTitle=Internationalize Plug-ins
2061
InternationalizeWizard_PluginPage_pageDescription=Select the plug-ins to be internationalized.
2062
InternationalizeWizard_PluginPage_overwriteWithoutAsking=Overwrite existing projects without warning
2063
InternationalizeWizard_PluginPage_individualFragments=Create individual fragment projects for each locale
2064
InternationalizeWizard_PluginPage_templateError=The name template cannot be blank.
2065
InternationalizeWizard_PluginPage_selectionError=At least one plug-in must be selected.
2066
InternationalizeWizard_LocalePage_pageTitle=Internationalize Plug-ins
2067
InternationalizeWizard_LocalePage_pageDescription=Select the locales for which plug-ins should be internationalized.
2068
InternationalizeWizard_LocalePage_internationalizeList = Locales to include:
2069
InternationalizeWizard_LocalePage_availableList = Available locales:
2070
InternationalizeWizard_LocalePage_filter = Filter available locales:
2071
InternationalizeWizard_LocalePage_selectionError=At least one locale must be selected.
2072
InternationalizeWizard_NLSFragmentGenerator_overwriteTitle = Confirm Overwrite 
2073
InternationalizeWizard_NLSFragmentGenerator_overwriteMessage = A fragment project with the name "{0}" already exists. Overwrite?
2074
InternationalizeWizard_NLSFragmentGenerator_errorMessage = An error occured while generating an NL Fragment.
2075
InternationalizeWizard_NLSFragmentGenerator_errorTitle = Error
2076
2077
2053
2078
2054
MainTab_jreSection = Java Runtime Environment
2079
MainTab_jreSection = Java Runtime Environment
2055
EquinoxLaunchConfiguration_oldTarget=The org.eclipse.osgi plug-in is missing from this configuration.
2080
EquinoxLaunchConfiguration_oldTarget=The org.eclipse.osgi plug-in is missing from this configuration.
(-)src/org/eclipse/pde/internal/ui/PDEUIMessages.java (+40 lines)
Lines 2472-2477 Link Here
2472
2472
2473
	public static String ExternalizeStringsWizardPage_keySuggested;
2473
	public static String ExternalizeStringsWizardPage_keySuggested;
2474
2474
2475
	public static String InternationalizeAction_internationalizeTitle;
2476
2477
	public static String InternationalizeAction_internationalizeMessage;
2478
2479
	public static String InternationalizeWizard_title;
2480
2481
	public static String InternationalizeWizard_PluginPage_internationalizeList;
2482
2483
	public static String InternationalizeWizard_PluginPage_availableList;
2484
2485
	public static String InternationalizeWizard_PluginPage_filter;
2486
2487
	public static String InternationalizeWizard_PluginPage_templateLabel;
2488
2489
	public static String InternationalizeWizard_PluginPage_pageTitle;
2490
2491
	public static String InternationalizeWizard_PluginPage_pageDescription;
2492
2493
	public static String InternationalizeWizard_PluginPage_overwriteWithoutAsking;
2494
	public static String InternationalizeWizard_PluginPage_templateError;
2495
	public static String InternationalizeWizard_PluginPage_selectionError;
2496
	public static String InternationalizeWizard_PluginPage_individualFragments;
2497
2498
	public static String InternationalizeWizard_LocalePage_pageTitle;
2499
2500
	public static String InternationalizeWizard_LocalePage_pageDescription;
2501
2502
	public static String InternationalizeWizard_LocalePage_internationalizeList;
2503
2504
	public static String InternationalizeWizard_LocalePage_availableList;
2505
	public static String InternationalizeWizard_LocalePage_selectionError;
2506
2507
	public static String InternationalizeWizard_LocalePage_filter;
2508
2509
	public static String InternationalizeWizard_NLSFragmentGenerator_overwriteTitle;
2510
2511
	public static String InternationalizeWizard_NLSFragmentGenerator_overwriteMessage;
2512
	public static String InternationalizeWizard_NLSFragmentGenerator_errorMessage;
2513
	public static String InternationalizeWizard_NLSFragmentGenerator_errorTitle;
2514
2475
	public static String NewProjectCreationPage_target;
2515
	public static String NewProjectCreationPage_target;
2476
2516
2477
	public static String NewProjectCreationPage_ftarget;
2517
	public static String NewProjectCreationPage_ftarget;
(-)src/org/eclipse/pde/internal/ui/nls/GetNonExternalizedStringsOperation.java (-7 / +29 lines)
Lines 12-17 Link Here
12
12
13
import java.lang.reflect.InvocationTargetException;
13
import java.lang.reflect.InvocationTargetException;
14
import java.util.ArrayList;
14
import java.util.ArrayList;
15
import java.util.Iterator;
15
import org.eclipse.core.resources.IFile;
16
import org.eclipse.core.resources.IFile;
16
import org.eclipse.core.resources.IProject;
17
import org.eclipse.core.resources.IProject;
17
import org.eclipse.core.runtime.*;
18
import org.eclipse.core.runtime.*;
Lines 37-44 Link Here
37
	private ModelChangeTable fModelChangeTable;
38
	private ModelChangeTable fModelChangeTable;
38
	private boolean fCanceled;
39
	private boolean fCanceled;
39
40
40
	public GetNonExternalizedStringsOperation(ISelection selection) {
41
	//Azure: To indicate that only selected plug-ins under <code>fSelection</code> are to be externalized.
42
	private boolean fExternalizeSelectedPluginsOnly;
43
44
	public GetNonExternalizedStringsOperation(ISelection selection, boolean externalizeSelectedPluginsOnly) {
41
		fSelection = selection;
45
		fSelection = selection;
46
		fExternalizeSelectedPluginsOnly = externalizeSelectedPluginsOnly;
42
	}
47
	}
43
48
44
	public void run(IProgressMonitor monitor) throws InvocationTargetException, InterruptedException {
49
	public void run(IProgressMonitor monitor) throws InvocationTargetException, InterruptedException {
Lines 56-67 Link Here
56
61
57
			fModelChangeTable = new ModelChangeTable();
62
			fModelChangeTable = new ModelChangeTable();
58
63
59
			IPluginModelBase[] pluginModels = PluginRegistry.getWorkspaceModels();
64
			/*
60
			monitor.beginTask(PDEUIMessages.GetNonExternalizedStringsOperation_taskMessage, pluginModels.length);
65
			 * Azure: This will add only the preselected plug-ins to the ModelChangeTable
61
			for (int i = 0; i < pluginModels.length && !fCanceled; i++) {
66
			 * instead of adding the list of all plug-ins in the workspace. This is useful
62
				IProject project = pluginModels[i].getUnderlyingResource().getProject();
67
			 * when the Internationalize action is run on a set of non-externalized plug-ins
63
				if (!WorkspaceModelManager.isBinaryProject(project))
68
			 * where there is no need to display all non-externalized plug-ins in the
64
					getUnExternalizedStrings(project, new SubProgressMonitor(monitor, 1));
69
			 * workspace, but only those selected.
70
			 */
71
			if (fExternalizeSelectedPluginsOnly) {
72
				monitor.beginTask(PDEUIMessages.GetNonExternalizedStringsOperation_taskMessage, fSelectedModels.size());
73
				Iterator iterator = fSelectedModels.iterator();
74
				while (iterator.hasNext() && !fCanceled) {
75
					IProject project = (IProject) iterator.next();
76
					if (!WorkspaceModelManager.isBinaryProject(project))
77
						getUnExternalizedStrings(project, new SubProgressMonitor(monitor, 1));
78
				}
79
			} else {
80
				IPluginModelBase[] pluginModels = PluginRegistry.getWorkspaceModels();
81
				monitor.beginTask(PDEUIMessages.GetNonExternalizedStringsOperation_taskMessage, pluginModels.length);
82
				for (int i = 0; i < pluginModels.length && !fCanceled; i++) {
83
					IProject project = pluginModels[i].getUnderlyingResource().getProject();
84
					if (!WorkspaceModelManager.isBinaryProject(project))
85
						getUnExternalizedStrings(project, new SubProgressMonitor(monitor, 1));
86
				}
65
			}
87
			}
66
		}
88
		}
67
	}
89
	}
(-)src/org/eclipse/pde/internal/ui/nls/GetNonExternalizedStringsAction.java (-3 / +53 lines)
Lines 23-34 Link Here
23
public class GetNonExternalizedStringsAction implements IWorkbenchWindowActionDelegate {
23
public class GetNonExternalizedStringsAction implements IWorkbenchWindowActionDelegate {
24
24
25
	private ISelection fSelection;
25
	private ISelection fSelection;
26
	//Azure: To indicate that only selected plug-ins are to be externalized. False by default.
27
	private boolean fExternalizeSelectedPluginsOnly = false;
28
29
	//Azure: To indicate that the post-externalization message dialog should not be displayed.
30
	private boolean fSkipMessageDialog = false;
26
31
27
	public GetNonExternalizedStringsAction() {
32
	public GetNonExternalizedStringsAction() {
28
	}
33
	}
29
34
30
	public void run(IAction action) {
35
	public void run(IAction action) {
31
		GetNonExternalizedStringsOperation runnable = new GetNonExternalizedStringsOperation(fSelection);
36
		/* 
37
		 * Azure: Pass <code>fExternalizeSelectedPluginsOnly</code> to the operation to indicate
38
		 * that only the plug-ins passed in the selection are to be externalized and such that
39
		 * only those are displayed on the change table in the ExternalizeStringsWizard.
40
		 */
41
		GetNonExternalizedStringsOperation runnable = new GetNonExternalizedStringsOperation(fSelection, fExternalizeSelectedPluginsOnly);
32
		try {
42
		try {
33
			PlatformUI.getWorkbench().getProgressService().busyCursorWhile(runnable);
43
			PlatformUI.getWorkbench().getProgressService().busyCursorWhile(runnable);
34
		} catch (InvocationTargetException e) {
44
		} catch (InvocationTargetException e) {
Lines 47-54 Link Here
47
					op.run(PDEPlugin.getActiveWorkbenchShell(), ""); //$NON-NLS-1$
57
					op.run(PDEPlugin.getActiveWorkbenchShell(), ""); //$NON-NLS-1$
48
				} catch (final InterruptedException irex) {
58
				} catch (final InterruptedException irex) {
49
				}
59
				}
50
			} else
60
			} else {
51
				MessageDialog.openInformation(PlatformUI.getWorkbench().getActiveWorkbenchWindow().getShell(), PDEUIMessages.GetNonExternalizedStringsAction_allExternalizedTitle, PDEUIMessages.GetNonExternalizedStringsAction_allExternalizedMessage);
61
				/* 
62
				 * Azure: When the InternationalizeAction invokes the ExternalizeStringsAction,
63
				 * <code>fSkipMessageDialog</code> is set to true in order for no intermediate
64
				 * message to appear if all selected plug-ins were already externalized.
65
				 */
66
				if (!fSkipMessageDialog)
67
					MessageDialog.openInformation(PlatformUI.getWorkbench().getActiveWorkbenchWindow().getShell(), PDEUIMessages.GetNonExternalizedStringsAction_allExternalizedTitle, PDEUIMessages.GetNonExternalizedStringsAction_allExternalizedMessage);
68
			}
52
		}
69
		}
53
	}
70
	}
54
71
Lines 61-64 Link Here
61
78
62
	public void init(IWorkbenchWindow window) {
79
	public void init(IWorkbenchWindow window) {
63
	}
80
	}
81
	
82
	
83
	/**
84
	 * TODO: Azure Documentation
85
	 * @param externalizeSelectedPluginsOnly
86
	 */
87
	public void setExternalizeSelectedPluginsOnly(boolean externalizeSelectedPluginsOnly) {
88
		fExternalizeSelectedPluginsOnly = externalizeSelectedPluginsOnly;
89
	}
90
91
	/**
92
	 * TODO: Azure Documentation
93
	 * @return
94
	 */
95
	public boolean isExternalizeSelectedPluginsOnly() {
96
		return fExternalizeSelectedPluginsOnly;
97
	}
98
99
	/**
100
	 * TODO: Azure Documentation
101
	 * @param skipMessageDialog
102
	 */
103
	public void setSkipMessageDialog(boolean skipMessageDialog) {
104
		this.fSkipMessageDialog = skipMessageDialog;
105
	}
106
107
	/**
108
	 * TODO: Azure Documentation
109
	 * @return
110
	 */
111
	public boolean isSkipMessageDialog() {
112
		return fSkipMessageDialog;
113
	}
64
}
114
}
(-)src/org/eclipse/pde/internal/ui/nls/InternationalizationWizardPage.java (+55 lines)
Added Link Here
1
/*******************************************************************************
2
 * Copyright (c) 2008 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.nls;
13
14
import org.eclipse.jface.resource.ImageDescriptor;
15
import org.eclipse.jface.wizard.WizardPage;
16
import org.eclipse.swt.SWT;
17
import org.eclipse.swt.layout.GridData;
18
import org.eclipse.swt.layout.GridLayout;
19
import org.eclipse.swt.widgets.*;
20
21
public abstract class InternationalizationWizardPage extends WizardPage {
22
23
	public InternationalizationWizardPage(String pageName) {
24
		super(pageName);
25
	}
26
27
	public InternationalizationWizardPage(String pageName, String title, ImageDescriptor titleImage) {
28
		super(pageName, title, titleImage);
29
	}
30
31
	protected Group createFilterContainer(Composite parent, String title, String label) {
32
		Group container = new Group(parent, SWT.NONE);
33
		GridLayout layout = new GridLayout(2, false);
34
		layout.marginWidth = layout.marginHeight = 6;
35
		container.setLayout(layout);
36
37
		GridData gd = new GridData(GridData.FILL_HORIZONTAL);
38
		gd.horizontalSpan = 3;
39
		container.setLayoutData(gd);
40
		container.setText(title);
41
42
		Label templateLabel = new Label(container, SWT.NONE);
43
		templateLabel.setText(label);
44
		return container;
45
	}
46
47
	protected Text createFilterText(Composite parent, String initial) {
48
		Text text = new Text(parent, SWT.BORDER);
49
		text.setText(initial);
50
		GridData gd = new GridData(GridData.FILL_HORIZONTAL);
51
		text.setLayoutData(gd);
52
		return text;
53
	}
54
55
}
(-)src/org/eclipse/pde/internal/ui/nls/NLSFragmentGenerator.java (+543 lines)
Added Link Here
1
/*******************************************************************************
2
 * Copyright (c) 2008 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.nls;
13
14
import java.io.*;
15
import java.lang.reflect.InvocationTargetException;
16
import java.util.*;
17
import java.util.zip.ZipEntry;
18
import java.util.zip.ZipFile;
19
import org.eclipse.core.resources.*;
20
import org.eclipse.core.runtime.*;
21
import org.eclipse.jface.dialogs.ErrorDialog;
22
import org.eclipse.jface.dialogs.MessageDialog;
23
import org.eclipse.jface.operation.IRunnableWithProgress;
24
import org.eclipse.jface.wizard.IWizardContainer;
25
import org.eclipse.osgi.util.NLS;
26
import org.eclipse.pde.core.plugin.IPluginModelBase;
27
import org.eclipse.pde.internal.core.TargetPlatformHelper;
28
import org.eclipse.pde.internal.core.plugin.ExternalPluginModelBase;
29
import org.eclipse.pde.internal.ui.*;
30
import org.eclipse.pde.internal.ui.wizards.IProjectProvider;
31
import org.eclipse.pde.internal.ui.wizards.plugin.FragmentFieldData;
32
import org.eclipse.pde.internal.ui.wizards.plugin.NewProjectCreationOperation;
33
import org.eclipse.swt.widgets.Display;
34
import org.eclipse.swt.widgets.Shell;
35
36
/**
37
 * 
38
 * Generates the fragment projects for the list of selected plug-ins.
39
 * Each fragment contains a series of properties files specific to the locales
40
 * the user selected. For example plugin_fr.properties for the french locale
41
 * selection. The generated locale-specific properties files contain the same
42
 * key-value pairs as the properties file of the initial plug-in.
43
 * 
44
 * @author Team Azure
45
 *
46
 */
47
public class NLSFragmentGenerator {
48
	public static final String PLUGIN_NAME_MACRO = "${plugin_name}"; //$NON-NLS-1$
49
	public static final String LOCALE_NAME_MACRO = "${locale}"; //$NON-NLS-1$
50
51
	private static final String HTML_EXTENSION = ".html"; //$NON-NLS-1$
52
	private static final String XML_EXTENSION = ".xml"; //$NON-NLS-1$
53
	private static final String CLASS_EXTENSION = ".class"; //$NON-NLS-1$
54
	private static final String JAVA_EXTENSION = ".java"; //$NON-NLS-1$
55
	private static final String PROPERTIES_EXTENSION = ".properties"; //$NON-NLS-1$
56
	private static final String JAR_EXTENSION = ".jar"; //$NON-NLS-1$
57
58
	private static final String PLUGIN_XML = "plugin.xml"; //$NON-NLS-1$
59
	private static final String BUILD_PROPERTIES = "build.properties"; //$NON-NLS-1$
60
61
	private static final String BIN = "/bin/"; //$NON-NLS-1$
62
	private static final String EMPTY_STRING = ""; //$NON-NLS-1$
63
	private static final String BACKSLASH = "\\"; //$NON-NLS-1$
64
	private static final String SLASH = "/"; //$NON-NLS-1$
65
	private static final String RESOURCE_FOLDER_PARENT = "/nl"; //$NON-NLS-1$
66
	private static final double LATEST_ECLIPSE_VERSION = 3.4;
67
68
	private static final String ZERO = "0"; //$NON-NLS-1$
69
	private static final String PERIOD = "."; //$NON-NLS-1$
70
	private static final String MIN_MINOR = ZERO;
71
	private static final String MAX_MINOR = "9"; //$NON-NLS-1$
72
	private static final String LEFT_SQUARE_BRACKET = "["; //$NON-NLS-1$
73
	private static final String RIGHT_PARENTHESIS = ")"; //$NON-NLS-1$
74
	private static final String DEFAULT_VERSION = "1.0.0"; //$NON-NLS-1$
75
	private static final String VERSION_FORMAT_WITH_QUALIFIER = "\\d+\\.\\d+\\.\\d+\\..+"; //$NON-NLS-1$
76
	private static final String LOCALE_INFIX_SEPERATOR = "_"; //$NON-NLS-1$
77
78
	private final IWizardContainer container;
79
	private final String template;
80
	private final List plugins;
81
	private final List locales;
82
	private final boolean overwriteWithoutAsking;
83
	private IProgressMonitor monitor;
84
85
	private final Filters resourceFilter = new Filters(false) {
86
		{
87
			add(new AbstractFilter(false) {
88
				public boolean matches(Object object) {
89
					String resource = object.toString();
90
					return resource.endsWith(PROPERTIES_EXTENSION) || resource.endsWith(CLASS_EXTENSION) || resource.endsWith(JAVA_EXTENSION);
91
				}
92
			});
93
94
			add(new AbstractFilter(false) {
95
				public boolean matches(Object object) {
96
					String path = object.toString();
97
					return path.indexOf(BIN) != -1 || path.endsWith(SLASH) || path.endsWith(PLUGIN_XML);
98
				}
99
			});
100
101
			add(new AbstractFilter(true) {
102
				public boolean matches(Object object) {
103
					String path = object.toString();
104
					return path.endsWith(XML_EXTENSION) || path.endsWith(HTML_EXTENSION);
105
				}
106
			});
107
		}
108
	};
109
110
	private final Filters propertiesFilter = new Filters(false) {
111
		{
112
			add(new AbstractFilter(false) {
113
				public boolean matches(Object object) {
114
					String path = object.toString();
115
					return path.indexOf(BIN) != -1 || path.endsWith(BUILD_PROPERTIES);
116
				}
117
			});
118
119
			add(new AbstractFilter(true) {
120
				public boolean matches(Object object) {
121
					return object.toString().endsWith(PROPERTIES_EXTENSION);
122
				}
123
			});
124
		}
125
	};
126
127
	public NLSFragmentGenerator(String template, List plugins, List locales, IWizardContainer container, boolean overwriteWithoutAsking) {
128
		this.plugins = plugins;
129
		this.locales = locales;
130
		this.container = container;
131
		this.template = template;
132
		this.overwriteWithoutAsking = overwriteWithoutAsking;
133
	}
134
135
	private synchronized void setProgressMonitor(IProgressMonitor monitor) {
136
		this.monitor = monitor;
137
	}
138
139
	private synchronized IProgressMonitor getProgressMonitor() {
140
		return monitor;
141
	}
142
143
	public boolean generate() {
144
		try {
145
			final Map overwrites = promptForOverwrite(plugins, locales);
146
147
			container.run(false, false, new IRunnableWithProgress() {
148
				public void run(IProgressMonitor monitor) throws InvocationTargetException, InterruptedException {
149
					setProgressMonitor(monitor);
150
					try {
151
						internationalizePlugins(plugins, locales, overwrites);
152
					} catch (final Exception ex) {
153
						Display.getDefault().syncExec(new Runnable() {
154
							public void run() {
155
								IStatus status = new Status(IStatus.ERROR, IPDEUIConstants.PLUGIN_ID, PDEUIMessages.InternationalizeWizard_NLSFragmentGenerator_errorMessage, ex);
156
								PDEPlugin.getDefault().getLog().log(status);
157
								ErrorDialog.openError(PDEPlugin.getActiveWorkbenchShell(), PDEUIMessages.InternationalizeWizard_NLSFragmentGenerator_errorTitle, null, status);
158
								ex.printStackTrace();
159
							}
160
						});
161
					}
162
				}
163
			});
164
		} catch (Exception e) {
165
			e.printStackTrace();
166
		}
167
		return true;
168
	}
169
170
	/**
171
	 * Creates an NL fragment project along with the locale specific properties
172
	 * files.
173
	 * @throws CoreException 
174
	 * @throws IOException 
175
	 * @throws InvocationTargetException 
176
	 * @throws InterruptedException 
177
	 */
178
	private void internationalizePlugins(List plugins, List locales, Map overwrites) throws CoreException, IOException, InvocationTargetException, InterruptedException {
179
180
		Set created = new HashSet();
181
182
		for (Iterator it = plugins.iterator(); it.hasNext();) {
183
			IPluginModelBase plugin = (IPluginModelBase) it.next();
184
185
			for (Iterator iter = locales.iterator(); iter.hasNext();) {
186
				Locale locale = (Locale) iter.next();
187
188
				IProject project = getNLProject(plugin, locale);
189
				if (created.contains(project) || overwriteWithoutAsking || !project.exists() || OVERWRITE == overwrites.get(project.getName())) {
190
					if (!created.contains(project) && project.exists()) {
191
						project.delete(true, getProgressMonitor());
192
					}
193
194
					if (!created.contains(project)) {
195
						createNLFragment(plugin, project, locale);
196
						created.add(project);
197
						project.getFolder(RESOURCE_FOLDER_PARENT).create(false, true, getProgressMonitor());
198
					}
199
200
					project.getFolder(RESOURCE_FOLDER_PARENT).getFolder(locale.toString()).create(true, true, getProgressMonitor());
201
					createLocaleSpecificPropertiesFile(project, plugin, locale);
202
				}
203
			}
204
		}
205
	}
206
207
	private Object OVERWRITE = new Object();
208
209
	private Map promptForOverwrite(List plugins, List locales) {
210
		Map overwrites = new HashMap();
211
212
		if (overwriteWithoutAsking)
213
			return overwrites;
214
215
		for (Iterator iter = plugins.iterator(); iter.hasNext();) {
216
			IPluginModelBase plugin = (IPluginModelBase) iter.next();
217
			for (Iterator it = locales.iterator(); it.hasNext();) {
218
				Locale locale = (Locale) it.next();
219
				IProject project = getNLProject(plugin, locale);
220
221
				if (project.exists() && !overwrites.containsKey(project.getName())) {
222
					boolean overwrite = MessageDialog.openConfirm(PDEPlugin.getActiveWorkbenchShell(), PDEUIMessages.InternationalizeWizard_NLSFragmentGenerator_overwriteTitle, NLS.bind(PDEUIMessages.InternationalizeWizard_NLSFragmentGenerator_overwriteMessage, pluginName(plugin, locale)));
223
					overwrites.put(project.getName(), overwrite ? OVERWRITE : null);
224
				}
225
			}
226
		}
227
228
		return overwrites;
229
	}
230
231
	private IProject getNLProject(final IPluginModelBase name, final Locale locale) {
232
		return ResourcesPlugin.getWorkspace().getRoot().getProject(pluginName(name, locale));
233
	}
234
235
	/**
236
	 * Creates a fragment project for the specified plug-in and populates
237
	 * the field data.
238
	 * @param plugin
239
	 * @throws CoreException 
240
	 * @throws InvocationTargetException 
241
	 * @throws InterruptedException 
242
	 */
243
	private void createNLFragment(final IPluginModelBase plugin, final IProject project, final Locale locale) throws CoreException, InvocationTargetException, InterruptedException {
244
		FragmentFieldData fragmentData = populateFieldData(plugin, locale);
245
246
		IProjectProvider projectProvider = new IProjectProvider() {
247
			public String getProjectName() {
248
				return project.getName();
249
			}
250
251
			public IProject getProject() {
252
				return project;
253
			}
254
255
			public IPath getLocationPath() {
256
				return project.getLocation();
257
			}
258
		};
259
260
		new NewProjectCreationOperation(fragmentData, projectProvider, null).run(getProgressMonitor());
261
	}
262
263
	private String pluginName(IPluginModelBase plugin, Locale locale) {
264
		return template.replaceAll(quote(PLUGIN_NAME_MACRO), plugin.getPluginBase().getId()).replaceAll(quote(LOCALE_NAME_MACRO), locale.toString());
265
	}
266
267
	/**
268
	 * The fields are populated based on the plug-in attributes. Some fields
269
	 * are set to their default values.
270
	 */
271
	private FragmentFieldData populateFieldData(IPluginModelBase plugin, Locale locale) {
272
		FragmentFieldData fragmentData = new FragmentFieldData();
273
274
		fragmentData.setId(pluginName(plugin, locale));
275
		fragmentData.setVersion(DEFAULT_VERSION);
276
		fragmentData.setMatch(0);
277
278
		fragmentData.setPluginId(plugin.getPluginBase().getId());
279
		fragmentData.setPluginVersion(incrementRelease(plugin.getPluginBase().getVersion()));
280
		fragmentData.setName(pluginName(plugin, locale) + " Fragment"); //$NON-NLS-1$
281
		fragmentData.setProvider(EMPTY_STRING);
282
		fragmentData.setSimple(true);
283
284
		if (!(plugin instanceof ExternalPluginModelBase)) {
285
			fragmentData.setSourceFolderName("src"); //$NON-NLS-1$
286
			fragmentData.setOutputFolderName("bin"); //$NON-NLS-1$
287
		}
288
289
		fragmentData.setLegacy(false);
290
		fragmentData.setTargetVersion(Double.toString(ensureTargetVersionCompatibility(TargetPlatformHelper.getTargetVersion())));
291
		fragmentData.setHasBundleStructure(true);
292
		fragmentData.setOSGiFramework(null);
293
		fragmentData.setWorkingSets(null);
294
295
		return fragmentData;
296
	}
297
298
	/**
299
	 * Adjusts the plug-in's version to reflect the required
300
	 * fragment-host bundle-version range. For example, 
301
	 * fragment-host's bundle-version range would be: "[1.0.0, 1.1.0)" 
302
	 * if the host's version is 1.0.0
303
	 * @param oldVersion
304
	 * @return adjusted plug-in version
305
	 */
306
	private String incrementRelease(String oldVersion) {
307
		if (oldVersion.matches(VERSION_FORMAT_WITH_QUALIFIER)) {
308
			oldVersion = oldVersion.substring(0, oldVersion.lastIndexOf(PERIOD));
309
		}
310
311
		String newVersion = LEFT_SQUARE_BRACKET + oldVersion + ',';
312
		String oldMinor = oldVersion.substring(oldVersion.indexOf(PERIOD) + 1, oldVersion.lastIndexOf(PERIOD));
313
314
		if (oldMinor.compareTo(MAX_MINOR) == 0) {
315
			String major = Integer.toString(Integer.parseInt(oldVersion.substring(0, oldVersion.indexOf(PERIOD))) + 1);
316
			newVersion += major + PERIOD + MIN_MINOR + PERIOD + ZERO + RIGHT_PARENTHESIS;
317
		} else {
318
			String major = oldVersion.substring(0, oldVersion.indexOf(PERIOD));
319
			String newMinor = Integer.toString(Integer.parseInt(oldMinor) + 1);
320
			newVersion += major + PERIOD + newMinor + PERIOD + ZERO + RIGHT_PARENTHESIS;
321
		}
322
323
		return newVersion;
324
	}
325
326
	/**
327
	 * Creates a locale specific properties file within the fragment project 
328
	 * based on the content of the host plug-in's properties file.
329
	 * @param fragmentProject
330
	 * @param locale
331
	 * @throws CoreException 
332
	 * @throws IOException 
333
	 */
334
	private void createLocaleSpecificPropertiesFile(final IProject fragmentProject, IPluginModelBase plugin, final Locale locale) throws CoreException, IOException {
335
		final IFolder localeResourceFolder = fragmentProject.getFolder(RESOURCE_FOLDER_PARENT).getFolder(locale.toString());
336
337
		//Case 1: External plug-in
338
		if (plugin instanceof ExternalPluginModelBase) {
339
			final String installLocation = plugin.getInstallLocation();
340
			//Case 1a: External plug-in is a jar file
341
			if (installLocation.endsWith(JAR_EXTENSION)) {
342
				ZipFile zf = new ZipFile(installLocation);
343
				for (Enumeration e = zf.entries(); e.hasMoreElements();) {
344
					worked();
345
346
					ZipEntry zfe = (ZipEntry) e.nextElement();
347
					String name = zfe.getName();
348
349
					String[] segments = name.split(SLASH);
350
					IPath path = Path.fromPortableString(join(SLASH, segments, 0, segments.length - 1));
351
					String resourceName = segments[segments.length - 1];
352
					String localizedResourceName = localeSpecificName(resourceName, locale);
353
					if (propertiesFilter.include(name)) {
354
355
						createParents(fragmentProject, path);
356
						IFile file = fragmentProject.getFile(path.append(localizedResourceName));
357
						InputStream is = zf.getInputStream(zfe);
358
						file.create(is, false, getProgressMonitor());
359
					} else if (resourceFilter.include(name)) {
360
						IPath target = localeResourceFolder.getFullPath().append(path).append(resourceName);
361
						createParents(fragmentProject, target.removeLastSegments(1).removeFirstSegments(1));
362
						IFile file = fragmentProject.getFile(target.removeFirstSegments(1));
363
						file.create(zf.getInputStream(zfe), false, getProgressMonitor());
364
					}
365
				}
366
			}
367
			//Case 1b: External plug-in has a folder structure
368
			else {
369
				Visitor visitor = new Visitor() {
370
					public void visit(File file) throws CoreException, FileNotFoundException {
371
						worked();
372
373
						String relativePath = file.getAbsolutePath().substring(installLocation.length()).replaceAll(File.separator, SLASH);
374
						String[] segments = relativePath.split(SLASH);
375
						IPath path = Path.fromPortableString(join(SLASH, segments, 0, segments.length - 1));
376
						String resourceName = segments[segments.length - 1];
377
						String localizedResourceName = localeSpecificName(resourceName, locale);
378
379
						if (propertiesFilter.include(relativePath + (file.isDirectory() ? SLASH : EMPTY_STRING))) {
380
							createParents(fragmentProject, path);
381
							IFile iFile = fragmentProject.getFile(path.append(localizedResourceName));
382
							iFile.create(new FileInputStream(file), false, getProgressMonitor());
383
						} else if (resourceFilter.include(relativePath + (file.isDirectory() ? SLASH : EMPTY_STRING))) {
384
							IPath target = localeResourceFolder.getFullPath().append(relativePath);
385
							createParents(fragmentProject, target.removeLastSegments(1).removeFirstSegments(1));
386
							IFile iFile = fragmentProject.getFile(target.removeFirstSegments(1));
387
							iFile.create(new FileInputStream(file), false, getProgressMonitor());
388
						}
389
390
						if (file.isDirectory()) {
391
							File[] children = file.listFiles();
392
							for (int i = 0; i < children.length; i++) {
393
								visit(children[i]);
394
							}
395
						}
396
					}
397
				};
398
399
				visitor.visit(new File(installLocation));
400
			}
401
		}
402
		//Case 2: Workspace plug-in
403
		else {
404
			final IProject project = plugin.getUnderlyingResource().getProject();
405
406
			project.accept(new IResourceVisitor() {
407
				public boolean visit(IResource resource) throws CoreException {
408
					worked();
409
410
					IPath parent = resource.getFullPath().removeLastSegments(1).removeFirstSegments(1);
411
					if (propertiesFilter.include(resource)) {
412
						String segment = localeSpecificName(resource.getFullPath().lastSegment(), locale);
413
						IPath fragmentResource = fragmentProject.getFullPath().append(parent).append(segment);
414
415
						createParents(fragmentProject, parent);
416
						resource.copy(fragmentResource, true, getProgressMonitor());
417
					} else if (resourceFilter.include(resource)) {
418
						IPath target = localeResourceFolder.getFullPath().append(parent).append(resource.getFullPath().lastSegment());
419
						createParents(fragmentProject, target.removeLastSegments(1).removeFirstSegments(1));
420
						resource.copy(target, true, getProgressMonitor());
421
					}
422
					return true;
423
				}
424
			});
425
		}
426
427
	}
428
429
	private void worked() {
430
		Shell shell = container.getShell();
431
		Display display = shell.getDisplay();
432
		if (display != null && !shell.isDisposed()) {
433
			display.readAndDispatch();
434
		}
435
	}
436
437
	private void createParents(IProject fragmentProject, IPath parent) throws CoreException {
438
		String[] segments = parent.segments();
439
		String path = new String();
440
441
		for (int i = 0; i < segments.length; i++) {
442
			path += SLASH + segments[i];
443
			IFolder folder = fragmentProject.getFolder(path);
444
			if (!folder.exists()) {
445
				folder.create(true, true, getProgressMonitor());
446
			}
447
		}
448
	}
449
450
	private String join(String delimiter, String[] parts) {
451
		return join(delimiter, parts, 0, parts.length);
452
	}
453
454
	private String join(String delimiter, String[] parts, int offset, int n) {
455
		StringBuffer builder = new StringBuffer();
456
		for (int i = offset; i < n; i++) {
457
			builder.append(parts[i]);
458
			if (i < parts.length - 1) {
459
				builder.append(delimiter);
460
			}
461
		}
462
		return builder.toString();
463
	}
464
465
	private String localeSpecificName(String name, Locale locale) {
466
		String[] parts = name.split(BACKSLASH + PERIOD);
467
		parts[0] = parts[0] + LOCALE_INFIX_SEPERATOR + locale;
468
		return join(PERIOD, parts);
469
	}
470
471
	private static class Filters {
472
		private final List filters = new LinkedList();
473
		private final boolean default_;
474
475
		public Filters(boolean default_) {
476
			this.default_ = default_;
477
		}
478
479
		public void add(Filter filter) {
480
			filters.add(filter);
481
		}
482
483
		public void remove(Filter filter) {
484
			filters.remove(filter);
485
		}
486
487
		public boolean include(Object object) {
488
			if (object instanceof IResource) {
489
				IResource resource = (IResource) object;
490
				IPath path = IResource.FILE == resource.getType() ? resource.getFullPath() : resource.getFullPath().addTrailingSeparator();
491
				object = path.toPortableString();
492
			}
493
494
			for (Iterator iter = filters.iterator(); iter.hasNext();) {
495
				Filter filter = (Filter) iter.next();
496
				if (filter.matches(object)) {
497
					return filter.inclusive();
498
				}
499
			}
500
			return default_;
501
		}
502
	}
503
504
	private static abstract class AbstractFilter implements Filter {
505
506
		private final boolean inclusive;
507
508
		public AbstractFilter(boolean inclusive) {
509
			this.inclusive = inclusive;
510
511
		}
512
513
		public boolean inclusive() {
514
			return inclusive;
515
		}
516
	}
517
518
	private static interface Filter {
519
		boolean inclusive();
520
521
		boolean matches(Object object);
522
	}
523
524
	private static interface Visitor {
525
		void visit(File file) throws CoreException, FileNotFoundException;
526
	}
527
528
	private String quote(String pattern) {
529
		return "\\Q" + pattern + "\\E"; //$NON-NLS-1$ //$NON-NLS-2$
530
	}
531
532
	/**
533
	 * Ensures that the target version is compatible.
534
	 * @param targetVersion
535
	 * @return target version
536
	 */
537
	private double ensureTargetVersionCompatibility(double targetVersion) {
538
		if (targetVersion < 3.0) {
539
			return LATEST_ECLIPSE_VERSION;
540
		}
541
		return targetVersion;
542
	}
543
}
(-)src/org/eclipse/pde/internal/ui/nls/InternationalizeWizardOpenOperation.java (+75 lines)
Added Link Here
1
/*******************************************************************************
2
 * Copyright (c) 2008 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.nls;
13
14
import org.eclipse.core.resources.ResourcesPlugin;
15
import org.eclipse.core.runtime.Assert;
16
import org.eclipse.core.runtime.OperationCanceledException;
17
import org.eclipse.core.runtime.jobs.IJobManager;
18
import org.eclipse.core.runtime.jobs.Job;
19
import org.eclipse.jface.dialogs.Dialog;
20
import org.eclipse.jface.window.Window;
21
import org.eclipse.jface.wizard.IWizardContainer;
22
import org.eclipse.jface.wizard.WizardDialog;
23
import org.eclipse.swt.custom.BusyIndicator;
24
import org.eclipse.swt.widgets.Shell;
25
26
/**
27
 * A helper class to open an InternationalizeWizard dialog.
28
 * 
29
 * @author Team Azure
30
 */
31
public class InternationalizeWizardOpenOperation {
32
33
	private InternationalizeWizard fWizard;
34
35
	public InternationalizeWizardOpenOperation(InternationalizeWizard wizard) {
36
		Assert.isNotNull(wizard);
37
		fWizard = wizard;
38
	}
39
40
	public int run(final Shell parent, final String dialogTitle) throws InterruptedException {
41
		Assert.isNotNull(dialogTitle);
42
		final IJobManager manager = Job.getJobManager();
43
		final int[] result = new int[1];
44
		final InterruptedException[] canceled = new InterruptedException[1];
45
46
		Runnable r = new Runnable() {
47
			public void run() {
48
				try {
49
					manager.beginRule(ResourcesPlugin.getWorkspace().getRoot(), null);
50
51
					Dialog dialog = new WizardDialog(parent, fWizard);
52
					dialog.create();
53
54
					IWizardContainer wizardContainer = (IWizardContainer) dialog;
55
					if (wizardContainer.getCurrentPage() == null) {
56
						//Close the dialog if there are no pages
57
						result[0] = Window.CANCEL;
58
					} else {
59
						//Open the wizard dialog
60
						result[0] = dialog.open();
61
					}
62
63
				} catch (OperationCanceledException e) {
64
					canceled[0] = new InterruptedException(e.getMessage());
65
				} finally {
66
					manager.endRule(ResourcesPlugin.getWorkspace().getRoot());
67
				}
68
			}
69
		};
70
		BusyIndicator.showWhile(parent.getDisplay(), r);
71
		if (canceled[0] != null)
72
			throw canceled[0];
73
		return result[0];
74
	}
75
}
(-)src/org/eclipse/pde/internal/ui/nls/InternationalizeAction.java (+79 lines)
Added Link Here
1
/*******************************************************************************
2
 * Copyright (c) 2008 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.pde.internal.ui.nls;
12
13
import java.lang.reflect.InvocationTargetException;
14
import org.eclipse.jface.action.IAction;
15
import org.eclipse.jface.dialogs.MessageDialog;
16
import org.eclipse.jface.viewers.ISelection;
17
import org.eclipse.jface.viewers.IStructuredSelection;
18
import org.eclipse.pde.internal.ui.PDEPlugin;
19
import org.eclipse.pde.internal.ui.PDEUIMessages;
20
import org.eclipse.ui.*;
21
22
/**
23
 * This action class is responsible for creating and initializing the
24
 * InternationalizeWizard.
25
 * 
26
 * @author Team Azure
27
 *
28
 */
29
public class InternationalizeAction implements IWorkbenchWindowActionDelegate {
30
31
	private IStructuredSelection fSelection;
32
33
	public InternationalizeAction() {
34
	}
35
36
	public void run(IAction action) {
37
		//Create an InternationalizeOperation on the workbench selection.
38
		InternationalizeOperation runnable = new InternationalizeOperation(fSelection);
39
		try {
40
			PlatformUI.getWorkbench().getProgressService().busyCursorWhile(runnable);
41
		} catch (InvocationTargetException e) {
42
		} catch (InterruptedException e) {
43
		} finally {
44
			if (runnable.wasCanceled()) {
45
				return;
46
			}
47
48
			/*	Get the plugin model table containing the list of workspace and 
49
			 * 	external plug-ins
50
			 */
51
			InternationalizeModelTable pluginTable = runnable.getPluginTable();
52
53
			if (!pluginTable.isEmpty()) {
54
55
				InternationalizeWizard wizard = new InternationalizeWizard(action, pluginTable);
56
				wizard.init(PlatformUI.getWorkbench(), fSelection);
57
58
				//Create an operation to start and run the wizard
59
				InternationalizeWizardOpenOperation op = new InternationalizeWizardOpenOperation(wizard);
60
				try {
61
					op.run(PDEPlugin.getActiveWorkbenchShell(), ""); //$NON-NLS-1$
62
				} catch (final InterruptedException irex) {
63
				}
64
			} else {
65
				MessageDialog.openInformation(PlatformUI.getWorkbench().getActiveWorkbenchWindow().getShell(), PDEUIMessages.InternationalizeAction_internationalizeTitle, PDEUIMessages.InternationalizeAction_internationalizeMessage);
66
			}
67
		}
68
	}
69
70
	public void selectionChanged(IAction action, ISelection selection) {
71
		fSelection = (IStructuredSelection) selection;
72
	}
73
74
	public void dispose() {
75
	}
76
77
	public void init(IWorkbenchWindow window) {
78
	}
79
}
(-)src/org/eclipse/pde/internal/ui/nls/InternationalizeModelTable.java (+103 lines)
Added Link Here
1
/*******************************************************************************
2
 * Copyright (c) 2008 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.nls;
13
14
import java.util.ArrayList;
15
import java.util.List;
16
17
/**
18
 * 
19
 * Stores the list of BundlePluginModels and ExternalPluginModels to be passed to the
20
 * InternationalizeWizard. This class could also used to populate the list of locales
21
 * to which plug-ins will be internationalized.
22
 * 
23
 * @author Team Azure
24
 *
25
 */
26
public class InternationalizeModelTable {
27
	private List fModels;
28
	private List fPreSelected; //Models preselected by the user
29
30
	public InternationalizeModelTable() {
31
		fModels = new ArrayList();
32
		fPreSelected = new ArrayList();
33
	}
34
35
	/**
36
	 * Adds the model to the model table. Takes into consideration the specified
37
	 * selection.
38
	 * @param model
39
	 * @param selected
40
	 */
41
	public void addToModelTable(Object model, boolean selected) {
42
		if (selected)
43
			fPreSelected.add(model);
44
		else
45
			fModels.add(model);
46
	}
47
48
	/**
49
	 * Adds the model to the model table.
50
	 * @param model
51
	 */
52
	public void addModel(Object model) {
53
		fModels.add(model);
54
	}
55
56
	/**
57
	 * Removes the specified model from the model table.
58
	 * @param model
59
	 */
60
	public void removeModel(Object model) {
61
		fModels.remove(model);
62
	}
63
64
	/**
65
	 * 
66
	 * @return the number of models in the table
67
	 */
68
	public int getModelCount() {
69
		return fPreSelected.size() + fModels.size();
70
	}
71
72
	/**
73
	 * Returns the list of models stored in the model table
74
	 * @return the array of models
75
	 */
76
	public Object[] getModels() {
77
		return fModels.toArray();
78
	}
79
80
	/**
81
	 * Returns the list of preselected models stored in the model table
82
	 * @return the array of preselected models
83
	 */
84
	public Object[] getPreSelected() {
85
		return fPreSelected.toArray();
86
	}
87
88
	/**
89
	 * 
90
	 * @return whether or not the model table contains preselected models
91
	 */
92
	public boolean hasPreSelected() {
93
		return fPreSelected.size() > 0;
94
	}
95
96
	/**
97
	 * 
98
	 * @return whether or not the list of models is empty
99
	 */
100
	public boolean isEmpty() {
101
		return fModels.size() == 0;
102
	}
103
}
(-)src/org/eclipse/pde/internal/ui/nls/AvailableFilter.java (+60 lines)
Added Link Here
1
/*******************************************************************************
2
 * Copyright (c) 2008 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.nls;
13
14
import java.util.Map;
15
import java.util.regex.Pattern;
16
import org.eclipse.jface.viewers.*;
17
import org.eclipse.pde.internal.core.util.PatternConstructor;
18
19
public class AvailableFilter extends ViewerFilter {
20
	public static final String WILDCARD = "*"; //$NON-NLS-1$
21
	private Pattern fPattern;
22
	private final Map selected;
23
	private final ILabelProvider labelProvider;
24
25
	public AvailableFilter(Map selected, ILabelProvider labelProvider) {
26
		setPattern(WILDCARD);
27
		this.selected = selected;
28
		this.labelProvider = labelProvider;
29
	}
30
31
	public boolean select(Viewer viewer, Object parentElement, Object element) {
32
		// filter out any items that are currently selected
33
		// on a full refresh, these will have been added back to the list
34
		if (selected.containsKey(element))
35
			return false;
36
37
		String displayName = labelProvider.getText(element);
38
		return matches(element.toString()) || matches(displayName);
39
	}
40
41
	private boolean matches(String s) {
42
		return fPattern.matcher(s.toLowerCase()).matches();
43
	}
44
45
	public boolean setPattern(String pattern) {
46
		String newPattern = pattern.toLowerCase();
47
48
		if (!newPattern.endsWith(WILDCARD))
49
			newPattern += WILDCARD;
50
		if (!newPattern.startsWith(WILDCARD))
51
			newPattern = WILDCARD + newPattern;
52
		if (fPattern != null) {
53
			String oldPattern = fPattern.pattern();
54
			if (newPattern.equals(oldPattern))
55
				return false;
56
		}
57
		fPattern = PatternConstructor.createPattern(newPattern, true);
58
		return true;
59
	}
60
}
(-)src/org/eclipse/pde/internal/ui/nls/InternationalizeWizardLocalePage.java (+498 lines)
Added Link Here
1
/*******************************************************************************
2
 * Copyright (c) 2008 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.nls;
13
14
import java.util.*;
15
import java.util.List;
16
import org.eclipse.core.runtime.*;
17
import org.eclipse.jface.dialogs.Dialog;
18
import org.eclipse.jface.dialogs.IDialogSettings;
19
import org.eclipse.jface.viewers.*;
20
import org.eclipse.jface.wizard.IWizardContainer;
21
import org.eclipse.osgi.util.NLS;
22
import org.eclipse.pde.core.IModelProviderEvent;
23
import org.eclipse.pde.core.IModelProviderListener;
24
import org.eclipse.pde.internal.core.PDECore;
25
import org.eclipse.pde.internal.ui.PDEPlugin;
26
import org.eclipse.pde.internal.ui.PDEUIMessages;
27
import org.eclipse.pde.internal.ui.elements.DefaultContentProvider;
28
import org.eclipse.pde.internal.ui.util.SWTUtil;
29
import org.eclipse.pde.internal.ui.wizards.ListUtil;
30
import org.eclipse.swt.SWT;
31
import org.eclipse.swt.custom.ScrolledComposite;
32
import org.eclipse.swt.events.*;
33
import org.eclipse.swt.layout.GridData;
34
import org.eclipse.swt.layout.GridLayout;
35
import org.eclipse.swt.widgets.*;
36
import org.eclipse.ui.progress.WorkbenchJob;
37
38
public class InternationalizeWizardLocalePage extends InternationalizationWizardPage implements IModelProviderListener {
39
40
	public static final String PAGE_NAME = "InternationalizeWizardLocalePage"; //$NON-NLS-1$
41
42
	protected Locale[] fModels = new Locale[0];
43
	private String fLocation;
44
45
	protected TableViewer fSelectedListViewer;
46
	private boolean fRefreshNeeded = true;
47
48
	private Label fCountLabel;
49
	private TableViewer fAvailableListViewer;
50
51
	// this job is used to delay the full filter refresh for 200 milliseconds in case the user is still typing
52
	private WorkbenchJob fFilterJob;
53
	private Text fFilterText;
54
	private AvailableFilter fFilter;
55
56
	// fSelected is used to track the selection in a HashMap so we can efficiently
57
	// filter selected items out of the available item list
58
	private HashMap fSelected;
59
	// used to block the selection listeners from updating button enablement when programatically removing items
60
	private boolean fBlockSelectionListeners;
61
	private Button fAddButton;
62
	private Button fAddAllButton;
63
	private Button fRemoveButton;
64
	private Button fRemoveAllButton;
65
66
	private InternationalizeModelTable fInternationalizeModelTable;
67
68
	private class ContentProvider extends DefaultContentProvider implements IStructuredContentProvider {
69
		public Object[] getElements(Object inputElement) {
70
			return ((InternationalizeModelTable) inputElement).getModels();
71
		}
72
	}
73
74
	public InternationalizeWizardLocalePage(InternationalizeModelTable modelTable, String pageName) {
75
		super(pageName);
76
		setTitle(PDEUIMessages.InternationalizeWizard_LocalePage_pageTitle);
77
		setDescription(PDEUIMessages.InternationalizeWizard_LocalePage_pageDescription);
78
79
		PDEPlugin.getDefault().getLabelProvider().connect(this);
80
		PDECore.getDefault().getModelManager().getExternalModelManager().addModelProviderListener(this);
81
82
		fInternationalizeModelTable = modelTable;
83
		fSelected = new HashMap();
84
85
		IWizardContainer container = getContainer();
86
		if (container != null)
87
			container.updateButtons();
88
	}
89
90
	private void addFilter() {
91
		fFilter = new AvailableFilter(fSelected, new LocaleLabelProvider());
92
		fAvailableListViewer.addFilter(fFilter);
93
		fFilterJob = new WorkbenchJob("FilterJob") { //$NON-NLS-1$
94
			public IStatus runInUIThread(IProgressMonitor monitor) {
95
				handleFilter();
96
				return Status.OK_STATUS;
97
			}
98
		};
99
		fFilterJob.setSystem(true);
100
	}
101
102
	private void handleFilter() {
103
		boolean changed = false;
104
		String newFilter;
105
		if (fFilterText == null || (newFilter = fFilterText.getText().trim()).length() == 0)
106
			newFilter = AvailableFilter.WILDCARD;
107
		changed = fFilter.setPattern(newFilter);
108
		if (changed) {
109
			fAvailableListViewer.getTable().setRedraw(false);
110
			fAvailableListViewer.refresh();
111
			fAvailableListViewer.getTable().setRedraw(true);
112
			updateButtonEnablement(false, false);
113
		}
114
	}
115
116
	/* (non-Javadoc)
117
	 * @see org.eclipse.jface.dialogs.IDialogPage#createControl(org.eclipse.swt.widgets.Composite)
118
	 */
119
	public void createControl(Composite parent) {
120
		Composite container = new Composite(parent, SWT.NONE);
121
		GridLayout layout = new GridLayout();
122
		layout.numColumns = 3;
123
		layout.makeColumnsEqualWidth = false;
124
		layout.horizontalSpacing = 5;
125
		layout.verticalSpacing = 20;
126
		container.setLayout(layout);
127
128
		createScrollArea(container);
129
		createAvailableList(container).setLayoutData(new GridData(GridData.FILL_BOTH));
130
		createButtonArea(container);
131
		createLocaleList(container).setLayoutData(new GridData(GridData.FILL_BOTH));
132
		updateCount();
133
134
		addViewerListeners();
135
		addFilter();
136
137
		initialize();
138
		setControl(container);
139
		Dialog.applyDialogFont(container);
140
	}
141
142
	protected Composite createLocaleList(Composite parent) {
143
		Composite container = new Composite(parent, SWT.NONE);
144
		GridLayout layout = new GridLayout();
145
		layout.marginWidth = 0;
146
		layout.marginHeight = 0;
147
		container.setLayout(layout);
148
		container.setLayoutData(new GridData(GridData.FILL_BOTH));
149
150
		Label label = new Label(container, SWT.NONE);
151
		label.setText(PDEUIMessages.InternationalizeWizard_LocalePage_internationalizeList);
152
153
		Table table = new Table(container, SWT.BORDER | SWT.MULTI | SWT.V_SCROLL);
154
		GridData gd = new GridData(GridData.FILL_BOTH);
155
		gd.widthHint = 225;
156
		table.setLayoutData(gd);
157
158
		fSelectedListViewer = new TableViewer(table);
159
		fSelectedListViewer.setLabelProvider(new LocaleLabelProvider());
160
		fSelectedListViewer.setContentProvider(new ContentProvider());
161
		fSelectedListViewer.setComparator(ListUtil.NAME_COMPARATOR);
162
		return container;
163
	}
164
165
	protected boolean isRefreshNeeded() {
166
		if (fRefreshNeeded) {
167
			fRefreshNeeded = false;
168
			return true;
169
		}
170
		if (fLocation == null) {
171
			return true;
172
		}
173
		return false;
174
	}
175
176
	protected void addLocale(Locale model, ArrayList selected) {
177
		if (!selected.contains(model)) {
178
			selected.add(model);
179
		}
180
	}
181
182
	public List getLocalesForInternationalization() {
183
		TableItem[] items = fSelectedListViewer.getTable().getItems();
184
		List result = new ArrayList();
185
		for (int i = 0; i < items.length; i++) {
186
			result.add(items[i].getData());
187
		}
188
		return result;
189
	}
190
191
	public void storeSettings() {
192
		IDialogSettings settings = getDialogSettings();
193
	}
194
195
	/* (non-Javadoc)
196
	 * @see org.eclipse.pde.core.IModelProviderListener#modelsChanged(org.eclipse.pde.core.IModelProviderEvent)
197
	 */
198
	public void modelsChanged(IModelProviderEvent event) {
199
		fRefreshNeeded = true;
200
	}
201
202
	private void initialize() {
203
		updateButtonEnablement(true, true);
204
		setPageComplete(false);
205
	}
206
207
	private void addViewerListeners() {
208
		fAvailableListViewer.addDoubleClickListener(new IDoubleClickListener() {
209
			public void doubleClick(DoubleClickEvent event) {
210
				handleAdd();
211
			}
212
		});
213
214
		fSelectedListViewer.addDoubleClickListener(new IDoubleClickListener() {
215
			public void doubleClick(DoubleClickEvent event) {
216
				handleRemove();
217
			}
218
		});
219
220
		fAvailableListViewer.addSelectionChangedListener(new ISelectionChangedListener() {
221
			public void selectionChanged(SelectionChangedEvent event) {
222
				if (!fBlockSelectionListeners)
223
					updateSelectionBasedEnablement(event.getSelection(), true);
224
			}
225
		});
226
227
		fSelectedListViewer.addSelectionChangedListener(new ISelectionChangedListener() {
228
			public void selectionChanged(SelectionChangedEvent event) {
229
				if (!fBlockSelectionListeners)
230
					updateSelectionBasedEnablement(event.getSelection(), false);
231
			}
232
		});
233
234
		fFilterText.addModifyListener(new ModifyListener() {
235
			public void modifyText(ModifyEvent e) {
236
				fFilterJob.cancel();
237
				fFilterJob.schedule(200);
238
			}
239
		});
240
241
	}
242
243
	private Composite createAvailableList(Composite parent) {
244
		Composite container = new Composite(parent, SWT.NONE);
245
		GridLayout layout = new GridLayout();
246
		layout.marginWidth = 0;
247
		layout.marginHeight = 0;
248
		container.setLayout(layout);
249
		container.setLayoutData(new GridData());
250
251
		Label label = new Label(container, SWT.NONE);
252
		label.setText(PDEUIMessages.InternationalizeWizard_LocalePage_availableList);
253
254
		Table table = new Table(container, SWT.BORDER | SWT.MULTI | SWT.V_SCROLL);
255
		GridData gd = new GridData(GridData.FILL_BOTH);
256
		gd.widthHint = 225;
257
		gd.heightHint = 400;
258
		table.setLayoutData(gd);
259
260
		fAvailableListViewer = new TableViewer(table);
261
		fAvailableListViewer.setLabelProvider(new LocaleLabelProvider());
262
		fAvailableListViewer.setContentProvider(new ContentProvider());
263
		fAvailableListViewer.setInput(fInternationalizeModelTable);
264
		fAvailableListViewer.setComparator(ListUtil.NAME_COMPARATOR);
265
266
		return container;
267
	}
268
269
	private Composite createButtonArea(Composite parent) {
270
		ScrolledComposite comp = new ScrolledComposite(parent, SWT.V_SCROLL | SWT.H_SCROLL);
271
		GridLayout layout = new GridLayout();
272
		layout.marginWidth = layout.marginHeight = 0;
273
		comp.setLayoutData(new GridData(GridData.FILL_VERTICAL));
274
		Composite container = new Composite(comp, SWT.NONE);
275
		layout = new GridLayout();
276
		layout.marginWidth = 0;
277
		layout.marginTop = 50;
278
		container.setLayout(layout);
279
		GridData gd = new GridData(GridData.FILL_VERTICAL);
280
		gd.verticalIndent = 15;
281
		container.setLayoutData(gd);
282
283
		fAddButton = new Button(container, SWT.PUSH);
284
		fAddButton.setText(PDEUIMessages.ImportWizard_DetailedPage_add);
285
		fAddButton.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
286
		fAddButton.addSelectionListener(new SelectionAdapter() {
287
			public void widgetSelected(SelectionEvent e) {
288
				handleAdd();
289
			}
290
		});
291
		SWTUtil.setButtonDimensionHint(fAddButton);
292
293
		fAddAllButton = new Button(container, SWT.PUSH);
294
		fAddAllButton.setText(PDEUIMessages.ImportWizard_DetailedPage_addAll);
295
		fAddAllButton.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
296
		fAddAllButton.addSelectionListener(new SelectionAdapter() {
297
			public void widgetSelected(SelectionEvent e) {
298
				handleAddAll();
299
			}
300
		});
301
		SWTUtil.setButtonDimensionHint(fAddAllButton);
302
303
		fRemoveButton = new Button(container, SWT.PUSH);
304
		fRemoveButton.setText(PDEUIMessages.ImportWizard_DetailedPage_remove);
305
		fRemoveButton.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
306
		fRemoveButton.addSelectionListener(new SelectionAdapter() {
307
			public void widgetSelected(SelectionEvent e) {
308
				handleRemove();
309
			}
310
		});
311
		SWTUtil.setButtonDimensionHint(fRemoveButton);
312
313
		fRemoveAllButton = new Button(container, SWT.PUSH);
314
		fRemoveAllButton.setText(PDEUIMessages.ImportWizard_DetailedPage_removeAll);
315
		fRemoveAllButton.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
316
		fRemoveAllButton.addSelectionListener(new SelectionAdapter() {
317
			public void widgetSelected(SelectionEvent e) {
318
				handleRemoveAll();
319
			}
320
		});
321
		SWTUtil.setButtonDimensionHint(fRemoveAllButton);
322
323
		fCountLabel = new Label(container, SWT.NONE);
324
		fCountLabel.setLayoutData(new GridData(GridData.HORIZONTAL_ALIGN_CENTER));
325
		comp.setContent(container);
326
		comp.setMinHeight(250);
327
		comp.setExpandHorizontal(true);
328
		comp.setExpandVertical(true);
329
		return container;
330
	}
331
332
	private Composite createScrollArea(Composite parent) {
333
		Group container = createFilterContainer(parent, PDEUIMessages.InternationalizeWizard_LocalePage_filter, PDEUIMessages.ImportWizard_DetailedPage_search);
334
		fFilterText = createFilterText(container, ""); //$NON-NLS-1$
335
		return container;
336
	}
337
338
	protected void refreshPage() {
339
		fSelectedListViewer.getTable().removeAll();
340
		fSelected = new HashMap();
341
		fAvailableListViewer.refresh();
342
		pageChanged();
343
	}
344
345
	protected void pageChanged() {
346
		pageChanged(false, false);
347
	}
348
349
	protected void pageChanged(boolean doAddEnablement, boolean doRemoveEnablement) {
350
		if (fSelectedListViewer.getTable().getItemCount() == 0) {
351
			setErrorMessage(PDEUIMessages.InternationalizeWizard_LocalePage_selectionError);
352
		} else {
353
			setErrorMessage(null);
354
		}
355
356
		updateCount();
357
		updateButtonEnablement(doAddEnablement, doRemoveEnablement);
358
		setPageComplete(fSelectedListViewer.getTable().getItemCount() > 0);
359
	}
360
361
	private void updateCount() {
362
		fCountLabel.setText(NLS.bind(PDEUIMessages.ImportWizard_DetailedPage_count, (new String[] {new Integer(fSelectedListViewer.getTable().getItemCount()).toString(), new Integer(fAvailableListViewer.getTable().getItemCount() + fSelectedListViewer.getTable().getItemCount()).toString()})));
363
		fCountLabel.getParent().layout();
364
	}
365
366
	private void updateButtonEnablement(boolean doAddEnablement, boolean doRemoveEnablement) {
367
		int availableCount = fAvailableListViewer.getTable().getItemCount();
368
		int importCount = fSelectedListViewer.getTable().getItemCount();
369
370
		if (doAddEnablement)
371
			updateSelectionBasedEnablement(fAvailableListViewer.getSelection(), true);
372
		if (doRemoveEnablement)
373
			updateSelectionBasedEnablement(fSelectedListViewer.getSelection(), false);
374
375
		fAddAllButton.setEnabled(availableCount > 0);
376
		fRemoveAllButton.setEnabled(importCount > 0);
377
	}
378
379
	private void updateSelectionBasedEnablement(ISelection theSelection, boolean available) {
380
		if (available)
381
			fAddButton.setEnabled(!theSelection.isEmpty());
382
		else
383
			fRemoveButton.setEnabled(!theSelection.isEmpty());
384
	}
385
386
	private void handleAdd() {
387
		IStructuredSelection ssel = (IStructuredSelection) fAvailableListViewer.getSelection();
388
		if (ssel.size() > 0) {
389
			Table table = fAvailableListViewer.getTable();
390
			int index = table.getSelectionIndices()[0];
391
			Object[] selection = ssel.toArray();
392
			setBlockSelectionListeners(true);
393
			setRedraw(false);
394
			for (int i = 0; i < selection.length; i++) {
395
				doAdd(selection[i]);
396
			}
397
			setRedraw(true);
398
			setBlockSelectionListeners(false);
399
			table.setSelection(index < table.getItemCount() ? index : table.getItemCount() - 1);
400
			pageChanged(true, false);
401
		}
402
	}
403
404
	private void handleAddAll() {
405
		TableItem[] items = fAvailableListViewer.getTable().getItems();
406
407
		ArrayList data = new ArrayList();
408
		for (int i = 0; i < items.length; i++) {
409
			data.add(items[i].getData());
410
		}
411
		if (data.size() > 0) {
412
			Object[] datas = data.toArray();
413
			setBlockSelectionListeners(true);
414
			setRedraw(false);
415
			for (int i = 0; i < datas.length; i++) {
416
				doAdd(datas[i]);
417
			}
418
			setRedraw(true);
419
			setBlockSelectionListeners(false);
420
			pageChanged(true, false);
421
		}
422
	}
423
424
	private void handleRemove() {
425
		IStructuredSelection ssel = (IStructuredSelection) fSelectedListViewer.getSelection();
426
		if (ssel.size() > 0) {
427
			Table table = fSelectedListViewer.getTable();
428
			int index = table.getSelectionIndices()[0];
429
			Object[] selection = ssel.toArray();
430
			setBlockSelectionListeners(true);
431
			setRedraw(false);
432
			for (int i = 0; i < selection.length; i++) {
433
				doRemove(selection[i]);
434
			}
435
			setRedraw(true);
436
			setBlockSelectionListeners(false);
437
			table.setSelection(index < table.getItemCount() ? index : table.getItemCount() - 1);
438
			pageChanged(false, true);
439
		}
440
	}
441
442
	private void doAdd(Object o) {
443
		fInternationalizeModelTable.removeModel(o);
444
		fSelectedListViewer.add(o);
445
		fAvailableListViewer.remove(o);
446
		fSelected.put(o, null);
447
	}
448
449
	private void doRemove(Object o) {
450
		fInternationalizeModelTable.addModel(o);
451
		fSelected.remove(o);
452
		fSelectedListViewer.remove(o);
453
		fAvailableListViewer.add(o);
454
	}
455
456
	// used to prevent flicker during operations that move items between lists
457
	private void setRedraw(boolean redraw) {
458
		fAvailableListViewer.getTable().setRedraw(redraw);
459
		fSelectedListViewer.getTable().setRedraw(redraw);
460
	}
461
462
	private void handleRemoveAll() {
463
		TableItem[] items = fSelectedListViewer.getTable().getItems();
464
465
		ArrayList data = new ArrayList();
466
		for (int i = 0; i < items.length; i++) {
467
			data.add(items[i].getData());
468
		}
469
		if (data.size() > 0) {
470
			Object[] datas = data.toArray();
471
			setBlockSelectionListeners(true);
472
			setRedraw(false);
473
			for (int i = 0; i < datas.length; i++) {
474
				doRemove(datas[i]);
475
			}
476
			setRedraw(true);
477
			setBlockSelectionListeners(false);
478
			pageChanged(false, true);
479
		}
480
	}
481
482
	public void dispose() {
483
		PDEPlugin.getDefault().getLabelProvider().disconnect(this);
484
		PDECore.getDefault().getModelManager().getExternalModelManager().removeModelProviderListener(this);
485
	}
486
487
	private void setBlockSelectionListeners(boolean blockSelectionListeners) {
488
		fBlockSelectionListeners = blockSelectionListeners;
489
	}
490
491
	public boolean isCurrentPage() {
492
		return super.isCurrentPage();
493
	}
494
495
	public boolean canFlipToNextPage() {
496
		return false;
497
	}
498
}
(-)src/org/eclipse/pde/internal/ui/nls/InternationalizeWizard.java (+206 lines)
Added Link Here
1
/*******************************************************************************
2
 * Copyright (c) 2008 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.nls;
13
14
import java.util.*;
15
import org.eclipse.core.resources.IProject;
16
import org.eclipse.jface.action.IAction;
17
import org.eclipse.jface.dialogs.IDialogSettings;
18
import org.eclipse.jface.viewers.IStructuredSelection;
19
import org.eclipse.jface.viewers.StructuredSelection;
20
import org.eclipse.jface.wizard.IWizardPage;
21
import org.eclipse.jface.wizard.Wizard;
22
import org.eclipse.pde.core.plugin.IPluginModelBase;
23
import org.eclipse.pde.internal.core.plugin.ExternalPluginModel;
24
import org.eclipse.pde.internal.ui.*;
25
import org.eclipse.ui.IImportWizard;
26
import org.eclipse.ui.IWorkbench;
27
28
/**
29
 * An InternationalizeWizard is responsible for internationalizing a list of
30
 * specified plug-ins (workspace and external) to a set of specified locales.
31
 * This involves creating an NLS fragment project for every plug-in, which would
32
 * contain properties files for each specified locale. The first page of the wizard
33
 * allows the user to select the desired plug-ins and the second page the desired
34
 * locales. Also, the wizard ensures the plug-ins are externalized before proceeding
35
 * with internationlization.
36
 * 
37
 * @author Team Azure
38
 *
39
 */
40
public class InternationalizeWizard extends Wizard implements IImportWizard {
41
	private static final String STORE_SECTION = "InternationalizeWizard"; //$NON-NLS-1$
42
43
	private IAction action;
44
	private IStructuredSelection selection;
45
46
	//An intermediate selection passed to the ExternalizeStringsWizard
47
	private IStructuredSelection externalizeSelection;
48
49
	private InternationalizeWizardPluginPage page1;
50
	private InternationalizeWizardLocalePage page2;
51
52
	//Contains the list of plug-ins to be internationalized
53
	private InternationalizeModelTable fInternationalizePluginModelTable;
54
55
	//Contains the list of locales
56
	private InternationalizeModelTable fInternationalizeLocaleModelTable;
57
58
	public InternationalizeWizard(IAction action, InternationalizeModelTable pluginTable) {
59
		fInternationalizePluginModelTable = pluginTable;
60
		populateLocaleModelTable();
61
		IDialogSettings masterSettings = PDEPlugin.getDefault().getDialogSettings();
62
		setDialogSettings(getSettingsSection(masterSettings));
63
		setDefaultPageImageDescriptor(PDEPluginImages.DESC_XHTML_CONVERT_WIZ);
64
		setWindowTitle(PDEUIMessages.InternationalizeWizard_title);
65
		this.action = action;
66
		setHelpAvailable(false);
67
	}
68
69
	/**
70
	 * Populates the local InternationalizeModelTable with the list of all
71
	 * available locales
72
	 */
73
	private void populateLocaleModelTable() {
74
		fInternationalizeLocaleModelTable = new InternationalizeModelTable();
75
		Locale[] availableLocales = Locale.getAvailableLocales();
76
		for (int i = 0; i < availableLocales.length; i++) {
77
			fInternationalizeLocaleModelTable.addModel(availableLocales[i]);
78
		}
79
	}
80
81
	/**
82
	 * Initialises selections
83
	 */
84
	public void init(IWorkbench workbench, IStructuredSelection selection) {
85
		this.selection = selection;
86
		externalizeSelection = this.selection;
87
	}
88
89
	/**
90
	 * Adds the plug-in and locale pages to the wizard
91
	 */
92
	public void addPages() {
93
		setNeedsProgressMonitor(true);
94
		page1 = new InternationalizeWizardPluginPage(fInternationalizePluginModelTable, "Plug-ins"); //$NON-NLS-1$
95
		addPage(page1);
96
97
		page2 = new InternationalizeWizardLocalePage(fInternationalizeLocaleModelTable, "Locales"); //$NON-NLS-1$
98
		addPage(page2);
99
	}
100
101
	/**
102
	 * 
103
	 * @param master
104
	 * @return the created setting for the InternationalizeWizard
105
	 */
106
	private IDialogSettings getSettingsSection(IDialogSettings master) {
107
		IDialogSettings setting = master.getSection(STORE_SECTION);
108
		if (setting == null) {
109
			setting = master.addNewSection(STORE_SECTION);
110
		}
111
		return setting;
112
	}
113
114
	/**
115
	 * 
116
	 * @return the list of plug-ins selected for internationalization
117
	 */
118
	private List getPluginModelsForInternationalization() {
119
		return page1.getModelsToInternationalize();
120
	}
121
122
	/**
123
	 * 
124
	 * @return the list of locales specified for internationalization
125
	 */
126
	private List getLocalesForInternationalization() {
127
		return page2.getLocalesForInternationalization();
128
	}
129
130
	public boolean performFinish() {
131
		page1.storeSettings();
132
		page2.storeSettings();
133
134
		//Generate an NL fragment project for each of the selected plug-ins with the specified locales
135
		String template = page1.getTemplate() + (page1.createIndividualFragments() ? "." + NLSFragmentGenerator.LOCALE_NAME_MACRO : ""); //$NON-NLS-1$ //$NON-NLS-2$
136
		NLSFragmentGenerator fragmentGenerator = new NLSFragmentGenerator(template, getPluginModelsForInternationalization(), getLocalesForInternationalization(), this.getContainer(), page1.overwriteWithoutAsking());
137
		return fragmentGenerator.generate();
138
	}
139
140
	/**
141
	 * 
142
	 * @param currentPage
143
	 * @return the next wizard page
144
	 */
145
	public IWizardPage getNextPage(IWizardPage currentPage) {
146
		if (currentPage.equals(page1)) {
147
			ensurePluginsAreExternalized();
148
			return page2;
149
		}
150
		return null;
151
	}
152
153
	/**
154
	 * 
155
	 * @param currentPage
156
	 * @return the previous wizard page
157
	 */
158
	public IWizardPage getPreviousPage(IWizardPage currentPage) {
159
		if (currentPage.equals(page2)) {
160
			return page1;
161
		}
162
		return null;
163
	}
164
165
	public boolean canFinish() {
166
		return getPluginModelsForInternationalization().size() > 0 && getLocalesForInternationalization().size() > 0;
167
	}
168
169
	/**
170
	 * Checks whether or not the selected plug-ins are already externalized. This
171
	 * method invokes the ExternalizeStringsWizard on the selected plug-ins.
172
	 */
173
	public void ensurePluginsAreExternalized() {
174
		GetNonExternalizedStringsAction externalize = new GetNonExternalizedStringsAction();
175
176
		List projects = new ArrayList();
177
		List pluginModels = getPluginModelsForInternationalization();
178
		selection = new StructuredSelection(pluginModels); //Save the plug-ins selected for internationalization in a StructuredSelection
179
180
		for (Iterator it = pluginModels.iterator(); it.hasNext();) {
181
			IPluginModelBase pluginModel = (IPluginModelBase) it.next();
182
			//Externalize only workspace plug-ins since external plug-ins are already externalized
183
			if (!(pluginModel instanceof ExternalPluginModel)) {
184
				IProject project = pluginModel.getUnderlyingResource().getProject();
185
				projects.add(project);
186
			}
187
		}
188
189
		//Set the selection for the non-externalized plug-ins that 
190
		//should be passed to the ExternalizeStringsWizard
191
		externalizeSelection = new StructuredSelection(projects);
192
193
		externalize.selectionChanged(action, externalizeSelection);
194
		externalize.setExternalizeSelectedPluginsOnly(true);
195
		externalize.setSkipMessageDialog(true);
196
		externalize.run(action);
197
	}
198
199
	public boolean performCancel() {
200
		return super.performCancel();
201
	}
202
203
	public boolean isHelpAvailable() {
204
		return false;
205
	}
206
}
(-)src/org/eclipse/pde/internal/ui/nls/LocaleLabelProvider.java (+50 lines)
Added Link Here
1
/*******************************************************************************
2
 * Copyright (c) 2008 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.nls;
13
14
import java.util.Locale;
15
import org.eclipse.jface.viewers.ILabelProvider;
16
import org.eclipse.jface.viewers.ILabelProviderListener;
17
import org.eclipse.pde.internal.ui.PDEPluginImages;
18
import org.eclipse.swt.graphics.Image;
19
20
public class LocaleLabelProvider implements ILabelProvider {
21
22
	public Image getImage(Object element) {
23
		return PDEPluginImages.DESC_DISCOVERY.createImage();
24
	}
25
26
	public String getText(Object element) {
27
		Locale locale = (Locale) element;
28
		String country = " (" + locale.getDisplayCountry() + ")";
29
		return locale.getDisplayLanguage() + (" ()".equals(country) ? "" : country);
30
	}
31
32
	public void addListener(ILabelProviderListener listener) {
33
		// TODO Auto-generated method stub
34
35
	}
36
37
	public void dispose() {
38
		// TODO Auto-generated method stub
39
	}
40
41
	public boolean isLabelProperty(Object element, String property) {
42
		// TODO Auto-generated method stub
43
		return false;
44
	}
45
46
	public void removeListener(ILabelProviderListener listener) {
47
		// TODO Auto-generated method stub
48
49
	}
50
}
(-)src/org/eclipse/pde/internal/ui/nls/InternationalizeOperation.java (+104 lines)
Added Link Here
1
/*******************************************************************************
2
 * Copyright (c) 2008 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.nls;
13
14
import java.lang.reflect.InvocationTargetException;
15
import java.util.ArrayList;
16
import org.eclipse.core.resources.IFile;
17
import org.eclipse.core.resources.IProject;
18
import org.eclipse.core.runtime.IProgressMonitor;
19
import org.eclipse.jface.operation.IRunnableWithProgress;
20
import org.eclipse.jface.viewers.ISelection;
21
import org.eclipse.jface.viewers.IStructuredSelection;
22
import org.eclipse.pde.core.plugin.IPluginModelBase;
23
import org.eclipse.pde.core.plugin.PluginRegistry;
24
import org.eclipse.pde.internal.core.WorkspaceModelManager;
25
import org.eclipse.pde.internal.ui.PDEUIMessages;
26
27
/**
28
 * InternationalizeOperation is responsible for populating a plug-in model table
29
 * containing the list of plug-ins (workspace and external) prior to running the
30
 * wizard. An instance of this class must be created before creating an
31
 * InternationlizeWizard instance.
32
 * 
33
 * @author Team Azure
34
 *
35
 */
36
public class InternationalizeOperation implements IRunnableWithProgress {
37
38
	private ISelection fSelection;
39
	private ArrayList fSelectedModels;
40
	private InternationalizeModelTable fModelPluginTable;
41
	private boolean fCanceled;
42
43
	/**
44
	 * 
45
	 * @param selection represents the preselected plug-in projects in the workbench
46
	 */
47
	public InternationalizeOperation(ISelection selection) {
48
		fSelection = selection;
49
	}
50
51
	public void run(IProgressMonitor monitor) throws InvocationTargetException, InterruptedException {
52
53
		if (fSelection instanceof IStructuredSelection) {
54
55
			Object[] elems = ((IStructuredSelection) fSelection).toArray();
56
57
			fSelectedModels = new ArrayList(elems.length);
58
			for (int i = 0; i < elems.length; i++) {
59
				//If a file was selected, get its parent project
60
				if (elems[i] instanceof IFile)
61
					elems[i] = ((IFile) elems[i]).getProject();
62
63
				//Add the project to the preselected model list
64
				if (elems[i] instanceof IProject && WorkspaceModelManager.isPluginProject((IProject) elems[i]) && !WorkspaceModelManager.isBinaryProject((IProject) elems[i]))
65
					fSelectedModels.add(elems[i]);
66
			}
67
		}
68
69
		//Get all models (workspace and external) excluding fragment models
70
		IPluginModelBase[] pluginModels = PluginRegistry.getAllModels(false);
71
		monitor.beginTask(PDEUIMessages.GetNonExternalizedStringsOperation_taskMessage, pluginModels.length);
72
73
		//Populate list to an InternationalizeModelTable
74
		fModelPluginTable = new InternationalizeModelTable();
75
		for (int i = 0; i < pluginModels.length; i++) {
76
			fModelPluginTable.addToModelTable(pluginModels[i], pluginModels[i].getUnderlyingResource() != null ? selected(pluginModels[i].getUnderlyingResource().getProject()) : false);
77
		}
78
	}
79
80
	/**
81
	 * 
82
	 * @return whether or not the operation was cancelled
83
	 */
84
	public boolean wasCanceled() {
85
		return fCanceled;
86
	}
87
88
	/**
89
	 * 
90
	 * @param project
91
	 * @return whether or not the project was preselected
92
	 */
93
	public boolean selected(IProject project) {
94
		return fSelectedModels.contains(project);
95
	}
96
97
	/**
98
	 * 
99
	 * @return the InternationalizeModelTable containing the plug-ins
100
	 */
101
	public InternationalizeModelTable getPluginTable() {
102
		return fModelPluginTable;
103
	}
104
}
(-)src/org/eclipse/pde/internal/ui/nls/InternationalizeWizardPluginPage.java (+645 lines)
Added Link Here
1
/*******************************************************************************
2
 * Copyright (c) 2008 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.nls;
13
14
import java.util.*;
15
import java.util.List;
16
import org.eclipse.core.runtime.*;
17
import org.eclipse.jface.dialogs.Dialog;
18
import org.eclipse.jface.dialogs.IDialogSettings;
19
import org.eclipse.jface.viewers.*;
20
import org.eclipse.jface.wizard.IWizardContainer;
21
import org.eclipse.osgi.util.NLS;
22
import org.eclipse.pde.core.IModelProviderEvent;
23
import org.eclipse.pde.core.IModelProviderListener;
24
import org.eclipse.pde.core.plugin.*;
25
import org.eclipse.pde.internal.core.ClasspathUtilCore;
26
import org.eclipse.pde.internal.core.PDECore;
27
import org.eclipse.pde.internal.ui.PDEPlugin;
28
import org.eclipse.pde.internal.ui.PDEUIMessages;
29
import org.eclipse.pde.internal.ui.elements.DefaultContentProvider;
30
import org.eclipse.pde.internal.ui.util.SWTUtil;
31
import org.eclipse.pde.internal.ui.wizards.ListUtil;
32
import org.eclipse.swt.SWT;
33
import org.eclipse.swt.custom.ScrolledComposite;
34
import org.eclipse.swt.events.*;
35
import org.eclipse.swt.layout.GridData;
36
import org.eclipse.swt.layout.GridLayout;
37
import org.eclipse.swt.widgets.*;
38
import org.eclipse.ui.progress.WorkbenchJob;
39
40
/**
41
 * The first page of the InternationalizeWizard. This page allows the user to 
42
 * select the desired plug-ins for internationalization. These could be plug-ins
43
 * in the user's workspace or external ones.
44
 * 
45
 * @author Team Azure
46
 *
47
 */
48
public class InternationalizeWizardPluginPage extends InternationalizationWizardPage implements IModelProviderListener {
49
50
	private static final String CREATE_INDIVIDUAL_FRAGMENTS = "create individual fragments";
51
	private static final String TEMPLATE = "name_template"; //$NON-NLS-1$
52
	private static final String OVERWRITE = "overwrite?"; //$NON-NLS-1$
53
	public static final String PAGE_NAME = "InternationalizeWizardPluginPage"; //$NON-NLS-1$
54
55
	protected IPluginModelBase[] fModels = new IPluginModelBase[0];
56
57
	private boolean fRefreshNeeded = true;
58
59
	private Label fCountLabel; //Displays "x out of y selected"
60
61
	private TableViewer fAvailableViewer; //All available plug-ins
62
	protected TableViewer fSelectedViewer; //Selected plug-ins
63
64
	private WorkbenchJob fFilterJob;
65
	private Text fFilterText;
66
	private Text fTemplateText;
67
	private AvailableFilter fFilter;
68
69
	// Used to track the selection in a HashMap so as to filter
70
	// selected items out of the available item list
71
	private final Map fSelected = new HashMap();
72
73
	// Used to block the selection listeners from updating button enablement
74
	// when programatically removing items
75
	private boolean fBlockSelectionListeners;
76
	private Button fAddButton;
77
	private Button fAddAllButton;
78
	private Button fRemoveButton;
79
	private Button fRemoveAllButton;
80
81
	// Used to store the plug-ins
82
	private InternationalizeModelTable fInternationalizeModelTable;
83
84
	private Button overwriteOption;
85
	private Button individualFragments;
86
87
	private class ContentProvider extends DefaultContentProvider implements IStructuredContentProvider {
88
		/**
89
		 * @return the list of available non-selected plug-ins
90
		 */
91
		public Object[] getElements(Object parent) {
92
			return fInternationalizeModelTable.getModels();
93
		}
94
	}
95
96
	private class SelectedContentProvider extends DefaultContentProvider implements IStructuredContentProvider {
97
		/**
98
		 * @return the list of selected plug-ins
99
		 */
100
		public Object[] getElements(Object parent) {
101
			return fInternationalizeModelTable.getPreSelected();
102
		}
103
	}
104
105
	public InternationalizeWizardPluginPage(InternationalizeModelTable modelTable, String pageName) {
106
107
		super(pageName);
108
		setTitle(PDEUIMessages.InternationalizeWizard_PluginPage_pageTitle);
109
		setDescription(PDEUIMessages.InternationalizeWizard_PluginPage_pageDescription);
110
111
		PDEPlugin.getDefault().getLabelProvider().connect(this);
112
		PDECore.getDefault().getModelManager().getExternalModelManager().addModelProviderListener(this);
113
114
		fInternationalizeModelTable = modelTable;
115
116
		IWizardContainer container = getContainer();
117
		if (container != null)
118
			container.updateButtons();
119
	}
120
121
	/**
122
	 * Adds a filter to the list of available plug-ins
123
	 */
124
	private void addFilter() {
125
		fFilter = new AvailableFilter(fSelected, PDEPlugin.getDefault().getLabelProvider());
126
		fAvailableViewer.addFilter(fFilter);
127
		fFilterJob = new WorkbenchJob("FilterJob") { //$NON-NLS-1$
128
			public IStatus runInUIThread(IProgressMonitor monitor) {
129
				handleFilter();
130
				return Status.OK_STATUS;
131
			}
132
		};
133
		fFilterJob.setSystem(true);
134
	}
135
136
	/**
137
	 * Handles changes to the list based on changes to the text field.
138
	 */
139
	private void handleFilter() {
140
		boolean changed = false;
141
		String newFilter;
142
		if (fFilterText == null || (newFilter = fFilterText.getText().trim()).length() == 0)
143
			newFilter = AvailableFilter.WILDCARD;
144
		changed = fFilter.setPattern(newFilter);
145
		if (changed) {
146
			fAvailableViewer.getTable().setRedraw(false);
147
			fAvailableViewer.refresh();
148
			fAvailableViewer.getTable().setRedraw(true);
149
			updateButtonEnablement(false, false);
150
		}
151
	}
152
153
	/* (non-Javadoc)
154
	 * @see org.eclipse.jface.dialogs.IDialogPage#createControl(org.eclipse.swt.widgets.Composite)
155
	 */
156
	public void createControl(Composite parent) {
157
		Composite container = new Composite(parent, SWT.NONE);
158
		GridLayout layout = new GridLayout();
159
		layout.numColumns = 3;
160
		layout.makeColumnsEqualWidth = false;
161
		layout.horizontalSpacing = 5;
162
		layout.verticalSpacing = 20;
163
		container.setLayout(layout);
164
165
		createScrollArea(container);
166
		createAvailableList(container).setLayoutData(new GridData(GridData.FILL_BOTH));
167
		createButtonArea(container);
168
		createInternationalizeList(container).setLayoutData(new GridData(GridData.FILL_BOTH));
169
		updateCount();
170
171
		GridData data = new GridData(GridData.FILL_HORIZONTAL);
172
		data.horizontalSpan = 3;
173
		Composite comp = new Composite(container, SWT.NONE);
174
		comp.setLayoutData(data);
175
		GridLayout fl = new GridLayout(2, false);
176
		comp.setLayout(fl);
177
178
		IDialogSettings settings = getDialogSettings();
179
		String template = settings.get(TEMPLATE);
180
181
		Label label = new Label(comp, SWT.NONE);
182
		label.setText(PDEUIMessages.InternationalizeWizard_PluginPage_templateLabel);
183
		fTemplateText = new Text(comp, SWT.BORDER);
184
		fTemplateText.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
185
		fTemplateText.setText(template != null ? template : NLSFragmentGenerator.PLUGIN_NAME_MACRO + ".nl1"); //$NON-NLS-1$
186
		fTemplateText.addModifyListener(new ModifyListener() {
187
			public void modifyText(ModifyEvent e) {
188
				pageChanged();
189
			}
190
		});
191
192
		GridData gd = new GridData(GridData.FILL_HORIZONTAL);
193
		gd.horizontalSpan = 2;
194
195
		overwriteOption = new Button(comp, SWT.CHECK);
196
		overwriteOption.setText(PDEUIMessages.InternationalizeWizard_PluginPage_overwriteWithoutAsking);
197
		overwriteOption.setSelection(settings.getBoolean(OVERWRITE));
198
		overwriteOption.setLayoutData(gd);
199
200
		individualFragments = new Button(comp, SWT.CHECK);
201
		individualFragments.setText(PDEUIMessages.InternationalizeWizard_PluginPage_individualFragments);
202
		individualFragments.setSelection(settings.getBoolean(CREATE_INDIVIDUAL_FRAGMENTS));
203
		individualFragments.setLayoutData(gd);
204
205
		addViewerListeners();
206
		addFilter();
207
208
		initialize();
209
		setControl(container);
210
		Dialog.applyDialogFont(container);
211
	}
212
213
	/**
214
	 * @param parent
215
	 * @return the container holding the available plug-ins list
216
	 */
217
	private Composite createAvailableList(Composite parent) {
218
		Composite container = createViewerContainer(parent, PDEUIMessages.InternationalizeWizard_PluginPage_availableList);
219
		fAvailableViewer = createTableViewer(container, new ContentProvider(), PDECore.getDefault().getModelManager());
220
		return container;
221
	}
222
223
	protected Composite createInternationalizeList(Composite parent) {
224
		Composite container = createViewerContainer(parent, PDEUIMessages.InternationalizeWizard_PluginPage_internationalizeList);
225
		fSelectedViewer = createTableViewer(container, new SelectedContentProvider(), PDECore.getDefault().getModelManager().getExternalModelManager());
226
		return container;
227
	}
228
229
	private Composite createViewerContainer(Composite parent, String message) {
230
		Composite container = new Composite(parent, SWT.NONE);
231
		GridLayout layout = new GridLayout();
232
		layout.marginWidth = 0;
233
		layout.marginHeight = 0;
234
		container.setLayout(layout);
235
		container.setLayoutData(new GridData(GridData.FILL_BOTH));
236
237
		Label label = new Label(container, SWT.NONE);
238
		label.setText(message);
239
		return container;
240
	}
241
242
	private static TableViewer createTableViewer(Composite container, IContentProvider provider, Object manager) {
243
		Table table = new Table(container, SWT.BORDER | SWT.MULTI | SWT.V_SCROLL);
244
		GridData gd = new GridData(GridData.FILL_BOTH);
245
		gd.heightHint = 200;
246
		gd.widthHint = 225;
247
		table.setLayoutData(gd);
248
249
		TableViewer viewer = new TableViewer(table);
250
		viewer.setLabelProvider(PDEPlugin.getDefault().getLabelProvider());
251
		viewer.setContentProvider(provider);
252
		viewer.setInput(manager);
253
		viewer.setComparator(ListUtil.PLUGIN_COMPARATOR);
254
		return viewer;
255
	}
256
257
	protected boolean isRefreshNeeded() {
258
		if (fRefreshNeeded) {
259
			fRefreshNeeded = false;
260
			return true;
261
		}
262
263
		return false;
264
	}
265
266
	private IPluginModelBase findModel(String id) {
267
		for (int i = 0; i < fModels.length; i++) {
268
			String modelId = fModels[i].getPluginBase().getId();
269
			if (modelId != null && modelId.equals(id))
270
				return fModels[i];
271
		}
272
		return null;
273
	}
274
275
	private IFragmentModel[] findFragments(IPlugin plugin) {
276
		ArrayList result = new ArrayList();
277
		for (int i = 0; i < fModels.length; i++) {
278
			if (fModels[i] instanceof IFragmentModel) {
279
				IFragment fragment = ((IFragmentModel) fModels[i]).getFragment();
280
				if (plugin.getId().equalsIgnoreCase(fragment.getPluginId())) {
281
					result.add(fModels[i]);
282
				}
283
			}
284
		}
285
		return (IFragmentModel[]) result.toArray(new IFragmentModel[result.size()]);
286
	}
287
288
	protected void addPluginAndDependencies(IPluginModelBase model, ArrayList selected, boolean addFragments) {
289
290
		boolean containsVariable = false;
291
		if (!selected.contains(model)) {
292
			selected.add(model);
293
			boolean hasextensibleAPI = ClasspathUtilCore.hasExtensibleAPI(model);
294
			if (!addFragments && !hasextensibleAPI && model instanceof IPluginModel) {
295
				IPluginLibrary[] libraries = model.getPluginBase().getLibraries();
296
				for (int i = 0; i < libraries.length; i++) {
297
					if (ClasspathUtilCore.containsVariables(libraries[i].getName())) {
298
						containsVariable = true;
299
						break;
300
					}
301
				}
302
			}
303
			addDependencies(model, selected, addFragments || containsVariable || hasextensibleAPI);
304
		}
305
	}
306
307
	protected void addDependencies(IPluginModelBase model, ArrayList selected, boolean addFragments) {
308
309
		IPluginImport[] required = model.getPluginBase().getImports();
310
		if (required.length > 0) {
311
			for (int i = 0; i < required.length; i++) {
312
				IPluginModelBase found = findModel(required[i].getId());
313
				if (found != null) {
314
					addPluginAndDependencies(found, selected, addFragments);
315
				}
316
			}
317
		}
318
319
		if (addFragments) {
320
			if (model instanceof IPluginModel) {
321
				IFragmentModel[] fragments = findFragments(((IPluginModel) model).getPlugin());
322
				for (int i = 0; i < fragments.length; i++) {
323
					addPluginAndDependencies(fragments[i], selected, addFragments);
324
				}
325
			} else {
326
				IFragment fragment = ((IFragmentModel) model).getFragment();
327
				IPluginModelBase found = findModel(fragment.getPluginId());
328
				if (found != null) {
329
					addPluginAndDependencies(found, selected, addFragments);
330
				}
331
			}
332
		}
333
	}
334
335
	public List getModelsToInternationalize() {
336
		TableItem[] items = fSelectedViewer.getTable().getItems();
337
		List result = new ArrayList();
338
		for (int i = 0; i < items.length; i++) {
339
			result.add(items[i].getData());
340
		}
341
		return result;
342
	}
343
344
	public void storeSettings() {
345
		IDialogSettings settings = getDialogSettings();
346
		settings.put(OVERWRITE, overwriteWithoutAsking());
347
		settings.put(TEMPLATE, getTemplate());
348
		settings.put(CREATE_INDIVIDUAL_FRAGMENTS, createIndividualFragments());
349
	}
350
351
	public boolean createIndividualFragments() {
352
		return individualFragments.getSelection();
353
	}
354
355
	/* (non-Javadoc)
356
	 * @see org.eclipse.pde.core.IModelProviderListener#modelsChanged(org.eclipse.pde.core.IModelProviderEvent)
357
	 */
358
	public void modelsChanged(IModelProviderEvent event) {
359
		fRefreshNeeded = true;
360
	}
361
362
	private void initialize() {
363
		updateButtonEnablement(true, true);
364
		setPageComplete(false);
365
	}
366
367
	private void addViewerListeners() {
368
		fAvailableViewer.addDoubleClickListener(new IDoubleClickListener() {
369
			public void doubleClick(DoubleClickEvent event) {
370
				handleAdd();
371
			}
372
		});
373
374
		fSelectedViewer.addDoubleClickListener(new IDoubleClickListener() {
375
			public void doubleClick(DoubleClickEvent event) {
376
				handleRemove();
377
			}
378
		});
379
380
		fAvailableViewer.addSelectionChangedListener(new ISelectionChangedListener() {
381
			public void selectionChanged(SelectionChangedEvent event) {
382
				if (!fBlockSelectionListeners)
383
					updateSelectionBasedEnablement(event.getSelection(), true);
384
			}
385
		});
386
387
		fSelectedViewer.addSelectionChangedListener(new ISelectionChangedListener() {
388
			public void selectionChanged(SelectionChangedEvent event) {
389
				if (!fBlockSelectionListeners)
390
					updateSelectionBasedEnablement(event.getSelection(), false);
391
			}
392
		});
393
394
		fFilterText.addModifyListener(new ModifyListener() {
395
			public void modifyText(ModifyEvent e) {
396
				fFilterJob.cancel();
397
				fFilterJob.schedule(200);
398
			}
399
		});
400
401
	}
402
403
	private Composite createButtonArea(Composite parent) {
404
		ScrolledComposite comp = new ScrolledComposite(parent, SWT.V_SCROLL | SWT.H_SCROLL);
405
		GridLayout layout = new GridLayout();
406
		layout.marginWidth = layout.marginHeight = 0;
407
		comp.setLayoutData(new GridData(GridData.FILL_VERTICAL));
408
		Composite container = new Composite(comp, SWT.NONE);
409
		layout = new GridLayout();
410
		layout.marginWidth = 0;
411
		layout.marginTop = 50;
412
		container.setLayout(layout);
413
		GridData gd = new GridData(GridData.FILL_VERTICAL);
414
		gd.verticalIndent = 15;
415
		container.setLayoutData(gd);
416
417
		fAddButton = new Button(container, SWT.PUSH);
418
		fAddButton.setText(PDEUIMessages.ImportWizard_DetailedPage_add);
419
		fAddButton.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
420
		fAddButton.addSelectionListener(new SelectionAdapter() {
421
			public void widgetSelected(SelectionEvent e) {
422
				handleAdd();
423
			}
424
		});
425
		SWTUtil.setButtonDimensionHint(fAddButton);
426
427
		fAddAllButton = new Button(container, SWT.PUSH);
428
		fAddAllButton.setText(PDEUIMessages.ImportWizard_DetailedPage_addAll);
429
		fAddAllButton.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
430
		fAddAllButton.addSelectionListener(new SelectionAdapter() {
431
			public void widgetSelected(SelectionEvent e) {
432
				handleAddAll();
433
			}
434
		});
435
		SWTUtil.setButtonDimensionHint(fAddAllButton);
436
437
		fRemoveButton = new Button(container, SWT.PUSH);
438
		fRemoveButton.setText(PDEUIMessages.ImportWizard_DetailedPage_remove);
439
		fRemoveButton.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
440
		fRemoveButton.addSelectionListener(new SelectionAdapter() {
441
			public void widgetSelected(SelectionEvent e) {
442
				handleRemove();
443
			}
444
		});
445
		SWTUtil.setButtonDimensionHint(fRemoveButton);
446
447
		fRemoveAllButton = new Button(container, SWT.PUSH);
448
		fRemoveAllButton.setText(PDEUIMessages.ImportWizard_DetailedPage_removeAll);
449
		fRemoveAllButton.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
450
		fRemoveAllButton.addSelectionListener(new SelectionAdapter() {
451
			public void widgetSelected(SelectionEvent e) {
452
				handleRemoveAll();
453
			}
454
		});
455
		SWTUtil.setButtonDimensionHint(fRemoveAllButton);
456
457
		fCountLabel = new Label(container, SWT.NONE);
458
		fCountLabel.setLayoutData(new GridData(GridData.HORIZONTAL_ALIGN_CENTER));
459
		comp.setContent(container);
460
		comp.setMinHeight(250);
461
		comp.setExpandHorizontal(true);
462
		comp.setExpandVertical(true);
463
		return container;
464
	}
465
466
	private Composite createScrollArea(Composite parent) {
467
		Group container = createFilterContainer(parent, PDEUIMessages.InternationalizeWizard_PluginPage_filter, PDEUIMessages.ImportWizard_DetailedPage_search);
468
		fFilterText = createFilterText(container, ""); //$NON-NLS-1$
469
		return container;
470
	}
471
472
	protected void refreshPage() {
473
		fSelectedViewer.getTable().removeAll();
474
		fSelected.clear();
475
		fAvailableViewer.refresh();
476
		pageChanged();
477
	}
478
479
	protected void pageChanged() {
480
		pageChanged(false, false);
481
	}
482
483
	protected void pageChanged(boolean doAddEnablement, boolean doRemoveEnablement) {
484
		if (fTemplateText.getText().length() == 0) {
485
			setErrorMessage(PDEUIMessages.InternationalizeWizard_PluginPage_templateError);
486
		} else if (fSelectedViewer.getTable().getItemCount() == 0) {
487
			setErrorMessage(PDEUIMessages.InternationalizeWizard_PluginPage_selectionError);
488
		} else {
489
			setErrorMessage(null);
490
		}
491
492
		updateCount();
493
		updateButtonEnablement(doAddEnablement, doRemoveEnablement);
494
		setPageComplete(fSelectedViewer.getTable().getItemCount() > 0);
495
	}
496
497
	private void updateCount() {
498
		fCountLabel.setText(NLS.bind(PDEUIMessages.ImportWizard_DetailedPage_count, (new String[] {new Integer(fSelectedViewer.getTable().getItemCount()).toString(), new Integer(fAvailableViewer.getTable().getItemCount() + fSelectedViewer.getTable().getItemCount()).toString()})));
499
		fCountLabel.getParent().layout();
500
	}
501
502
	private void updateButtonEnablement(boolean doAddEnablement, boolean doRemoveEnablement) {
503
		int availableCount = fAvailableViewer.getTable().getItemCount();
504
		int importCount = fSelectedViewer.getTable().getItemCount();
505
506
		if (doAddEnablement)
507
			updateSelectionBasedEnablement(fAvailableViewer.getSelection(), true);
508
		if (doRemoveEnablement)
509
			updateSelectionBasedEnablement(fSelectedViewer.getSelection(), false);
510
511
		fAddAllButton.setEnabled(availableCount > 0);
512
		fRemoveAllButton.setEnabled(importCount > 0);
513
	}
514
515
	private void updateSelectionBasedEnablement(ISelection theSelection, boolean available) {
516
		if (available)
517
			fAddButton.setEnabled(!theSelection.isEmpty());
518
		else
519
			fRemoveButton.setEnabled(!theSelection.isEmpty());
520
	}
521
522
	private void handleAdd() {
523
		IStructuredSelection ssel = (IStructuredSelection) fAvailableViewer.getSelection();
524
		if (ssel.size() > 0) {
525
			Table table = fAvailableViewer.getTable();
526
			int index = table.getSelectionIndices()[0];
527
			Object[] selection = ssel.toArray();
528
			setBlockSelectionListeners(true);
529
			setRedraw(false);
530
			for (int i = 0; i < selection.length; i++) {
531
				doAdd(selection[i]);
532
			}
533
			setRedraw(true);
534
			setBlockSelectionListeners(false);
535
			table.setSelection(index < table.getItemCount() ? index : table.getItemCount() - 1);
536
			pageChanged(true, false);
537
		}
538
	}
539
540
	private void handleAddAll() {
541
		TableItem[] items = fAvailableViewer.getTable().getItems();
542
543
		ArrayList data = new ArrayList();
544
		for (int i = 0; i < items.length; i++) {
545
			data.add(items[i].getData());
546
		}
547
		if (data.size() > 0) {
548
			Object[] datas = data.toArray();
549
			setBlockSelectionListeners(true);
550
			setRedraw(false);
551
			for (int i = 0; i < datas.length; i++) {
552
				doAdd(datas[i]);
553
			}
554
			setRedraw(true);
555
			setBlockSelectionListeners(false);
556
			pageChanged(true, false);
557
		}
558
	}
559
560
	private void handleRemove() {
561
		IStructuredSelection ssel = (IStructuredSelection) fSelectedViewer.getSelection();
562
		if (ssel.size() > 0) {
563
			Table table = fSelectedViewer.getTable();
564
			int index = table.getSelectionIndices()[0];
565
			Object[] selection = ssel.toArray();
566
			setBlockSelectionListeners(true);
567
			setRedraw(false);
568
			for (int i = 0; i < selection.length; i++) {
569
				doRemove(selection[i]);
570
			}
571
			setRedraw(true);
572
			setBlockSelectionListeners(false);
573
			table.setSelection(index < table.getItemCount() ? index : table.getItemCount() - 1);
574
			pageChanged(false, true);
575
		}
576
	}
577
578
	private void doAdd(Object o) {
579
		fInternationalizeModelTable.removeModel(o);
580
		fSelectedViewer.add(o);
581
		fAvailableViewer.remove(o);
582
		fSelected.put(o, null);
583
	}
584
585
	private void doRemove(Object o) {
586
		fInternationalizeModelTable.addModel(o);
587
		fSelected.remove(o);
588
		fSelectedViewer.remove(o);
589
		fAvailableViewer.add(o);
590
	}
591
592
	// used to prevent flicker during operations that move items between lists
593
	private void setRedraw(boolean redraw) {
594
		fAvailableViewer.getTable().setRedraw(redraw);
595
		fSelectedViewer.getTable().setRedraw(redraw);
596
	}
597
598
	private void handleRemoveAll() {
599
		TableItem[] items = fSelectedViewer.getTable().getItems();
600
601
		ArrayList data = new ArrayList();
602
		for (int i = 0; i < items.length; i++) {
603
			data.add(items[i].getData());
604
		}
605
		if (data.size() > 0) {
606
			Object[] datas = data.toArray();
607
			setBlockSelectionListeners(true);
608
			setRedraw(false);
609
			for (int i = 0; i < datas.length; i++) {
610
				doRemove(datas[i]);
611
			}
612
			setRedraw(true);
613
			setBlockSelectionListeners(false);
614
			pageChanged(false, true);
615
		}
616
	}
617
618
	public void dispose() {
619
		PDEPlugin.getDefault().getLabelProvider().disconnect(this);
620
		PDECore.getDefault().getModelManager().getExternalModelManager().removeModelProviderListener(this);
621
	}
622
623
	private void setBlockSelectionListeners(boolean blockSelectionListeners) {
624
		fBlockSelectionListeners = blockSelectionListeners;
625
	}
626
627
	public boolean isCurrentPage() {
628
		return super.isCurrentPage();
629
	}
630
631
	public boolean canFlipToNextPage() {
632
		if (fSelectedViewer.getTable().getItems().length > 0 && getTemplate().length() > 0) {
633
			return true;
634
		}
635
		return false;
636
	}
637
638
	public String getTemplate() {
639
		return fTemplateText.getText();
640
	}
641
642
	public boolean overwriteWithoutAsking() {
643
		return overwriteOption.getSelection();
644
	}
645
}

Return to bug 201998