Fix for SF bug #1122813: Tab-related crash on posting unload calltips file
[nedit.git] / source / windowTitle.c
blob7bc6e4287a1b447330035462a99ac7ca74274adc
1 static const char CVSID[] = "$Id: windowTitle.c,v 1.15 2004/12/23 22:25:47 edg Exp $";
2 /*******************************************************************************
3 * *
4 * windowTitle.c -- Nirvana Editor window title customization *
5 * *
6 * Copyright (C) 2001, Arne Forlie *
7 * *
8 * This is free software; you can redistribute it and/or modify it under the *
9 * terms of the GNU General Public License as published by the Free Software *
10 * Foundation; either version 2 of the License, or (at your option) any later *
11 * version. In addition, you may distribute versions of this program linked to *
12 * Motif or Open Motif. See README for details. *
13 * *
14 * This software is distributed in the hope that it will be useful, but WITHOUT *
15 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or *
16 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for *
17 * more details. *
18 * *
19 * You should have received a copy of the GNU General Public License along with *
20 * software; if not, write to the Free Software Foundation, Inc., 59 Temple *
21 * Place, Suite 330, Boston, MA 02111-1307 USA *
22 * *
23 * Nirvana Text Editor *
24 * July 31, 2001 *
25 * *
26 * Written by Arne Forlie, http://arne.forlie.com *
27 * *
28 *******************************************************************************/
30 #ifdef HAVE_CONFIG_H
31 #include "../config.h"
32 #endif
34 #include "windowTitle.h"
35 #include "textBuf.h"
36 #include "nedit.h"
37 #include "preferences.h"
38 #include "help.h"
39 #include "../util/prefFile.h"
40 #include "../util/misc.h"
41 #include "../util/DialogF.h"
42 #include "../util/utils.h"
43 #include "../util/fileUtils.h"
45 #include <stdlib.h>
46 #include <stdio.h>
47 #include <ctype.h>
48 #include <string.h>
49 #ifdef VMS
50 #include "../util/VMSparam.h"
51 #else
52 #ifndef __MVS__
53 #include <sys/param.h>
54 #endif
55 #include "../util/clearcase.h"
56 #endif /*VMS*/
58 #include <Xm/Xm.h>
59 #include <Xm/SelectioB.h>
60 #include <Xm/Form.h>
61 #include <Xm/List.h>
62 #include <Xm/SeparatoG.h>
63 #include <Xm/LabelG.h>
64 #include <Xm/PushBG.h>
65 #include <Xm/PushB.h>
66 #include <Xm/ToggleBG.h>
67 #include <Xm/ToggleB.h>
68 #include <Xm/RowColumn.h>
69 #include <Xm/CascadeBG.h>
70 #include <Xm/Frame.h>
71 #include <Xm/Text.h>
72 #include <Xm/TextF.h>
74 #ifdef HAVE_DEBUG_H
75 #include "../debug.h"
76 #endif
79 #define WINDOWTITLE_MAX_LEN 500
81 /* Customize window title dialog information */
82 static struct {
83 Widget form;
84 Widget shell;
85 WindowInfo* window;
86 Widget previewW;
87 Widget formatW;
89 Widget ccW;
90 Widget fileW;
91 Widget hostW;
92 Widget dirW;
93 Widget statusW;
94 Widget shortStatusW;
95 Widget serverW;
96 Widget nameW;
97 Widget mdirW;
98 Widget ndirW;
100 Widget oDirW;
101 Widget oCcViewTagW;
102 Widget oServerNameW;
103 Widget oFileChangedW;
104 Widget oFileLockedW;
105 Widget oFileReadOnlyW;
106 Widget oServerEqualViewW;
108 char filename[MAXPATHLEN];
109 char path[MAXPATHLEN];
110 char viewTag[MAXPATHLEN];
111 char serverName[MAXPATHLEN];
112 int isServer;
113 int filenameSet;
114 int lockReasons;
115 int fileChanged;
117 int suppressFormatUpdate;
118 } etDialog = {NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,
119 NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,
120 NULL,NULL,"","","","",0,0,0,0,0};
124 static char* removeSequence(char* sourcePtr, char c)
126 while (*sourcePtr == c) {
127 sourcePtr++;
129 return(sourcePtr);
134 ** Two functions for performing safe insertions into a finite
135 ** size buffer so that we don't get any memory overruns.
137 static char* safeStrCpy(char* dest, char* destEnd, const char* source)
139 int len = (int)strlen(source);
140 if (len <= (destEnd - dest)) {
141 strcpy(dest, source);
142 return(dest + len);
144 else {
145 strncpy(dest, source, destEnd - dest);
146 *destEnd = '\0';
147 return(destEnd);
151 static char* safeCharAdd(char* dest, char* destEnd, char c)
153 if (destEnd - dest > 0)
155 *dest++ = c;
156 *dest = '\0';
158 return(dest);
162 ** Remove empty paranthesis pairs and multiple spaces in a row
163 ** with one space.
164 ** Also remove leading and trailing spaces and dashes.
166 static void compressWindowTitle(char *title)
168 /* Compress the title */
169 int modified;
170 do {
171 char *sourcePtr = title;
172 char *destPtr = sourcePtr;
173 char c = *sourcePtr++;
175 modified = False;
177 /* Remove leading spaces and dashes */
178 while (c == ' ' || c == '-') {
179 c= *sourcePtr++;
182 /* Remove empty constructs */
183 while (c != '\0') {
184 switch (c) {
185 /* remove sequences */
186 case ' ':
187 case '-':
188 sourcePtr = removeSequence(sourcePtr, c);
189 *destPtr++ = c; /* leave one */
190 break;
192 /* remove empty paranthesis pairs */
193 case '(':
194 if (*sourcePtr == ')') {
195 modified = True;
196 sourcePtr++;
198 else *destPtr++ = c;
199 sourcePtr = removeSequence(sourcePtr, ' ');
200 break;
202 case '[':
203 if (*sourcePtr == ']') {
204 modified = True;
205 sourcePtr++;
207 else *destPtr++ = c;
208 sourcePtr = removeSequence(sourcePtr, ' ');
209 break;
211 case '{':
212 if (*sourcePtr == '}') {
213 modified = True;
214 sourcePtr++;
216 else *destPtr++ = c;
217 sourcePtr = removeSequence(sourcePtr, ' ');
218 break;
220 default:
221 *destPtr++ = c;
222 break;
224 c = *sourcePtr++;
225 *destPtr = '\0';
228 /* Remove trailing spaces and dashes */
229 while (destPtr-- > title) {
230 if (*destPtr != ' ' && *destPtr != '-')
231 break;
232 *destPtr = '\0';
234 } while (modified == True);
239 ** Format the windows title using a printf like formatting string.
240 ** The following flags are recognised:
241 ** %c : ClearCase view tag
242 ** %s : server name
243 ** %[n]d : directory, with one optional digit specifying the max number
244 ** of trailing directory components to display. Skipped components are
245 ** replaced by an ellipsis (...).
246 ** %f : file name
247 ** %h : host name
248 ** %S : file status
249 ** %u : user name
251 ** if the ClearCase view tag and server name are identical, only the first one
252 ** specified in the formatting string will be displayed.
254 char *FormatWindowTitle(const char* filename,
255 const char* path,
256 const char* clearCaseViewTag,
257 const char* serverName,
258 int isServer,
259 int filenameSet,
260 int lockReasons,
261 int fileChanged,
262 const char* titleFormat)
264 static char title[WINDOWTITLE_MAX_LEN];
265 char *titlePtr = title;
266 char* titleEnd = title + WINDOWTITLE_MAX_LEN - 1;
269 /* Flags to supress one of these if both are specified and they are identical */
270 int serverNameSeen = False;
271 int clearCaseViewTagSeen = False;
273 int fileNamePresent = False;
274 int hostNamePresent = False;
275 int userNamePresent = False;
276 int serverNamePresent = False;
277 int clearCasePresent = False;
278 int fileStatusPresent = False;
279 int dirNamePresent = False;
280 int noOfComponents = -1;
281 int shortStatus = False;
283 *titlePtr = '\0'; /* always start with an empty string */
285 while (*titleFormat != '\0' && titlePtr < titleEnd) {
286 char c = *titleFormat++;
287 if (c == '%') {
288 c = *titleFormat++;
289 if (c == '\0')
291 titlePtr = safeCharAdd(titlePtr, titleEnd, '%');
292 break;
294 switch (c) {
295 case 'c': /* ClearCase view tag */
296 clearCasePresent = True;
297 if (clearCaseViewTag != NULL) {
298 if (serverNameSeen == False ||
299 strcmp(serverName, clearCaseViewTag) != 0) {
300 titlePtr = safeStrCpy(titlePtr, titleEnd, clearCaseViewTag);
301 clearCaseViewTagSeen = True;
304 break;
306 case 's': /* server name */
307 serverNamePresent = True;
308 if (isServer && serverName[0] != '\0') { /* only applicable for servers */
309 if (clearCaseViewTagSeen == False ||
310 strcmp(serverName, clearCaseViewTag) != 0) {
311 titlePtr = safeStrCpy(titlePtr, titleEnd, serverName);
312 serverNameSeen = True;
315 break;
317 case 'd': /* directory without any limit to no. of components */
318 dirNamePresent = True;
319 if (filenameSet) {
320 titlePtr = safeStrCpy(titlePtr, titleEnd, path);
322 break;
324 case '0': /* directory with limited no. of components */
325 case '1':
326 case '2':
327 case '3':
328 case '4':
329 case '5':
330 case '6':
331 case '7':
332 case '8':
333 case '9':
334 if (*titleFormat == 'd') {
335 dirNamePresent = True;
336 noOfComponents = c - '0';
337 titleFormat++; /* delete the argument */
339 if (filenameSet) {
340 const char* trailingPath = GetTrailingPathComponents(path,
341 noOfComponents);
343 /* prefix with ellipsis if components were skipped */
344 if (trailingPath > path) {
345 titlePtr = safeStrCpy(titlePtr, titleEnd, "...");
347 titlePtr = safeStrCpy(titlePtr, titleEnd, trailingPath);
350 break;
352 case 'f': /* file name */
353 fileNamePresent = True;
354 titlePtr = safeStrCpy(titlePtr, titleEnd, filename);
355 break;
357 case 'h': /* host name */
358 hostNamePresent = True;
359 titlePtr = safeStrCpy(titlePtr, titleEnd, GetNameOfHost());
360 break;
362 case 'S': /* file status */
363 fileStatusPresent = True;
364 if (IS_ANY_LOCKED_IGNORING_USER(lockReasons) && fileChanged)
365 titlePtr = safeStrCpy(titlePtr, titleEnd, "read only, modified");
366 else if (IS_ANY_LOCKED_IGNORING_USER(lockReasons))
367 titlePtr = safeStrCpy(titlePtr, titleEnd, "read only");
368 else if (IS_USER_LOCKED(lockReasons) && fileChanged)
369 titlePtr = safeStrCpy(titlePtr, titleEnd, "locked, modified");
370 else if (IS_USER_LOCKED(lockReasons))
371 titlePtr = safeStrCpy(titlePtr, titleEnd, "locked");
372 else if (fileChanged)
373 titlePtr = safeStrCpy(titlePtr, titleEnd, "modified");
374 break;
376 case 'u': /* user name */
377 userNamePresent = True;
378 titlePtr = safeStrCpy(titlePtr, titleEnd, GetUserName());
379 break;
381 case '%': /* escaped % */
382 titlePtr = safeCharAdd(titlePtr, titleEnd, '%');
383 break;
385 case '*': /* short file status ? */
386 fileStatusPresent = True;
387 if (*titleFormat && *titleFormat == 'S')
389 ++titleFormat;
390 shortStatus = True;
391 if (IS_ANY_LOCKED_IGNORING_USER(lockReasons) && fileChanged)
392 titlePtr = safeStrCpy(titlePtr, titleEnd, "RO*");
393 else if (IS_ANY_LOCKED_IGNORING_USER(lockReasons))
394 titlePtr = safeStrCpy(titlePtr, titleEnd, "RO");
395 else if (IS_USER_LOCKED(lockReasons) && fileChanged)
396 titlePtr = safeStrCpy(titlePtr, titleEnd, "LO*");
397 else if (IS_USER_LOCKED(lockReasons))
398 titlePtr = safeStrCpy(titlePtr, titleEnd, "LO");
399 else if (fileChanged)
400 titlePtr = safeStrCpy(titlePtr, titleEnd, "*");
401 break;
403 /* fall-through */
404 default:
405 titlePtr = safeCharAdd(titlePtr, titleEnd, c);
406 break;
409 else {
410 titlePtr = safeCharAdd(titlePtr, titleEnd, c);
414 compressWindowTitle(title);
416 if (title[0] == 0)
418 sprintf(&title[0], "<empty>"); /* For preview purposes only */
421 if (etDialog.form)
423 /* Prevent recursive callback loop */
424 etDialog.suppressFormatUpdate = True;
426 /* Sync radio buttons with format string (in case the user entered
427 the format manually) */
428 XmToggleButtonSetState(etDialog.fileW, fileNamePresent, False);
429 XmToggleButtonSetState(etDialog.statusW, fileStatusPresent, False);
430 XmToggleButtonSetState(etDialog.serverW, serverNamePresent, False);
431 #ifndef VMS
432 XmToggleButtonSetState(etDialog.ccW, clearCasePresent, False);
433 #endif /* VMS */
434 XmToggleButtonSetState(etDialog.dirW, dirNamePresent, False);
435 XmToggleButtonSetState(etDialog.hostW, hostNamePresent, False);
436 XmToggleButtonSetState(etDialog.nameW, userNamePresent, False);
438 XtSetSensitive(etDialog.shortStatusW, fileStatusPresent);
439 if (fileStatusPresent)
441 XmToggleButtonSetState(etDialog.shortStatusW, shortStatus, False);
444 /* Directory components are also sensitive to presence of dir */
445 XtSetSensitive(etDialog.ndirW, dirNamePresent);
446 XtSetSensitive(etDialog.mdirW, dirNamePresent);
448 if (dirNamePresent) /* Avoid erasing number when not active */
450 if (noOfComponents >= 0)
452 char* value = XmTextGetString(etDialog.ndirW);
453 char buf[2];
454 sprintf(&buf[0], "%d", noOfComponents);
455 if (strcmp(&buf[0], value)) /* Don't overwrite unless diff. */
456 SetIntText(etDialog.ndirW, noOfComponents);
457 XtFree(value);
459 else
461 XmTextSetString(etDialog.ndirW, "");
465 /* Enable/disable test buttons, depending on presence of codes */
466 XtSetSensitive(etDialog.oFileChangedW, fileStatusPresent);
467 XtSetSensitive(etDialog.oFileReadOnlyW, fileStatusPresent);
468 XtSetSensitive(etDialog.oFileLockedW, fileStatusPresent &&
469 !IS_PERM_LOCKED(etDialog.lockReasons));
471 XtSetSensitive(etDialog.oServerNameW, serverNamePresent);
473 #ifndef VMS
474 XtSetSensitive(etDialog.oCcViewTagW, clearCasePresent);
475 XtSetSensitive(etDialog.oServerEqualViewW, clearCasePresent &&
476 serverNamePresent);
477 #endif /* VMS */
479 XtSetSensitive(etDialog.oDirW, dirNamePresent);
481 etDialog.suppressFormatUpdate = False;
484 return(title);
489 /* a utility that sets the values of all toggle buttons */
490 static void setToggleButtons(void)
492 XmToggleButtonSetState(etDialog.oDirW,
493 etDialog.filenameSet == True, False);
494 XmToggleButtonSetState(etDialog.oFileChangedW,
495 etDialog.fileChanged == True, False);
496 XmToggleButtonSetState(etDialog.oFileReadOnlyW,
497 IS_PERM_LOCKED(etDialog.lockReasons), False);
498 XmToggleButtonSetState(etDialog.oFileLockedW,
499 IS_USER_LOCKED(etDialog.lockReasons), False);
500 /* Read-only takes precedence on locked */
501 XtSetSensitive(etDialog.oFileLockedW, !IS_PERM_LOCKED(etDialog.lockReasons));
503 #ifdef VMS
504 XmToggleButtonSetState(etDialog.oServerNameW, etDialog.isServer, False);
505 #else
506 XmToggleButtonSetState(etDialog.oCcViewTagW,
507 GetClearCaseViewTag() != NULL, False);
508 XmToggleButtonSetState(etDialog.oServerNameW,
509 etDialog.isServer, False);
511 if (GetClearCaseViewTag() != NULL &&
512 etDialog.isServer &&
513 GetPrefServerName()[0] != '\0' &&
514 strcmp(GetClearCaseViewTag(), GetPrefServerName()) == 0) {
515 XmToggleButtonSetState(etDialog.oServerEqualViewW,
516 True, False);
517 } else {
518 XmToggleButtonSetState(etDialog.oServerEqualViewW,
519 False, False);
521 #endif /* VMS */
524 static void formatChangedCB(Widget w, XtPointer clientData, XtPointer callData)
526 char *format;
527 int filenameSet = XmToggleButtonGetState(etDialog.oDirW);
528 char *title;
529 const char* serverName;
531 if (etDialog.suppressFormatUpdate)
533 return; /* Prevent recursive feedback */
536 format = XmTextGetString(etDialog.formatW);
538 #ifndef VMS
539 if (XmToggleButtonGetState(etDialog.oServerEqualViewW) &&
540 XmToggleButtonGetState(etDialog.ccW)) {
541 serverName = etDialog.viewTag;
542 } else
543 #endif /* VMS */
545 serverName = XmToggleButtonGetState(etDialog.oServerNameW) ?
546 etDialog.serverName : "";
549 title = FormatWindowTitle(
550 etDialog.filename,
551 etDialog.filenameSet == True ?
552 etDialog.path :
553 "/a/very/long/path/used/as/example/",
554 #ifdef VMS
555 NULL,
556 #else
557 XmToggleButtonGetState(etDialog.oCcViewTagW) ?
558 etDialog.viewTag : NULL,
559 #endif /* VMS */
560 serverName,
561 etDialog.isServer,
562 filenameSet,
563 etDialog.lockReasons,
564 XmToggleButtonGetState(etDialog.oFileChangedW),
565 format);
566 XtFree(format);
567 XmTextFieldSetString(etDialog.previewW, title);
570 #ifndef VMS
571 static void ccViewTagCB(Widget w, XtPointer clientData, XtPointer callData)
573 if (XmToggleButtonGetState(w) == False) {
574 XmToggleButtonSetState(etDialog.oServerEqualViewW, False, False);
576 formatChangedCB(w, clientData, callData);
578 #endif /* VMS */
580 static void serverNameCB(Widget w, XtPointer clientData, XtPointer callData)
582 if (XmToggleButtonGetState(w) == False) {
583 XmToggleButtonSetState(etDialog.oServerEqualViewW, False, False);
585 etDialog.isServer = XmToggleButtonGetState(w);
586 formatChangedCB(w, clientData, callData);
589 static void fileChangedCB(Widget w, XtPointer clientData, XtPointer callData)
591 etDialog.fileChanged = XmToggleButtonGetState(w);
592 formatChangedCB(w, clientData, callData);
595 static void fileLockedCB(Widget w, XtPointer clientData, XtPointer callData)
597 SET_USER_LOCKED(etDialog.lockReasons, XmToggleButtonGetState(w));
598 formatChangedCB(w, clientData, callData);
601 static void fileReadOnlyCB(Widget w, XtPointer clientData, XtPointer callData)
603 SET_PERM_LOCKED(etDialog.lockReasons, XmToggleButtonGetState(w));
604 formatChangedCB(w, clientData, callData);
607 #ifndef VMS
608 static void serverEqualViewCB(Widget w, XtPointer clientData, XtPointer callData)
610 if (XmToggleButtonGetState(w) == True) {
611 XmToggleButtonSetState(etDialog.oCcViewTagW, True, False);
612 XmToggleButtonSetState(etDialog.oServerNameW, True, False);
613 etDialog.isServer = True;
615 formatChangedCB(w, clientData, callData);
617 #endif /* VMS */
619 static void applyCB(Widget w, XtPointer clientData, XtPointer callData)
621 char *format = XmTextGetString(etDialog.formatW);
623 /* pop down the dialog */
624 /* XtUnmanageChild(etDialog.form); */
626 if (strcmp(format, GetPrefTitleFormat()) != 0) {
627 SetPrefTitleFormat(format);
629 XtFree(format);
632 static void closeCB(Widget w, XtPointer clientData, XtPointer callData)
634 /* pop down the dialog */
635 XtUnmanageChild(etDialog.form);
638 static void restoreCB(Widget w, XtPointer clientData, XtPointer callData)
640 XmTextSetString(etDialog.formatW, "{%c} [%s] %f (%S) - %d");
643 static void helpCB(Widget w, XtPointer clientData, XtPointer callData)
645 Help(HELP_CUSTOM_TITLE_DIALOG);
648 static void wtDestroyCB(Widget w, XtPointer clientData, XtPointer callData)
650 if (w == etDialog.form) /* Prevent disconnecting the replacing dialog */
651 etDialog.form = NULL;
654 static void wtUnmapCB(Widget w, XtPointer clientData, XtPointer callData)
656 if (etDialog.form == w) /* Prevent destroying the replacing dialog */
657 XtDestroyWidget(etDialog.form);
660 static void appendToFormat(const char* string)
662 char *format = XmTextGetString(etDialog.formatW);
663 char *buf = XtMalloc(strlen(string) + strlen(format) + 1);
664 strcpy(buf, format);
665 strcat(buf, string);
666 XmTextSetString(etDialog.formatW, buf);
667 XtFree(format);
668 XtFree(buf);
671 static void removeFromFormat(const char* string)
673 char *format = XmTextGetString(etDialog.formatW);
674 char* pos;
676 /* There can be multiple occurences */
677 while ((pos = strstr(format, string)))
679 /* If the string is preceded or followed by a brace, include
680 the brace(s) for removal */
681 char* start = pos;
682 char* end = pos + strlen(string);
683 char post = *end;
685 if (post == '}' || post == ')' || post == ']' || post == '>')
687 end += 1;
688 post = *end;
691 if (start > format)
693 char pre = *(start-1);
694 if (pre == '{' || pre == '(' || pre == '[' || pre == '<')
695 start -= 1;
697 if (start > format)
699 char pre = *(start-1);
700 /* If there is a space in front and behind, remove one space
701 (there can be more spaces, but in that case it is likely
702 that the user entered them manually); also remove trailing
703 space */
704 if (pre == ' ' && post == ' ')
706 end += 1;
708 else if (pre == ' ' && post == (char)0)
710 /* Remove (1) trailing space */
711 start -= 1;
715 /* Contract the string: move end to start */
716 strcpy(start, end);
719 /* Remove leading and trailing space */
720 pos = format;
721 while (*pos == ' ') ++pos;
722 strcpy(format, pos);
724 pos = format + strlen(format) - 1;
725 while (pos >= format && *pos == ' ')
727 --pos;
729 *(pos+1) = (char)0;
731 XmTextSetString(etDialog.formatW, format);
732 XtFree(format);
736 static void toggleFileCB(Widget w, XtPointer clientData, XtPointer callData)
738 if (XmToggleButtonGetState(etDialog.fileW))
739 appendToFormat(" %f");
740 else
741 removeFromFormat("%f");
744 static void toggleServerCB(Widget w, XtPointer clientData, XtPointer callData)
746 if (XmToggleButtonGetState(etDialog.serverW))
747 appendToFormat(" [%s]");
748 else
749 removeFromFormat("%s");
752 static void toggleHostCB(Widget w, XtPointer clientData, XtPointer callData)
754 if (XmToggleButtonGetState(etDialog.hostW))
755 appendToFormat(" [%h]");
756 else
757 removeFromFormat("%h");
760 #ifndef VMS
761 static void toggleClearCaseCB(Widget w, XtPointer clientData, XtPointer callData)
763 if (XmToggleButtonGetState(etDialog.ccW))
764 appendToFormat(" {%c}");
765 else
766 removeFromFormat("%c");
768 #endif /* VMS */
770 static void toggleStatusCB(Widget w, XtPointer clientData, XtPointer callData)
772 if (XmToggleButtonGetState(etDialog.statusW))
774 if (XmToggleButtonGetState(etDialog.shortStatusW))
775 appendToFormat(" (%*S)");
776 else
777 appendToFormat(" (%S)");
779 else
781 removeFromFormat("%S");
782 removeFromFormat("%*S");
786 static void toggleShortStatusCB(Widget w, XtPointer clientData, XtPointer callData)
788 char *format, *pos;
790 if (etDialog.suppressFormatUpdate)
792 return;
795 format = XmTextGetString(etDialog.formatW);
797 if (XmToggleButtonGetState(etDialog.shortStatusW))
799 /* Find all %S occurrences and replace them by %*S */
802 pos = strstr(format, "%S");
803 if (pos)
805 char* tmp = (char*)XtMalloc((strlen(format)+2)*sizeof(char));
806 strncpy(tmp, format, (size_t)(pos-format+1));
807 tmp[pos-format+1] = 0;
808 strcat(tmp, "*");
809 strcat(tmp, pos+1);
810 XtFree(format);
811 format = tmp;
814 while (pos);
816 else
818 /* Replace all %*S occurences by %S */
821 pos = strstr(format, "%*S");
822 if (pos)
824 strcpy(pos+1, pos+2);
827 while(pos);
830 XmTextSetString(etDialog.formatW, format);
831 XtFree(format);
834 static void toggleUserCB(Widget w, XtPointer clientData, XtPointer callData)
836 if (XmToggleButtonGetState(etDialog.nameW))
837 appendToFormat(" %u");
838 else
839 removeFromFormat("%u");
842 static void toggleDirectoryCB(Widget w, XtPointer clientData, XtPointer callData)
844 if (XmToggleButtonGetState(etDialog.dirW))
846 char buf[20];
847 int maxComp;
848 char *value = XmTextGetString(etDialog.ndirW);
849 if (*value)
851 if (sscanf(value, "%d", &maxComp) > 0)
853 sprintf(&buf[0], " %%%dd ", maxComp);
855 else
857 sprintf(&buf[0], " %%d "); /* Should not be necessary */
860 else
862 sprintf(&buf[0], " %%d ");
864 XtFree(value);
865 appendToFormat(buf);
867 else
869 int i;
870 removeFromFormat("%d");
871 for (i=0; i<=9; ++i)
873 char buf[20];
874 sprintf(&buf[0], "%%%dd", i);
875 removeFromFormat(buf);
880 static void enterMaxDirCB(Widget w, XtPointer clientData, XtPointer callData)
882 int maxComp = -1;
883 char *format;
884 char *value;
886 if (etDialog.suppressFormatUpdate)
888 return;
891 format = XmTextGetString(etDialog.formatW);
892 value = XmTextGetString(etDialog.ndirW);
894 if (*value)
896 if (sscanf(value, "%d", &maxComp) <= 0)
898 /* Don't allow non-digits to be entered */
899 XBell(XtDisplay(w), 0);
900 XmTextSetString(etDialog.ndirW, "");
904 if (maxComp >= 0)
906 char *pos;
907 int found = False;
908 char insert[2];
909 insert[0] = (char)('0' + maxComp);
910 insert[1] = (char)0; /* '0' digit and 0 char ! */
912 /* Find all %d and %nd occurrences and replace them by the new value */
915 int i;
916 found = False;
917 pos = strstr(format, "%d");
918 if (pos)
920 char* tmp = (char*)XtMalloc((strlen(format)+2)*sizeof(char));
921 strncpy(tmp, format, (size_t)(pos-format+1));
922 tmp[pos-format+1] = 0;
923 strcat(tmp, &insert[0]);
924 strcat(tmp, pos+1);
925 XtFree(format);
926 format = tmp;
927 found = True;
930 for (i=0; i<=9; ++i)
932 char buf[20];
933 sprintf(&buf[0], "%%%dd", i);
934 if (i != maxComp)
936 pos = strstr(format, &buf[0]);
937 if (pos)
939 *(pos+1) = insert[0];
940 found = True;
945 while (found);
947 else
949 int found = True;
951 /* Replace all %nd occurences by %d */
954 int i;
955 found = False;
956 for (i=0; i<=9; ++i)
958 char buf[20];
959 char *pos;
960 sprintf(&buf[0], "%%%dd", i);
961 pos = strstr(format, &buf[0]);
962 if (pos)
964 strcpy(pos+1, pos+2);
965 found = True;
969 while(found);
972 XmTextSetString(etDialog.formatW, format);
973 XtFree(format);
974 XtFree(value);
977 static void createEditTitleDialog(Widget parent)
979 #define LEFT_MARGIN_POS 2
980 #define RIGHT_MARGIN_POS 98
981 #define V_MARGIN 5
982 #define RADIO_INDENT 3
984 Widget buttonForm, formatLbl, previewFrame;
985 Widget previewForm, previewBox, selectFrame, selectBox, selectForm;
986 Widget testLbl, selectLbl;
987 Widget applyBtn, closeBtn, restoreBtn, helpBtn;
988 XmString s1;
989 XmFontList fontList;
990 Arg args[20];
991 int defaultBtnOffset;
992 Dimension shadowThickness;
993 Dimension radioHeight, textHeight;
994 Pixel background;
996 int ac = 0;
997 XtSetArg(args[ac], XmNautoUnmanage, False); ac++;
998 XtSetArg(args[ac], XmNtitle, "Customize Window Title"); ac++;
999 etDialog.form = CreateFormDialog(parent, "customizeTitle", args, ac);
1002 * Destroy the dialog every time it is unmapped (otherwise it 'sticks'
1003 * to the window for which it was created originally).
1005 XtAddCallback(etDialog.form, XmNunmapCallback, wtUnmapCB, NULL);
1006 XtAddCallback(etDialog.form, XmNdestroyCallback, wtDestroyCB, NULL);
1008 etDialog.shell = XtParent(etDialog.form);
1010 /* Definition form */
1011 selectFrame = XtVaCreateManagedWidget("selectionFrame", xmFrameWidgetClass,
1012 etDialog.form,
1013 XmNleftAttachment, XmATTACH_POSITION,
1014 XmNleftPosition, LEFT_MARGIN_POS,
1015 XmNtopAttachment, XmATTACH_FORM,
1016 XmNtopOffset, V_MARGIN,
1017 XmNrightAttachment, XmATTACH_POSITION,
1018 XmNrightPosition, RIGHT_MARGIN_POS, NULL);
1020 XtVaCreateManagedWidget("titleLabel", xmLabelGadgetClass,
1021 selectFrame,
1022 XmNlabelString,
1023 s1=XmStringCreateSimple("Title definition"),
1024 XmNchildType, XmFRAME_TITLE_CHILD,
1025 XmNchildHorizontalAlignment, XmALIGNMENT_BEGINNING, NULL);
1026 XmStringFree(s1);
1028 selectForm = XtVaCreateManagedWidget("selectForm", xmFormWidgetClass,
1029 selectFrame ,
1030 XmNleftAttachment, XmATTACH_POSITION,
1031 XmNleftPosition, LEFT_MARGIN_POS,
1032 XmNtopAttachment, XmATTACH_FORM,
1033 XmNtopOffset, V_MARGIN,
1034 XmNrightAttachment, XmATTACH_POSITION,
1035 XmNrightPosition, RIGHT_MARGIN_POS, NULL);
1037 selectLbl = XtVaCreateManagedWidget("selectLabel", xmLabelGadgetClass,
1038 selectForm,
1039 XmNlabelString, s1=XmStringCreateSimple("Select title components to include: "),
1040 XmNleftAttachment, XmATTACH_POSITION,
1041 XmNleftPosition, LEFT_MARGIN_POS,
1042 XmNtopOffset, 5,
1043 XmNbottomOffset, 5,
1044 XmNtopAttachment, XmATTACH_FORM, NULL);
1045 XmStringFree(s1);
1047 selectBox = XtVaCreateManagedWidget("selectBox", xmFormWidgetClass,
1048 selectForm,
1049 XmNorientation, XmHORIZONTAL,
1050 XmNpacking, XmPACK_TIGHT,
1051 XmNradioBehavior, False,
1052 XmNleftAttachment, XmATTACH_FORM,
1053 XmNrightAttachment, XmATTACH_FORM,
1054 XmNtopOffset, 5,
1055 XmNtopAttachment, XmATTACH_WIDGET,
1056 XmNtopWidget, selectLbl,
1057 NULL);
1059 etDialog.fileW = XtVaCreateManagedWidget("file",
1060 xmToggleButtonWidgetClass, selectBox,
1061 XmNleftAttachment, XmATTACH_POSITION,
1062 XmNleftPosition, RADIO_INDENT,
1063 XmNtopAttachment, XmATTACH_FORM,
1064 XmNlabelString, s1=XmStringCreateSimple("File name (%f)"),
1065 XmNmnemonic, 'F', NULL);
1066 XtAddCallback(etDialog.fileW, XmNvalueChangedCallback, toggleFileCB, NULL);
1067 XmStringFree(s1);
1069 etDialog.statusW = XtVaCreateManagedWidget("status",
1070 xmToggleButtonWidgetClass, selectBox,
1071 XmNleftAttachment, XmATTACH_POSITION,
1072 XmNleftPosition, RADIO_INDENT,
1073 XmNtopAttachment, XmATTACH_WIDGET,
1074 XmNtopWidget, etDialog.fileW,
1075 XmNlabelString, s1=XmStringCreateSimple("File status (%S) "),
1076 XmNmnemonic, 't', NULL);
1077 XtAddCallback(etDialog.statusW, XmNvalueChangedCallback, toggleStatusCB, NULL);
1078 XmStringFree(s1);
1080 etDialog.shortStatusW = XtVaCreateManagedWidget("shortStatus",
1081 xmToggleButtonWidgetClass, selectBox,
1082 XmNleftAttachment, XmATTACH_WIDGET,
1083 XmNleftWidget, etDialog.statusW,
1084 XmNtopAttachment, XmATTACH_WIDGET,
1085 XmNtopWidget, etDialog.fileW,
1086 XmNlabelString, s1=XmStringCreateSimple("brief"),
1087 XmNmnemonic, 'b', NULL);
1088 XtAddCallback(etDialog.shortStatusW, XmNvalueChangedCallback, toggleShortStatusCB, NULL);
1089 XmStringFree(s1);
1091 etDialog.ccW = XtVaCreateManagedWidget("ccView",
1092 xmToggleButtonWidgetClass, selectBox,
1093 XmNleftAttachment, XmATTACH_POSITION,
1094 XmNleftPosition, RADIO_INDENT,
1095 XmNtopAttachment, XmATTACH_WIDGET,
1096 XmNtopWidget, etDialog.statusW,
1097 XmNlabelString, s1=XmStringCreateSimple("ClearCase view tag (%c) "),
1098 XmNmnemonic, 'C', NULL);
1099 #ifdef VMS
1100 XtSetSensitive(etDialog.ccW, False);
1101 #else
1102 XtAddCallback(etDialog.ccW, XmNvalueChangedCallback, toggleClearCaseCB, NULL);
1103 #endif /* VMS */
1104 XmStringFree(s1);
1106 etDialog.dirW = XtVaCreateManagedWidget("directory",
1107 xmToggleButtonWidgetClass, selectBox,
1108 XmNleftAttachment, XmATTACH_POSITION,
1109 XmNleftPosition, RADIO_INDENT,
1110 XmNtopAttachment, XmATTACH_WIDGET,
1111 XmNtopWidget, etDialog.ccW,
1112 XmNlabelString, s1=XmStringCreateSimple("Directory (%d),"),
1113 XmNmnemonic, 'D', NULL);
1114 XtAddCallback(etDialog.dirW, XmNvalueChangedCallback, toggleDirectoryCB, NULL);
1115 XmStringFree(s1);
1117 XtVaGetValues(etDialog.fileW, XmNheight, &radioHeight, NULL);
1118 etDialog.mdirW = XtVaCreateManagedWidget("componentLab",
1119 xmLabelGadgetClass, selectBox,
1120 XmNheight, radioHeight,
1121 XmNleftAttachment, XmATTACH_WIDGET,
1122 XmNleftWidget, etDialog.dirW,
1123 XmNtopAttachment, XmATTACH_WIDGET,
1124 XmNtopWidget, etDialog.ccW,
1125 XmNlabelString, s1=XmStringCreateSimple("max. components: "),
1126 XmNmnemonic, 'x', NULL);
1127 XmStringFree(s1);
1129 etDialog.ndirW = XtVaCreateManagedWidget("dircomp",
1130 xmTextWidgetClass, selectBox,
1131 XmNcolumns, 1,
1132 XmNmaxLength, 1,
1133 XmNleftAttachment, XmATTACH_WIDGET,
1134 XmNleftWidget, etDialog.mdirW,
1135 XmNtopAttachment, XmATTACH_WIDGET,
1136 XmNtopWidget, etDialog.ccW,
1137 NULL);
1138 XtAddCallback(etDialog.ndirW, XmNvalueChangedCallback, enterMaxDirCB, NULL);
1139 RemapDeleteKey(etDialog.ndirW);
1140 XtVaSetValues(etDialog.mdirW, XmNuserData, etDialog.ndirW, NULL); /* mnemonic processing */
1142 XtVaGetValues(etDialog.ndirW, XmNheight, &textHeight, NULL);
1143 XtVaSetValues(etDialog.dirW, XmNheight, textHeight, NULL);
1144 XtVaSetValues(etDialog.mdirW, XmNheight, textHeight, NULL);
1146 etDialog.hostW = XtVaCreateManagedWidget("host",
1147 xmToggleButtonWidgetClass, selectBox,
1148 XmNleftAttachment, XmATTACH_POSITION,
1149 XmNleftPosition, 50 + RADIO_INDENT,
1150 XmNtopAttachment, XmATTACH_FORM,
1151 XmNlabelString, s1=XmStringCreateSimple("Host name (%h)"),
1152 XmNmnemonic, 'H', NULL);
1153 XtAddCallback(etDialog.hostW, XmNvalueChangedCallback, toggleHostCB, NULL);
1154 XmStringFree(s1);
1156 etDialog.nameW = XtVaCreateManagedWidget("name",
1157 xmToggleButtonWidgetClass, selectBox,
1158 XmNleftAttachment, XmATTACH_POSITION,
1159 XmNleftPosition, 50 + RADIO_INDENT,
1160 XmNtopAttachment, XmATTACH_WIDGET,
1161 XmNtopWidget, etDialog.hostW,
1162 XmNlabelString, s1=XmStringCreateSimple("User name (%u)"),
1163 XmNmnemonic, 'U', NULL);
1164 XtAddCallback(etDialog.nameW, XmNvalueChangedCallback, toggleUserCB, NULL);
1165 XmStringFree(s1);
1167 etDialog.serverW = XtVaCreateManagedWidget("server",
1168 xmToggleButtonWidgetClass, selectBox,
1169 XmNleftAttachment, XmATTACH_POSITION,
1170 XmNleftPosition, 50 + RADIO_INDENT,
1171 XmNtopAttachment, XmATTACH_WIDGET,
1172 XmNtopWidget, etDialog.nameW,
1173 XmNlabelString, s1=XmStringCreateSimple("NEdit server name (%s)"),
1174 XmNmnemonic, 's', NULL);
1175 XtAddCallback(etDialog.serverW, XmNvalueChangedCallback, toggleServerCB, NULL);
1176 XmStringFree(s1);
1178 formatLbl = XtVaCreateManagedWidget("formatLbl", xmLabelGadgetClass,
1179 selectForm,
1180 XmNlabelString, s1=XmStringCreateSimple("Format: "),
1181 XmNmnemonic, 'r',
1182 XmNleftAttachment, XmATTACH_POSITION,
1183 XmNleftPosition, LEFT_MARGIN_POS,
1184 XmNtopAttachment, XmATTACH_WIDGET,
1185 XmNtopWidget, selectBox,
1186 XmNbottomAttachment, XmATTACH_FORM, NULL);
1187 XmStringFree(s1);
1188 etDialog.formatW = XtVaCreateManagedWidget("format", xmTextWidgetClass,
1189 selectForm,
1190 XmNmaxLength, WINDOWTITLE_MAX_LEN,
1191 XmNtopAttachment, XmATTACH_WIDGET,
1192 XmNtopWidget, selectBox,
1193 XmNtopOffset, 5,
1194 XmNleftAttachment, XmATTACH_WIDGET,
1195 XmNleftWidget, formatLbl,
1196 XmNrightAttachment, XmATTACH_POSITION,
1197 XmNrightPosition, RIGHT_MARGIN_POS,
1198 XmNbottomAttachment, XmATTACH_FORM,
1199 XmNbottomOffset, 5, NULL);
1200 RemapDeleteKey(etDialog.formatW);
1201 XtVaSetValues(formatLbl, XmNuserData, etDialog.formatW, NULL);
1202 XtAddCallback(etDialog.formatW, XmNvalueChangedCallback, formatChangedCB, NULL);
1204 XtVaGetValues(etDialog.formatW, XmNheight, &textHeight, NULL);
1205 XtVaSetValues(formatLbl, XmNheight, textHeight, NULL);
1207 previewFrame = XtVaCreateManagedWidget("previewFrame", xmFrameWidgetClass,
1208 etDialog.form,
1209 XmNtopAttachment, XmATTACH_WIDGET,
1210 XmNtopWidget, selectFrame,
1211 XmNleftAttachment, XmATTACH_POSITION,
1212 XmNleftPosition, LEFT_MARGIN_POS,
1213 XmNrightAttachment, XmATTACH_POSITION,
1214 XmNrightPosition, RIGHT_MARGIN_POS, NULL);
1216 XtVaCreateManagedWidget("previewLabel", xmLabelGadgetClass,
1217 previewFrame,
1218 XmNlabelString, s1=XmStringCreateSimple("Preview"),
1219 XmNchildType, XmFRAME_TITLE_CHILD,
1220 XmNchildHorizontalAlignment, XmALIGNMENT_BEGINNING, NULL);
1221 XmStringFree(s1);
1223 previewForm = XtVaCreateManagedWidget("previewForm", xmFormWidgetClass,
1224 previewFrame,
1225 XmNleftAttachment, XmATTACH_FORM,
1226 XmNleftPosition, LEFT_MARGIN_POS,
1227 XmNtopAttachment, XmATTACH_FORM,
1228 XmNtopOffset, V_MARGIN,
1229 XmNrightAttachment, XmATTACH_FORM,
1230 XmNrightPosition, RIGHT_MARGIN_POS, NULL);
1232 /* Copy a variable width font from one of the labels to use for the
1233 preview (no editing is allowed, and with a fixed size font the
1234 preview easily gets partially obscured). Also copy the form background
1235 color to make it clear that this field is not editable */
1236 XtVaGetValues(formatLbl, XmNfontList, &fontList, NULL);
1237 XtVaGetValues(previewForm, XmNbackground, &background, NULL);
1239 etDialog.previewW = XtVaCreateManagedWidget("sample",
1240 xmTextFieldWidgetClass, previewForm,
1241 XmNeditable, False,
1242 XmNcursorPositionVisible, False,
1243 XmNtopAttachment, XmATTACH_FORM,
1244 XmNleftAttachment, XmATTACH_FORM,
1245 XmNleftOffset, V_MARGIN,
1246 XmNrightAttachment, XmATTACH_FORM,
1247 XmNrightOffset, V_MARGIN,
1248 XmNfontList, fontList,
1249 XmNbackground, background,
1250 NULL);
1252 previewBox = XtVaCreateManagedWidget("previewBox", xmFormWidgetClass,
1253 previewForm,
1254 XmNorientation, XmHORIZONTAL,
1255 XmNpacking, XmPACK_TIGHT,
1256 XmNradioBehavior, False,
1257 XmNleftAttachment, XmATTACH_FORM,
1258 XmNrightAttachment, XmATTACH_FORM,
1259 XmNtopAttachment, XmATTACH_WIDGET,
1260 XmNtopWidget, etDialog.previewW, NULL);
1262 testLbl = XtVaCreateManagedWidget("testLabel", xmLabelGadgetClass,
1263 previewBox,
1264 XmNlabelString, s1=XmStringCreateSimple("Test settings: "),
1265 XmNleftAttachment, XmATTACH_POSITION,
1266 XmNleftPosition, LEFT_MARGIN_POS,
1267 XmNtopOffset, 5,
1268 XmNbottomOffset, 5,
1269 XmNtopAttachment, XmATTACH_FORM, NULL);
1270 XmStringFree(s1);
1272 etDialog.oFileChangedW = XtVaCreateManagedWidget("fileChanged",
1273 xmToggleButtonWidgetClass, previewBox,
1274 XmNleftAttachment, XmATTACH_POSITION,
1275 XmNleftPosition, RADIO_INDENT,
1276 XmNtopAttachment, XmATTACH_WIDGET,
1277 XmNtopWidget, testLbl,
1278 XmNlabelString, s1=XmStringCreateSimple("File modified"),
1279 XmNmnemonic, 'o', NULL);
1280 XtAddCallback(etDialog.oFileChangedW, XmNvalueChangedCallback, fileChangedCB, NULL);
1281 XmStringFree(s1);
1283 etDialog.oFileReadOnlyW = XtVaCreateManagedWidget("fileReadOnly",
1284 xmToggleButtonWidgetClass, previewBox,
1285 XmNleftAttachment, XmATTACH_WIDGET,
1286 XmNleftWidget, etDialog.oFileChangedW,
1287 XmNtopAttachment, XmATTACH_WIDGET,
1288 XmNtopWidget, testLbl,
1289 XmNlabelString, s1=XmStringCreateSimple("File read only"),
1290 XmNmnemonic, 'n', NULL);
1291 XtAddCallback(etDialog.oFileReadOnlyW, XmNvalueChangedCallback, fileReadOnlyCB, NULL);
1292 XmStringFree(s1);
1294 etDialog.oFileLockedW = XtVaCreateManagedWidget("fileLocked",
1295 xmToggleButtonWidgetClass, previewBox,
1296 XmNleftAttachment, XmATTACH_WIDGET,
1297 XmNleftWidget, etDialog.oFileReadOnlyW,
1298 XmNtopAttachment, XmATTACH_WIDGET,
1299 XmNtopWidget, testLbl,
1300 XmNlabelString, s1=XmStringCreateSimple("File locked"),
1301 XmNmnemonic, 'l', NULL);
1302 XtAddCallback(etDialog.oFileLockedW, XmNvalueChangedCallback, fileLockedCB, NULL);
1303 XmStringFree(s1);
1305 etDialog.oServerNameW = XtVaCreateManagedWidget("servernameSet",
1306 xmToggleButtonWidgetClass, previewBox,
1307 XmNleftAttachment, XmATTACH_POSITION,
1308 XmNleftPosition, RADIO_INDENT,
1309 XmNtopAttachment, XmATTACH_WIDGET,
1310 XmNtopWidget, etDialog.oFileChangedW,
1311 XmNlabelString, s1=XmStringCreateSimple("Server name present"),
1312 XmNmnemonic, 'v', NULL);
1313 XtAddCallback(etDialog.oServerNameW, XmNvalueChangedCallback, serverNameCB, NULL);
1314 XmStringFree(s1);
1316 etDialog.oCcViewTagW = XtVaCreateManagedWidget("ccViewTagSet",
1317 xmToggleButtonWidgetClass, previewBox,
1318 XmNleftAttachment, XmATTACH_POSITION,
1319 XmNleftPosition, RADIO_INDENT,
1320 XmNtopAttachment, XmATTACH_WIDGET,
1321 XmNtopWidget, etDialog.oServerNameW,
1322 XmNlabelString, s1=XmStringCreateSimple("CC view tag present"),
1323 #ifdef VMS
1324 XmNset, False,
1325 #else
1326 XmNset, GetClearCaseViewTag() != NULL,
1327 #endif /* VMS */
1328 XmNmnemonic, 'w', NULL);
1329 #ifdef VMS
1330 XtSetSensitive(etDialog.oCcViewTagW, False);
1331 #else
1332 XtAddCallback(etDialog.oCcViewTagW, XmNvalueChangedCallback, ccViewTagCB, NULL);
1333 #endif /* VMS */
1334 XmStringFree(s1);
1336 etDialog.oServerEqualViewW = XtVaCreateManagedWidget("serverEqualView",
1337 xmToggleButtonWidgetClass, previewBox,
1338 XmNleftAttachment, XmATTACH_WIDGET,
1339 XmNleftWidget, etDialog.oCcViewTagW,
1340 XmNtopAttachment, XmATTACH_WIDGET,
1341 XmNtopWidget, etDialog.oServerNameW,
1342 XmNlabelString, s1=XmStringCreateSimple("Server name equals CC view tag "),
1343 XmNmnemonic, 'q', NULL);
1344 #ifdef VMS
1345 XtSetSensitive(etDialog.oServerEqualViewW, False);
1346 #else
1347 XtAddCallback(etDialog.oServerEqualViewW, XmNvalueChangedCallback, serverEqualViewCB, NULL);
1348 #endif /* VMS */
1349 XmStringFree(s1);
1351 etDialog.oDirW = XtVaCreateManagedWidget("pathSet",
1352 xmToggleButtonWidgetClass, previewBox,
1353 XmNleftAttachment, XmATTACH_POSITION,
1354 XmNleftPosition, RADIO_INDENT,
1355 XmNtopAttachment, XmATTACH_WIDGET,
1356 XmNtopWidget, etDialog.oCcViewTagW,
1357 XmNlabelString, s1=XmStringCreateSimple("Directory present"),
1358 XmNmnemonic, 'i', NULL);
1359 XtAddCallback(etDialog.oDirW, XmNvalueChangedCallback, formatChangedCB, NULL);
1360 XmStringFree(s1);
1362 /* Button box */
1363 buttonForm = XtVaCreateManagedWidget("buttonForm", xmFormWidgetClass,
1364 etDialog.form,
1365 XmNleftAttachment, XmATTACH_POSITION,
1366 XmNleftPosition, LEFT_MARGIN_POS,
1367 XmNtopAttachment, XmATTACH_WIDGET,
1368 XmNtopWidget, previewFrame,
1369 XmNtopOffset, V_MARGIN,
1370 XmNbottomOffset, V_MARGIN,
1371 XmNbottomAttachment, XmATTACH_FORM,
1372 XmNrightAttachment, XmATTACH_POSITION,
1373 XmNrightPosition, RIGHT_MARGIN_POS, NULL);
1375 applyBtn = XtVaCreateManagedWidget("apply", xmPushButtonWidgetClass,
1376 buttonForm,
1377 XmNhighlightThickness, 2,
1378 XmNlabelString, s1=XmStringCreateSimple("Apply"),
1379 XmNshowAsDefault, (short)1,
1380 XmNleftAttachment, XmATTACH_POSITION,
1381 XmNleftPosition, 6,
1382 XmNrightAttachment, XmATTACH_POSITION,
1383 XmNrightPosition, 25,
1384 XmNbottomAttachment, XmATTACH_FORM,
1385 NULL);
1386 XtAddCallback(applyBtn, XmNactivateCallback, applyCB, NULL);
1387 XmStringFree(s1);
1388 XtVaGetValues(applyBtn, XmNshadowThickness, &shadowThickness, NULL);
1389 defaultBtnOffset = shadowThickness + 4;
1391 closeBtn = XtVaCreateManagedWidget("close", xmPushButtonWidgetClass,
1392 buttonForm,
1393 XmNhighlightThickness, 2,
1394 XmNlabelString, s1=XmStringCreateSimple("Close"),
1395 XmNleftAttachment, XmATTACH_POSITION,
1396 XmNleftPosition, 52,
1397 XmNrightAttachment, XmATTACH_POSITION,
1398 XmNrightPosition, 71,
1399 XmNbottomAttachment, XmATTACH_FORM,
1400 XmNbottomOffset, defaultBtnOffset,
1401 NULL);
1402 XtAddCallback(closeBtn, XmNactivateCallback, closeCB, NULL);
1403 XmStringFree(s1);
1405 restoreBtn = XtVaCreateManagedWidget("restore", xmPushButtonWidgetClass,
1406 buttonForm,
1407 XmNhighlightThickness, 2,
1408 XmNlabelString, s1=XmStringCreateSimple("Default"),
1409 XmNleftAttachment, XmATTACH_POSITION,
1410 XmNleftPosition, 29,
1411 XmNrightAttachment, XmATTACH_POSITION,
1412 XmNrightPosition, 48,
1413 XmNbottomAttachment, XmATTACH_FORM,
1414 XmNbottomOffset, defaultBtnOffset,
1415 XmNmnemonic, 'e', NULL);
1416 XtAddCallback(restoreBtn, XmNactivateCallback, restoreCB, NULL);
1417 XmStringFree(s1);
1419 helpBtn = XtVaCreateManagedWidget("help", xmPushButtonWidgetClass,
1420 buttonForm,
1421 XmNhighlightThickness, 2,
1422 XmNlabelString, s1=XmStringCreateSimple("Help"),
1423 XmNleftAttachment, XmATTACH_POSITION,
1424 XmNleftPosition, 75,
1425 XmNrightAttachment, XmATTACH_POSITION,
1426 XmNrightPosition, 94,
1427 XmNbottomAttachment, XmATTACH_FORM,
1428 XmNbottomOffset, defaultBtnOffset,
1429 XmNmnemonic, 'p', NULL);
1430 XtAddCallback(helpBtn, XmNactivateCallback, helpCB, NULL);
1431 XmStringFree(s1);
1433 /* Set initial default button */
1434 XtVaSetValues(etDialog.form, XmNdefaultButton, applyBtn, NULL);
1435 XtVaSetValues(etDialog.form, XmNcancelButton, closeBtn, NULL);
1437 /* Handle mnemonic selection of buttons and focus to dialog */
1438 AddDialogMnemonicHandler(etDialog.form, FALSE);
1440 etDialog.suppressFormatUpdate = FALSE;
1443 void EditCustomTitleFormat(WindowInfo *window)
1445 /* copy attributes from current window so that we can use as many
1446 * 'real world' defaults as possible when testing the effect
1447 * of different formatting strings.
1449 strcpy(etDialog.path, window->path);
1450 strcpy(etDialog.filename, window->filename);
1451 #ifndef VMS
1452 strcpy(etDialog.viewTag, GetClearCaseViewTag() != NULL ?
1453 GetClearCaseViewTag() :
1454 "viewtag");
1455 #endif /* VMS */
1456 strcpy(etDialog.serverName, IsServer ?
1457 GetPrefServerName() :
1458 "servername");
1459 etDialog.isServer = IsServer;
1460 etDialog.filenameSet = window->filenameSet;
1461 etDialog.lockReasons = window->lockReasons;
1462 etDialog.fileChanged = window->fileChanged;
1464 if (etDialog.window != window && etDialog.form)
1466 /* Destroy the dialog owned by the other window.
1467 Note: don't rely on the destroy event handler to reset the
1468 form. Events are handled asynchronously, so the old dialog
1469 may continue to live for a while. */
1470 XtDestroyWidget(etDialog.form);
1471 etDialog.form = NULL;
1474 etDialog.window = window;
1476 /* Create the dialog if it doesn't already exist */
1477 if (etDialog.form == NULL)
1479 createEditTitleDialog(window->shell);
1481 else
1483 /* If the window is already up, just pop it to the top */
1484 if (XtIsManaged(etDialog.form)) {
1486 RaiseDialogWindow(XtParent(etDialog.form));
1488 /* force update of the dialog */
1489 setToggleButtons();
1490 formatChangedCB(0, 0, 0);
1491 return;
1495 /* set initial value of format field */
1496 XmTextSetString(etDialog.formatW, (char *)GetPrefTitleFormat());
1498 /* force update of the dialog */
1499 setToggleButtons();
1500 formatChangedCB(0, 0, 0);
1502 /* put up dialog and wait for user to press ok or cancel */
1503 ManageDialogCenteredOnPointer(etDialog.form);