[EGIT PATCH 04/11] Add new class ExceptionCollector for grouping exceptions

Previous thread: none

Next thread: What's cooking in git.git (Feb 2009, #02; Wed, 04) by Junio C Hamano on Wednesday, February 4, 2009 - 6:32 pm. (3 messages)
From: Tor Arne Vestbø
Date: Wednesday, February 4, 2009 - 6:00 pm

This series adds support for customizable label decorations, which
is usefull for hiding selected decorations, or tweaking the format
of the decoration text.

Decorations are edited using the new Team->Git->Label Decorations
preference page, which is based off similar functionality from the
existing CVS and SVN team providers.

Icons can be enabled and disabled individually, and text can be
customized by reordering and editing the set of mapped variables.
Boolean variables like 'dirty' and 'staged' can be customized by
postfixing the variable name with a colon and a selected string
that should be insert if the variable evaluates to true.

The two general options control traversal of child and parent
elements during decoration. The first, 'Also re-decorate...',
controls whether or not ancestor elements of the current decorated
elment will also be scheduled for re-recoration. The second, 
'Inspect dirty state...', controls whether decoration of container
elements such as projects and folders should traverse child elements
to decide if the container is dirty.

Disabling these options will improve performance for large trees.

The code should be solid enough for normal use, but I may have
missed situations that the code does not handle -- resuling in
crash and burn. If so, please let me know.

Known issues are:

  - If a project has a repository more than one level above the
    project directory decorations will fail.

  - When a Java resource is dirty, each parent package in the
    package hierarcy will appear dirty, even when the layout is
    set to 'flat'.

I've sprinkled the code with TODOs where I found possible future
improvments. One such improvment is performance, where for example
refactoring to use one shared status cache should help.

Tor Arne

PS: This is my first major patch to EGit, so apologies in advance
if I messed up the steps of the submit process in any way :)


Tor Arne Vestbø (11):
  Add support code to handle plugin property changes
  Use ...
From: Tor Arne Vestbø
Date: Wednesday, February 4, 2009 - 6:00 pm

Signed-off-by: Tor Arne Vestbø <torarnv@gmail.com>
---
 .../src/org/spearce/egit/ui/Activator.java         |   52 ++++++++++++++++++++
 1 files changed, 52 insertions(+), 0 deletions(-)

diff --git a/org.spearce.egit.ui/src/org/spearce/egit/ui/Activator.java b/org.spearce.egit.ui/src/org/spearce/egit/ui/Activator.java
index fced643..d4a9e8e 100644
--- a/org.spearce.egit.ui/src/org/spearce/egit/ui/Activator.java
+++ b/org.spearce.egit.ui/src/org/spearce/egit/ui/Activator.java
@@ -10,9 +10,11 @@
 
 import java.net.Authenticator;
 import java.net.ProxySelector;
+import java.util.ArrayList;
 import java.util.HashSet;
 import java.util.Iterator;
 import java.util.LinkedHashSet;
+import java.util.List;
 import java.util.Set;
 
 import org.eclipse.core.net.proxy.IProxyService;
@@ -27,6 +29,8 @@
 import org.eclipse.core.runtime.SubProgressMonitor;
 import org.eclipse.core.runtime.jobs.ISchedulingRule;
 import org.eclipse.core.runtime.jobs.Job;
+import org.eclipse.jface.util.IPropertyChangeListener;
+import org.eclipse.jface.util.PropertyChangeEvent;
 import org.eclipse.jsch.core.IJSchService;
 import org.eclipse.swt.graphics.Font;
 import org.eclipse.ui.plugin.AbstractUIPlugin;
