Fix testing for valid window placement Xaw
[xboard.git] / xaw / xoptions.c
index a475c58..f70e80f 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * xoptions.c -- Move list window, part of X front end for XBoard
  *
- * Copyright 2000, 2009, 2010, 2011, 2012 Free Software Foundation, Inc.
+ * Copyright 2000, 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc.
  * ------------------------------------------------------------------------
  *
  * GNU XBoard is free software: you can redistribute it and/or modify
@@ -142,6 +142,11 @@ static Arg formArgs[] = {
     { XtNresizable, (XtArgVal) True },
 };
 
+void
+CursorAtEnd (Option *opt)
+{
+}
+
 void
 GetWidgetText (Option *opt, char **buf)
 {
@@ -192,7 +197,7 @@ SetDialogTitle (DialogClass dlg, char *title)
 }
 
 void
-LoadListBox (Option *opt, char *emptyText)
+LoadListBox (Option *opt, char *emptyText, int n1, int n2)
 {
     static char *dummyList[2];
     dummyList[0] = emptyText; // empty listboxes tend to crash X, so display user-supplied warning string instead
@@ -259,6 +264,15 @@ SelectedListBoxItem (Option *opt)
     return rs->list_index;
 }
 
+void
+HighlightText (Option *opt, int start, int end, Boolean on)
+{
+    if(on)
+       XawTextSetSelection( opt->handle, start, end ); // for lack of a better method, use selection for highighting
+    else
+       XawTextSetSelection( opt->handle, 0, 0 );
+}
+
 void
 FocusOnWidget (Option *opt, DialogClass dlg)
 {
@@ -359,6 +373,46 @@ CreateMenuItem (Widget menu, char *msg, XtCallbackProc CB, int n)
     return entry;
 }
 
+char *
+format_accel (char *input)
+{
+  char *output;
+  char *key,*test;
+
+  output = strdup("");
+
+  if( strstr(input, "<Ctrl>") )
+    {
+      output = realloc(output, strlen(output) + strlen(_("Ctrl"))+2);
+      strncat(output, _("Ctrl"), strlen(_("Ctrl")) +1);
+      strncat(output, "+", 1);
+    };
+  if( strstr(input, "<Alt>") )
+    {
+      output = realloc(output, strlen(output) + strlen(_("Alt"))+2);
+      strncat(output, _("Alt"), strlen(_("Alt")) +1);
+      strncat(output, "+", 1);
+    };
+  if( strstr(input, "<Shift>") )
+    {
+      output = realloc(output, strlen(output) + strlen(_("Shift"))+2);
+      strncat(output, _("Shift"), strlen(_("Shift")) +1);
+      strncat(output, "+", 1);
+    };
+
+  test = strrchr(input, '>');
+  if ( test==NULL )
+    key = strdup(input);
+  else
+    key = strdup(++test); // remove ">"
+
+  output = realloc(output, strlen(output) + strlen(_(key))+2);
+  strncat(output, _(key), strlen(key) +1);
+
+  free(key);
+  return output;
+}
+
 static Widget
 CreateComboPopup (Widget parent, Option *opt, int n, int fromList, int def)
 {   // fromList determines if the item texts are taken from a list of strings, or from a menu table
@@ -367,20 +421,47 @@ CreateComboPopup (Widget parent, Option *opt, int n, int fromList, int def)
     Arg arg;
     MenuItem *mb = (MenuItem *) opt->choice;
     char **list = (char **) opt->choice;
+    int maxlength=0;
+
 
     if(list[0] == NULL) return NULL; // avoid empty menus, as they cause crash
     menu = XtCreatePopupShell(opt->name, simpleMenuWidgetClass, parent, NULL, 0);
 
-    for (i=0; 1; i++) 
+    if(!fromList)
+      for (i=0; mb[i].string; i++)
+       if (maxlength < strlen(_(mb[i].string)) )
+         maxlength = strlen(_(mb[i].string) );
+
+    for (i=0; 1; i++)
       {
        char *msg = fromList ? list[i] : mb[i].string;
+       char *label=NULL;
+
        if(!msg) break;
-       entry = CreateMenuItem(menu, opt->min & NO_GETTEXT ? msg : _(msg), (XtCallbackProc) ComboSelect, (n<<16)+i);
+
+       if(!fromList && mb[i].accel)
+         {
+           char *menuname = opt->min & NO_GETTEXT ? msg : _(msg);
+           char *accel = format_accel(mb[i].accel);
+           size_t len;
+           int fill = maxlength - strlen(menuname) +2+strlen(accel);
+
+           len = strlen(menuname)+fill+1;
+           label = malloc(len);
+
+           snprintf(label,len,"%s%*s",menuname,fill,accel);
+           free(accel);
+         }
+       else
+         label = strdup(opt->min & NO_GETTEXT ? msg : _(msg));
+
+       entry = CreateMenuItem(menu, label, (XtCallbackProc) ComboSelect, (n<<16)+i);
        if(!fromList) mb[i].handle = (void*) entry; // save item ID, for enabling / checkmarking
        if(i==def) {
            XtSetArg(arg, XtNpopupOnEntry, entry);
            XtSetValues(menu, &arg, 1);
        }
+       free(label);
       }
       return menu;
 }
@@ -399,7 +480,7 @@ char *translationTable[] = { // beware: order is essential!
 };
 
 void
-AddHandler (Option *opt, int nr)
+AddHandler (Option *opt, DialogClass dlg, int nr)
 {
     XtOverrideTranslations(opt->handle, XtParseTranslationTable(translationTable[nr]));
 }
@@ -443,7 +524,7 @@ RaiseWindow (DialogClass dlg)
           SubstructureRedirectMask | SubstructureNotifyMask,
           &xev);
 
