diff options
5 files changed, 523 insertions, 83 deletions
diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/UIText.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/UIText.java index 7f3f2fb96a..0f2c47eafd 100644 --- a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/UIText.java +++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/UIText.java @@ -310,7 +310,10 @@ public class UIText extends NLS { public static String RepositorySearchDialog_ScanningForRepositories_message; /** */ - public static String RepositorySearchDialog_ToggleSelection_button; + public static String RepositorySearchDialog_DeselectAll_button; + + /** */ + public static String RepositorySearchDialog_SelectAll_button; /** */ public static String CompareWithIndexAction_FileNotInIndex; @@ -343,6 +346,9 @@ public class UIText extends NLS { public static String RepositorySearchDialog_searchRepositories; /** */ + public static String RepositorySearchDialog_searchRepositoriesMessage; + + /** */ public static String RepositorySelectionPage_BrowseLocalFile; /** */ diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/CachedCheckboxTreeViewer.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/CachedCheckboxTreeViewer.java new file mode 100644 index 0000000000..9a8200bcbf --- /dev/null +++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/CachedCheckboxTreeViewer.java @@ -0,0 +1,262 @@ +/******************************************************************************* + * Copyright (c) 2010 Red Hat, Inc. + * 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: + * Chris Aniszczyk <caniszczyk@gmail.com> - initial implementation + *******************************************************************************/ +package org.eclipse.egit.ui.internal; + +import java.util.*; +import org.eclipse.jface.viewers.*; +import org.eclipse.swt.widgets.Tree; +import org.eclipse.ui.dialogs.ContainerCheckedTreeViewer; + +/** + * Copy of ContainerCheckedTreeViewer which is specialized for use + * with {@link FilteredCheckboxTree}. This container caches + * the check state of leaf nodes in the tree. When a filter + * is applied the cache stores which nodes are checked. When + * a filter is removed the viewer can be told to restore check + * state from the cache. This viewer updates the check state of + * parent items the same way as {@link CachedCheckboxTreeViewer} + * <p> + * Note: If duplicate items are added to the tree the cache will treat them + * as a single entry. + * </p> + */ +public class CachedCheckboxTreeViewer extends ContainerCheckedTreeViewer { + + private Set checkState = new HashSet(); + + /** + * Constructor for ContainerCheckedTreeViewer. + * @see CheckboxTreeViewer#CheckboxTreeViewer(Tree) + */ + protected CachedCheckboxTreeViewer(Tree tree) { + super(tree); + addCheckStateListener(new ICheckStateListener() { + public void checkStateChanged(CheckStateChangedEvent event) { + updateCheckState(event.getElement(), event.getChecked()); + } + }); + setUseHashlookup(true); + } + + /** + * @param element + * @param state + */ + protected void updateCheckState(final Object element, final boolean state) { + if (state) { + // Add the item (or its children) to the cache + if (checkState == null) { + checkState = new HashSet(); + } + + ITreeContentProvider contentProvider = null; + if (getContentProvider() instanceof ITreeContentProvider) { + contentProvider = (ITreeContentProvider) getContentProvider(); + } + + if (contentProvider != null) { + Object[] children = contentProvider.getChildren(element); + if (children != null && children.length > 0) { + for (int i = 0; i < children.length; i++) { + updateCheckState(children[i], state); + } + } else { + checkState.add(element); + } + } else { + checkState.add(element); + } + } else if (checkState != null) { + // Remove the item (or its children) from the cache + ITreeContentProvider contentProvider = null; + if (getContentProvider() instanceof ITreeContentProvider) { + contentProvider = (ITreeContentProvider) getContentProvider(); + } + + if (contentProvider != null) { + Object[] children = contentProvider.getChildren(element); + if (children.length > 0) { + for (int i = 0; i < children.length; i++) { + updateCheckState(children[i], state); + } + + } + } + checkState.remove(element); + } + } + + /** + * Restores the checked state of items based on the cached check state. This + * will only check leaf nodes, but parent items will be updated by the container + * viewer. No events will be fired. + */ + public void restoreLeafCheckState() { + if (checkState == null) + return; + + getTree().setRedraw(false); + // Call the super class so we don't mess up the cache + super.setCheckedElements(new Object[0]); + setGrayedElements(new Object[0]); + // Now we are only going to set the check state of the leaf nodes + // and rely on our container checked code to update the parents properly. + Iterator iter = checkState.iterator(); + Object element = null; + if (iter.hasNext()) + expandAll(); + while (iter.hasNext()) { + element = iter.next(); + // Call the super class as there is no need to update the check state + super.setChecked(element, true); + } + getTree().setRedraw(true); + } + + /** + * Returns the contents of the cached check state. The contents will be all + * checked leaf nodes ignoring any filters. + * + * @return checked leaf elements + */ + public Object[] getCheckedLeafElements() { + if (checkState == null) { + return new Object[0]; + } + return checkState.toArray(new Object[checkState.size()]); + } + + /** + * Returns the number of leaf nodes checked. This method uses its internal check + * state cache to determine what has been checked, not what is visible in the viewer. + * The cache does not count duplicate items in the tree. + * + * @return number of leaf nodes checked according to the cached check state + */ + public int getCheckedLeafCount() { + if (checkState == null) { + return 0; + } + return checkState.size(); + } + + /* (non-Javadoc) + * @see org.eclipse.jface.viewers.ICheckable#setChecked(java.lang.Object, boolean) + */ + public boolean setChecked(Object element, boolean state) { + updateCheckState(element, state); + return super.setChecked(element, state); + } + + /* (non-Javadoc) + * @see org.eclipse.jface.viewers.CheckboxTreeViewer#setCheckedElements(java.lang.Object[]) + */ + public void setCheckedElements(Object[] elements) { + super.setCheckedElements(elements); + if (checkState == null) { + checkState = new HashSet(); + } else { + checkState.clear(); + } + ITreeContentProvider contentProvider = null; + if (getContentProvider() instanceof ITreeContentProvider) { + contentProvider = (ITreeContentProvider) getContentProvider(); + } + + for (int i = 0; i < elements.length; i++) { + Object[] children = contentProvider != null ? contentProvider.getChildren(elements[i]) : null; + if (!getGrayed(elements[i]) && (children == null || children.length == 0)) { + if (!checkState.contains(elements[i])) { + checkState.add(elements[i]); + } + } + } + } + + /* (non-Javadoc) + * @see org.eclipse.jface.viewers.CheckboxTreeViewer#setAllChecked(boolean) + */ + public void setAllChecked(boolean state) { + super.setAllChecked(state); + if (state) { + + // Find all visible children, add only the visible leaf nodes to the check state cache + Object[] visible = getFilteredChildren(getRoot()); + if (checkState == null) { + checkState = new HashSet(); + } + + ITreeContentProvider contentProvider = null; + if (getContentProvider() instanceof ITreeContentProvider) { + contentProvider = (ITreeContentProvider) getContentProvider(); + } + + if (contentProvider == null) { + for (int i = 0; i < visible.length; i++) { + checkState.add(visible[i]); + } + } else { + Set toCheck = new HashSet(); + for (int i = 0; i < visible.length; i++) { + addFilteredChildren(visible[i], contentProvider, toCheck); + } + checkState.addAll(toCheck); + } + } else { + // Remove any item in the check state that is visible (passes the filters) + if (checkState != null) { + Object[] visible = filter(checkState.toArray()); + for (int i = 0; i < visible.length; i++) { + checkState.remove(visible[i]); + } + } + } + } + + /** + * If the element is a leaf node, it is added to the result collection. If the element has + * children, this method will recursively look at the children and add any visible leaf nodes + * to the collection. + * + * @param element element to check + * @param contentProvider tree content provider to check for children + * @param result collection to collect leaf nodes in + */ + private void addFilteredChildren(Object element, ITreeContentProvider contentProvider, Collection result) { + if (!contentProvider.hasChildren(element)) { + result.add(element); + } else { + Object[] visibleChildren = getFilteredChildren(element); + for (int i = 0; i < visibleChildren.length; i++) { + addFilteredChildren(visibleChildren[i], contentProvider, result); + } + } + } + + /* (non-Javadoc) + * @see org.eclipse.jface.viewers.AbstractTreeViewer#remove(java.lang.Object[]) + */ + public void remove(Object[] elementsOrTreePaths) { + for (int i = 0; i < elementsOrTreePaths.length; i++) { + updateCheckState(elementsOrTreePaths[i], false); + } + super.remove(elementsOrTreePaths); + } + + /* (non-Javadoc) + * @see org.eclipse.jface.viewers.AbstractTreeViewer#remove(java.lang.Object) + */ + public void remove(Object elementsOrTreePaths) { + updateCheckState(elementsOrTreePaths, false); + super.remove(elementsOrTreePaths); + } + +} diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/FilteredCheckboxTree.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/FilteredCheckboxTree.java new file mode 100644 index 0000000000..859dcd7995 --- /dev/null +++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/FilteredCheckboxTree.java @@ -0,0 +1,139 @@ +/******************************************************************************* + * Copyright (c) 2010 Red Hat, Inc. + * 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: + * Chris Aniszczyk <caniszczyk@gmail.com> - initial implementation + *******************************************************************************/ +package org.eclipse.egit.ui.internal; + +import org.eclipse.core.runtime.jobs.IJobChangeEvent; +import org.eclipse.core.runtime.jobs.JobChangeAdapter; +import org.eclipse.jface.viewers.TreeViewer; +import org.eclipse.swt.SWT; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Text; +import org.eclipse.swt.widgets.Tree; +import org.eclipse.ui.dialogs.FilteredTree; +import org.eclipse.ui.dialogs.PatternFilter; +import org.eclipse.ui.forms.widgets.FormToolkit; +import org.eclipse.ui.progress.WorkbenchJob; + +/** + * A FilteredCheckboxTree implementation to be used internally in EGit code. This tree stores + * all the tree elements internally, and keeps the check state in sync. This way, even if an + * element is filtered, the caller can get and set the checked state. + */ +public class FilteredCheckboxTree extends FilteredTree { + + private static final long FILTER_DELAY = 400; + + FormToolkit fToolkit; + CachedCheckboxTreeViewer checkboxViewer; + + /** + * Constructor that creates a tree with preset style bits and a CachedContainerCheckedTreeViewer for the tree. + * + * @param parent parent composite + * @param toolkit optional toolkit to create UI elements with, required if the tree is being created in a form editor + */ + public FilteredCheckboxTree(Composite parent, FormToolkit toolkit) { + this(parent, toolkit, SWT.NONE); + } + + /** + * Constructor that creates a tree with preset style bits and a CachedContainerCheckedTreeViewer for the tree. + * + * @param parent parent composite + * @param toolkit optional toolkit to create UI elements with, required if the tree is being created in a form editor + * @param treeStyle + */ + public FilteredCheckboxTree(Composite parent, FormToolkit toolkit, int treeStyle) { + this(parent, toolkit, treeStyle, new PatternFilter()); + } + + /** + * Constructor that creates a tree with preset style bits and a CachedContainerCheckedTreeViewer for the tree. + * + * @param parent parent composite + * @param toolkit optional toolkit to create UI elements with, required if the tree is being created in a form editor + * @param treeStyle + * @param filter pattern filter to use in the filter control + */ + public FilteredCheckboxTree(Composite parent, FormToolkit toolkit, int treeStyle, PatternFilter filter) { + super(parent, true); + fToolkit = toolkit; + init(treeStyle, filter); + } + + /* (non-Javadoc) + * @see org.eclipse.ui.dialogs.FilteredTree#doCreateTreeViewer(org.eclipse.swt.widgets.Composite, int) + */ + protected TreeViewer doCreateTreeViewer(Composite parent, int style) { + int treeStyle = style | SWT.CHECK | SWT.MULTI | SWT.V_SCROLL | SWT.H_SCROLL | SWT.BORDER; + Tree tree = null; + if (fToolkit != null) { + tree = fToolkit.createTree(parent, treeStyle); + } else { + tree = new Tree(parent, treeStyle); + } + + checkboxViewer = new CachedCheckboxTreeViewer(tree); + return checkboxViewer; + } + + /* + * Overridden to hook a listener on the job and set the deferred content provider + * to synchronous mode before a filter is done. + * @see org.eclipse.ui.dialogs.FilteredTree#doCreateRefreshJob() + */ + protected WorkbenchJob doCreateRefreshJob() { + WorkbenchJob filterJob = super.doCreateRefreshJob(); + filterJob.addJobChangeListener(new JobChangeAdapter() { + public void done(IJobChangeEvent event) { + if (event.getResult().isOK()) { + getDisplay().asyncExec(new Runnable() { + public void run() { + if (checkboxViewer.getTree().isDisposed()) + return; + checkboxViewer.restoreLeafCheckState(); + } + }); + } + } + }); + return filterJob; + } + + /* (non-Javadoc) + * @see org.eclipse.ui.dialogs.FilteredTree#doCreateFilterText(org.eclipse.swt.widgets.Composite) + */ + protected Text doCreateFilterText(Composite parent) { + // Overridden so the text gets create using the toolkit if we have one + Text parentText = super.doCreateFilterText(parent); + if (fToolkit != null) { + int style = parentText.getStyle(); + parentText.dispose(); + return fToolkit.createText(parent, null, style); + } + return parentText; + } + + /** + * @return The checkbox treeviewer + */ + public CachedCheckboxTreeViewer getCheckboxTreeViewer() { + return checkboxViewer; + } + + /* + * (non-Javadoc) + * @see org.eclipse.ui.dialogs.FilteredTree#getRefreshJobDelay() + */ + protected long getRefreshJobDelay() { + return FILTER_DELAY; + } +}
\ No newline at end of file diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/repository/RepositorySearchDialog.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/repository/RepositorySearchDialog.java index 40dd43133e..dd0f116adc 100644 --- a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/repository/RepositorySearchDialog.java +++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/repository/RepositorySearchDialog.java @@ -25,23 +25,29 @@ import org.eclipse.core.runtime.Status; import org.eclipse.core.runtime.preferences.IEclipsePreferences; import org.eclipse.core.runtime.preferences.InstanceScope; import org.eclipse.egit.core.Activator; +import org.eclipse.egit.ui.UIIcons; import org.eclipse.egit.ui.UIText; -import org.eclipse.jface.dialogs.Dialog; +import org.eclipse.egit.ui.internal.FilteredCheckboxTree; import org.eclipse.jface.dialogs.IDialogConstants; import org.eclipse.jface.dialogs.ProgressMonitorDialog; +import org.eclipse.jface.dialogs.TitleAreaDialog; import org.eclipse.jface.layout.GridDataFactory; import org.eclipse.jface.operation.IRunnableWithProgress; -import org.eclipse.jface.viewers.BaseLabelProvider; +import org.eclipse.jface.resource.JFaceResources; +import org.eclipse.jface.resource.LocalResourceManager; +import org.eclipse.jface.resource.ResourceManager; import org.eclipse.jface.viewers.CheckStateChangedEvent; -import org.eclipse.jface.viewers.CheckboxTableViewer; +import org.eclipse.jface.viewers.CheckboxTreeViewer; import org.eclipse.jface.viewers.ICheckStateListener; import org.eclipse.jface.viewers.IColorProvider; -import org.eclipse.jface.viewers.IStructuredContentProvider; -import org.eclipse.jface.viewers.ITableLabelProvider; +import org.eclipse.jface.viewers.ITreeContentProvider; +import org.eclipse.jface.viewers.LabelProvider; import org.eclipse.jface.viewers.Viewer; import org.eclipse.jgit.lib.RepositoryCache; import org.eclipse.osgi.util.NLS; import org.eclipse.swt.SWT; +import org.eclipse.swt.events.ModifyEvent; +import org.eclipse.swt.events.ModifyListener; import org.eclipse.swt.events.SelectionAdapter; import org.eclipse.swt.events.SelectionEvent; import org.eclipse.swt.graphics.Color; @@ -54,30 +60,34 @@ import org.eclipse.swt.widgets.Control; import org.eclipse.swt.widgets.DirectoryDialog; import org.eclipse.swt.widgets.Label; import org.eclipse.swt.widgets.Shell; -import org.eclipse.swt.widgets.Table; import org.eclipse.swt.widgets.Text; import org.osgi.service.prefs.BackingStoreException; /** * Searches for Git directories under a path that can be selected by the user */ -public class RepositorySearchDialog extends Dialog { +public class RepositorySearchDialog extends TitleAreaDialog { private static final String PREF_DEEP_SEARCH = "RepositorySearchDialogDeepSearch"; //$NON-NLS-1$ private static final String PREF_PATH = "RepositorySearchDialogSearchPath"; //$NON-NLS-1$ - private final Set<String> existingRepositoryDirs = new HashSet<String>(); + private final Set<String> fExistingDirectories = new HashSet<String>(); - private Set<String> result; + private Set<String> fResult; - CheckboxTableViewer tv; + private FilteredCheckboxTree fTree; - private Button btnToggleSelect; + private CheckboxTreeViewer fTreeViewer; - private Table tab; + private Button fSelectAllButton; - private final class ContentProvider implements IStructuredContentProvider { + private Button fDeselectAllButton; + + private final ResourceManager fImageCache = new LocalResourceManager(JFaceResources + .getResources()); + + private final class ContentProvider implements ITreeContentProvider { @SuppressWarnings("unchecked") public Object[] getElements(Object inputElement) { @@ -92,16 +102,32 @@ public class RepositorySearchDialog extends Dialog { // nothing } + public Object[] getChildren(Object parentElement) { + // nothing + return null; + } + + public Object getParent(Object element) { + // nothing + return null; + } + + public boolean hasChildren(Object element) { + // nothing + return false; + } + } - private final class LabelProvider extends BaseLabelProvider implements - ITableLabelProvider, IColorProvider { + private final class RepositoryLabelProvider extends LabelProvider implements IColorProvider { - public Image getColumnImage(Object element, int columnIndex) { - return null; + @Override + public Image getImage(Object element) { + return fImageCache.createImage(UIIcons.REPOSITORY); } - public String getColumnText(Object element, int columnIndex) { + @Override + public String getText(Object element) { return element.toString(); } @@ -110,12 +136,16 @@ public class RepositorySearchDialog extends Dialog { } public Color getForeground(Object element) { - if (existingRepositoryDirs.contains(element)) + if (fExistingDirectories.contains(element)) return getShell().getDisplay().getSystemColor(SWT.COLOR_GRAY); return null; } + public void dispose() { + fImageCache.dispose(); + } + } /** @@ -125,7 +155,7 @@ public class RepositorySearchDialog extends Dialog { public RepositorySearchDialog(Shell parentShell, Collection<String> existingDirs) { super(parentShell); - this.existingRepositoryDirs.addAll(existingDirs); + this.fExistingDirectories.addAll(existingDirs); setShellStyle(getShellStyle() | SWT.SHELL_TRIM); } @@ -134,28 +164,31 @@ public class RepositorySearchDialog extends Dialog { * @return the directories */ public Set<String> getDirectories() { - return result; + return fResult; } @Override protected void configureShell(Shell newShell) { super.configureShell(newShell); newShell.setText(UIText.RepositorySearchDialog_searchRepositories); + setTitleImage(fImageCache.createImage(UIIcons.WIZBAN_IMPORT_REPO)); } @Override protected void okPressed() { - result = new HashSet<String>(); - Object[] checked = tv.getCheckedElements(); + fResult = new HashSet<String>(); + Object[] checked = fTreeViewer.getCheckedElements(); for (Object o : checked) { - result.add((String) o); + fResult.add((String) o); } super.okPressed(); } @Override protected Control createDialogArea(Composite parent) { - + super.createDialogArea(parent); + setTitle(UIText.RepositorySearchDialog_searchRepositories); + setMessage(UIText.RepositorySearchDialog_searchRepositoriesMessage); final IEclipsePreferences prefs = new InstanceScope().getNode(Activator .getPluginId()); @@ -198,22 +231,24 @@ public class RepositorySearchDialog extends Dialog { }); - // we fill the room under the "Directory" label - new Label(main, SWT.NONE); + fTree = new FilteredCheckboxTree(main, null, SWT.BORDER); + fTreeViewer = fTree.getCheckboxTreeViewer(); + GridDataFactory.fillDefaults().grab(true, true).span(4, 1).minSize(0, 300).applyTo(fTree); + fTree.setEnabled(false); - final Button btnLookForNested = new Button(main, SWT.CHECK); - btnLookForNested.setLayoutData(new GridData(SWT.LEFT, SWT.CENTER, + final Button lookForNestedButton = new Button(main, SWT.CHECK); + lookForNestedButton.setLayoutData(new GridData(SWT.LEFT, SWT.CENTER, false, false, 2, 1)); - btnLookForNested + lookForNestedButton .setSelection(prefs.getBoolean(PREF_DEEP_SEARCH, false)); - btnLookForNested + lookForNestedButton .setText(UIText.RepositorySearchDialog_DeepSearch_button); - btnLookForNested.addSelectionListener(new SelectionAdapter() { + lookForNestedButton.addSelectionListener(new SelectionAdapter() { @Override public void widgetSelected(SelectionEvent e) { - prefs.putBoolean(PREF_DEEP_SEARCH, btnLookForNested + prefs.putBoolean(PREF_DEEP_SEARCH, lookForNestedButton .getSelection()); try { prefs.flush(); @@ -224,57 +259,48 @@ public class RepositorySearchDialog extends Dialog { }); - Button search = new Button(main, SWT.PUSH); - search.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, false, false, - 1, 1)); - search.setText(UIText.RepositorySearchDialog_search); - - tv = CheckboxTableViewer.newCheckList(main, SWT.BORDER); - tab = tv.getTable(); - tab.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true, 3, 1)); - tab.setEnabled(false); - btnToggleSelect = new Button(main, SWT.NONE); - btnToggleSelect.setLayoutData(new GridData(SWT.FILL, SWT.TOP, false, + fSelectAllButton = new Button(main, SWT.NONE); + fSelectAllButton.setLayoutData(new GridData(SWT.RIGHT, SWT.TOP, false, false, 1, 1)); - btnToggleSelect - .setText(UIText.RepositorySearchDialog_ToggleSelection_button); - btnToggleSelect.setEnabled(false); - btnToggleSelect.addSelectionListener(new SelectionAdapter() { + fSelectAllButton + .setText(UIText.RepositorySearchDialog_SelectAll_button); + fSelectAllButton.setEnabled(false); + fSelectAllButton.addSelectionListener(new SelectionAdapter() { @Override public void widgetSelected(SelectionEvent e) { - - for (int i = 0; i < tab.getItemCount(); i++) { - if (!existingRepositoryDirs.contains(tv.getElementAt(i))) - tv.setChecked(tv.getElementAt(i), !tv.getChecked(tv - .getElementAt(i))); - } + fTreeViewer.setAllChecked(true); getButton(IDialogConstants.OK_ID).setEnabled( - tv.getCheckedElements().length > 0); + fTreeViewer.getCheckedElements().length > 0); } }); - tv.addCheckStateListener(new ICheckStateListener() { + fDeselectAllButton = new Button(main, SWT.NONE); + fDeselectAllButton.setLayoutData(new GridData(SWT.RIGHT, SWT.TOP, false, + false, 1, 1)); + fDeselectAllButton + .setText(UIText.RepositorySearchDialog_DeselectAll_button); + fDeselectAllButton.setEnabled(false); + fDeselectAllButton.addSelectionListener(new SelectionAdapter() { - public void checkStateChanged(CheckStateChangedEvent event) { - if (existingRepositoryDirs.contains(event.getElement())) - event.getCheckable().setChecked(event.getElement(), false); + @Override + public void widgetSelected(SelectionEvent e) { + fTreeViewer.setAllChecked(false); getButton(IDialogConstants.OK_ID).setEnabled( - tv.getCheckedElements().length > 0); + fTreeViewer.getCheckedElements().length > 0); } }); - tv.setContentProvider(new ContentProvider()); - tv.setLabelProvider(new LabelProvider()); - - search.addSelectionListener(new SelectionAdapter() { + // TODO this isn't the most optimal way of handling this... ideally we should have some type of delay + // if we could use databinding an observeDelayedValue would totally work here + dir.addModifyListener(new ModifyListener() { - @Override - public void widgetSelected(SelectionEvent e) { + public void modifyText(ModifyEvent e) { + // perform the search... final TreeSet<String> directories = new TreeSet<String>(); final File file = new File(dir.getText()); - final boolean lookForNested = btnLookForNested.getSelection(); + final boolean lookForNested = lookForNestedButton.getSelection(); if (file.exists()) { try { prefs.put(PREF_PATH, file.getCanonicalPath()); @@ -324,29 +350,34 @@ public class RepositorySearchDialog extends Dialog { boolean foundNew = false; for (String foundDir : directories) { - if (!existingRepositoryDirs.contains(foundDir)) { + if (!fExistingDirectories.contains(foundDir)) { foundNew = true; break; } } - btnToggleSelect.setEnabled(foundNew); - tab.setEnabled(directories.size() > 0); - tv.setInput(directories); + fSelectAllButton.setEnabled(foundNew); + fDeselectAllButton.setEnabled(foundNew); + fTree.setEnabled(directories.size() > 0); + fTreeViewer.setInput(directories); } } + }); + + fTreeViewer.addCheckStateListener(new ICheckStateListener() { + public void checkStateChanged(CheckStateChangedEvent event) { + if (fExistingDirectories.contains(event.getElement())) + event.getCheckable().setChecked(event.getElement(), false); + getButton(IDialogConstants.OK_ID).setEnabled( + fTreeViewer.getCheckedElements().length > 0); + } }); - return main; - } + fTreeViewer.setContentProvider(new ContentProvider()); + fTreeViewer.setLabelProvider(new RepositoryLabelProvider()); - @Override - protected Control createButtonBar(Composite parent) { - // disable the OK button until the user selects something - Control bar = super.createButtonBar(parent); - getButton(IDialogConstants.OK_ID).setEnabled(false); - return bar; + return main; } private void findGitDirsRecursive(File root, TreeSet<String> strings, diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/uitext.properties b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/uitext.properties index 53a465ec8f..852500d207 100644 --- a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/uitext.properties +++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/uitext.properties @@ -115,15 +115,17 @@ RepositoryRemotePropertySource_PushLabel=Remote Push Specification RepositoryRemotePropertySource_RemoteFetchURL_label=Remote Fetch URL RepositoryRemotePropertySource_RemotePushUrl_label=Remote Push URL -RepositorySearchDialog_DeepSearch_button=Look for Nested Repositories +RepositorySearchDialog_DeepSearch_button=Look for nested repositories RepositorySearchDialog_RepositoriesFound_message={0} Git repositories found... RepositorySearchDialog_ScanningForRepositories_message=Scanning for GIT repositories... -RepositorySearchDialog_ToggleSelection_button=Toggle Selection +RepositorySearchDialog_SelectAll_button=Select All +RepositorySearchDialog_DeselectAll_button=Deselect All RepositorySearchDialog_browse=Browse... -RepositorySearchDialog_directory=Directory +RepositorySearchDialog_directory=Directory: RepositorySearchDialog_errorOccurred=Error occurred RepositorySearchDialog_search=Search RepositorySearchDialog_searchRepositories=Search Git Repositories +RepositorySearchDialog_searchRepositoriesMessage=Search for local Git repositories on the file system RepositorySelectionPage_BrowseLocalFile=Local file... RepositorySelectionPage_sourceSelectionTitle=Source Git Repository RepositorySelectionPage_sourceSelectionDescription=Enter the location of the source repository. |