@@ -44,9 +48,24 @@
  * This is a plugin singleton mostly controlling logging.
  */
 public class Activator extends AbstractUIPlugin {
+
+	/**
+	 *  The one and only instance
+	 */
 	private static Activator plugin;
 
 	/**
+	 * Property listeners for plugin specific events
+	 */
+	private static List<IPropertyChangeListener> propertyChangeListeners =
+		new ArrayList<IPropertyChangeListener>(5);
+
+	/**
+	 * Property constant indicating the decorator configuration has changed.
+	 */
+	public static final String DECORATORS_CHANGED = "org.spearce.egit.ui.DECORATORS_CHANGED"; //$NON-NLS-1$
+
+	/**
 	 * @return the {@link Activator} singleton.
 	 */
 	public static Activator getDefault() {
@@ -167,6 +186,39 @@ private void setupRepoIndexRefresh() {
 ...
From: Tor Arne Vestbø
Date: Wednesday, February 4, 2009 - 6:00 pm

Also, add method for removing listeners, and remove unused
private method for getting the current listeners.

Signed-off-by: Tor Arne Vestbø <torarnv@gmail.com>
---
 .../spearce/egit/core/project/GitProjectData.java  |   33 +++++++++-----------
 1 files changed, 15 insertions(+), 18 deletions(-)

diff --git a/org.spearce.egit.core/src/org/spearce/egit/core/project/GitProjectData.java b/org.spearce.egit.core/src/org/spearce/egit/core/project/GitProjectData.java
index db5f20b..4ca4f8e 100644
--- a/org.spearce.egit.core/src/org/spearce/egit/core/project/GitProjectData.java
+++ b/org.spearce.egit.core/src/org/spearce/egit/core/project/GitProjectData.java
@@ -52,7 +52,7 @@
 
 	private static final Map<File, WeakReference> repositoryCache = new HashMap<File, WeakReference>();
 
-	private static RepositoryChangeListener[] repositoryChangeListeners = {};
+	private static Set<RepositoryChangeListener> repositoryChangeListeners = new HashSet<RepositoryChangeListener>();
 
 	@SuppressWarnings("synthetic-access")
 	private static final IResourceChangeListener rcl = new RCL();
@@ -112,16 +112,18 @@ public static synchronized void addRepositoryChangeListener(
 			final RepositoryChangeListener objectThatCares) {
 		if (objectThatCares == null)
 			throw new NullPointerException();
-		for (int k = repositoryChangeListeners.length - 1; k >= 0; k--) {
-			if (repositoryChangeListeners[k] == objectThatCares)
-				return;
-		}
-		final int p = repositoryChangeListeners.length;
-		final RepositoryChangeListener[] n;
-		n = new RepositoryChangeListener[p + 1];
-		System.arraycopy(repositoryChangeListeners, 0, n, 0, p);
-		n[p] = objectThatCares;
-		repositoryChangeListeners = n;
+		repositoryChangeListeners.add(objectThatCares);
+	}
+
+	/**
+	 * Remove a registered {@link RepositoryChangeListener}
+	 * 
+	 * @param objectThatCares
+	 *            The listener to remove
+	 */
+	public static synchronized void removeRepositoryChangeListener(
+			final RepositoryChangeListener ...
From: Tor Arne Vestbø
Date: Wednesday, February 4, 2009 - 6:00 pm

Copied largly from org.eclipse.team.internal.ccvs.core (CVS) and
org.tigris.subversion.subclipse.core (SVN), and then cleaned up.

Signed-off-by: Tor Arne Vestbø <torarnv@gmail.com>
---
 .../src/org/spearce/egit/core/GitException.java    |  168 ++++++++++++++++++++
 1 files changed, 168 insertions(+), 0 deletions(-)
 create mode 100644 org.spearce.egit.core/src/org/spearce/egit/core/GitException.java

diff --git a/org.spearce.egit.core/src/org/spearce/egit/core/GitException.java b/org.spearce.egit.core/src/org/spearce/egit/core/GitException.java
new file mode 100644
index 0000000..7217fb7
--- /dev/null
+++ b/org.spearce.egit.core/src/org/spearce/egit/core/GitException.java
@@ -0,0 +1,168 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2007 IBM Corporation and others.
+ * Copyright (c) 2003, 2006 Subclipse project and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * See LICENSE for the full license text, also available.
+ *******************************************************************************/
+
+package org.spearce.egit.core;
+
+import java.io.IOException;
+import java.lang.reflect.InvocationTargetException;
+
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.runtime.*;
+import org.eclipse.team.core.TeamException;
+import org.eclipse.team.core.TeamStatus;
+
+/**
+ * A checked exception representing a failure in the Git plugin.
+ * <p>
+ * Git exceptions contain a status object describing the cause of the exception.
+ * </p>
+ * 
+ * @see IStatus
+ */
+public class GitException extends TeamException {
+
+	private static final long serialVersionUID = 1L;
+
+	/**
+	 * Constructs a new Git exception
+	 * 
+	 * @param severity
+	 * @param code
+	 * @param message
+	 * @param e
+	 */
+	public GitException(int severity, int code, String message, Throwable e) ...
From: Tor Arne Vestbø
Date: Wednesday, February 4, 2009 - 6:00 pm

Copied from org.eclipse.team.internal.core

Signed-off-by: Tor Arne Vestbø <torarnv@gmail.com>
---
 org.spearce.egit.core/META-INF/MANIFEST.MF         |    5 +-
 .../core/internal/util/ExceptionCollector.java     |  128 ++++++++++++++++++++
 2 files changed, 131 insertions(+), 2 deletions(-)
 create mode 100644 org.spearce.egit.core/src/org/spearce/egit/core/internal/util/ExceptionCollector.java

diff --git a/org.spearce.egit.core/META-INF/MANIFEST.MF b/org.spearce.egit.core/META-INF/MANIFEST.MF
index e13732b..20df15f 100644
--- a/org.spearce.egit.core/META-INF/MANIFEST.MF
+++ b/org.spearce.egit.core/META-INF/MANIFEST.MF
@@ -12,8 +12,9 @@ Require-Bundle: org.eclipse.core.runtime,
  org.spearce.jgit,
  org.eclipse.core.filesystem,
  org.eclipse.ui
-Export-Package: org.spearce.egit.core.internal.storage;x-friends:="org.spearce.egit.ui",
- org.spearce.egit.core,
+Export-Package: org.spearce.egit.core,
+ org.spearce.egit.core.internal.storage;x-friends:="org.spearce.egit.ui",
+ org.spearce.egit.core.internal.util;x-friends:="org.spearce.egit.ui",
  org.spearce.egit.core.op,
  org.spearce.egit.core.project
 Bundle-ActivationPolicy: lazy
diff --git a/org.spearce.egit.core/src/org/spearce/egit/core/internal/util/ExceptionCollector.java b/org.spearce.egit.core/src/org/spearce/egit/core/internal/util/ExceptionCollector.java
new file mode 100644
index 0000000..d99d651
--- /dev/null
+++ b/org.spearce.egit.core/src/org/spearce/egit/core/internal/util/ExceptionCollector.java
@@ -0,0 +1,128 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2006 IBM Corporation and others.
+ * 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:
+ *     IBM Corporation - initial API and implementation
+ ...
From: Tor Arne Vestbø
Date: Wednesday, February 4, 2009 - 6:00 pm

Copied verbatim from org.eclipse.team.internal.ui and documented

Signed-off-by: Tor Arne Vestbø <torarnv@gmail.com>
---
 .../src/org/spearce/egit/ui/internal/SWTUtils.java |  595 ++++++++++++++++++++
 1 files changed, 595 insertions(+), 0 deletions(-)
 create mode 100644 org.spearce.egit.ui/src/org/spearce/egit/ui/internal/SWTUtils.java

diff --git a/org.spearce.egit.ui/src/org/spearce/egit/ui/internal/SWTUtils.java b/org.spearce.egit.ui/src/org/spearce/egit/ui/internal/SWTUtils.java
new file mode 100644
index 0000000..fe65bbb
--- /dev/null
+++ b/org.spearce.egit.ui/src/org/spearce/egit/ui/internal/SWTUtils.java
@@ -0,0 +1,595 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * 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:
+ *	 IBM Corporation - initial API and implementation
+ *******************************************************************************/
+
+package org.spearce.egit.ui.internal;
+
+import org.eclipse.core.runtime.Assert;
+import org.eclipse.jface.dialogs.Dialog;
+import org.eclipse.jface.dialogs.IDialogConstants;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.graphics.FontMetrics;
+import org.eclipse.swt.graphics.GC;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.*;
+import org.eclipse.ui.dialogs.PreferenceLinkArea;
+import org.eclipse.ui.preferences.IWorkbenchPreferenceContainer;
+
+/**
+ * A collection of factory methods for creating common SWT controls
+ */
+public class SWTUtils {
+
+	/** */
+	public static final int MARGINS_DEFAULT = -1;
+
+	/** */
+	public static final int MARGINS_NONE = 0;
+
+	/** */
+	public static final int MARGINS_DIALOG = ...
From: Tor Arne Vestbø
Date: Wednesday, February 4, 2009 - 6:00 pm

Currently the only binding available is the resource name, but
this commit enables a framework for adding more bindings.

Signed-off-by: Tor Arne Vestbø <torarnv@gmail.com>
---
 org.spearce.egit.ui/plugin.properties              |    1 +
 org.spearce.egit.ui/plugin.xml                     |   12 +-
 .../src/org/spearce/egit/ui/Activator.java         |   16 +
 .../egit/ui/PluginPreferenceInitializer.java       |    8 +
 .../src/org/spearce/egit/ui/UIPreferences.java     |    9 +
 .../src/org/spearce/egit/ui/UIText.java            |   63 ++-
 .../egit/ui/internal/actions/BranchAction.java     |    4 +-
 .../egit/ui/internal/actions/Disconnect.java       |    4 +-
 .../egit/ui/internal/actions/ResetAction.java      |    4 +-
 .../decorators/GitLightweightDecorator.java        |  538 ++++++++++++++
 .../internal/decorators/GitResourceDecorator.java  |  454 ------------
 .../internal/decorators/IDecoratableResource.java  |   31 +
 .../preferences/GitDecoratorPreferencePage.java    |  735 ++++++++++++++++++++
 .../src/org/spearce/egit/ui/uitext.properties      |   25 +-
 14 files changed, 1438 insertions(+), 466 deletions(-)
 create mode 100644 org.spearce.egit.ui/src/org/spearce/egit/ui/internal/decorators/GitLightweightDecorator.java
 delete mode 100644 org.spearce.egit.ui/src/org/spearce/egit/ui/internal/decorators/GitResourceDecorator.java
 create mode 100644 org.spearce.egit.ui/src/org/spearce/egit/ui/internal/decorators/IDecoratableResource.java
 create mode 100644 org.spearce.egit.ui/src/org/spearce/egit/ui/internal/preferences/GitDecoratorPreferencePage.java

diff --git a/org.spearce.egit.ui/plugin.properties b/org.spearce.egit.ui/plugin.properties
index fa043f1..58b879f 100644
--- a/org.spearce.egit.ui/plugin.properties
+++ b/org.spearce.egit.ui/plugin.properties
@@ -64,3 +64,4 @@ Theme_CommitMessageFont_description=This font is used to show a commit message.
 GitPreferences_name=Git
 GitPreferences_HistoryPreferencePage_name=History
 ...
From: Tor Arne Vestbø
Date: Wednesday, February 4, 2009 - 6:00 pm

This is an example of how to add more bindings to the
decoration preferences, and how they are implemented in
the decorator.

Signed-off-by: Tor Arne Vestbø <torarnv@gmail.com>
---
 .../src/org/spearce/egit/ui/UIText.java            |    3 ++
 .../decorators/GitLightweightDecorator.java        |   26 ++++++++++++++++---
 .../internal/decorators/IDecoratableResource.java  |    8 ++++++
 .../preferences/GitDecoratorPreferencePage.java    |   21 +++++++++++----
 .../src/org/spearce/egit/ui/uitext.properties      |    3 +-
 5 files changed, 50 insertions(+), 11 deletions(-)

diff --git a/org.spearce.egit.ui/src/org/spearce/egit/ui/UIText.java b/org.spearce.egit.ui/src/org/spearce/egit/ui/UIText.java
index 23498c8..f939558 100644
--- a/org.spearce.egit.ui/src/org/spearce/egit/ui/UIText.java
+++ b/org.spearce.egit.ui/src/org/spearce/egit/ui/UIText.java
@@ -956,6 +956,9 @@
 	public static String DecoratorPreferencesPage_nameResourceVariable;
 
 	/** */
+	public static String DecoratorPreferencesPage_bindingBranchName;
+
+	/** */
 	public static String DecoratorPreferencesPage_selectFormats;
 
 	/** */
diff --git a/org.spearce.egit.ui/src/org/spearce/egit/ui/internal/decorators/GitLightweightDecorator.java b/org.spearce.egit.ui/src/org/spearce/egit/ui/internal/decorators/GitLightweightDecorator.java
index 85b9173..265d5a3 100644
--- a/org.spearce.egit.ui/src/org/spearce/egit/ui/internal/decorators/GitLightweightDecorator.java
+++ b/org.spearce.egit.ui/src/org/spearce/egit/ui/internal/decorators/GitLightweightDecorator.java
@@ -13,6 +13,7 @@
 
 package org.spearce.egit.ui.internal.decorators;
 
+import java.io.IOException;
 import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.HashSet;
@@ -44,6 +45,7 @@
 import org.eclipse.team.ui.TeamUI;
 import org.eclipse.ui.IContributorResourceAdapter;
 import org.eclipse.ui.PlatformUI;
+import org.spearce.egit.core.GitException;
 import org.spearce.egit.core.internal.util.ExceptionCollector;
 import ...
From: Tor Arne Vestbø
Date: Wednesday, February 4, 2009 - 6:00 pm

Can be enabled/disabled in the preferences

Signed-off-by: Tor Arne Vestbø <torarnv@gmail.com>
---
 org.spearce.egit.ui/icons/ovr/shared.gif           |  Bin 106 -> 0 bytes
 org.spearce.egit.ui/icons/ovr/untracked.gif        |  Bin 0 -> 79 bytes
 .../egit/ui/PluginPreferenceInitializer.java       |    4 +-
 .../src/org/spearce/egit/ui/UIIcons.java           |    6 +-
 .../src/org/spearce/egit/ui/UIPreferences.java     |    4 +
 .../src/org/spearce/egit/ui/UIText.java            |    6 +
 .../decorators/GitLightweightDecorator.java        |  162 ++++++++++++++++++--
 .../internal/decorators/IDecoratableResource.java  |   15 ++
 .../preferences/GitDecoratorPreferencePage.java    |   89 +++++++++--
 .../src/org/spearce/egit/ui/uitext.properties      |    2 +
 10 files changed, 259 insertions(+), 29 deletions(-)
 delete mode 100644 org.spearce.egit.ui/icons/ovr/shared.gif
 create mode 100644 org.spearce.egit.ui/icons/ovr/untracked.gif

diff --git a/org.spearce.egit.ui/icons/ovr/shared.gif b/org.spearce.egit.ui/icons/ovr/shared.gif
deleted file mode 100644
index eb71a3c742e133c2ed61c958e237c71e0f7cb6aa..0000000000000000000000000000000000000000
GIT binary patch
literal 0
HcmV?d00001

literal 106
zcmZ?wbhEHbWM|-D*v!E2|KHF5k5c|0Q~7_){{ITmE8U{M-dx?8EBgQce+Fzo@h1x-
p15m3DND^cQ1B<x8$xa82iYrMhmeJo^<v0pdEtw8K%o1d<1^~aoAP)cl

diff --git a/org.spearce.egit.ui/icons/ovr/untracked.gif b/org.spearce.egit.ui/icons/ovr/untracked.gif
new file mode 100644
index 0000000000000000000000000000000000000000..45ca32060700d71abcb88bbcdb1000d503fe11cf
GIT binary patch
literal 79
zcmZ?wbhEHbWM|-DSj51<z}U+mGMhnsAy57};pVIV!2l?%_>+Z^fq{)d2gqgssbydm
biP#m!(lAAgdxkboj%vJ&f(EaJDuXouU6m8v

literal 0
HcmV?d00001

diff --git a/org.spearce.egit.ui/src/org/spearce/egit/ui/PluginPreferenceInitializer.java b/org.spearce.egit.ui/src/org/spearce/egit/ui/PluginPreferenceInitializer.java
index 79c2665..7465444 100644
--- a/org.spearce.egit.ui/src/org/spearce/egit/ui/PluginPreferenceInitializer.java
+++ ...
From: Tor Arne Vestbø
Date: Wednesday, February 4, 2009 - 6:00 pm

Signed-off-by: Tor Arne Vestbø <torarnv@gmail.com>
---
 org.spearce.egit.ui/icons/ovr/assumevalid.gif      |  Bin 64 -> 0 bytes
 org.spearce.egit.ui/icons/ovr/conflict.gif         |  Bin 64 -> 164 bytes
 org.spearce.egit.ui/icons/ovr/pending_add.gif      |  Bin 64 -> 0 bytes
 org.spearce.egit.ui/icons/ovr/pending_remove.gif   |  Bin 111 -> 0 bytes
 org.spearce.egit.ui/icons/ovr/staged.gif           |  Bin 0 -> 114 bytes
 org.spearce.egit.ui/icons/ovr/staged_added.gif     |  Bin 0 -> 114 bytes
 org.spearce.egit.ui/icons/ovr/staged_removed.gif   |  Bin 0 -> 114 bytes
 .../egit/ui/PluginPreferenceInitializer.java       |    2 +
 .../src/org/spearce/egit/ui/UIIcons.java           |   13 +-
 .../src/org/spearce/egit/ui/UIPreferences.java     |    4 +
 .../src/org/spearce/egit/ui/UIText.java            |   14 +-
 .../decorators/GitLightweightDecorator.java        |  284 ++++++++++++++++----
 .../internal/decorators/IDecoratableResource.java  |   39 +++
 .../preferences/GitDecoratorPreferencePage.java    |  131 ++++++++--
 .../src/org/spearce/egit/ui/uitext.properties      |   14 +-
 15 files changed, 427 insertions(+), 74 deletions(-)
 delete mode 100644 org.spearce.egit.ui/icons/ovr/assumevalid.gif
 delete mode 100644 org.spearce.egit.ui/icons/ovr/pending_add.gif
 delete mode 100644 org.spearce.egit.ui/icons/ovr/pending_remove.gif
 create mode 100644 org.spearce.egit.ui/icons/ovr/staged.gif
 create mode 100644 org.spearce.egit.ui/icons/ovr/staged_added.gif
 create mode 100644 org.spearce.egit.ui/icons/ovr/staged_removed.gif

diff --git a/org.spearce.egit.ui/icons/ovr/assumevalid.gif b/org.spearce.egit.ui/icons/ovr/assumevalid.gif
deleted file mode 100644
index c7262ed4e3f9437a51806f70fbc851e3a6f951d3..0000000000000000000000000000000000000000
GIT binary patch
literal 0
HcmV?d00001

literal 64
zcmZ?wbhEHbWM|-D_{abP{~H+o{|7M?f3h$#FfcRdfH)v|1}4Ed_6CP$GF;`pupzry
Lj9oc|fx#L8z0(dE

diff --git a/org.spearce.egit.ui/icons/ovr/conflict.gif ...
From: Tor Arne Vestbø
Date: Wednesday, February 4, 2009 - 6:00 pm

Not all resources have corresponding labels that are visible,
so by using LabelProviderChangedEvent() we ensure that only
the visible labels are refreshed.

The downside is that we lose project precition, so all
projects are included, but only visible labels in those
projects are re-decorated, so it is OK for now.

Signed-off-by: Tor Arne Vestbø <torarnv@gmail.com>
---
 .../decorators/GitLightweightDecorator.java        |   28 +++-----------------
 1 files changed, 4 insertions(+), 24 deletions(-)

diff --git a/org.spearce.egit.ui/src/org/spearce/egit/ui/internal/decorators/GitLightweightDecorator.java b/org.spearce.egit.ui/src/org/spearce/egit/ui/internal/decorators/GitLightweightDecorator.java
index aa6a261..45b9f83 100644
--- a/org.spearce.egit.ui/src/org/spearce/egit/ui/internal/decorators/GitLightweightDecorator.java
+++ b/org.spearce.egit.ui/src/org/spearce/egit/ui/internal/decorators/GitLightweightDecorator.java
@@ -14,11 +14,9 @@
 package org.spearce.egit.ui.internal.decorators;
 
 import java.io.IOException;
-import java.util.ArrayList;
 import java.util.Collections;
 import java.util.HashMap;
 import java.util.HashSet;
-import java.util.List;
 import java.util.Map;
 import java.util.Set;
 
@@ -28,7 +26,6 @@
 import org.eclipse.core.resources.IResourceChangeListener;
 import org.eclipse.core.resources.IResourceDelta;
 import org.eclipse.core.resources.IResourceDeltaVisitor;
-import org.eclipse.core.resources.IResourceVisitor;
 import org.eclipse.core.resources.ResourcesPlugin;
 import org.eclipse.core.resources.mapping.ResourceMapping;
 import org.eclipse.core.runtime.CoreException;
@@ -682,7 +679,7 @@ public void propertyChange(PropertyChangeEvent event) {
 		if (prop.equals(TeamUI.GLOBAL_IGNORES_CHANGED)
 				|| prop.equals(TeamUI.GLOBAL_FILE_TYPES_CHANGED)
 				|| prop.equals(Activator.DECORATORS_CHANGED)) {
-			postLabelEvent(new LabelProviderChangedEvent(this, null /* all */));
+			postLabelEvent(new LabelProviderChangedEvent(this));
 		}
 	}
 
@@ ...
From: Tor Arne Vestbø
Date: Wednesday, February 4, 2009 - 6:00 pm

The option "Inspect dirty state of children..." controls
if the decoration process should look at child resources
to decide if a container is dirty or not. For large/deep
projects this can be quite time consuming.

The other option, "Also re-decorate ancestors..." controls if
parents of a re-decorated resource also should be updated, for
example to signal that the containing folder is now dirty.

Signed-off-by: Tor Arne Vestbø <torarnv@gmail.com>
---
 org.spearce.egit.ui/.options                       |    8 +-
 .../src/org/spearce/egit/ui/Activator.java         |    2 +-
 .../egit/ui/PluginPreferenceInitializer.java       |    3 +-
 .../src/org/spearce/egit/ui/UIPreferences.java     |    4 +-
 .../src/org/spearce/egit/ui/UIText.java            |    5 +-
 .../decorators/GitLightweightDecorator.java        |  344 +++++++++++++++-----
 .../preferences/GitDecoratorPreferencePage.java    |   33 ++-
 .../src/org/spearce/egit/ui/uitext.properties      |    3 +-
 8 files changed, 311 insertions(+), 91 deletions(-)

diff --git a/org.spearce.egit.ui/.options b/org.spearce.egit.ui/.options
index a084b35..8fc1c19 100644
--- a/org.spearce.egit.ui/.options
+++ b/org.spearce.egit.ui/.options
@@ -1 +1,7 @@
-org.spearce.egit.ui/trace/verbose = false
+# Debugging options for the org.spearce.egit.ui plugin.
+
+# Show general verbose output
+org.spearce.egit.ui/verbose = false
+
+# Show debug output for label decorations
+org.spearce.egit.ui/decorations = false
\ No newline at end of file
diff --git a/org.spearce.egit.ui/src/org/spearce/egit/ui/Activator.java b/org.spearce.egit.ui/src/org/spearce/egit/ui/Activator.java
index 9d03c70..45010ce 100644
--- a/org.spearce.egit.ui/src/org/spearce/egit/ui/Activator.java
+++ b/org.spearce.egit.ui/src/org/spearce/egit/ui/Activator.java
@@ -190,7 +190,7 @@ public Activator() {
 
 	public void start(final BundleContext context) throws Exception {
 		super.start(context);
-		traceVerbose = isOptionSet("/trace/verbose");
+		traceVerbose = ...
From: Robin Rosenberg
Date: Thursday, February 5, 2009 - 1:02 pm

The size of the components of the page is wrong forcing unnecessary scrollb=
ars.

The terms use should probably have a cleared explanation/definition=20
and the same terms used for the flags/icons. The explanation could
probably be done using longer tooltips.

I miss the red attention-gathering red conflict icon we had. I also
have a hard time distinguishing the staged/added/removed icons
without reading glasses. The decorations are only 1.3 mm on my
screen (150 dpi), so I think the icons should have different colors and
different shapes instead of a few different pixels withing a square=20
box.

I'd also like to see the conflict state for files inherited by parent
folder and projects.

The checkboxes in the general tab have no effect on the preview.

=2D- robin
From: Tor Arne Vestbø
Date: Thursday, February 5, 2009 - 1:21 pm

Argh, I've been battling those layouts on Linux, but though it was


Happy to replace. If I remember correctly that's the symbol used by
other plugins to indicate conflicts, so I was aiming for consistency and



True. Should be easy to fix.

Thanks for the feedback!

Tor Arne
--

From: Tor Arne Vestbø
Date: Thursday, February 5, 2009 - 2:00 pm

Okey, I've replaced the blue one with the default conflict icon from the

Here are two alternatives. The first one (A) uses the same icons as
before, but adds red and green shading. The second one (B) uses the
green plus sign for added (which is used all over the place in Eclipse
to mean 'added'), and the gray x for removed (which is also used all
over the place in Eclipse for that same concept).

http://img443.imageshack.us/img443/5138/egitmockupmm7.png

I favor solution B, as it uses recognizable concepts from the existing
Eclipse UI, plus that having a red removed-icon conflicts too much with
the conflict-icon (pun intended). There's also a very similar red icon
in JDT that indicates that something needs fixing (a red medic kit),
which is another reason to go with solution B.

What do you say?


--

From: Robin Rosenberg
Date: Thursday, February 5, 2009 - 2:36 pm

I go with B.

Btw, shouldn't staged, added and removed also count as outgoing, i.e. ">" ?

-- robin

--

From: Tor Arne Vestbø
Date: Thursday, February 5, 2009 - 2:44 pm

Currently there's two variables, 'dirty', and 'staged'. The former
mappps to a diff between working directory and index, and has the
default symbol '>'. The latter mapps to a diff between index and
repository, with the default symbol '*'.

The default decoration for files does not have the 'staged' variable,
but you can add {staged} for a *, or override with {staged:>} for a >.

The idea was to get both states between wd and index and index and repo
in the decorators. We could add an option to treat both as one, ie only
care about wd vs repo?

I plan to implement the synchronize view too, in which case we could
share these two pieces of information between the Package Explorer (wd
vs index), and the Synchronize View (index vs repo), similar to how git
gui works.

Tor Arne
--

From: Robin Rosenberg
Date: Thursday, February 5, 2009 - 1:04 pm

The "assume unchanged" decoration seems lost.

-- robin
--

From: Shawn O. Pearce
Date: Thursday, February 5, 2009 - 8:48 am

See anything wrong here, like that the Set can be modified while
GitProjectData's class lock is held, but its being read here without
any locking?

The array trick worked before because we always made a copy anytime
the array was modified.  So we could safely return the array to the
caller and let the caller iterate it unlocked; we just had to read
the current array using a synchronized method to ensure we had a
stable read.

You'll need to copy the Set somehow while inside of a synchronized
method, then return the copy to the fireRepositoryChanged() method
so it can iterate the copy to fire the events.

-- 
Shawn.
--

From: Tor Arne Vestbø
Date: Thursday, February 5, 2009 - 9:36 am

You're perfectly right. New patch coming up!

Tor Arne
--

From: Tor Arne Vestbø
Date: Thursday, February 5, 2009 - 11:28 am

Also, add method for removing listeners.

Signed-off-by: Tor Arne Vestbø <torarnv@gmail.com>
---
 .../spearce/egit/core/project/GitProjectData.java  |   40 ++++++++++++-------
 1 files changed, 25 insertions(+), 15 deletions(-)

diff --git a/org.spearce.egit.core/src/org/spearce/egit/core/project/GitProjectData.java b/org.spearce.egit.core/src/org/spearce/egit/core/project/GitProjectData.java
index db5f20b..b12a85f 100644
--- a/org.spearce.egit.core/src/org/spearce/egit/core/project/GitProjectData.java
+++ b/org.spearce.egit.core/src/org/spearce/egit/core/project/GitProjectData.java
@@ -52,7 +52,7 @@
 
 	private static final Map<File, WeakReference> repositoryCache = new HashMap<File, WeakReference>();
 
-	private static RepositoryChangeListener[] repositoryChangeListeners = {};
+	private static Set<RepositoryChangeListener> repositoryChangeListeners = new HashSet<RepositoryChangeListener>();
 
 	@SuppressWarnings("synthetic-access")
 	private static final IResourceChangeListener rcl = new RCL();
@@ -112,16 +112,18 @@ public static synchronized void addRepositoryChangeListener(
 			final RepositoryChangeListener objectThatCares) {
 		if (objectThatCares == null)
 			throw new NullPointerException();
-		for (int k = repositoryChangeListeners.length - 1; k >= 0; k--) {
-			if (repositoryChangeListeners[k] == objectThatCares)
-				return;
-		}
-		final int p = repositoryChangeListeners.length;
-		final RepositoryChangeListener[] n;
-		n = new RepositoryChangeListener[p + 1];
-		System.arraycopy(repositoryChangeListeners, 0, n, 0, p);
-		n[p] = objectThatCares;
-		repositoryChangeListeners = n;
+		repositoryChangeListeners.add(objectThatCares);
+	}
+
+	/**
+	 * Remove a registered {@link RepositoryChangeListener}
+	 * 
+	 * @param objectThatCares
+	 *            The listener to remove
+	 */
+	public static synchronized void removeRepositoryChangeListener(
+			final RepositoryChangeListener objectThatCares) {
+		repositoryChangeListeners.remove(objectThatCares);
 	}
 ...
From: Shawn O. Pearce
Date: Thursday, February 5, 2009 - 8:53 am

None of these list accesses are thread-safe.  Are we certain they
call will come from a single thread, e.g. the SWT event thread?
Or do we need to put synchronized protection in here?

-- 
Shawn.
--

From: Tor Arne Vestbø
Date: Thursday, February 5, 2009 - 9:35 am

It's the singleton instance, referenced from Activator.getDefault(). I

The addPropertyChangeListener method is called at startup from the
GitLightweightDecorator constructor, in one of the worker threads, and
same thing with removePropertyChangeListener from dispose(). The
broadcastPropertyChange method is called in the main thread every time
the Git decorator preference page is closes.

This is the sync model used by other Eclipse plugins for keeping track
of propertyChangeListeners, for example in the TeamUIPlugin, that's why
I assumed it was OK. I'm perfectly fine with syncrhronizing it though,
similar to repositoryChangeListeners in GitProjectData?

Tor Arne


--

From: Shawn O. Pearce
Date: Thursday, February 5, 2009 - 9:40 am

*sigh*.  I haven't had enough caffiene yet this morning.  Yes,
I see what you mean, its only the Javadoc that was added.  OK,

OK, I see.  I'd perhaps prefer to make this thread-safe just in case.
If its always coming off the SWT event thread, then just tossing
a synchronized keyword on all 3 methods should be Good Enough(tm).

-- 
Shawn.
--

From: Tor Arne Vestbø
Date: Thursday, February 5, 2009 - 11:22 am

Signed-off-by: Tor Arne Vestbø <torarnv@gmail.com>
---
 .../src/org/spearce/egit/ui/Activator.java         |   52 ++++++++++++++++++++
 1 files changed, 52 insertions(+), 0 deletions(-)

diff --git a/org.spearce.egit.ui/src/org/spearce/egit/ui/Activator.java b/org.spearce.egit.ui/src/org/spearce/egit/ui/Activator.java
index fced643..534c408 100644
--- a/org.spearce.egit.ui/src/org/spearce/egit/ui/Activator.java
+++ b/org.spearce.egit.ui/src/org/spearce/egit/ui/Activator.java
@@ -10,9 +10,11 @@
 
 import java.net.Authenticator;
 import java.net.ProxySelector;
+import java.util.ArrayList;
 import java.util.HashSet;
 import java.util.Iterator;
 import java.util.LinkedHashSet;
+import java.util.List;
 import java.util.Set;
 
 import org.eclipse.core.net.proxy.IProxyService;
@@ -27,6 +29,8 @@
 import org.eclipse.core.runtime.SubProgressMonitor;
 import org.eclipse.core.runtime.jobs.ISchedulingRule;
 import org.eclipse.core.runtime.jobs.Job;
+import org.eclipse.jface.util.IPropertyChangeListener;
+import org.eclipse.jface.util.PropertyChangeEvent;
 import org.eclipse.jsch.core.IJSchService;
 import org.eclipse.swt.graphics.Font;
 import org.eclipse.ui.plugin.AbstractUIPlugin;
@@ -44,9 +48,24 @@
  * This is a plugin singleton mostly controlling logging.
  */
 public class Activator extends AbstractUIPlugin {
+
+	/**
+	 *  The one and only instance
+	 */
 	private static Activator plugin;
 
 	/**
+	 * Property listeners for plugin specific events
+	 */
+	private static List<IPropertyChangeListener> propertyChangeListeners =
+		new ArrayList<IPropertyChangeListener>(5);
+
+	/**
+	 * Property constant indicating the decorator configuration has changed.
+	 */
+	public static final String DECORATORS_CHANGED = "org.spearce.egit.ui.DECORATORS_CHANGED"; //$NON-NLS-1$
+
+	/**
 	 * @return the {@link Activator} singleton.
 	 */
 	public static Activator getDefault() {
@@ -167,6 +186,39 @@ private void setupRepoIndexRefresh() {
 ...
From: Tor Arne Vestbø
Date: Wednesday, February 4, 2009 - 6:04 pm

From: Shawn O. Pearce
Date: Thursday, February 5, 2009 - 9:06 am

Aside from my two remarks about the synchronized collections,
I like it.  There's no display for "added and dirty", aka doing:

  echo a >a; # create a
  git add a
  echo b >>a; # append a and dirty it

This still shows as just "added".  It should be "added and dirty",

I'd like to see this fixed in the near-ish future, but I don't

Bah.  I've seen the Java compiler error marks also report like this.
I don't think its our issue.  But maybe I'm wrong.

-- 
Shawn.
--

From: Tor Arne Vestbø
Date: Thursday, February 5, 2009 - 9:17 am

That's a bug, should work the same as "staged and dirty", with [*] >,

Yepp, It's on my list. This series is basically the minimum feature-set
I could produce that has most of what the current decorators have, so I

The CVS plugin handles this -- possibly through the TeamStateProvider
and friends -- so it is possible. Something to look at.

Tor Arne
--

From: Robin Rosenberg
Date: Thursday, February 5, 2009 - 11:32 am

I'm not sure this is Tore's bug. We've had problems with nested

It's our choice here. Generally, I think we should shift behavior here
depending on layout. Java packages are not hierarchical in nature.

Currently it may look like this with flat package layout:

	>org.spearce.jgit.treewalk
		CanonicalTreeParserTest.java
		EmptyTreeIteratorTest.java
		FileTreeIteratorTest.java
		NameConflictTreeWalkTest.java
		PostOrderTreeWalkTest.java
		TreeWalkBasicDiffTest.java

	>org.spearce.jgit.treewalk.filter
		AlwaysCloneTreeFilter.java
		>NotTreeFilterTest.java
		TreeFilterTest.java


Which is odd when looking at org.spearce.jgit.treewalk, because
no files in that package have been changed. A tricky question is
how to decorate empty packages. like org, org.spearce. Probably
as unchanged.

-- robin
--

From: Tor Arne Vestbø
Date: Thursday, February 5, 2009 - 11:37 am

Agreed. But, as the CVS plugin seems to handle this gracefully, without
any JDT specific code (from my brief investigations), it seems that this
is something we can get for free from the team plugins. I will look into
it as soon as this series is done cooking.

Tor Arne
--

From: Robin Rosenberg
Date: Thursday, February 5, 2009 - 3:09 pm

My guess is it has to do with traversal according to the structure layout, so
JDT only does the layout and the CVS decorator follows that one.

-- robin
--

Previous thread: none

Next thread: What's cooking in git.git (Feb 2009, #02; Wed, 04) by Junio C Hamano on Wednesday, February 4, 2009 - 6:32 pm. (3 messages)