  Add coloring to the windows menu to indicate modified buffers

 This is a modified version of Arne Førlie's patch:

 http://sourceforge.net/tracker/index.php?func=detail&aid=937063&group_id=11005&atid=311005
	    [ 937063 ] Coloured file names in Windows menu
	    89330: colored_win _v2.patch	2004-06-02 16:17

 This patch color-codes the file names in the windows
 menu according to state.
 By default the patch uses the following colours
  - modified (unsaved) files are red
  - read-only files are blue
  - otherwise they are black

 For modified and read-only, you can also change the background
 color used; this is normally set to "white"; set it to "default"
 to use the normal menu background color.

 A set of X resources are used to modify the defaults.
 They are documented in the help (do 'make docs' to
 update the help files before building the executables).
	    nedit.coloredWinMenu: True
	    nedit.defaultWinMenuColor: black
	    nedit.modifiedWinMenuColor: red
	    nedit.readOnlyWinMenuColor: blue
	    nedit.backgroundWinMenuColor: white

 2006-08-14, ...

 Updated to be synchronised with CVS head.

 2007-06-12

 Added new resource backgroundWinMenuColor

 2007-07-02

 Removed irrelevant help info (thanks to Bert Wesarg)

diff -ur -b nedit_official nedit_mod
diff -ur -b nedit_official/doc/help.etx nedit_mod/doc/help.etx
--- nedit_official/doc/help.etx	2007-01-04 02:42:23.000000000 +0100
+++ nedit_mod/doc/help.etx	2007-06-14 01:27:23.000000000 +0200
@@ -4261,6 +4261,32 @@
   set to False, the "Case Sensitive" buttons are independent of the "Regular
   Expression" toggle.
 
+**nedit.coloredWinMenu**: True
+
+  Controls if the Windows  menu shall use colors to code the file's status.
+  
+  If above resource is set to True, the following four resources can be used
+  to define the colors to use. For all three cases a color value of "default"
+  can be used to specify that the default color as specified by the window
+  manager shall be used.
+
+**nedit.defaultWinMenuColor**: black
+
+  Defines the default color of files in the Windows menu.
+
+**nedit.modifiedWinMenuColor**: red
+
+  Defines the color of modified (unsaved) files in the Windows menu.
+
+**nedit.readOnlyWinMenuColor**: blue
+
+  Defines the color of read-only files in the Windows menu.
+
+**nedit.backgroundWinMenuColor**: white
+
+  Defines the color of the background used for colored Windows menu items
+  when using either the modified or read-only foreground color.
+
 **nedit.multiClickTime**: (system specific)
 
   Maximum time in milliseconds allowed between mouse clicks within double and
diff -ur -b nedit_official/source/menu.c nedit_mod/source/menu.c
--- nedit_official/source/menu.c	2006-12-02 11:27:06.000000000 +0100
+++ nedit_mod/source/menu.c	2007-06-14 01:38:14.000000000 +0200
@@ -4556,6 +4556,42 @@
     WriteNEditDB();
 }
 
