MotifUtilities.cpp
// Copyright 2010 ESRI // // All rights reserved under the copyright laws of the United States // and applicable international laws, treaties, and conventions. // // You may freely redistribute and use this sample code, with or // without modification, provided you include the original copyright // notice and use restrictions. // // See the use restrictions. // // MotifUtilities.cpp #include "MotifUtilities.h" // Routine to display a modal prompt with 2 choices to a user. int ModalPrompt ( XtAppContext app, Widget parent, const char* question, const char* ans1, const char* ans2, int default_ans) { static Widget dialog = (Widget) 0; XmString text, yes, no; static int answer; if (!dialog) { XmString title = XmStringCreateLocalized(const_cast<char*>("Input")); dialog = XmCreateQuestionDialog (parent, const_cast<char*>("dialog"), NULL, 0); XtVaSetValues (dialog, XmNdialogStyle, XmDIALOG_FULL_APPLICATION_MODAL, NULL); XtVaSetValues (dialog, XmNdialogTitle, title, NULL); XmStringFree(title); XtSetSensitive (XtNameToWidget (dialog, "Help"), False); XtAddCallback (dialog, XmNokCallback, ModalPromptCallback, (XtPointer) &answer); XtAddCallback (dialog, XmNcancelCallback, ModalPromptCallback, (XtPointer) &answer); } // Initialize response and dialog answer = 0; text = XmStringCreateLocalized (const_cast<char*>(question)); yes = XmStringCreateLocalized (const_cast<char*>(ans1)); no = XmStringCreateLocalized (const_cast<char*>(ans2)); XtVaSetValues (dialog, XmNmessageString, text, XmNokLabelString, yes, XmNcancelLabelString, no, XmNdefaultButtonType, (default_ans == BUTTON1? XmDIALOG_OK_BUTTON: XmDIALOG_CANCEL_BUTTON), NULL); XmStringFree (text); XmStringFree (yes); XmStringFree (no); // Show the prompt and wait for a response XtManageChild (dialog); while (answer == 0) XtAppProcessEvent (app, XtIMAll); // Make sure dialog disappears XtUnmanageChild (dialog); XSync (XtDisplay (dialog), 0); XmUpdateDisplay (parent); return answer; } // Callback for ModalPrompt, copies the user's choice into the static // int answer. void ModalPromptCallback (Widget widget, XtPointer client_data, XtPointer call_data) { int *answer = (int *) client_data; XmAnyCallbackStruct *cbs = (XmAnyCallbackStruct *) call_data; if (cbs->reason == XmCR_OK) *answer = BUTTON1; else if (cbs->reason == XmCR_CANCEL) *answer = BUTTON2; } // Routine to display a modal text prompt to a user char *ModalTextPrompt (XtAppContext app, Widget parent, const char* inPrompt, int *outClickedCancel) { static Widget modaltextpromptdialog = (Widget) 0; static ModalTextPromptCallDataStruct resp; if (!modaltextpromptdialog) { XmString title = XmStringCreateLocalized(const_cast<char*>("Input")); modaltextpromptdialog = XmCreatePromptDialog(parent, const_cast<char*>("prompt"), NULL, 0); XtVaSetValues (modaltextpromptdialog, XmNdialogStyle, XmDIALOG_FULL_APPLICATION_MODAL, XmNdefaultButtonType, XmDIALOG_OK_BUTTON, XmNdialogTitle, title, NULL); XmStringFree (title); Widget remove1 = XmSelectionBoxGetChild(modaltextpromptdialog, XmDIALOG_HELP_BUTTON); XtUnmanageChild(remove1); XtAddCallback (modaltextpromptdialog, XmNokCallback, ModalTextPromptCallback, (XtPointer) &resp); XtAddCallback (modaltextpromptdialog, XmNcancelCallback, ModalTextPromptCallback, (XtPointer) &resp); } // Initialize response resp.answer = 0; strncpy(resp.strResp, "", 256); Widget txtwidget = XmSelectionBoxGetChild(modaltextpromptdialog, XmDIALOG_TEXT); XmTextSetString(txtwidget, const_cast<char*>("")); XmString prompt = XmStringCreateLocalized (const_cast<char*>(inPrompt)); XtVaSetValues (modaltextpromptdialog, XmNmessageString, prompt, XmNselectionLabelString, prompt, NULL); XmStringFree (prompt); // Show the prompt and wait for a response XtManageChild (modaltextpromptdialog); while (resp.answer == 0) XtAppProcessEvent (app, XtIMAll); *outClickedCancel = resp.answer; XtUnmanageChild (modaltextpromptdialog); // Make sure dialog disappears XSync (XtDisplay (modaltextpromptdialog), 0); XmUpdateDisplay (parent); return resp.strResp; } // Callback for ModalTextPrompt, copies the user's response into the // static structure used to hold it. void ModalTextPromptCallback (Widget widget, XtPointer client_data, XtPointer call_data) { ModalTextPromptCallDataStruct *resp = (ModalTextPromptCallDataStruct *) client_data; XmSelectionBoxCallbackStruct *cbs = (XmSelectionBoxCallbackStruct *) call_data; char *fileName; if (cbs->reason == XmCR_OK) { // Get the layer name and check for errors if (!XmStringGetLtoR(cbs->value, XmFONTLIST_DEFAULT_TAG, &fileName)) { cerr << "Internal error in ModalTextPromptCallback\n"; return; } strncpy(resp->strResp, fileName, 256); XtFree (fileName); resp->answer = OK; } else if (cbs->reason == XmCR_CANCEL) resp->answer = CANCEL; } // Routine to display a modal selection dialog to a user and get a response char *ModalSelectionDialog ( XtAppContext app, Widget parent, const char* inPrompt, XmString *inItems, int inItemCount, int *outClickedCancel) { static Widget modalselectiondialog = (Widget) 0; static ModalTextPromptCallDataStruct resp; if (!modalselectiondialog) { XmString title = XmStringCreateLocalized(const_cast<char*>("Select")); XmString t = XmStringCreateLocalized(const_cast<char*>("Items"));; modalselectiondialog = XmCreateSelectionDialog(parent, const_cast<char*>("select"), NULL, 0); XtVaSetValues(modalselectiondialog, XmNdialogStyle, XmDIALOG_FULL_APPLICATION_MODAL, XmNdefaultButtonType, XmDIALOG_OK_BUTTON, XmNlistLabelString, t, XmNdialogTitle, title, NULL); XmStringFree (title); XmStringFree (t); Widget remove1 = XmSelectionBoxGetChild(modalselectiondialog, XmDIALOG_HELP_BUTTON); XtUnmanageChild(remove1); remove1 = XmSelectionBoxGetChild(modalselectiondialog, XmDIALOG_APPLY_BUTTON); XtUnmanageChild(remove1); XtAddCallback (modalselectiondialog, XmNokCallback, ModalSelectionDialogCallback, (XtPointer) &resp); XtAddCallback (modalselectiondialog, XmNcancelCallback, ModalSelectionDialogCallback, (XtPointer) &resp); XtAddCallback (modalselectiondialog, XmNnoMatchCallback, ModalSelectionDialogCallback, (XtPointer) &resp); } // Initialize response resp.answer = 0; strncpy(resp.strResp, "", 256); XmString prompt = XmStringCreateLocalized (const_cast<char*>(inPrompt)); XtVaSetValues (modalselectiondialog, XmNmessageString, prompt, XmNselectionLabelString, prompt, XmNlistItems, inItems, XmNlistItemCount, inItemCount, NULL); XmStringFree (prompt); // Show the prompt and wait for a response XtManageChild (modalselectiondialog); while (resp.answer == 0) XtAppProcessEvent (app, XtIMAll); *outClickedCancel = resp.answer; XtUnmanageChild (modalselectiondialog); // Make sure dialog disappears XSync (XtDisplay (modalselectiondialog), 0); XmUpdateDisplay (parent); return resp.strResp; } // Callback for ModalTextPrompt, copies the user's response into the // static structure used to hold it. void ModalSelectionDialogCallback (Widget widget, XtPointer client_data, XtPointer call_data) { ModalTextPromptCallDataStruct *resp = (ModalTextPromptCallDataStruct *) client_data; XmSelectionBoxCallbackStruct *cbs = (XmSelectionBoxCallbackStruct *) call_data; char *fileName; if (cbs->reason == XmCR_OK) { // Get the layer name and check for errors if (!XmStringGetLtoR(cbs->value, XmFONTLIST_DEFAULT_TAG, &fileName)) { cerr << "Internal error in ModalSelectionDialogCallback\n"; return; } strncpy(resp->strResp, fileName, 256); XtFree (fileName); resp->answer = BUTTON1; } // Treat cancel and no match the same else if (cbs->reason == XmCR_CANCEL || cbs->reason == XmCR_NO_MATCH) resp->answer = BUTTON2; } // Routine to display a modal selection dialog to a user and get a response char *ModalFileSelectionDialog (XtAppContext app, Widget parent, const char* inTitle, const char* inMask, int *outClickedCancel) { static Widget modalfileselectiondialog = (Widget) 0; static ModalTextPromptCallDataStruct resp; if (!modalfileselectiondialog) { XmString title = XmStringCreateLocalized(const_cast<char*>(inTitle)); XmString mask = XmStringCreateLocalized(const_cast<char*>(inMask)); modalfileselectiondialog = XmCreateFileSelectionDialog(parent, const_cast<char*>("new"), NULL, 0); XtVaSetValues(modalfileselectiondialog, XmNdialogStyle, XmDIALOG_FULL_APPLICATION_MODAL, XmNdefaultButtonType, XmDIALOG_OK_BUTTON, XmNdirMask, mask, XmNdialogTitle, title, NULL); XmStringFree (title); XmStringFree (mask); Widget remove1 = XmFileSelectionBoxGetChild(modalfileselectiondialog, XmDIALOG_HELP_BUTTON); XtUnmanageChild(remove1); XtAddCallback (modalfileselectiondialog, XmNokCallback, ModalFileSelectionDialogCallback, (XtPointer) &resp); XtAddCallback (modalfileselectiondialog, XmNcancelCallback, ModalFileSelectionDialogCallback, (XtPointer) &resp); XtAddCallback (modalfileselectiondialog, XmNnoMatchCallback, ModalFileSelectionDialogCallback, (XtPointer) &resp); } // Initialize response resp.answer = 0; strncpy(resp.strResp, "", 256); // Show the prompt and wait for a response XtManageChild (modalfileselectiondialog); while (resp.answer == 0) XtAppProcessEvent (app, XtIMAll); *outClickedCancel = resp.answer; XtUnmanageChild (modalfileselectiondialog); // Make sure dialog disappears XSync (XtDisplay (modalfileselectiondialog), 0); XmUpdateDisplay (parent); return resp.strResp; } // Callback for ModalTextPrompt, copies the user's response into the // static structure used to hold it. void ModalFileSelectionDialogCallback (Widget widget, XtPointer client_data, XtPointer call_data) { ModalTextPromptCallDataStruct *resp = (ModalTextPromptCallDataStruct *) client_data; XmFileSelectionBoxCallbackStruct *cbs = (XmFileSelectionBoxCallbackStruct *)call_data; char *fileName; if (cbs->reason == XmCR_OK) { // Get the layer name and check for errors if (!XmStringGetLtoR(cbs->value, XmFONTLIST_DEFAULT_TAG, &fileName)) { cerr << "Internal error in ModalFileSelectionDialogCallback\n"; return; } strncpy(resp->strResp, fileName, 256); XtFree (fileName); resp->answer = BUTTON1; } // Treat cancel and no match the same else if (cbs->reason == XmCR_CANCEL || cbs->reason == XmCR_NO_MATCH) resp->answer = BUTTON2; } // Utility function to dispay a MessageDialog void ShowMessage (Widget parent, const char* dialogtitle, const char* text, bool asError) { // Create a MessageDialog Widget err; Arg args[1]; XmString str; int n = 0; str = XmStringCreateLocalized(const_cast<char*>(text)); XtSetArg(args[n], XmNmessageString, str); n++; if (asError) err = XmCreateErrorDialog(parent, const_cast<char*>("error"), args, n); else err = XmCreateInformationDialog(parent, const_cast<char*>("info"), args, n); // Remove the help and cancel buttons Widget remove; remove = XmMessageBoxGetChild(err, XmDIALOG_HELP_BUTTON); XtUnmanageChild(remove); remove = XmMessageBoxGetChild(err, XmDIALOG_CANCEL_BUTTON); XtUnmanageChild(remove); // Set the title of the MessageDialog XmString title; title = XmStringCreateLocalized(const_cast<char*>(dialogtitle)); XtVaSetValues(err, XmNdialogTitle, title, NULL); XmStringFree(title); XtManageChild(err); XmStringFree(str); } // Remove all items from a combobox widget void ClearCombo(Widget w) { // Delete items from the combobox if any exist int itemcount = 0; XtVaGetValues(w, XmNitemCount, &itemcount, NULL); for (int j=1; j<itemcount; j++) XmComboBoxDeletePos(w, 0); if (itemcount > 0) XmComboBoxDeletePos(w, 0); XtVaSetValues(w, XmNselectedItem, NULL, NULL); } // Removes the item w/ value inItem from the inCombobox and resets its // textfield. void RemovePosition(Widget inCombobox, char* inItem) { XmString searchItem = XmStringCreateLocalized(inItem); XmString selectedItem; int itemCount; XtVaGetValues(inCombobox, XmNitemCount, &itemCount, NULL); if (itemCount == 1) { XmComboBoxDeletePos (inCombobox, 0); } else { XmStringTable items; XtVaGetValues(inCombobox, XmNitems, &items, NULL); for (int i=0; i<itemCount; i++) { if (XmStringCompare(searchItem, items[i]) == True) { XmComboBoxDeletePos (inCombobox, i+1); } } } XtVaGetValues(inCombobox, XmNselectedItem, &selectedItem, NULL); if (XmStringCompare(searchItem, selectedItem)) XtVaSetValues(inCombobox, XmNselectedItem, NULL, NULL); XmStringFree (searchItem); } // Method to set the contents of a combobox void SetComboboxItems (Widget inCombobox, XmString *inItems, int inItemCount) { ::ClearCombo(inCombobox); XtVaSetValues( inCombobox, XmNitems, inItems, XmNitemCount, inItemCount, NULL); XmComboBoxUpdate(inCombobox ); } // Create a menu containing the items specified in items. Uses the // global variable mainmenu as the menubar. mnem can be NULL, // everything else cannot be (except for items when number == 0). void CreateMenu (Widget menubar, Widget menu, const char* menuname, char mnem, MenuItem *items, int number, Widget widgetIDs []) { Widget pushbutton, cascade; Arg args[4]; XmString menulabel; int n = 0; menu = XmCreatePulldownMenu (menubar, const_cast<char*>(menuname), NULL, 0); menulabel = XmStringCreateLocalized(const_cast<char*>(menuname)); XtSetArg (args[n], XmNlabelString, menulabel); n++; if (mnem) { XtSetArg (args[n], XmNmnemonic, mnem); n++; } XtSetArg (args[n], XmNsubMenuId, menu); n++; cascade = XmCreateCascadeButton (menubar, const_cast<char*>(menuname), args, n); XtManageChild (cascade); XmStringFree(menulabel); for (int i=0; i<number; i++) { n = 0; XmString accelText; if (items[i].accelText) { accelText = XmStringCreateLocalized(const_cast<char*>(items[i].accelText)); XtSetArg (args[n], XmNacceleratorText, accelText); n++; } if (items[i].accel) { XtSetArg (args[n], XmNaccelerator, items[i].accel); n++; } pushbutton = XmCreatePushButtonGadget (menu, const_cast<char*>(items[i].text), args, n); widgetIDs[i] = pushbutton; if (items[i].accelText) XmStringFree(accelText); if (items[i].callback) { XtAddCallback(pushbutton, XmNactivateCallback, items[i].callback, items[i].callbackData); } XtManageChild (pushbutton); } } // Centers the shell of toCenter in centerOver based on the location // and size of centerOver's top level shell and toCenter's top level // shell void CenterDialog (Widget centerOver, Widget toCenter) { Widget topShell = XtParent(centerOver); while (topShell && !XtIsWMShell (topShell)) topShell = XtParent (topShell); Widget dialogShell = XtParent(toCenter); while (dialogShell && !XtIsWMShell (dialogShell)) dialogShell = XtParent (dialogShell); Dimension parentW, parentH, dialogW, dialogH; Position parentX, parentY, dialogX, dialogY; XtVaGetValues(topShell, XmNx, &parentX, XmNy, &parentY, XmNwidth, &parentW, XmNheight, &parentH, NULL); XtVaGetValues(dialogShell, XmNwidth, &dialogW, XmNheight, &dialogH, NULL); dialogX = parentX + ((parentW - dialogW) / 2); dialogY = parentY + ((parentH - dialogH) / 2); XtVaSetValues(dialogShell, XmNx, dialogX, XmNy, dialogY, NULL); }