In progress: [Issue 104] Update "Next Id" comment when generating a the
tag number of a field or literal

Made progress on the "Numeric Tags" preference page.
diff --git a/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/ProtobufUiModule.java b/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/ProtobufUiModule.java
index 32ff714..9d316c3 100644
--- a/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/ProtobufUiModule.java
+++ b/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/ProtobufUiModule.java
@@ -12,20 +12,16 @@
 import static org.eclipse.ui.PlatformUI.isWorkbenchRunning;
 
 import org.eclipse.jface.text.hyperlink.IHyperlinkDetector;
-import org.eclipse.ui.IWorkbenchWindow;
-import org.eclipse.ui.PlatformUI;
+import org.eclipse.ui.*;
 import org.eclipse.ui.plugin.AbstractUIPlugin;
 import org.eclipse.ui.views.contentoutline.IContentOutlinePage;
 import org.eclipse.xtext.documentation.IEObjectDocumentationProvider;
 import org.eclipse.xtext.ui.LanguageSpecific;
-import org.eclipse.xtext.ui.editor.IURIEditorOpener;
-import org.eclipse.xtext.ui.editor.IXtextEditorCallback;
+import org.eclipse.xtext.ui.editor.*;
 import org.eclipse.xtext.ui.editor.model.XtextDocumentProvider;
 import org.eclipse.xtext.ui.editor.outline.actions.IOutlineContribution;
-import org.eclipse.xtext.ui.editor.preferences.IPreferenceStoreAccess;
-import org.eclipse.xtext.ui.editor.preferences.IPreferenceStoreInitializer;
-import org.eclipse.xtext.ui.editor.syntaxcoloring.IHighlightingConfiguration;
-import org.eclipse.xtext.ui.editor.syntaxcoloring.ISemanticHighlightingCalculator;
+import org.eclipse.xtext.ui.editor.preferences.*;
+import org.eclipse.xtext.ui.editor.syntaxcoloring.*;
 
 import com.google.eclipse.protobuf.scoping.IFileUriResolver;
 import com.google.eclipse.protobuf.ui.builder.AutoAddNatureEditorCallback;
@@ -33,13 +29,12 @@
 import com.google.eclipse.protobuf.ui.editor.ProtobufUriEditorOpener;
 import com.google.eclipse.protobuf.ui.editor.hyperlinking.ProtobufHyperlinkDetector;
 import com.google.eclipse.protobuf.ui.editor.model.ProtobufDocumentProvider;
-import com.google.eclipse.protobuf.ui.editor.syntaxcoloring.HighlightingConfiguration;
-import com.google.eclipse.protobuf.ui.editor.syntaxcoloring.ProtobufSemanticHighlightingCalculator;
+import com.google.eclipse.protobuf.ui.editor.syntaxcoloring.*;
 import com.google.eclipse.protobuf.ui.internal.ProtobufActivator;
-import com.google.eclipse.protobuf.ui.outline.LinkWithEditor;
-import com.google.eclipse.protobuf.ui.outline.ProtobufOutlinePage;
+import com.google.eclipse.protobuf.ui.outline.*;
 import com.google.eclipse.protobuf.ui.preferences.PreferenceStoreAccess;
 import com.google.eclipse.protobuf.ui.preferences.pages.compiler.CompilerPreferenceStoreInitializer;
+import com.google.eclipse.protobuf.ui.preferences.pages.editor.numerictag.NumericTagPreferenceStoreInitializer;
 import com.google.eclipse.protobuf.ui.preferences.pages.editor.save.SaveActionsPreferenceStoreInitializer;
 import com.google.eclipse.protobuf.ui.preferences.pages.general.GeneralPreferenceStoreInitializer;
 import com.google.eclipse.protobuf.ui.preferences.pages.paths.PathsPreferenceStoreInitializer;
@@ -97,6 +92,10 @@
     configurePreferenceInitializer(binder, "pathsPreferences", PathsPreferenceStoreInitializer.class);
   }
 