+static void colorWindowMenuEntries(const WindowInfo* window, Widget widget)
+{
+    if (GetPrefColoredWinMenu() == True)
+    {
+        Pixel oldFg, oldBg;
+        const char* bgcolor = "default";
+        int bgcolorLength = 7;
+        const char* color;
+        int colorLength;
+        if (IS_ANY_LOCKED(window->lockReasons)) {
+            color = GetPrefRoMenuColor(&colorLength);
+            bgcolor = GetPrefBgMenuColor(&bgcolorLength);
+        }
+        else if (window->fileChanged == TRUE) {
+            color = GetPrefModMenuColor(&colorLength);
+            bgcolor = GetPrefBgMenuColor(&bgcolorLength);
+        }
+        else {
+            color = GetPrefDefMenuColor(&colorLength);
+            /* leave background for the default color alone */
+        }
+        XtVaGetValues(XtParent(widget), XmNforeground, &oldFg,
+                                        XmNbackground, &oldBg, NULL);
+        if (strcmp(color, "default") != 0) {
+            XtVaSetValues(widget, XtVaTypedArg, XmNforeground, XmRString, color, colorLength + 1, NULL);
+        } else {
+            XtVaSetValues(widget, XmNforeground, oldFg, NULL);
+        }
+        if (strcmp(bgcolor, "default") != 0) {
+            XtVaSetValues(widget, XtVaTypedArg, XmNbackground, XmRString, bgcolor, bgcolorLength + 1, NULL);
+        } else {
+            XtVaSetValues(widget, XmNbackground, oldBg, NULL);
+        }
+    }
+}
+
 static char* getWindowsMenuEntry(const WindowInfo* window)
 {
     static char fullTitle[MAXPATHLEN * 2 + 3+ 1];
@@ -4628,6 +4664,7 @@
                 char* title = getWindowsMenuEntry(windows[windowIndex]);
 		XtVaSetValues(items[n], XmNlabelString,
     	    		st1=XmStringCreateSimple(title), NULL);
+                colorWindowMenuEntries(windows[windowIndex], items[n]);
 		XtRemoveAllCallbacks(items[n], XmNactivateCallback);
 		XtAddCallback(items[n], XmNactivateCallback,
 			(XtCallbackProc)raiseCB, windows[windowIndex]);
@@ -4646,6 +4683,8 @@
     		XmNlabelString, st1=XmStringCreateSimple(title),
 		XmNmarginHeight, 0,
     		XmNuserData, TEMPORARY_MENU_ITEM, NULL);
+
+        colorWindowMenuEntries(windows[windowIndex], btn);
 	XtAddCallback(btn, XmNactivateCallback, (XtCallbackProc)raiseCB, 
 	    	windows[windowIndex]);
     	XmStringFree(st1);
diff -ur -b nedit_official/source/preferences.c nedit_mod/source/preferences.c
--- nedit_official/source/preferences.c	2007-05-09 15:11:45.000000000 +0200
+++ nedit_mod/source/preferences.c	2007-06-14 01:27:23.000000000 +0200
@@ -108,6 +108,9 @@
 /* maximum number of file extensions allowed in a language mode */
 #define MAX_FILE_EXTENSIONS 20
 
+/* maximum size of color string */
+#define MAX_COLOR_LENGTH 256
+
 /* Return values for checkFontStatus */
 enum fontStatus {GOOD_FONT, BAD_PRIMARY, BAD_FONT, BAD_SIZE, BAD_SPACING};
 
@@ -324,6 +327,17 @@
     Boolean honorSymlinks;
     int truncSubstitution;
     Boolean forceOSConversion;
+    /* Color of modified, readonly, and normal menu items for the filenames
+     * in the window menu*/
+    int coloredWinMenu;
+    char modMenuColor[MAX_COLOR_LENGTH];
+    int modMenuColorLength;
+    char roMenuColor[MAX_COLOR_LENGTH];
+    int roMenuColorLength;
+    char defMenuColor[MAX_COLOR_LENGTH];
+    int defMenuColorLength;
+    char bgMenuColor[MAX_COLOR_LENGTH];
+    int bgMenuColorLength;
 } PrefData;
 
 /* Temporary storage for preferences strings which are discarded after being
@@ -1075,7 +1089,17 @@
     {"truncSubstitution", "TruncSubstitution", PREF_ENUM, "Fail",
             &PrefData.truncSubstitution, TruncSubstitutionModes, False},
     {"honorSymlinks", "HonorSymlinks", PREF_BOOLEAN, "True",
-            &PrefData.honorSymlinks, NULL, False}
+            &PrefData.honorSymlinks, NULL, False},
+    {"coloredWinMenu", "ColoredWinMenu", PREF_BOOLEAN, "True",
+        &PrefData.coloredWinMenu, NULL, False},
+    {"modifiedWinMenuColor", "ModifiedWinMenuColor", PREF_STRING, "red",
+        PrefData.modMenuColor, (void *)sizeof(PrefData.modMenuColor), False},
+    {"readOnlyWinMenuColor", "ReadOnlyWinMenuColor", PREF_STRING, "blue",
+        PrefData.roMenuColor, (void *)sizeof(PrefData.roMenuColor), False},
+    {"defaultWinMenuColor", "DefaultWinMenuColor", PREF_STRING, "black",
+        PrefData.defMenuColor, (void *)sizeof(PrefData.defMenuColor), False},
+    {"backgroundWinMenuColor", "BackgroundWinMenuColor", PREF_STRING, "white",
+        PrefData.bgMenuColor, (void *)sizeof(PrefData.bgMenuColor), False},
 };
 
 static XrmOptionDescRec OpTable[] = {
@@ -1418,6 +1442,12 @@
     if (PrefData.autoIndent == 3) PrefData.autoIndent = AUTO_INDENT;
     if (PrefData.autoIndent == 4) PrefData.autoIndent = NO_AUTO_INDENT;
 
+    /* For efficiency, precalculate the lengths of window menu colors */
+    SetPrefModMenuColorLength(PrefData.modMenuColor);
+    SetPrefRoMenuColorLength (PrefData.roMenuColor);
+    SetPrefDefMenuColorLength(PrefData.defMenuColor);
+    SetPrefBgMenuColorLength(PrefData.bgMenuColor);
+
     /* setup language mode dependent info of user menus (to increase
        performance when switching between documents of different
        language modes) */
