Fix text typo
[nedit.git] / source / windowTitle.c
blob89f3b41bd334960788f436af54291964a9dd42d7
1 static const char CVSID[] = "$Id: windowTitle.c,v 1.16 2007/12/31 11:12:44 yooden 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 && etDialog.isServer
512 && GetPrefServerName()[0] != '\0'
513 && strcmp(GetClearCaseViewTag(), GetPrefServerName()) == 0) {
514 XmToggleButtonSetState(etDialog.oServerEqualViewW, True, False);
515 } else {
516 XmToggleButtonSetState(etDialog.oServerEqualViewW, False, False);
518 #endif /* VMS */
521 static void formatChangedCB(Widget w, XtPointer clientData, XtPointer callData)
523 char *format;
524 int filenameSet = XmToggleButtonGetState(etDialog.oDirW);
525 char *title;
526 const char* serverName;
528 if (etDialog.suppressFormatUpdate)
530 return; /* Prevent recursive feedback */
533 format = XmTextGetString(etDialog.formatW);
535 #ifndef VMS
536 if (XmToggleButtonGetState(etDialog.oServerEqualViewW) &&
537 XmToggleButtonGetState(etDialog.ccW)) {
538 serverName = etDialog.viewTag;
539 } else
540 #endif /* VMS */
542 serverName = XmToggleButtonGetState(etDialog.oServerNameW) ?
543 etDialog.serverName : "";
546 title = FormatWindowTitle(
547 etDialog.filename,
548 etDialog.filenameSet == True ?
549 etDialog.path :
550 "/a/very/long/path/used/as/example/",
551 #ifdef VMS
552 NULL,
553 #else
554 XmToggleButtonGetState(etDialog.oCcViewTagW) ?
555 etDialog.viewTag : NULL,
556 #endif /* VMS */
557 serverName,
558 etDialog.isServer,
559 filenameSet,
560 etDialog.lockReasons,
561 XmToggleButtonGetState(etDialog.oFileChangedW),
562 format);
563 XtFree(format);
564 XmTextFieldSetString(etDialog.previewW, title);
567 #ifndef VMS
568 static void ccViewTagCB(Widget w, XtPointer clientData, XtPointer callData)
570 if (XmToggleButtonGetState(w) == False) {
571 XmToggleButtonSetState(etDialog.oServerEqualViewW, False, False);
573 formatChangedCB(w, clientData, callData);
575 #endif /* VMS */
577 static void serverNameCB(Widget w, XtPointer clientData, XtPointer callData)
579 if (XmToggleButtonGetState(w) == False) {
580 XmToggleButtonSetState(etDialog.oServerEqualViewW, False, False);
582 etDialog.isServer = XmToggleButtonGetState(w);
583 formatChangedCB(w, clientData, callData);
586 static void fileChangedCB(Widget w, XtPointer clientData, XtPointer callData)
588 etDialog.fileChanged = XmToggleButtonGetState(w);
589 formatChangedCB(w, clientData, callData);
592 static void fileLockedCB(Widget w, XtPointer clientData, XtPointer callData)
594 SET_USER_LOCKED(etDialog.lockReasons, XmToggleButtonGetState(w));
595 formatChangedCB(w, clientData, callData);
598 static void fileReadOnlyCB(Widget w, XtPointer clientData, XtPointer callData)
600 SET_PERM_LOCKED(etDialog.lockReasons, XmToggleButtonGetState(w));
601 formatChangedCB(w, clientData, callData);
604 #ifndef VMS
605 static void serverEqualViewCB(Widget w, XtPointer clientData, XtPointer callData)
607 if (XmToggleButtonGetState(w) == True) {
608 XmToggleButtonSetState(etDialog.oCcViewTagW, True, False);
609 XmToggleButtonSetState(etDialog.oServerNameW, True, False);
610 etDialog.isServer = True;
612 formatChangedCB(w, clientData, callData);
614 #endif /* VMS */
616 static void applyCB(Widget w, XtPointer clientData, XtPointer callData)
618 char *format = XmTextGetString(etDialog.formatW);
620 /* pop down the dialog */
621 /* XtUnmanageChild(etDialog.form); */
623 if (strcmp(format, GetPrefTitleFormat()) != 0) {
624 SetPrefTitleFormat(format);
626 XtFree(format);
629 static void closeCB(Widget w, XtPointer clientData, XtPointer callData)
631 /* pop down the dialog */
632 XtUnmanageChild(etDialog.form);
635 static void restoreCB(Widget w, XtPointer clientData, XtPointer callData)
637 XmTextSetString(etDialog.formatW, "{%c} [%s] %f (%S) - %d");
640 static void helpCB(Widget w, XtPointer clientData, XtPointer callData)
642 Help(HELP_CUSTOM_TITLE_DIALOG);
645 static void wtDestroyCB(Widget w, XtPointer clientData, XtPointer callData)
647 if (w == etDialog.form) /* Prevent disconnecting the replacing dialog */
648 etDialog.form = NULL;
651 static void wtUnmapCB(Widget w, XtPointer clientData, XtPointer callData)
653 if (etDialog.form == w) /* Prevent destroying the replacing dialog */
654 XtDestroyWidget(etDialog.form);
657 static void appendToFormat(const char* string)
659 char *format = XmTextGetString(etDialog.formatW);
660 char *buf = XtMalloc(strlen(string) + strlen(format) + 1);
661 strcpy(buf, format);
662 strcat(buf, string);
663 XmTextSetString(etDialog.formatW, buf);
664 XtFree(format);
665 XtFree(buf);
668 static void removeFromFormat(const char* string)
670 char *format = XmTextGetString(etDialog.formatW);
671 char* pos;
673 /* There can be multiple occurences */
674 while ((pos = strstr(format, string)))
676 /* If the string is preceded or followed by a brace, include
677 the brace(s) for removal */
678 char* start = pos;
679 char* end = pos + strlen(string);
680 char post = *end;
682 if (post == '}' || post == ')' || post == ']' || post == '>')
684 end += 1;
685 post = *end;
688 if (start > format)
690 char pre = *(start-1);
691 if (pre == '{' || pre == '(' || pre == '[' || pre == '<')
692 start -= 1;
694 if (start > format)
696 char pre = *(start-1);
697 /* If there is a space in front and behind, remove one space
698 (there can be more spaces, but in that case it is likely
699 that the user entered them manually); also remove trailing
700 space */
701 if (pre == ' ' && post == ' ')
703 end += 1;
705 else if (pre == ' ' && post == (char)0)
707 /* Remove (1) trailing space */
708 start -= 1;
712 /* Contract the string: move end to start */
713 strcpy(start, end);
716 /* Remove leading and trailing space */
717 pos = format;
718 while (*pos == ' ') ++pos;
719 strcpy(format, pos);
721 pos = format + strlen(format) - 1;
722 while (pos >= format && *pos == ' ')
724 --pos;
726 *(pos+1) = (char)0;
728 XmTextSetString(etDialog.formatW, format);
729 XtFree(format);
733 static void toggleFileCB(Widget w, XtPointer clientData, XtPointer callData)
735 if (XmToggleButtonGetState(etDialog.fileW))
736 appendToFormat(" %f");
737 else
738 removeFromFormat("%f");
741 static void toggleServerCB(Widget w, XtPointer clientData, XtPointer callData)
743 if (XmToggleButtonGetState(etDialog.serverW))
744 appendToFormat(" [%s]");
745 else
746 removeFromFormat("%s");
749 static void toggleHostCB(Widget w, XtPointer clientData, XtPointer callData)
751 if (XmToggleButtonGetState(etDialog.hostW))
752 appendToFormat(" [%h]");
753 else
754 removeFromFormat("%h");
757 #ifndef VMS
758 static void toggleClearCaseCB(Widget w, XtPointer clientData, XtPointer callData)
760 if (XmToggleButtonGetState(etDialog.ccW))
761 appendToFormat(" {%c}");
762 else
763 removeFromFormat("%c");
765 #endif /* VMS */
767 static void toggleStatusCB(Widget w, XtPointer clientData, XtPointer callData)
769 if (XmToggleButtonGetState(etDialog.statusW))
771 if (XmToggleButtonGetState(etDialog.shortStatusW))
772 appendToFormat(" (%*S)");
773 else
774 appendToFormat(" (%S)");
776 else
778 removeFromFormat("%S");
779 removeFromFormat("%*S");
783 static void toggleShortStatusCB(Widget w, XtPointer clientData, XtPointer callData)
785 char *format, *pos;
787 if (etDialog.suppressFormatUpdate)
789 return;
792 format = XmTextGetString(etDialog.formatW);
794 if (XmToggleButtonGetState(etDialog.shortStatusW))
796 /* Find all %S occurrences and replace them by %*S */
799 pos = strstr(format, "%S");
800 if (pos)
802 char* tmp = (char*)XtMalloc((strlen(format)+2)*sizeof(char));
803 strncpy(tmp, format, (size_t)(pos-format+1));
804 tmp[pos-format+1] = 0;
805 strcat(tmp, "*");
806 strcat(tmp, pos+1);
807 XtFree(format);
808 format = tmp;
811 while (pos);
813 else
815 /* Replace all %*S occurences by %S */
818 pos = strstr(format, "%*S");
819 if (pos)
821 strcpy(pos+1, pos+2);
824 while(pos);
827 XmTextSetString(etDialog.formatW, format);
828 XtFree(format);
831 static void toggleUserCB(Widget w, XtPointer clientData, XtPointer callData)
833 if (XmToggleButtonGetState(etDialog.nameW))
834 appendToFormat(" %u");
835 else
836 removeFromFormat("%u");
839 static void toggleDirectoryCB(Widget w, XtPointer clientData, XtPointer callData)
841 if (XmToggleButtonGetState(etDialog.dirW))
843 char buf[20];
844 int maxComp;
845 char *value = XmTextGetString(etDialog.ndirW);
846 if (*value)
848 if (sscanf(value, "%d", &maxComp) > 0)
850 sprintf(&buf[0], " %%%dd ", maxComp);
852 else
854 sprintf(&buf[0], " %%d "); /* Should not be necessary */
857 else
859 sprintf(&buf[0], " %%d ");
861 XtFree(value);
862 appendToFormat(buf);
864 else
866 int i;
867 removeFromFormat("%d");
868 for (i=0; i<=9; ++i)
870 char buf[20];
871 sprintf(&buf[0], "%%%dd", i);
872 removeFromFormat(buf);
877 static void enterMaxDirCB(Widget w, XtPointer clientData, XtPointer callData)
879 int maxComp = -1;
880 char *format;
881 char *value;
883 if (etDialog.suppressFormatUpdate)
885 return;
888 format = XmTextGetString(etDialog.formatW);
889 value = XmTextGetString(etDialog.ndirW);
891 if (*value)
893 if (sscanf(value, "%d", &maxComp) <= 0)
895 /* Don't allow non-digits to be entered */
896 XBell(XtDisplay(w), 0);
897 XmTextSetString(etDialog.ndirW, "");
901 if (maxComp >= 0)
903 char *pos;
904 int found = False;
905 char insert[2];
906 insert[0] = (char)('0' + maxComp);
907 insert[1] = (char)0; /* '0' digit and 0 char ! */
909 /* Find all %d and %nd occurrences and replace them by the new value */
912 int i;
913 found = False;
914 pos = strstr(format, "%d");
915 if (pos)
917 char* tmp = (char*)XtMalloc((strlen(format)+2)*sizeof(char));
918 strncpy(tmp, format, (size_t)(pos-format+1));
919 tmp[pos-format+1] = 0;
920 strcat(tmp, &insert[0]);
921 strcat(tmp, pos+1);
922 XtFree(format);
923 format = tmp;
924 found = True;
927 for (i=0; i<=9; ++i)
929 char buf[20];
930 sprintf(&buf[0], "%%%dd", i);
931 if (i != maxComp)
933 pos = strstr(format, &buf[0]);
934 if (pos)
936 *(pos+1) = insert[0];
937 found = True;
942 while (found);
944 else
946 int found = True;
948 /* Replace all %nd occurences by %d */
951 int i;
952 found = False;
953 for (i=0; i<=9; ++i)
955 char buf[20];
956 char *pos;
957 sprintf(&buf[0], "%%%dd", i);
958 pos = strstr(format, &buf[0]);
959 if (pos)
961 strcpy(pos+1, pos+2);
962 found = True;
966 while(found);
969 XmTextSetString(etDialog.formatW, format);
970 XtFree(format);
971 XtFree(value);
974 static void createEditTitleDialog(Widget parent)
976 #define LEFT_MARGIN_POS 2
977 #define RIGHT_MARGIN_POS 98
978 #define V_MARGIN 5
979 #define RADIO_INDENT 3
981 Widget buttonForm, formatLbl, previewFrame;
982 Widget previewForm, previewBox, selectFrame, selectBox, selectForm;
983 Widget testLbl, selectLbl;
984 Widget applyBtn, closeBtn, restoreBtn, helpBtn;
985 XmString s1;
986 XmFontList fontList;
987 Arg args[20];
988 int defaultBtnOffset;
989 Dimension shadowThickness;
990 Dimension radioHeight, textHeight;
991 Pixel background;
993 int ac = 0;
994 XtSetArg(args[ac], XmNautoUnmanage, False); ac++;
995 XtSetArg(args[ac], XmNtitle, "Customize Window Title"); ac++;
996 etDialog.form = CreateFormDialog(parent, "customizeTitle", args, ac);
999 * Destroy the dialog every time it is unmapped (otherwise it 'sticks'
1000 * to the window for which it was created originally).
1002 XtAddCallback(etDialog.form, XmNunmapCallback, wtUnmapCB, NULL);
1003 XtAddCallback(etDialog.form, XmNdestroyCallback, wtDestroyCB, NULL);
1005 etDialog.shell = XtParent(etDialog.form);
1007 /* Definition form */
1008 selectFrame = XtVaCreateManagedWidget("selectionFrame", xmFrameWidgetClass,
1009 etDialog.form,
1010 XmNleftAttachment, XmATTACH_POSITION,
1011 XmNleftPosition, LEFT_MARGIN_POS,
1012 XmNtopAttachment, XmATTACH_FORM,
1013 XmNtopOffset, V_MARGIN,
1014 XmNrightAttachment, XmATTACH_POSITION,
1015 XmNrightPosition, RIGHT_MARGIN_POS, NULL);
1017 XtVaCreateManagedWidget("titleLabel", xmLabelGadgetClass,
1018 selectFrame,
1019 XmNlabelString,
1020 s1=XmStringCreateSimple("Title definition"),
1021 XmNchildType, XmFRAME_TITLE_CHILD,
1022 XmNchildHorizontalAlignment, XmALIGNMENT_BEGINNING, NULL);
1023 XmStringFree(s1);
1025 selectForm = XtVaCreateManagedWidget("selectForm", xmFormWidgetClass,
1026 selectFrame ,
1027 XmNleftAttachment, XmATTACH_POSITION,
1028 XmNleftPosition, LEFT_MARGIN_POS,
1029 XmNtopAttachment, XmATTACH_FORM,
1030 XmNtopOffset, V_MARGIN,
1031 XmNrightAttachment, XmATTACH_POSITION,
1032 XmNrightPosition, RIGHT_MARGIN_POS, NULL);
1034 selectLbl = XtVaCreateManagedWidget("selectLabel", xmLabelGadgetClass,
1035 selectForm,
1036 XmNlabelString, s1=XmStringCreateSimple("Select title components to include: "),
1037 XmNleftAttachment, XmATTACH_POSITION,
1038 XmNleftPosition, LEFT_MARGIN_POS,
1039 XmNtopOffset, 5,
1040 XmNbottomOffset, 5,
1041 XmNtopAttachment, XmATTACH_FORM, NULL);
1042 XmStringFree(s1);
1044 selectBox = XtVaCreateManagedWidget("selectBox", xmFormWidgetClass,
1045 selectForm,
1046 XmNorientation, XmHORIZONTAL,
1047 XmNpacking, XmPACK_TIGHT,
1048 XmNradioBehavior, False,
1049 XmNleftAttachment, XmATTACH_FORM,
1050 XmNrightAttachment, XmATTACH_FORM,
1051 XmNtopOffset, 5,
1052 XmNtopAttachment, XmATTACH_WIDGET,
1053 XmNtopWidget, selectLbl,
1054 NULL);
1056 etDialog.fileW = XtVaCreateManagedWidget("file",
1057 xmToggleButtonWidgetClass, selectBox,
1058 XmNleftAttachment, XmATTACH_POSITION,
1059 XmNleftPosition, RADIO_INDENT,
1060 XmNtopAttachment, XmATTACH_FORM,
1061 XmNlabelString, s1=XmStringCreateSimple("File name (%f)"),
1062 XmNmnemonic, 'F', NULL);
1063 XtAddCallback(etDialog.fileW, XmNvalueChangedCallback, toggleFileCB, NULL);
1064 XmStringFree(s1);
1066 etDialog.statusW = XtVaCreateManagedWidget("status",
1067 xmToggleButtonWidgetClass, selectBox,
1068 XmNleftAttachment, XmATTACH_POSITION,
1069 XmNleftPosition, RADIO_INDENT,
1070 XmNtopAttachment, XmATTACH_WIDGET,
1071 XmNtopWidget, etDialog.fileW,
1072 XmNlabelString, s1=XmStringCreateSimple("File status (%S) "),
1073 XmNmnemonic, 't', NULL);
1074 XtAddCallback(etDialog.statusW, XmNvalueChangedCallback, toggleStatusCB, NULL);
1075 XmStringFree(s1);
1077 etDialog.shortStatusW = XtVaCreateManagedWidget("shortStatus",
1078 xmToggleButtonWidgetClass, selectBox,
1079 XmNleftAttachment, XmATTACH_WIDGET,
1080 XmNleftWidget, etDialog.statusW,
1081 XmNtopAttachment, XmATTACH_WIDGET,
1082 XmNtopWidget, etDialog.fileW,
1083 XmNlabelString, s1=XmStringCreateSimple("brief"),
1084 XmNmnemonic, 'b', NULL);
1085 XtAddCallback(etDialog.shortStatusW, XmNvalueChangedCallback, toggleShortStatusCB, NULL);
1086 XmStringFree(s1);
1088 etDialog.ccW = XtVaCreateManagedWidget("ccView",
1089 xmToggleButtonWidgetClass, selectBox,
1090 XmNleftAttachment, XmATTACH_POSITION,
1091 XmNleftPosition, RADIO_INDENT,
1092 XmNtopAttachment, XmATTACH_WIDGET,
1093 XmNtopWidget, etDialog.statusW,
1094 XmNlabelString, s1=XmStringCreateSimple("ClearCase view tag (%c) "),
1095 XmNmnemonic, 'C', NULL);
1096 #ifdef VMS
1097 XtSetSensitive(etDialog.ccW, False);
1098 #else
1099 XtAddCallback(etDialog.ccW, XmNvalueChangedCallback, toggleClearCaseCB, NULL);
1100 #endif /* VMS */
1101 XmStringFree(s1);
1103 etDialog.dirW = XtVaCreateManagedWidget("directory",
1104 xmToggleButtonWidgetClass, selectBox,
1105 XmNleftAttachment, XmATTACH_POSITION,
1106 XmNleftPosition, RADIO_INDENT,
1107 XmNtopAttachment, XmATTACH_WIDGET,
1108 XmNtopWidget, etDialog.ccW,
1109 XmNlabelString, s1=XmStringCreateSimple("Directory (%d),"),
1110 XmNmnemonic, 'D', NULL);
1111 XtAddCallback(etDialog.dirW, XmNvalueChangedCallback, toggleDirectoryCB, NULL);
1112 XmStringFree(s1);
1114 XtVaGetValues(etDialog.fileW, XmNheight, &radioHeight, NULL);
1115 etDialog.mdirW = XtVaCreateManagedWidget("componentLab",
1116 xmLabelGadgetClass, selectBox,
1117 XmNheight, radioHeight,
1118 XmNleftAttachment, XmATTACH_WIDGET,
1119 XmNleftWidget, etDialog.dirW,
1120 XmNtopAttachment, XmATTACH_WIDGET,
1121 XmNtopWidget, etDialog.ccW,
1122 XmNlabelString, s1=XmStringCreateSimple("max. components: "),
1123 XmNmnemonic, 'x', NULL);
1124 XmStringFree(s1);
1126 etDialog.ndirW = XtVaCreateManagedWidget("dircomp",
1127 xmTextWidgetClass, selectBox,
1128 XmNcolumns, 1,
1129 XmNmaxLength, 1,
1130 XmNleftAttachment, XmATTACH_WIDGET,
1131 XmNleftWidget, etDialog.mdirW,
1132 XmNtopAttachment, XmATTACH_WIDGET,
1133 XmNtopWidget, etDialog.ccW,
1134 NULL);
1135 XtAddCallback(etDialog.ndirW, XmNvalueChangedCallback, enterMaxDirCB, NULL);
1136 RemapDeleteKey(etDialog.ndirW);
1137 XtVaSetValues(etDialog.mdirW, XmNuserData, etDialog.ndirW, NULL); /* mnemonic processing */
1139 XtVaGetValues(etDialog.ndirW, XmNheight, &textHeight, NULL);
1140 XtVaSetValues(etDialog.dirW, XmNheight, textHeight, NULL);
1141 XtVaSetValues(etDialog.mdirW, XmNheight, textHeight, NULL);
1143 etDialog.hostW = XtVaCreateManagedWidget("host",
1144 xmToggleButtonWidgetClass, selectBox,
1145 XmNleftAttachment, XmATTACH_POSITION,
1146 XmNleftPosition, 50 + RADIO_INDENT,
1147 XmNtopAttachment, XmATTACH_FORM,
1148 XmNlabelString, s1=XmStringCreateSimple("Host name (%h)"),
1149 XmNmnemonic, 'H', NULL);
1150 XtAddCallback(etDialog.hostW, XmNvalueChangedCallback, toggleHostCB, NULL);
1151 XmStringFree(s1);
1153 etDialog.nameW = XtVaCreateManagedWidget("name",
1154 xmToggleButtonWidgetClass, selectBox,
1155 XmNleftAttachment, XmATTACH_POSITION,
1156 XmNleftPosition, 50 + RADIO_INDENT,
1157 XmNtopAttachment, XmATTACH_WIDGET,
1158 XmNtopWidget, etDialog.hostW,
1159 XmNlabelString, s1=XmStringCreateSimple("User name (%u)"),
1160 XmNmnemonic, 'U', NULL);
1161 XtAddCallback(etDialog.nameW, XmNvalueChangedCallback, toggleUserCB, NULL);
1162 XmStringFree(s1);
1164 etDialog.serverW = XtVaCreateManagedWidget("server",
1165 xmToggleButtonWidgetClass, selectBox,
1166 XmNleftAttachment, XmATTACH_POSITION,
1167 XmNleftPosition, 50 + RADIO_INDENT,
1168 XmNtopAttachment, XmATTACH_WIDGET,
1169 XmNtopWidget, etDialog.nameW,
1170 XmNlabelString, s1=XmStringCreateSimple("NEdit server name (%s)"),
1171 XmNmnemonic, 's', NULL);
1172 XtAddCallback(etDialog.serverW, XmNvalueChangedCallback, toggleServerCB, NULL);
1173 XmStringFree(s1);
1175 formatLbl = XtVaCreateManagedWidget("formatLbl", xmLabelGadgetClass,
1176 selectForm,
1177 XmNlabelString, s1=XmStringCreateSimple("Format: "),
1178 XmNmnemonic, 'r',
1179 XmNleftAttachment, XmATTACH_POSITION,
1180 XmNleftPosition, LEFT_MARGIN_POS,
1181 XmNtopAttachment, XmATTACH_WIDGET,
1182 XmNtopWidget, selectBox,
1183 XmNbottomAttachment, XmATTACH_FORM, NULL);
1184 XmStringFree(s1);
1185 etDialog.formatW = XtVaCreateManagedWidget("format", xmTextWidgetClass,
1186 selectForm,
1187 XmNmaxLength, WINDOWTITLE_MAX_LEN,
1188 XmNtopAttachment, XmATTACH_WIDGET,
1189 XmNtopWidget, selectBox,
1190 XmNtopOffset, 5,
1191 XmNleftAttachment, XmATTACH_WIDGET,
1192 XmNleftWidget, formatLbl,
1193 XmNrightAttachment, XmATTACH_POSITION,
1194 XmNrightPosition, RIGHT_MARGIN_POS,
1195 XmNbottomAttachment, XmATTACH_FORM,
1196 XmNbottomOffset, 5, NULL);
1197 RemapDeleteKey(etDialog.formatW);
1198 XtVaSetValues(formatLbl, XmNuserData, etDialog.formatW, NULL);
1199 XtAddCallback(etDialog.formatW, XmNvalueChangedCallback, formatChangedCB, NULL);
1201 XtVaGetValues(etDialog.formatW, XmNheight, &textHeight, NULL);
1202 XtVaSetValues(formatLbl, XmNheight, textHeight, NULL);
1204 previewFrame = XtVaCreateManagedWidget("previewFrame", xmFrameWidgetClass,
1205 etDialog.form,
1206 XmNtopAttachment, XmATTACH_WIDGET,
1207 XmNtopWidget, selectFrame,
1208 XmNleftAttachment, XmATTACH_POSITION,
1209 XmNleftPosition, LEFT_MARGIN_POS,
1210 XmNrightAttachment, XmATTACH_POSITION,
1211 XmNrightPosition, RIGHT_MARGIN_POS, NULL);
1213 XtVaCreateManagedWidget("previewLabel", xmLabelGadgetClass,
1214 previewFrame,
1215 XmNlabelString, s1=XmStringCreateSimple("Preview"),
1216 XmNchildType, XmFRAME_TITLE_CHILD,
1217 XmNchildHorizontalAlignment, XmALIGNMENT_BEGINNING, NULL);
1218 XmStringFree(s1);
1220 previewForm = XtVaCreateManagedWidget("previewForm", xmFormWidgetClass,
1221 previewFrame,
1222 XmNleftAttachment, XmATTACH_FORM,
1223 XmNleftPosition, LEFT_MARGIN_POS,
1224 XmNtopAttachment, XmATTACH_FORM,
1225 XmNtopOffset, V_MARGIN,
1226 XmNrightAttachment, XmATTACH_FORM,
1227 XmNrightPosition, RIGHT_MARGIN_POS, NULL);
1229 /* Copy a variable width font from one of the labels to use for the
1230 preview (no editing is allowed, and with a fixed size font the
1231 preview easily gets partially obscured). Also copy the form background
1232 color to make it clear that this field is not editable */
1233 XtVaGetValues(formatLbl, XmNfontList, &fontList, NULL);
1234 XtVaGetValues(previewForm, XmNbackground, &background, NULL);
1236 etDialog.previewW = XtVaCreateManagedWidget("sample",
1237 xmTextFieldWidgetClass, previewForm,
1238 XmNeditable, False,
1239 XmNcursorPositionVisible, False,
1240 XmNtopAttachment, XmATTACH_FORM,
1241 XmNleftAttachment, XmATTACH_FORM,
1242 XmNleftOffset, V_MARGIN,
1243 XmNrightAttachment, XmATTACH_FORM,
1244 XmNrightOffset, V_MARGIN,
1245 XmNfontList, fontList,
1246 XmNbackground, background,
1247 NULL);
1249 previewBox = XtVaCreateManagedWidget("previewBox", xmFormWidgetClass,
1250 previewForm,
1251 XmNorientation, XmHORIZONTAL,
1252 XmNpacking, XmPACK_TIGHT,
1253 XmNradioBehavior, False,
1254 XmNleftAttachment, XmATTACH_FORM,
1255 XmNrightAttachment, XmATTACH_FORM,
1256 XmNtopAttachment, XmATTACH_WIDGET,
1257 XmNtopWidget, etDialog.previewW, NULL);
1259 testLbl = XtVaCreateManagedWidget("testLabel", xmLabelGadgetClass,
1260 previewBox,
1261 XmNlabelString, s1=XmStringCreateSimple("Test settings: "),
1262 XmNleftAttachment, XmATTACH_POSITION,
1263 XmNleftPosition, LEFT_MARGIN_POS,
1264 XmNtopOffset, 5,
1265 XmNbottomOffset, 5,
1266 XmNtopAttachment, XmATTACH_FORM, NULL);
1267 XmStringFree(s1);
1269 etDialog.oFileChangedW = XtVaCreateManagedWidget("fileChanged",
1270 xmToggleButtonWidgetClass, previewBox,
1271 XmNleftAttachment, XmATTACH_POSITION,
1272 XmNleftPosition, RADIO_INDENT,
1273 XmNtopAttachment, XmATTACH_WIDGET,
1274 XmNtopWidget, testLbl,
1275 XmNlabelString, s1=XmStringCreateSimple("File modified"),
1276 XmNmnemonic, 'o', NULL);
1277 XtAddCallback(etDialog.oFileChangedW, XmNvalueChangedCallback, fileChangedCB, NULL);
1278 XmStringFree(s1);
1280 etDialog.oFileReadOnlyW = XtVaCreateManagedWidget("fileReadOnly",
1281 xmToggleButtonWidgetClass, previewBox,
1282 XmNleftAttachment, XmATTACH_WIDGET,
1283 XmNleftWidget, etDialog.oFileChangedW,
1284 XmNtopAttachment, XmATTACH_WIDGET,
1285 XmNtopWidget, testLbl,
1286 XmNlabelString, s1=XmStringCreateSimple("File read only"),
1287 XmNmnemonic, 'n', NULL);
1288 XtAddCallback(etDialog.oFileReadOnlyW, XmNvalueChangedCallback, fileReadOnlyCB, NULL);
1289 XmStringFree(s1);
1291 etDialog.oFileLockedW = XtVaCreateManagedWidget("fileLocked",
1292 xmToggleButtonWidgetClass, previewBox,
1293 XmNleftAttachment, XmATTACH_WIDGET,
1294 XmNleftWidget, etDialog.oFileReadOnlyW,
1295 XmNtopAttachment, XmATTACH_WIDGET,
1296 XmNtopWidget, testLbl,
1297 XmNlabelString, s1=XmStringCreateSimple("File locked"),
1298 XmNmnemonic, 'l', NULL);
1299 XtAddCallback(etDialog.oFileLockedW, XmNvalueChangedCallback, fileLockedCB, NULL);
1300 XmStringFree(s1);
1302 etDialog.oServerNameW = XtVaCreateManagedWidget("servernameSet",
1303 xmToggleButtonWidgetClass, previewBox,
1304 XmNleftAttachment, XmATTACH_POSITION,
1305 XmNleftPosition, RADIO_INDENT,
1306 XmNtopAttachment, XmATTACH_WIDGET,
1307 XmNtopWidget, etDialog.oFileChangedW,
1308 XmNlabelString, s1=XmStringCreateSimple("Server name present"),
1309 XmNmnemonic, 'v', NULL);
1310 XtAddCallback(etDialog.oServerNameW, XmNvalueChangedCallback, serverNameCB, NULL);
1311 XmStringFree(s1);
1313 etDialog.oCcViewTagW = XtVaCreateManagedWidget("ccViewTagSet",
1314 xmToggleButtonWidgetClass, previewBox,
1315 XmNleftAttachment, XmATTACH_POSITION,
1316 XmNleftPosition, RADIO_INDENT,
1317 XmNtopAttachment, XmATTACH_WIDGET,
1318 XmNtopWidget, etDialog.oServerNameW,
1319 XmNlabelString, s1=XmStringCreateSimple("CC view tag present"),
1320 #ifdef VMS
1321 XmNset, False,
1322 #else
1323 XmNset, GetClearCaseViewTag() != NULL,
1324 #endif /* VMS */
1325 XmNmnemonic, 'w', NULL);
1326 #ifdef VMS
1327 XtSetSensitive(etDialog.oCcViewTagW, False);
1328 #else
1329 XtAddCallback(etDialog.oCcViewTagW, XmNvalueChangedCallback, ccViewTagCB, NULL);
1330 #endif /* VMS */
1331 XmStringFree(s1);
1333 etDialog.oServerEqualViewW = XtVaCreateManagedWidget("serverEqualView",
1334 xmToggleButtonWidgetClass, previewBox,
1335 XmNleftAttachment, XmATTACH_WIDGET,
1336 XmNleftWidget, etDialog.oCcViewTagW,
1337 XmNtopAttachment, XmATTACH_WIDGET,
1338 XmNtopWidget, etDialog.oServerNameW,
1339 XmNlabelString, s1=XmStringCreateSimple("Server name equals CC view tag "),
1340 XmNmnemonic, 'q', NULL);
1341 #ifdef VMS
1342 XtSetSensitive(etDialog.oServerEqualViewW, False);
1343 #else
1344 XtAddCallback(etDialog.oServerEqualViewW, XmNvalueChangedCallback, serverEqualViewCB, NULL);
1345 #endif /* VMS */
1346 XmStringFree(s1);
1348 etDialog.oDirW = XtVaCreateManagedWidget("pathSet",
1349 xmToggleButtonWidgetClass, previewBox,
1350 XmNleftAttachment, XmATTACH_POSITION,
1351 XmNleftPosition, RADIO_INDENT,
1352 XmNtopAttachment, XmATTACH_WIDGET,
1353 XmNtopWidget, etDialog.oCcViewTagW,
1354 XmNlabelString, s1=XmStringCreateSimple("Directory present"),
1355 XmNmnemonic, 'i', NULL);
1356 XtAddCallback(etDialog.oDirW, XmNvalueChangedCallback, formatChangedCB, NULL);
1357 XmStringFree(s1);
1359 /* Button box */
1360 buttonForm = XtVaCreateManagedWidget("buttonForm", xmFormWidgetClass,
1361 etDialog.form,
1362 XmNleftAttachment, XmATTACH_POSITION,
1363 XmNleftPosition, LEFT_MARGIN_POS,
1364 XmNtopAttachment, XmATTACH_WIDGET,
1365 XmNtopWidget, previewFrame,
1366 XmNtopOffset, V_MARGIN,
1367 XmNbottomOffset, V_MARGIN,
1368 XmNbottomAttachment, XmATTACH_FORM,
1369 XmNrightAttachment, XmATTACH_POSITION,
1370 XmNrightPosition, RIGHT_MARGIN_POS, NULL);
1372 applyBtn = XtVaCreateManagedWidget("apply", xmPushButtonWidgetClass,
1373 buttonForm,
1374 XmNhighlightThickness, 2,
1375 XmNlabelString, s1=XmStringCreateSimple("Apply"),
1376 XmNshowAsDefault, (short)1,
1377 XmNleftAttachment, XmATTACH_POSITION,
1378 XmNleftPosition, 6,
1379 XmNrightAttachment, XmATTACH_POSITION,
1380 XmNrightPosition, 25,
1381 XmNbottomAttachment, XmATTACH_FORM,
1382 NULL);
1383 XtAddCallback(applyBtn, XmNactivateCallback, applyCB, NULL);
1384 XmStringFree(s1);
1385 XtVaGetValues(applyBtn, XmNshadowThickness, &shadowThickness, NULL);
1386 defaultBtnOffset = shadowThickness + 4;
1388 closeBtn = XtVaCreateManagedWidget("close", xmPushButtonWidgetClass,
1389 buttonForm,
1390 XmNhighlightThickness, 2,
1391 XmNlabelString, s1=XmStringCreateSimple("Close"),
1392 XmNleftAttachment, XmATTACH_POSITION,
1393 XmNleftPosition, 52,
1394 XmNrightAttachment, XmATTACH_POSITION,
1395 XmNrightPosition, 71,
1396 XmNbottomAttachment, XmATTACH_FORM,
1397 XmNbottomOffset, defaultBtnOffset,
1398 NULL);
1399 XtAddCallback(closeBtn, XmNactivateCallback, closeCB, NULL);
1400 XmStringFree(s1);
1402 restoreBtn = XtVaCreateManagedWidget("restore", xmPushButtonWidgetClass,
1403 buttonForm,
1404 XmNhighlightThickness, 2,
1405 XmNlabelString, s1=XmStringCreateSimple("Default"),
1406 XmNleftAttachment, XmATTACH_POSITION,
1407 XmNleftPosition, 29,
1408 XmNrightAttachment, XmATTACH_POSITION,
1409 XmNrightPosition, 48,
1410 XmNbottomAttachment, XmATTACH_FORM,
1411 XmNbottomOffset, defaultBtnOffset,
1412 XmNmnemonic, 'e', NULL);
1413 XtAddCallback(restoreBtn, XmNactivateCallback, restoreCB, NULL);
1414 XmStringFree(s1);
1416 helpBtn = XtVaCreateManagedWidget("help", xmPushButtonWidgetClass,
1417 buttonForm,
1418 XmNhighlightThickness, 2,
1419 XmNlabelString, s1=XmStringCreateSimple("Help"),
1420 XmNleftAttachment, XmATTACH_POSITION,
1421 XmNleftPosition, 75,
1422 XmNrightAttachment, XmATTACH_POSITION,
1423 XmNrightPosition, 94,
1424 XmNbottomAttachment, XmATTACH_FORM,
1425 XmNbottomOffset, defaultBtnOffset,
1426 XmNmnemonic, 'p', NULL);
1427 XtAddCallback(helpBtn, XmNactivateCallback, helpCB, NULL);
1428 XmStringFree(s1);
1430 /* Set initial default button */
1431 XtVaSetValues(etDialog.form, XmNdefaultButton, applyBtn, NULL);
1432 XtVaSetValues(etDialog.form, XmNcancelButton, closeBtn, NULL);
1434 /* Handle mnemonic selection of buttons and focus to dialog */
1435 AddDialogMnemonicHandler(etDialog.form, FALSE);
1437 etDialog.suppressFormatUpdate = FALSE;
1440 void EditCustomTitleFormat(WindowInfo *window)
1442 /* copy attributes from current window so that we can use as many
1443 * 'real world' defaults as possible when testing the effect
1444 * of different formatting strings.
1446 strcpy(etDialog.path, window->path);
1447 strcpy(etDialog.filename, window->filename);
1448 #ifndef VMS
1449 strcpy(etDialog.viewTag, GetClearCaseViewTag() != NULL ?
1450 GetClearCaseViewTag() :
1451 "viewtag");
1452 #endif /* VMS */
1453 strcpy(etDialog.serverName, IsServer ?
1454 GetPrefServerName() :
1455 "servername");
1456 etDialog.isServer = IsServer;
1457 etDialog.filenameSet = window->filenameSet;
1458 etDialog.lockReasons = window->lockReasons;
1459 etDialog.fileChanged = window->fileChanged;
1461 if (etDialog.window != window && etDialog.form)
1463 /* Destroy the dialog owned by the other window.
1464 Note: don't rely on the destroy event handler to reset the
1465 form. Events are handled asynchronously, so the old dialog
1466 may continue to live for a while. */
1467 XtDestroyWidget(etDialog.form);
1468 etDialog.form = NULL;
1471 etDialog.window = window;
1473 /* Create the dialog if it doesn't already exist */
1474 if (etDialog.form == NULL)
1476 createEditTitleDialog(window->shell);
1478 else
1480 /* If the window is already up, just pop it to the top */
1481 if (XtIsManaged(etDialog.form)) {
1483 RaiseDialogWindow(XtParent(etDialog.form));
1485 /* force update of the dialog */
1486 setToggleButtons();
1487 formatChangedCB(0, 0, 0);
1488 return;
1492 /* set initial value of format field */
1493 XmTextSetString(etDialog.formatW, (char *)GetPrefTitleFormat());
1495 /* force update of the dialog */
1496 setToggleButtons();
1497 formatChangedCB(0, 0, 0);
1499 /* put up dialog and wait for user to press ok or cancel */
1500 ManageDialogCenteredOnPointer(etDialog.form);