+  public void configureNumericTagPreferencesInitializer(Binder binder) {
+    configurePreferenceInitializer(binder, "numericTagPreferences", NumericTagPreferenceStoreInitializer.class);
+  }
+
   public void configureSaveActionsPreferencesInitializer(Binder binder) {
     configurePreferenceInitializer(binder, "saveActionsPreferences", SaveActionsPreferenceStoreInitializer.class);
   }
diff --git a/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/pages/editor/numerictag/Messages.java b/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/pages/editor/numerictag/Messages.java
new file mode 100644
index 0000000..302d846
--- /dev/null
+++ b/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/pages/editor/numerictag/Messages.java
@@ -0,0 +1,29 @@
+/*
+ * Copyright (c) 2011 Google 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
+ */
+package com.google.eclipse.protobuf.ui.preferences.pages.editor.numerictag;
+
+import org.eclipse.osgi.util.NLS;
+
+/**
+ * @author alruiz@google.com (Alex Ruiz)
+ */
+public class Messages extends NLS {
+
+  public static String add;
+  public static String edit;
+  public static String pageDescription;
+  public static String remove;
+
+  static {
+    Class<Messages> clazz = Messages.class;
+    NLS.initializeMessages(clazz.getName(), clazz);
+  }
+
+  private Messages() {}
+}
diff --git a/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/pages/editor/numerictag/Messages.properties b/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/pages/editor/numerictag/Messages.properties
new file mode 100644
index 0000000..937b364
--- /dev/null
+++ b/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/pages/editor/numerictag/Messages.properties
@@ -0,0 +1,4 @@
+add=&Add
+edit=&Edit
+pageDescription=Patterns to match the comments that track the next available tag number in message fields and enum literals.
+remove=&Remove
diff --git a/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/pages/editor/numerictag/NumericTagPreferencePage.java b/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/pages/editor/numerictag/NumericTagPreferencePage.java
index dfb2a51..6495ce1 100644
--- a/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/pages/editor/numerictag/NumericTagPreferencePage.java
+++ b/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/pages/editor/numerictag/NumericTagPreferencePage.java
@@ -8,14 +8,19 @@
  */
 package com.google.eclipse.protobuf.ui.preferences.pages.editor.numerictag;
 
+import static com.google.eclipse.protobuf.ui.preferences.pages.editor.numerictag.Messages.*;
+import static java.util.Arrays.asList;
+import static org.eclipse.xtext.util.Strings.*;
+
 import org.eclipse.jface.preference.IPreferenceStore;
 import org.eclipse.jface.viewers.ListViewer;
 import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.*;
 import org.eclipse.swt.layout.*;
 import org.eclipse.swt.widgets.*;
 
