Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorIgor Fedorenko2013-09-17 12:25:41 +0000
committerIgor Fedorenko2013-09-18 05:24:13 +0000
commitca8878d7b261bab75cd86e00176c387dd90fc88b (patch)
treef50d74080fbc659004933a5b760fd796d2f76771 /org.eclipse.m2e.core.ui/src/org
parentcc224de26006afcc749744c7a67c015b7b324700 (diff)
downloadm2e-core-ca8878d7b261bab75cd86e00176c387dd90fc88b.tar.gz
m2e-core-ca8878d7b261bab75cd86e00176c387dd90fc88b.tar.xz
m2e-core-ca8878d7b261bab75cd86e00176c387dd90fc88b.zip
417466 (re)create working sets action and dialog
Signed-off-by: Igor Fedorenko <igor@ifedorenko.com>
Diffstat (limited to 'org.eclipse.m2e.core.ui/src/org')
-rw-r--r--org.eclipse.m2e.core.ui/src/org/eclipse/m2e/core/ui/internal/Messages.java7
-rw-r--r--org.eclipse.m2e.core.ui/src/org/eclipse/m2e/core/ui/internal/actions/AssignWorkingSetAction.java35
-rw-r--r--org.eclipse.m2e.core.ui/src/org/eclipse/m2e/core/ui/internal/components/NestedProjectsComposite.java100
-rw-r--r--org.eclipse.m2e.core.ui/src/org/eclipse/m2e/core/ui/internal/dialogs/AssignWorkingSetDialog.java174
-rw-r--r--org.eclipse.m2e.core.ui/src/org/eclipse/m2e/core/ui/internal/messages.properties10
5 files changed, 287 insertions, 39 deletions
diff --git a/org.eclipse.m2e.core.ui/src/org/eclipse/m2e/core/ui/internal/Messages.java b/org.eclipse.m2e.core.ui/src/org/eclipse/m2e/core/ui/internal/Messages.java
index 339c4796..be568c01 100644
--- a/org.eclipse.m2e.core.ui/src/org/eclipse/m2e/core/ui/internal/Messages.java
+++ b/org.eclipse.m2e.core.ui/src/org/eclipse/m2e/core/ui/internal/Messages.java
@@ -43,6 +43,8 @@ public class Messages extends NLS {
public static String AddPluginAction_searchDialog_title;
+ public static String AssignWorkingSetDialog_title;
+
public static String ChangeNatureAction_job_changing;
public static String ChangeNatureAction_status_error;
@@ -887,6 +889,11 @@ public class Messages extends NLS {
public static String UpdateMavenProjectsDialog_btnRefreshFromLocal_text;
+ public static String AssignWorkingSetDialog_btnFilterAssignedProjects_text;
+
+ public static String AssignWorkingSetDialog_btnAssign_text;
+ public static String AssignWorkingSetDialog_btnFilterClosedProjects_text;
+
static {
// initialize resource bundle
NLS.initializeMessages(BUNDLE_NAME, Messages.class);
diff --git a/org.eclipse.m2e.core.ui/src/org/eclipse/m2e/core/ui/internal/actions/AssignWorkingSetAction.java b/org.eclipse.m2e.core.ui/src/org/eclipse/m2e/core/ui/internal/actions/AssignWorkingSetAction.java
new file mode 100644
index 00000000..17a95c81
--- /dev/null
+++ b/org.eclipse.m2e.core.ui/src/org/eclipse/m2e/core/ui/internal/actions/AssignWorkingSetAction.java
@@ -0,0 +1,35 @@
+/*******************************************************************************
+ * Copyright (c) 2013 Igor Fedorenko
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Igor Fedorenko - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.m2e.core.ui.internal.actions;
+
+import org.eclipse.core.resources.IProject;
+import org.eclipse.jface.action.IAction;
+import org.eclipse.jface.window.Window;
+
+import org.eclipse.m2e.core.ui.internal.dialogs.AssignWorkingSetDialog;
+
+
+/**
+ * @since 1.5
+ */
+public class AssignWorkingSetAction extends MavenProjectActionSupport {
+
+ public void run(IAction action) {
+ IProject[] initialSelection = getProjects();
+
+ AssignWorkingSetDialog dialog = new AssignWorkingSetDialog(getShell(), initialSelection);
+ if(dialog.open() == Window.OK) {
+ dialog.assignWorkingSets();
+ }
+ }
+
+}
diff --git a/org.eclipse.m2e.core.ui/src/org/eclipse/m2e/core/ui/internal/components/NestedProjectsComposite.java b/org.eclipse.m2e.core.ui/src/org/eclipse/m2e/core/ui/internal/components/NestedProjectsComposite.java
index 68739c59..19e2b3e6 100644
--- a/org.eclipse.m2e.core.ui/src/org/eclipse/m2e/core/ui/internal/components/NestedProjectsComposite.java
+++ b/org.eclipse.m2e.core.ui/src/org/eclipse/m2e/core/ui/internal/components/NestedProjectsComposite.java
@@ -37,13 +37,15 @@ import org.eclipse.jface.action.MenuManager;
import org.eclipse.jface.viewers.CheckboxTreeViewer;
import org.eclipse.jface.viewers.IDecoration;
import org.eclipse.jface.viewers.ISelection;
+import org.eclipse.jface.viewers.ISelectionChangedListener;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.viewers.ITreeContentProvider;
import org.eclipse.jface.viewers.LabelProvider;
+import org.eclipse.jface.viewers.SelectionChangedEvent;
import org.eclipse.jface.viewers.Viewer;
import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
-import org.eclipse.swt.events.SelectionListener;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
@@ -52,6 +54,7 @@ import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Menu;
import org.eclipse.swt.widgets.Tree;
+import org.eclipse.ui.ISharedImages;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.ide.IDE;
@@ -60,23 +63,23 @@ import org.eclipse.m2e.core.ui.internal.MavenImages;
import org.eclipse.m2e.core.ui.internal.Messages;
+@SuppressWarnings("restriction")
public class NestedProjectsComposite extends Composite implements IMenuListener {
private static final Logger log = LoggerFactory.getLogger(NestedProjectsComposite.class);
private static final String SEPARATOR = System.getProperty("file.separator"); //$NON-NLS-1$
- private final IProject[] initialSelection;
+ CheckboxTreeViewer codebaseViewer;
- private CheckboxTreeViewer codebaseViewer;
+ Map<String, IProject> projectPaths;
- private Map<String, IProject> projectPaths;
+ Collection<IProject> projects;
- private Collection<IProject> projects;
+ IProject[] selectedProjects;
public NestedProjectsComposite(Composite parent, int style, IProject[] initialSelection) {
super(parent, style);
- this.initialSelection = initialSelection;
setLayout(new GridLayout(2, false));
@@ -95,7 +98,7 @@ public class NestedProjectsComposite extends Composite implements IMenuListener
public Object[] getElements(Object element) {
if(element instanceof Collection) {
- return ((Collection) element).toArray();
+ return ((Collection<?>) element).toArray();
}
return null;
}
@@ -115,7 +118,7 @@ public class NestedProjectsComposite extends Composite implements IMenuListener
}
return children.toArray();
} else if(parentElement instanceof Collection) {
- return ((Collection) parentElement).toArray();
+ return ((Collection<?>) parentElement).toArray();
}
return null;
}
@@ -141,15 +144,19 @@ public class NestedProjectsComposite extends Composite implements IMenuListener
}
}
} else if(element instanceof Collection) {
- return !((Collection) element).isEmpty();
+ return !((Collection<?>) element).isEmpty();
}
return false;
}
});
codebaseViewer.setLabelProvider(new LabelProvider() {
public Image getImage(Object element) {
- return MavenImages.createOverlayImage(MavenImages.MVN_PROJECT, PlatformUI.getWorkbench().getSharedImages()
- .getImage(IDE.SharedImages.IMG_OBJ_PROJECT), MavenImages.MAVEN_OVERLAY, IDecoration.TOP_LEFT);
+ ISharedImages sharedImages = PlatformUI.getWorkbench().getSharedImages();
+ if(element instanceof IProject && !((IProject) element).isAccessible()) {
+ return sharedImages.getImage(IDE.SharedImages.IMG_OBJ_PROJECT_CLOSED);
+ }
+ return MavenImages.createOverlayImage(MavenImages.MVN_PROJECT,
+ sharedImages.getImage(IDE.SharedImages.IMG_OBJ_PROJECT), MavenImages.MAVEN_OVERLAY, IDecoration.TOP_LEFT);
}
public String getText(Object element) {
@@ -184,64 +191,62 @@ public class NestedProjectsComposite extends Composite implements IMenuListener
gl_selectionActionComposite.marginHeight = 0;
selectionActionComposite.setLayout(gl_selectionActionComposite);
+ createButtons(selectionActionComposite);
+
+ createMenu();
+
+ codebaseViewer.addSelectionChangedListener(new ISelectionChangedListener() {
+ public void selectionChanged(SelectionChangedEvent event) {
+ selectedProjects = internalGetSelectedProjects();
+ }
+ });
+
+ selectedProjects = internalGetSelectedProjects();
+ }
+
+ protected void createButtons(Composite selectionActionComposite) {
Button selectAllBtn = new Button(selectionActionComposite, SWT.NONE);
selectAllBtn.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, false, false, 1, 1));
selectAllBtn.setText(Messages.UpdateDepenciesDialog_selectAll);
- selectAllBtn.addSelectionListener(new SelectionListener() {
+ selectAllBtn.addSelectionListener(new SelectionAdapter() {
public void widgetSelected(SelectionEvent e) {
for(IProject project : projects) {
codebaseViewer.setSubtreeChecked(project, true);
}
}
-
- public void widgetDefaultSelected(SelectionEvent e) {
-
- }
});
Button deselectAllBtn = new Button(selectionActionComposite, SWT.NONE);
deselectAllBtn.setLayoutData(new GridData(SWT.FILL, SWT.TOP, false, false, 1, 1));
deselectAllBtn.setText(Messages.UpdateDepenciesDialog_deselectAll);
- deselectAllBtn.addSelectionListener(new SelectionListener() {
+ deselectAllBtn.addSelectionListener(new SelectionAdapter() {
public void widgetSelected(SelectionEvent e) {
for(IProject project : projects) {
codebaseViewer.setSubtreeChecked(project, false);
}
}
-
- public void widgetDefaultSelected(SelectionEvent e) {
-
- }
});
Button expandAllBtn = new Button(selectionActionComposite, SWT.NONE);
expandAllBtn.setLayoutData(new GridData(SWT.FILL, SWT.BOTTOM, false, false, 1, 1));
expandAllBtn.setText(Messages.UpdateDepenciesDialog_expandAll);
- expandAllBtn.addSelectionListener(new SelectionListener() {
+ expandAllBtn.addSelectionListener(new SelectionAdapter() {
public void widgetSelected(SelectionEvent e) {
codebaseViewer.expandAll();
}
-
- public void widgetDefaultSelected(SelectionEvent e) {
- }
});
Button collapseAllBtn = new Button(selectionActionComposite, SWT.NONE);
collapseAllBtn.setLayoutData(new GridData(SWT.FILL, SWT.BOTTOM, false, false, 1, 1));
collapseAllBtn.setText(Messages.UpdateDepenciesDialog_collapseAll);
- collapseAllBtn.addSelectionListener(new SelectionListener() {
+ collapseAllBtn.addSelectionListener(new SelectionAdapter() {
public void widgetSelected(SelectionEvent e) {
codebaseViewer.collapseAll();
}
-
- public void widgetDefaultSelected(SelectionEvent e) {
- }
});
-
- createMenu();
}
- private String getElePath(Object element) {
+ String getElePath(Object element) {
if(element instanceof IProject) {
IProject project = (IProject) element;
URI locationURI = project.getLocationURI();
@@ -257,7 +262,7 @@ public class NestedProjectsComposite extends Composite implements IMenuListener
return null;
}
- private IProject getProject(String path) {
+ IProject getProject(String path) {
return projectPaths.get(path);
}
@@ -266,7 +271,7 @@ public class NestedProjectsComposite extends Composite implements IMenuListener
for(IProject project : ResourcesPlugin.getWorkspace().getRoot().getProjects()) {
try {
- if(project.isAccessible() && project.hasNature(IMavenConstants.NATURE_ID)) {
+ if(isInteresting(project)) {
if(project.getLocationURI() != null) {
String path = getElePath(project);
if(path != null) {
@@ -282,7 +287,7 @@ public class NestedProjectsComposite extends Composite implements IMenuListener
if(projectPaths.isEmpty()) {
return Collections.<IProject> emptyList();
}
- projects = new ArrayList<IProject>();
+ List<IProject> projects = new ArrayList<IProject>();
String previous = projectPaths.keySet().iterator().next();
addProject(projects, previous);
for(String path : projectPaths.keySet()) {
@@ -297,6 +302,10 @@ public class NestedProjectsComposite extends Composite implements IMenuListener
return projects;
}
+ protected boolean isInteresting(IProject project) throws CoreException {
+ return project.isAccessible() && project.hasNature(IMavenConstants.NATURE_ID);
+ }
+
private static void addProject(Collection<IProject> projects, String location) {
IWorkspaceRoot root = ResourcesPlugin.getWorkspace().getRoot();
for(IContainer container : root.findContainersForLocationURI(new File(location).toURI())) {
@@ -340,7 +349,7 @@ public class NestedProjectsComposite extends Composite implements IMenuListener
}
};
- private IProject getSelection() {
+ IProject getSelection() {
ISelection selection = codebaseViewer.getSelection();
if(selection instanceof IStructuredSelection) {
return (IProject) ((IStructuredSelection) selection).getFirstElement();
@@ -349,6 +358,10 @@ public class NestedProjectsComposite extends Composite implements IMenuListener
}
public IProject[] getSelectedProjects() {
+ return selectedProjects;
+ }
+
+ IProject[] internalGetSelectedProjects() {
Object[] obj = codebaseViewer.getCheckedElements();
IProject[] projects = new IProject[obj.length];
for(int i = 0; i < obj.length; i++ ) {
@@ -356,4 +369,19 @@ public class NestedProjectsComposite extends Composite implements IMenuListener
}
return projects;
}
+
+ public void refresh() {
+ projects = getMavenCodebases();
+ codebaseViewer.setInput(projects);
+ codebaseViewer.expandAll();
+ }
+
+ public void reset() {
+ projects = getMavenCodebases();
+ codebaseViewer.setInput(projects);
+ codebaseViewer.expandAll();
+ for(IProject project : projects) {
+ codebaseViewer.setSubtreeChecked(project, false);
+ }
+ }
}
diff --git a/org.eclipse.m2e.core.ui/src/org/eclipse/m2e/core/ui/internal/dialogs/AssignWorkingSetDialog.java b/org.eclipse.m2e.core.ui/src/org/eclipse/m2e/core/ui/internal/dialogs/AssignWorkingSetDialog.java
new file mode 100644
index 00000000..3acd4bee
--- /dev/null
+++ b/org.eclipse.m2e.core.ui/src/org/eclipse/m2e/core/ui/internal/dialogs/AssignWorkingSetDialog.java
@@ -0,0 +1,174 @@
+/*******************************************************************************
+ * Copyright (c) 2013 Igor Fedorenko
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Igor Fedorenko - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.m2e.core.ui.internal.dialogs;
+
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IAdaptable;
+import org.eclipse.jface.dialogs.TitleAreaDialog;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.SelectionAdapter;
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Button;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.ui.IWorkingSet;
+import org.eclipse.ui.IWorkingSetManager;
+import org.eclipse.ui.PlatformUI;
+
+import org.eclipse.m2e.core.internal.IMavenConstants;
+import org.eclipse.m2e.core.ui.internal.Messages;
+import org.eclipse.m2e.core.ui.internal.components.NestedProjectsComposite;
+import org.eclipse.m2e.core.ui.internal.components.WorkingSetGroup;
+
+
+/**
+ * @since 1.5
+ */
+@SuppressWarnings("restriction")
+public class AssignWorkingSetDialog extends TitleAreaDialog {
+
+ private final IProject[] initialSelection;
+
+ NestedProjectsComposite selectedProjects;
+
+ private List<IWorkingSet> workingSets = new ArrayList<IWorkingSet>();
+
+ Set<IProject> allWorkingSetProjects = getAllWorkingSetProjects();
+
+ WorkingSetGroup workingSetGroup;
+
+ public AssignWorkingSetDialog(Shell parentShell, IProject[] initialSelection) {
+ super(parentShell);
+ this.initialSelection = initialSelection;
+ }
+
+ private static Set<IProject> getAllWorkingSetProjects() {
+ Set<IProject> projects = new HashSet<IProject>();
+ IWorkingSetManager manager = PlatformUI.getWorkbench().getWorkingSetManager();
+ for(IWorkingSet workingSet : manager.getAllWorkingSets()) {
+ try {
+ for(IAdaptable element : workingSet.getElements()) {
+ IProject project = (IProject) element.getAdapter(IProject.class);
+ if(project != null) {
+ projects.add(project);
+ }
+ }
+ } catch(IllegalStateException ignored) {
+ // ignore bad/misconfigured working sets
+ }
+ }
+ return projects;
+ }
+
+ protected Control createDialogArea(Composite parent) {
+ setTitle(Messages.AssignWorkingSetDialog_title);
+
+ Composite area = (Composite) super.createDialogArea(parent);
+
+ Composite composite = new Composite(area, SWT.NONE);
+ composite.setLayout(new GridLayout(3, false));
+ composite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true, 1, 1));
+
+ Composite filtersComposite = new Composite(composite, SWT.NONE);
+ filtersComposite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false, 3, 1));
+ GridLayout gl_filtersComposite = new GridLayout(4, false);
+ gl_filtersComposite.verticalSpacing = 0;
+ gl_filtersComposite.marginWidth = 0;
+ gl_filtersComposite.marginHeight = 0;
+ filtersComposite.setLayout(gl_filtersComposite);
+
+ final Button btnFilterAssignedProjects = new Button(filtersComposite, SWT.CHECK);
+ btnFilterAssignedProjects.setText(Messages.AssignWorkingSetDialog_btnFilterAssignedProjects_text);
+ btnFilterAssignedProjects.setSelection(true);
+ btnFilterAssignedProjects.addSelectionListener(new SelectionAdapter() {
+ @Override
+ public void widgetSelected(SelectionEvent e) {
+ selectedProjects.refresh();
+ }
+ });
+
+ final Button btnFilterClosedProjects = new Button(filtersComposite, SWT.CHECK);
+ btnFilterClosedProjects.setText(Messages.AssignWorkingSetDialog_btnFilterClosedProjects_text);
+ btnFilterClosedProjects.setSelection(true);
+ btnFilterClosedProjects.addSelectionListener(new SelectionAdapter() {
+ @Override
+ public void widgetSelected(SelectionEvent e) {
+ selectedProjects.refresh();
+ }
+ });
+
+ this.selectedProjects = new NestedProjectsComposite(composite, SWT.NONE, initialSelection) {
+ @Override
+ protected boolean isInteresting(IProject project) throws CoreException {
+ if(btnFilterClosedProjects.getSelection() && !project.isAccessible()) {
+ return false;
+ }
+ if(project.isAccessible() && !project.hasNature(IMavenConstants.NATURE_ID)) {
+ // project.hasNature throws an exception for inaccessible projects
+ return false;
+ }
+ return !btnFilterAssignedProjects.getSelection() || !allWorkingSetProjects.contains(project);
+ }
+
+ @Override
+ protected void createButtons(Composite selectionActionComposite) {
+ super.createButtons(selectionActionComposite);
+
+ Label label = new Label(selectionActionComposite, SWT.SEPARATOR | SWT.HORIZONTAL);
+ label.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, false, false, 1, 1));
+
+ Button btnAssign = new Button(selectionActionComposite, SWT.NONE);
+ btnAssign.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, false, false, 1, 1));
+ btnAssign.setText(Messages.AssignWorkingSetDialog_btnAssign_text);
+ btnAssign.addSelectionListener(new SelectionAdapter() {
+ public void widgetSelected(SelectionEvent e) {
+ assignWorkingSets();
+ reset();
+ }
+ });
+ }
+ };
+ selectedProjects.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true, 3, 1));
+
+ this.workingSetGroup = new WorkingSetGroup(composite, workingSets, getShell());
+
+ return area;
+ }
+
+ public IWorkingSet[] getWorkingSets() {
+ return workingSets.toArray(new IWorkingSet[workingSets.size()]);
+ }
+
+ public IProject[] getSelectedProjects() {
+ return selectedProjects.getSelectedProjects();
+ }
+
+ public void assignWorkingSets() {
+ IWorkingSetManager manager = PlatformUI.getWorkbench().getWorkingSetManager();
+ IWorkingSet[] workingSets = getWorkingSets();
+ for(IProject project : getSelectedProjects()) {
+ manager.addToWorkingSets(project, workingSets);
+ allWorkingSetProjects.add(project);
+ }
+ }
+
+}
diff --git a/org.eclipse.m2e.core.ui/src/org/eclipse/m2e/core/ui/internal/messages.properties b/org.eclipse.m2e.core.ui/src/org/eclipse/m2e/core/ui/internal/messages.properties
index cc7917f3..ebe9d71a 100644
--- a/org.eclipse.m2e.core.ui/src/org/eclipse/m2e/core/ui/internal/messages.properties
+++ b/org.eclipse.m2e.core.ui/src/org/eclipse/m2e/core/ui/internal/messages.properties
@@ -1,15 +1,19 @@
#Eclipse modern messages class
-#Mon Feb 18 09:07:54 EST 2013
+#Wed Sep 18 00:49:07 EDT 2013
AddDependencyAction_error_msg=Can't add dependency to {0}
AddDependencyAction_error_title=Add Dependency
AddDependencyAction_searchDialog_title=Add Dependency
-AddDependencyDialog_artifactId_label=Artifact Id\:
AddDependencyDialog_artifactId_error=Artifact Id cannot be empty
-AddDependencyDialog_groupId_label=Group Id\:
+AddDependencyDialog_artifactId_label=Artifact Id\:
AddDependencyDialog_groupId_error=Group Id cannot be empty
+AddDependencyDialog_groupId_label=Group Id\:
AddDependencyDialog_scope_label=Scope\:
AddDependencyDialog_version_label=Version\:
AddPluginAction_searchDialog_title=Add Plugin
+AssignWorkingSetDialog_btnAssign_text=Assign
+AssignWorkingSetDialog_btnFilterAssignedProjects_text=Filter assigned projects
+AssignWorkingSetDialog_btnFilterClosedProjects_text=Filter closed projects
+AssignWorkingSetDialog_title=Add projects to working sets
BuildDebugView_actionClear=Clear
BuildDebugView_actionCollapseAll=Collapse All
BuildDebugView_actionSuspend=Suspend

Back to the top