-    XFlush(xDisplay); 
+    XFlush(xDisplay);
     XSync(xDisplay, False);
 }
 
@@ -624,7 +705,7 @@ GenericCallback (Widget w, XtPointer client_data, XtPointer call_data)
     currentOption = dialogOptions[dlg=data>>16]; data &= 0xFFFF;
     oldSh = shells[dlg]; shells[dlg] = sh; // bow to reality
     if (data == 30000) { // cancel
-        PopDown(dlg); 
+        PopDown(dlg);
     } else
     if (data == 30001) { // save buttons imply OK
         if(GenericReadout(currentOption, -1)) PopDown(dlg); // calls OK-proc after full readout, but no popdown if it returns false
@@ -781,7 +862,6 @@ GenericPopUp (Option *option, char *title, DialogClass dlgNr, DialogClass parent
 
     if(engineDlg) { // Settings popup for engine: format through heuristic
        int n = currentCps->nrOptions;
-       if(!n) { DisplayNote(_("Engine has no options")); currentCps = NULL; return 0; }
        if(n > 50) width = 4; else if(n>24) width = 2; else width = 1;
        height = n / width + 1;
        if(n && (currentOption[n-1].type == Button || currentOption[n-1].type == SaveButton)) currentOption[n].min = SAME_ROW; // OK on same line
@@ -860,7 +940,7 @@ GenericPopUp (Option *option, char *title, DialogClass dlgNr, DialogClass parent
            XtSetArg(args[j], XtNdisplayCaret, False);  j++;
            XtSetArg(args[j], XtNresizable, True);  j++;
            XtSetArg(args[j], XtNinsertPosition, 9999);  j++;
-           XtSetArg(args[j], XtNstring, option[i].type==Spin || option[i].type==Fractional ? def : 
+           XtSetArg(args[j], XtNstring, option[i].type==Spin || option[i].type==Fractional ? def :
                                engineDlg ? option[i].textValue : *(char**)option[i].target);  j++;
            edit = last;
            option[i].handle = (void*)
@@ -910,6 +990,7 @@ GenericPopUp (Option *option, char *title, DialogClass dlgNr, DialogClass parent
            XtAddEventHandler(last, ButtonPressMask, False, CheckCallback, (XtPointer)(intptr_t) i + 256*dlgNr);
            shrink = TRUE; // following buttons must get text height
            break;
+         case Icon:
          case Label:
            msg = option[i].name;
            if(!msg) break;
@@ -1009,6 +1090,7 @@ GenericPopUp (Option *option, char *title, DialogClass dlgNr, DialogClass parent
          case PopUp: // note: used only after Graph, so 'last' refers to the Graph widget
            option[i].handle = (void*) CreateComboPopup(last, option + i, i + 256*dlgNr, TRUE, option[i].value);
            break;
+         case BarBegin:
          case BoxBegin:
            if(option[i].min & SAME_ROW) forelast = lastrow;
            j = SetPositionAndSize(args, last, lastrow, 0 /* border */,
@@ -1031,6 +1113,7 @@ GenericPopUp (Option *option, char *title, DialogClass dlgNr, DialogClass parent
                (last = XtCreateManagedWidget(option[i].name, menuButtonWidgetClass, form, args, j));
            option[i].textValue = (char*) CreateComboPopup(last, option + i, i + 256*dlgNr, FALSE, -1);
            break;
+         case BarEnd:
          case BoxEnd:
            XtManageChildren(&form, 1);
            SqueezeIntoBox(&option[box], i-box, option[box].max);
@@ -1142,13 +1225,17 @@ GenericPopUp (Option *option, char *title, DialogClass dlgNr, DialogClass parent
     shellUp[dlgNr]++; // count rather than flag
     previous = NULL;
     if(textField) SetFocus(textField, popup, (XEvent*) NULL, False);
-    if(dlgNr && wp[dlgNr] && wp[dlgNr]->width > 0) { // if persistent window-info available, reposition
+    if(dlgNr && wp[dlgNr]) { // if persistent window-info available, reposition
        j = 0;
-       XtSetArg(args[j], XtNheight, (Dimension) (wp[dlgNr]->height));  j++;
-       XtSetArg(args[j], XtNwidth,  (Dimension) (wp[dlgNr]->width));  j++;
-       XtSetArg(args[j], XtNx, (Position) (wp[dlgNr]->x));  j++;
-       XtSetArg(args[j], XtNy, (Position) (wp[dlgNr]->y));  j++;
-       XtSetValues(popup, args, j);
+       if(wp[dlgNr]->width > 0 && wp[dlgNr]->height > 0) {
+         XtSetArg(args[j], XtNheight, (Dimension) (wp[dlgNr]->height));  j++;
+         XtSetArg(args[j], XtNwidth,  (Dimension) (wp[dlgNr]->width));  j++;
+       }
+       if(wp[dlgNr]->x > 0 && wp[dlgNr]->y > 0) {
+         XtSetArg(args[j], XtNx, (Position) (wp[dlgNr]->x));  j++;
+         XtSetArg(args[j], XtNy, (Position) (wp[dlgNr]->y));  j++;
+       }
+       if(j) XtSetValues(popup, args, j);
     }
     RaiseWindow(dlgNr);
     return 1; // tells caller he must do initialization (e.g. add specific event handlers)
@@ -1213,4 +1300,8 @@ HardSetFocus (Option *opt)
     XSetInputFocus(xDisplay, XtWindow(opt->handle), RevertToPointerRoot, CurrentTime);
 }
 
-
+void
+FileNamePopUpWrapper (char *label, char *def, char *filter, FileProc proc, Boolean pathFlag, char *openMode, char **openName, FILE **openFP)
+{
+    Browse(BoardWindow, label, (def[0] ? def : NULL), filter, False, openMode, openName, openFP);
+}