@@ -2190,6 +2220,54 @@
 {
     return PrefData.honorSymlinks;
 }
+int GetPrefColoredWinMenu(void)
+{
+    return PrefData.coloredWinMenu;
+}
+ 
+const char *GetPrefModMenuColor(int* length)
+{
+    *length = PrefData.modMenuColorLength;
+    return PrefData.modMenuColor;
+}
+
+void SetPrefModMenuColorLength(const char* string)
+{
+    PrefData.modMenuColorLength = strlen(string);
+}
+
+const char *GetPrefRoMenuColor(int* length)
+{
+    *length = PrefData.roMenuColorLength;
+    return PrefData.roMenuColor;
+}
+
+void SetPrefRoMenuColorLength(const char* string)
+{
+    PrefData.roMenuColorLength = strlen(string);
+}
+
+const char *GetPrefDefMenuColor(int* length)
+{
+    *length = PrefData.defMenuColorLength;
+    return PrefData.defMenuColor;
+}
+
+void SetPrefDefMenuColorLength(const char* string)
+{
+    PrefData.defMenuColorLength = strlen(string);
+}
+
+const char *GetPrefBgMenuColor(int* length)
+{
+    *length = PrefData.bgMenuColorLength;
+    return PrefData.bgMenuColor;
+}
+
+void SetPrefBgMenuColorLength(const char* string)
+{
+    PrefData.bgMenuColorLength = strlen(string);
+}
 
 int GetPrefOverrideVirtKeyBindings(void)
 {
diff -ur -b nedit_official/source/preferences.h nedit_mod/source/preferences.h
--- nedit_official/source/preferences.h	2006-10-16 16:26:52.000000000 +0200
+++ nedit_mod/source/preferences.h	2007-06-14 01:27:23.000000000 +0200
@@ -194,6 +194,15 @@
 void SetLangModeMenu(Widget optMenu, const char *modeName);
 void CreateLanguageModeSubMenu(WindowInfo* window, const Widget parent,
         const char* name, const char* label, const char mnemonic);
+int GetPrefColoredWinMenu(void);
+const char *GetPrefModMenuColor(int* length);
+void SetPrefModMenuColorLength(const char* string);
+const char *GetPrefRoMenuColor(int* length);
+void SetPrefRoMenuColorLength(const char* string);
+const char *GetPrefDefMenuColor(int* length);
+void SetPrefDefMenuColorLength(const char* string);
+const char *GetPrefBgMenuColor(int* length);
+void SetPrefBgMenuColorLength(const char* string);
 void SetPrefFindReplaceUsesSelection(int state);
 int GetPrefFindReplaceUsesSelection(void);
 int GetPrefStickyCaseSenseBtn(void);