-import com.google.eclipse.protobuf.ui.preferences.BooleanPreference;
-import com.google.eclipse.protobuf.ui.preferences.binding.PreferenceBinder;
+import com.google.eclipse.protobuf.ui.preferences.*;
+import com.google.eclipse.protobuf.ui.preferences.binding.*;
 import com.google.eclipse.protobuf.ui.preferences.pages.PreferenceAndPropertyPage;
 
 /**
@@ -24,23 +29,27 @@
  * @author alruiz@google.com (Alex Ruiz)
  */
 public class NumericTagPreferencePage extends PreferenceAndPropertyPage {
-  public NumericTagPreferencePage() {
-  }
+
+  private static final String PATTERN_DELIMITER = "//t"; //$NON-NLS-1$
+  private static final String PREFERENCE_PAGE_ID = NumericTagPreferencePage.class.getName();
 
   private List lstPaths;
   private Button btnAdd;
+  private Button btnEdit;
+  private Button btnRemove;
 
   @Override protected void doCreateContents(Composite parent) {
     Label lblDescription = new Label(parent, SWT.WRAP);
-    GridData gridData = new GridData(SWT.FILL, SWT.BEGINNING, false, false, 3, 1);
+    GridData gridData = new GridData(SWT.FILL, SWT.CENTER, false, false, 2, 1);
     gridData.widthHint = 150; // only expand further if anyone else requires it
     lblDescription.setLayoutData(gridData);
-    lblDescription.setText("Patterns to match the comments that track the next available tag number in message fields and enum literals.");
+    lblDescription.setText(pageDescription);
+    new Label(parent, SWT.NONE);
 
     ListViewer lstVwrPaths = new ListViewer(parent, SWT.BORDER | SWT.V_SCROLL);
     lstPaths = lstVwrPaths.getList();
-    gridData = new GridData(SWT.FILL, SWT.CENTER, true, false, 2, 1);
-    gridData.heightHint = 121;
+    gridData = new GridData(SWT.FILL, SWT.CENTER, true, false, 1, 1);
+    gridData.heightHint = 127;
     lstPaths.setLayoutData(gridData);
 
     Composite composite = new Composite(parent, SWT.NONE);
@@ -48,27 +57,80 @@
     composite.setLayout(new GridLayout(1, false));
 
     btnAdd = new Button(composite, SWT.NONE);
-    btnAdd.setSize(88, 29);
-    btnAdd.setText("&Add");
+    btnAdd.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, false, false, 1, 1));
+    btnAdd.setText(add);
+
+    btnEdit = new Button(composite, SWT.NONE);
+    btnEdit.setEnabled(false);
+    btnEdit.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, false, false, 1, 1));
+    btnEdit.setText(edit);
+
+    btnRemove = new Button(composite, SWT.NONE);
+    btnRemove.setEnabled(false);
+    btnRemove.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, false, false, 1, 1));
+    btnRemove.setText(remove);
+
+    addEventListeners();
+  }
+
+  private void addEventListeners() {
+    lstPaths.addSelectionListener(new SelectionAdapter() {
+      @Override public void widgetSelected(SelectionEvent e) {
+        enableButtonsDependingOnListSelection();
+      }
+    });
+    btnRemove.addSelectionListener(new SelectionAdapter() {
+      @Override public void widgetSelected(SelectionEvent e) {
+        int index = lstPaths.getSelectionIndex();
+        if (index < 0) return;
+        lstPaths.remove(index);
+        enableButtonsDependingOnListSelection();
+      }
+    });
+  }
+
+  private void enableButtonsDependingOnListSelection() {
+    int selectionIndex = lstPaths.getSelectionIndex();
+    boolean hasSelection = selectionIndex >= 0;
+    btnEdit.setEnabled(hasSelection);
+    btnRemove.setEnabled(hasSelection);
   }
 
   @Override protected BooleanPreference enableProjectSettingsPreference(IPreferenceStore store) {
-    // TODO(alruiz): Auto-generated method stub
     return null;
   }
 
   @Override protected void setupBinding(PreferenceBinder preferenceBinder) {
-    // TODO(alruiz): Auto-generated method stub
+    RawPreferences preferences = new RawPreferences(getPreferenceStore());
+    final StringPreference patterns = preferences.patterns();
+    preferenceBinder.add(new Binding() {
+      public void applyPreferenceValueToTarget() {
+        setPatterns(patterns.value());
+      }
 
+      public void applyDefaultPreferenceValueToTarget() {
+        setPatterns(patterns.defaultValue());
+      }
+
+      public void savePreferenceValue() {
+        patterns.value(patterns());
+      }
+    });
   }
 
-  @Override protected void onProjectSettingsActivation(boolean projectSettingsActive) {
-    // TODO(alruiz): Auto-generated method stub
-
+  private void setPatterns(String value) {
+    lstPaths.removeAll();
+    for (String pattern : split(value, PATTERN_DELIMITER))
+      lstPaths.add(pattern);
   }
 
+  private String patterns() {
+    return concat(PATTERN_DELIMITER, asList(lstPaths.getItems()));
+  }
+
+  @Override protected void onProjectSettingsActivation(boolean projectSettingsActive) {}
+
   @Override protected String preferencePageId() {
-    // TODO(alruiz): Auto-generated method stub
-    return null;
+    return PREFERENCE_PAGE_ID;
   }
 }
diff --git a/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/pages/editor/numerictag/NumericTagPreferenceStoreInitializer.java b/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/pages/editor/numerictag/NumericTagPreferenceStoreInitializer.java
new file mode 100644
index 0000000..5e6499a
--- /dev/null
+++ b/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/pages/editor/numerictag/NumericTagPreferenceStoreInitializer.java
@@ -0,0 +1,27 @@
+/*
+ * Copyright (c) 2011 Google 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
+ */
+package com.google.eclipse.protobuf.ui.preferences.pages.editor.numerictag;
+
+import org.eclipse.jface.preference.IPreferenceStore;
+import org.eclipse.xtext.ui.editor.preferences.*;
+
+/**
+ * Initializes default values for the "Paths" preferences.
+ *
+ * @author alruiz@google.com (Alex Ruiz)
+ */
+public class NumericTagPreferenceStoreInitializer implements IPreferenceStoreInitializer {
+
+  /** {@inheritDoc} */
+  public void initialize(IPreferenceStoreAccess access) {
+    IPreferenceStore store = access.getWritablePreferenceStore();
+    RawPreferences preferences = new RawPreferences(store);
+    preferences.patterns().defaultValue("Next[\\s]+Id:[\\s]+[\\d]+");
+  }
+}
diff --git a/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/pages/editor/numerictag/RawPreferences.java b/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/pages/editor/numerictag/RawPreferences.java
new file mode 100644
index 0000000..5c6cee2
--- /dev/null
+++ b/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/pages/editor/numerictag/RawPreferences.java
@@ -0,0 +1,30 @@
+/*
+ * Copyright (c) 2011 Google Inc.
+ *
+ * All rights reserved. This program and the accompanying materials are made
+ * available under the terms of the Eclipse License v1.0 which accompanies this
+ * distribution, and is available at
+ *
+ * http://www.eclipse.org/legal/epl-v10.html
+ */
+package com.google.eclipse.protobuf.ui.preferences.pages.editor.numerictag;
+
+import org.eclipse.jface.preference.IPreferenceStore;
+
+import com.google.eclipse.protobuf.ui.preferences.StringPreference;
+
+/**
+ * @author alruiz@google.com (Alex Ruiz)
+ */
+class RawPreferences {
+
+  private final StringPreference patterns;
+
+  RawPreferences(IPreferenceStore store) {
+    patterns = new StringPreference("numericTag.patterns", store);
+  }
+
+  StringPreference patterns() {
+    return patterns;
+  }
+}
diff --git a/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/pages/editor/save/SaveActionsPreferencePage.java b/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/pages/editor/save/SaveActionsPreferencePage.java
index 7b1e989..5e3f81e 100644
--- a/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/pages/editor/save/SaveActionsPreferencePage.java
+++ b/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/pages/editor/save/SaveActionsPreferencePage.java
@@ -10,6 +10,7 @@
 package com.google.eclipse.protobuf.ui.preferences.pages.editor.save;
 
 import static com.google.eclipse.protobuf.ui.preferences.binding.BindingToButtonSelection.bindSelectionOf;
+import static com.google.eclipse.protobuf.ui.preferences.pages.editor.save.Messages.removeTrailingWhitespace;
 
 import org.eclipse.jface.preference.*;
 import org.eclipse.swt.SWT;
@@ -42,7 +43,7 @@
     contents.setLayout(new GridLayout(1, false));
     btnRemoveTrailingwhitespace = new Button(contents, SWT.CHECK);
     btnRemoveTrailingwhitespace.setLayoutData(new GridData(SWT.LEFT, SWT.TOP, true, false, 1, 1));
-    btnRemoveTrailingwhitespace.setText(Messages.removeTrailingWhitespace);
+    btnRemoveTrailingwhitespace.setText(removeTrailingWhitespace);
     setUpBinding();
     preferenceBinder.applyValues();
     return contents;