00001 /* 00002 GNU GENERAL PUBLIC LICENSE 00003 Version 2, June 1991 00004 00005 Copyright (C) 1989, 1991 Free Software Foundation, Inc. 00006 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 00007 Everyone is permitted to copy and distribute verbatim copies 00008 of this license document, but changing it is not allowed. 00009 00010 Preamble 00011 00012 The licenses for most software are designed to take away your 00013 freedom to share and change it. By contrast, the GNU General Public 00014 License is intended to guarantee your freedom to share and change free 00015 software--to make sure the software is free for all its users. This 00016 General Public License applies to most of the Free Software 00017 Foundation's software and to any other program whose authors commit to 00018 using it. (Some other Free Software Foundation software is covered by 00019 the GNU Library General Public License instead.) You can apply it to 00020 your programs, too. 00021 00022 When we speak of free software, we are referring to freedom, not 00023 price. Our General Public Licenses are designed to make sure that you 00024 have the freedom to distribute copies of free software (and charge for 00025 this service if you wish), that you receive source code or can get it 00026 if you want it, that you can change the software or use pieces of it 00027 in new free programs; and that you know you can do these things. 00028 00029 To protect your rights, we need to make restrictions that forbid 00030 anyone to deny you these rights or to ask you to surrender the rights. 00031 These restrictions translate to certain responsibilities for you if you 00032 distribute copies of the software, or if you modify it. 00033 00034 For example, if you distribute copies of such a program, whether 00035 gratis or for a fee, you must give the recipients all the rights that 00036 you have. You must make sure that they, too, receive or can get the 00037 source code. And you must show them these terms so they know their 00038 rights. 00039 00040 We protect your rights with two steps: (1) copyright the software, and 00041 (2) offer you this license which gives you legal permission to copy, 00042 distribute and/or modify the software. 00043 00044 Also, for each author's protection and ours, we want to make certain 00045 that everyone understands that there is no warranty for this free 00046 software. If the software is modified by someone else and passed on, we 00047 want its recipients to know that what they have is not the original, so 00048 that any problems introduced by others will not reflect on the original 00049 authors' reputations. 00050 00051 Finally, any free program is threatened constantly by software 00052 patents. We wish to avoid the danger that redistributors of a free 00053 program will individually obtain patent licenses, in effect making the 00054 program proprietary. To prevent this, we have made it clear that any 00055 patent must be licensed for everyone's free use or not licensed at all. 00056 00057 The precise terms and conditions for copying, distribution and 00058 modification follow. 00059 00060 GNU GENERAL PUBLIC LICENSE 00061 TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 00062 00063 0. This License applies to any program or other work which contains 00064 a notice placed by the copyright holder saying it may be distributed 00065 under the terms of this General Public License. The "Program", below, 00066 refers to any such program or work, and a "work based on the Program" 00067 means either the Program or any derivative work under copyright law: 00068 that is to say, a work containing the Program or a portion of it, 00069 either verbatim or with modifications and/or translated into another 00070 language. (Hereinafter, translation is included without limitation in 00071 the term "modification".) Each licensee is addressed as "you". 00072 00073 Activities other than copying, distribution and modification are not 00074 covered by this License; they are outside its scope. The act of 00075 running the Program is not restricted, and the output from the Program 00076 is covered only if its contents constitute a work based on the 00077 Program (independent of having been made by running the Program). 00078 Whether that is true depends on what the Program does. 00079 00080 1. You may copy and distribute verbatim copies of the Program's 00081 source code as you receive it, in any medium, provided that you 00082 conspicuously and appropriately publish on each copy an appropriate 00083 copyright notice and disclaimer of warranty; keep intact all the 00084 notices that refer to this License and to the absence of any warranty; 00085 and give any other recipients of the Program a copy of this License 00086 along with the Program. 00087 00088 You may charge a fee for the physical act of transferring a copy, and 00089 you may at your option offer warranty protection in exchange for a fee. 00090 00091 2. You may modify your copy or copies of the Program or any portion 00092 of it, thus forming a work based on the Program, and copy and 00093 distribute such modifications or work under the terms of Section 1 00094 above, provided that you also meet all of these conditions: 00095 00096 a) You must cause the modified files to carry prominent notices 00097 stating that you changed the files and the date of any change. 00098 00099 b) You must cause any work that you distribute or publish, that in 00100 whole or in part contains or is derived from the Program or any 00101 part thereof, to be licensed as a whole at no charge to all third 00102 parties under the terms of this License. 00103 00104 c) If the modified program normally reads commands interactively 00105 when run, you must cause it, when started running for such 00106 interactive use in the most ordinary way, to print or display an 00107 announcement including an appropriate copyright notice and a 00108 notice that there is no warranty (or else, saying that you provide 00109 a warranty) and that users may redistribute the program under 00110 these conditions, and telling the user how to view a copy of this 00111 License. (Exception: if the Program itself is interactive but 00112 does not normally print such an announcement, your work based on 00113 the Program is not required to print an announcement.) 00114 00115 These requirements apply to the modified work as a whole. If 00116 identifiable sections of that work are not derived from the Program, 00117 and can be reasonably considered independent and separate works in 00118 themselves, then this License, and its terms, do not apply to those 00119 sections when you distribute them as separate works. But when you 00120 distribute the same sections as part of a whole which is a work based 00121 on the Program, the distribution of the whole must be on the terms of 00122 this License, whose permissions for other licensees extend to the 00123 entire whole, and thus to each and every part regardless of who wrote it. 00124 00125 Thus, it is not the intent of this section to claim rights or contest 00126 your rights to work written entirely by you; rather, the intent is to 00127 exercise the right to control the distribution of derivative or 00128 collective works based on the Program. 00129 00130 In addition, mere aggregation of another work not based on the Program 00131 with the Program (or with a work based on the Program) on a volume of 00132 a storage or distribution medium does not bring the other work under 00133 the scope of this License. 00134 00135 3. You may copy and distribute the Program (or a work based on it, 00136 under Section 2) in object code or executable form under the terms of 00137 Sections 1 and 2 above provided that you also do one of the following: 00138 00139 a) Accompany it with the complete corresponding machine-readable 00140 source code, which must be distributed under the terms of Sections 00141 1 and 2 above on a medium customarily used for software interchange; or, 00142 00143 b) Accompany it with a written offer, valid for at least three 00144 years, to give any third party, for a charge no more than your 00145 cost of physically performing source distribution, a complete 00146 machine-readable copy of the corresponding source code, to be 00147 distributed under the terms of Sections 1 and 2 above on a medium 00148 customarily used for software interchange; or, 00149 00150 c) Accompany it with the information you received as to the offer 00151 to distribute corresponding source code. (This alternative is 00152 allowed only for noncommercial distribution and only if you 00153 received the program in object code or executable form with such 00154 an offer, in accord with Subsection b above.) 00155 00156 The source code for a work means the preferred form of the work for 00157 making modifications to it. For an executable work, complete source 00158 code means all the source code for all modules it contains, plus any 00159 associated interface definition files, plus the scripts used to 00160 control compilation and installation of the executable. However, as a 00161 special exception, the source code distributed need not include 00162 anything that is normally distributed (in either source or binary 00163 form) with the major components (compiler, kernel, and so on) of the 00164 operating system on which the executable runs, unless that component 00165 itself accompanies the executable. 00166 00167 If distribution of executable or object code is made by offering 00168 access to copy from a designated place, then offering equivalent 00169 access to copy the source code from the same place counts as 00170 distribution of the source code, even though third parties are not 00171 compelled to copy the source along with the object code. 00172 00173 4. You may not copy, modify, sublicense, or distribute the Program 00174 except as expressly provided under this License. Any attempt 00175 otherwise to copy, modify, sublicense or distribute the Program is 00176 void, and will automatically terminate your rights under this License. 00177 However, parties who have received copies, or rights, from you under 00178 this License will not have their licenses terminated so long as such 00179 parties remain in full compliance. 00180 00181 5. You are not required to accept this License, since you have not 00182 signed it. However, nothing else grants you permission to modify or 00183 distribute the Program or its derivative works. These actions are 00184 prohibited by law if you do not accept this License. Therefore, by 00185 modifying or distributing the Program (or any work based on the 00186 Program), you indicate your acceptance of this License to do so, and 00187 all its terms and conditions for copying, distributing or modifying 00188 the Program or works based on it. 00189 00190 6. Each time you redistribute the Program (or any work based on the 00191 Program), the recipient automatically receives a license from the 00192 original licensor to copy, distribute or modify the Program subject to 00193 these terms and conditions. You may not impose any further 00194 restrictions on the recipients' exercise of the rights granted herein. 00195 You are not responsible for enforcing compliance by third parties to 00196 this License. 00197 00198 7. If, as a consequence of a court judgment or allegation of patent 00199 infringement or for any other reason (not limited to patent issues), 00200 conditions are imposed on you (whether by court order, agreement or 00201 otherwise) that contradict the conditions of this License, they do not 00202 excuse you from the conditions of this License. If you cannot 00203 distribute so as to satisfy simultaneously your obligations under this 00204 License and any other pertinent obligations, then as a consequence you 00205 may not distribute the Program at all. For example, if a patent 00206 license would not permit royalty-free redistribution of the Program by 00207 all those who receive copies directly or indirectly through you, then 00208 the only way you could satisfy both it and this License would be to 00209 refrain entirely from distribution of the Program. 00210 00211 If any portion of this section is held invalid or unenforceable under 00212 any particular circumstance, the balance of the section is intended to 00213 apply and the section as a whole is intended to apply in other 00214 circumstances. 00215 00216 It is not the purpose of this section to induce you to infringe any 00217 patents or other property right claims or to contest validity of any 00218 such claims; this section has the sole purpose of protecting the 00219 integrity of the free software distribution system, which is 00220 implemented by public license practices. Many people have made 00221 generous contributions to the wide range of software distributed 00222 through that system in reliance on consistent application of that 00223 system; it is up to the author/donor to decide if he or she is willing 00224 to distribute software through any other system and a licensee cannot 00225 impose that choice. 00226 00227 This section is intended to make thoroughly clear what is believed to 00228 be a consequence of the rest of this License. 00229 00230 8. If the distribution and/or use of the Program is restricted in 00231 certain countries either by patents or by copyrighted interfaces, the 00232 original copyright holder who places the Program under this License 00233 may add an explicit geographical distribution limitation excluding 00234 those countries, so that distribution is permitted only in or among 00235 countries not thus excluded. In such case, this License incorporates 00236 the limitation as if written in the body of this License. 00237 00238 9. The Free Software Foundation may publish revised and/or new versions of the General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. 00239 00240 Each version is given a distinguishing version number. If the Program 00241 specifies a version number of this License which applies to it and "any 00242 later version", you have the option of following the terms and conditions 00243 either of that version or of any later version published by the Free Software 00244 Foundation. If the Program does not specify a version number of this License, 00245 you may choose any version ever published by the Free Software Foundation. 00246 00247 10. If you wish to incorporate parts of the Program into other free 00248 programs whose distribution conditions are different, write to the author to 00249 ask for permission. For software which is copyrighted by the Free Software 00250 Foundation, write to the Free Software Foundation; we sometimes make 00251 exceptions for this. Our decision will be guided by the two goals of 00252 preserving the free status of all derivatives of our free software and of 00253 promoting the sharing and reuse of software generally. 00254 00255 NO WARRANTY 00256 00257 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR 00258 THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN 00259 OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE 00260 THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, 00261 INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND 00262 FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND 00263 PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, 00264 YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 00265 00266 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING 00267 WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR 00268 REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, 00269 INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING 00270 OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO 00271 LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR 00272 THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), 00273 EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH 00274 DAMAGES. 00275 00276 END OF TERMS AND CONDITIONS ' 00277 */ 00278 static const char* Copyright= "(C) Copyright Michigan State University 2002, All rights reserved";/* 00279 ** Facility: 00280 ** Xamine - C++ Support objects for Motif. 00281 ** Abstract: 00282 ** XMDialogs.cc - This file contains support routines for the XM dialog 00283 ** objects. That is code which for one or another reason 00284 ** was not deemed appropriate for in-line definition. 00285 ** Author: 00286 ** Ron Fox 00287 ** NSCL 00288 ** Michigan State University 00289 ** East Lansing, MI 48824-1321 00290 ** Version: 00291 ** @(#)XMDialogs.cc 8.2 9/10/96 00292 */ 00293 #ifdef unix 00294 #pragma implementation "XMCallback.h" 00295 #endif 00296 static char *sccsinfo = "@(#)XMDialogs.cc 8.2 9/10/96 \n"; 00297 /* 00298 ** Include files: 00299 */ 00300 00301 #include <config.h> 00302 00303 #include "XMDialogs.h" 00304 #include <Xm/MwmUtil.h> 00305 #include <Xm/DialogS.h> 00306 #include <Xm/FileSB.h> 00307 #include <X11/Shell.h> 00308 #include <stdio.h> 00309 #include <assert.h> 00310 #include <string.h> 00311 #include <ctype.h> 00312 00313 #ifdef HAVE_STD_NAMESPACE 00314 using namespace std; 00315 #endif 00316 00317 00318 /* 00319 ** Functional Description: 00320 ** StripNonPrinting: 00321 ** Creates an output string which consists of the input string with all 00322 ** non printing characters stripped. 00323 ** Formal Parameters: 00324 ** char* out: 00325 ** output string. 00326 ** char* in: 00327 ** input string. 00328 */ 00329 static void StripNonPrinting(char* out, char* in) 00330 { 00331 int len = strlen(in); 00332 for(int i = 0; i < len; i++) { 00333 if(isprint(*in)) *out++ = *in; 00334 in++; 00335 } 00336 *out = '\0'; 00337 } 00338 00339 /* 00340 ** Functional Descriptions: 00341 ** SetupBorders: 00342 ** Sets up dialog box borders in motif to remove the menu. 00343 ** Formal Parameters: 00344 ** Widget id: 00345 ** Some widget in the dialog hierachy. 00346 */ 00347 static void SetupBorders(Widget id) 00348 { 00349 /* Locate the vendor shell where all this stuff is */ 00350 00351 while(!XtIsVendorShell(id)) 00352 id = XtParent(id); 00353 00354 /* Turn off the menu but keep everything else the same: */ 00355 00356 if(XmIsMotifWMRunning(id)) { /* Only applies to motif wm. */ 00357 int decorations; 00358 00359 XtVaGetValues(id, XmNmwmDecorations, &decorations, NULL); 00360 decorations = decorations & (MWM_DECOR_BORDER | MWM_DECOR_RESIZEH | 00361 MWM_DECOR_TITLE | MWM_DECOR_MAXIMIZE | 00362 MWM_DECOR_MINIMIZE); 00363 XtVaSetValues(id, XmNmwmDecorations, decorations, NULL); 00364 } 00365 } 00366 00367 /* 00368 ** Method Description: 00369 ** SetSelectionList - This function sets the selection list for a 00370 ** SelectionDialog object. 00371 ** In the special case that list_count == 0, 00372 ** We set the selection list pointer to NULL and 00373 ** zero the count. 00374 ** Formal Parameters: 00375 ** Cardinal list_count: 00376 ** The number of list items. 00377 ** char **selections: 00378 ** The set of selections to enter in the box. 00379 */ 00380 void 00381 XMSelectionDialog::SetSelectionList(Cardinal list_count, 00382 char **selections) 00383 { 00384 XmString *list; /* The LtoR'd strings. */ 00385 XmString *l; 00386 char **s; 00387 00388 /* Handle special list_count == 0 case */ 00389 /* Transform the chars to compound strings: */ 00390 00391 if(list_count == 0) { 00392 list = NULL; 00393 } 00394 else { 00395 00396 l = list = (XmString *)XtMalloc(list_count*sizeof(XmString)); 00397 s = selections; 00398 for(int i = 0; i < list_count; i++) { 00399 char* stripped = new char[strlen(*s) + 1]; 00400 StripNonPrinting(stripped, *s); 00401 *l++ = XmStringCreateSimple(stripped); 00402 s++; 00403 delete []stripped; 00404 } 00405 } 00406 /* Set the resources: */ 00407 00408 XtVaSetValues(id, XmNlistItems, list, 00409 XmNlistItemCount, list_count, 00410 NULL); 00411 00412 if(list_count) { 00413 l = list; 00414 for(int i = 0; i < list_count; i++) 00415 XmStringFree(*l++); 00416 XtFree((char *)list); 00417 } 00418 } 00419 00420 /* 00421 ** Method Description: 00422 ** FileListDialog::GetDirectory - Get the current search directory for 00423 ** a file selectionbox. 00424 ** Returns: 00425 ** Pointer to an XtAlloc'd string which must be freed by the caller. The 00426 ** string contains the ASCIZ directory path string. 00427 */ 00428 00429 char* 00430 XMFileListDialog::GetDirectory() { 00431 XmString dir_compound; 00432 char *directory; 00433 00434 GetAttribute(XmNdirectory, &dir_compound); 00435 00436 XmStringGetLtoR(dir_compound, XmSTRING_DEFAULT_CHARSET, &directory); 00437 XmStringFree(dir_compound); 00438 return directory; 00439 } 00440 00441 /* 00442 ** Method Description: 00443 ** FileListDialog::GetFileMask - Get the file search mask. 00444 ** Returns: 00445 ** pointer to an XtMalloc'd ASCIZ string which must be released by the caller 00446 */ 00447 char* 00448 XMFileListDialog::GetFileMask() 00449 { 00450 XmString mask_compound; 00451 char *mask; 00452 00453 GetAttribute(XmNdirMask, &mask_compound); 00454 XmStringGetLtoR(mask_compound, XmSTRING_DEFAULT_CHARSET, &mask); 00455 XmStringFree(mask_compound); 00456 return mask; 00457 } 00458 00459 /* 00460 ** Method Description: 00461 ** FileListDialog::GetFullSearchString() - Returns the full directory/search 00462 ** mask string. 00463 ** Returns: 00464 ** char * pointer to a null terminated string containing the mask. 00465 ** The string was XtMalloc'd and must therefore be XtFree'd by the caller 00466 ** after use. 00467 **/ 00468 char* 00469 XMFileListDialog::GetFullSearchString() 00470 { 00471 XmString search_compound; 00472 char *mask; 00473 00474 GetAttribute(XmNdirSpec, &search_compound); 00475 XmStringGetLtoR(search_compound, XmSTRING_DEFAULT_CHARSET, &mask); 00476 XmStringFree(search_compound); 00477 return mask; 00478 } 00479 00480 /* 00481 ** Method Description: 00482 ** XMCustomDialog::CreateDialog: 00483 ** This method create a skeleton custom dialog. Since this class 00484 ** is a superclass for all user defined custom dialogs, nothing is 00485 ** actually managed or popped up until Manage() is called. 00486 ** Formal Parameters: 00487 ** char *name: 00488 ** Name of the dialog... will be applied to the dialog shell. 00489 ** Widget parent: 00490 ** The dialog's parent. 00491 ** char *title: 00492 ** Contains the title that will be displayed on the banner of the dialog 00493 ** shell. 00494 ** ArgList l: 00495 ** List of resource argument which will be applied to the shell. 00496 ** Cardinal num_args: 00497 ** Count of resource argumnts which will be applied to the shell. 00498 */ 00499 void 00500 XMCustomDialog::CreateDialog(char *name, Widget parent, char *title, 00501 ArgList l, Cardinal num_args) 00502 { 00503 00504 /* Create the shell */ 00505 00506 id = XtVaCreatePopupShell(name, xmDialogShellWidgetClass, parent, 00507 XmNtitle, title, 00508 XmNdeleteResponse, XmDESTROY, 00509 NULL); 00510 00511 Widget shell = id; 00512 /* 00513 ** For motif custom dialogs we'll turn off the controls on the title bar. 00514 ** This will prevent closes from accidently destroying our widget 00515 ** Heirarchy. 00516 */ 00517 SetupBorders(id); 00518 00519 if( (num_args > 0) && (l != NULL)) XtSetValues(id, l, num_args); 00520 00521 /* Create a form which is used to allow the modalization to be controlled */ 00522 00523 shell_child = new XMForm("Dialog_Form", id); 00524 00525 /* Create the pane manager widget which manages the dialog elements */ 00526 00527 00528 Arg pane_args[2]; 00529 XtSetArg(pane_args[0], XmNsashWidth, 1); 00530 XtSetArg(pane_args[1], XmNsashHeight,1); 00531 00532 top_manager= new XMPanedWindow("Dialog_toplevel", 00533 *shell_child, pane_args, 2); 00534 /* Glue the pane to all corners of the form: */ 00535 00536 shell_child->SetTopAttachment(*top_manager, XmATTACH_FORM); 00537 shell_child->SetLeftAttachment(*top_manager, XmATTACH_FORM); 00538 shell_child->SetRightAttachment(*top_manager, XmATTACH_FORM); 00539 shell_child->SetBottomAttachment(*top_manager, XmATTACH_FORM); 00540 00541 /* Create the sub region managers: */ 00542 00543 work_area = new XMForm("Dialog_work_area", 00544 *top_manager); 00545 action_area= new XMRowColumn("Dialog_action_area", 00546 *top_manager); 00547 00548 00549 /* Put the buttons in the action area widget */ 00550 00551 action_area->SetOrientation(XmHORIZONTAL); 00552 action_area->SetPacking(XmPACK_COLUMN); 00553 00554 Ok = new XMPushButton("Ok", *action_area); 00555 Apply = new XMPushButton("Apply", *action_area); 00556 Cancel= new XMPushButton("Cancel", *action_area); 00557 Help = new XMPushButton("Help", *action_area); 00558 00559 00560 } 00561 00562 00563 /* 00564 ** Method Description: 00565 ** XMCustomDialog::Manage: 00566 ** This function manages the dialog. This involves managing the 00567 ** action_area, setting it's minimum/maximum pane size to actual 00568 ** pane size, and then managing the form, the pane and popping up the 00569 ** shell. 00570 */ 00571 void 00572 XMCustomDialog::Manage() 00573 { 00574 XtWidgetGeometry size; 00575 00576 /* Manage the action area and set up the pane height, turning off sashes */ 00577 00578 action_area->Manage(); 00579 00580 00581 00582 shell_child->SetTopAttachment(*top_manager, XmATTACH_FORM); 00583 shell_child->SetLeftAttachment(*top_manager, XmATTACH_FORM); 00584 shell_child->SetRightAttachment(*top_manager, XmATTACH_FORM); 00585 shell_child->SetBottomAttachment(*top_manager, XmATTACH_FORM); 00586 00587 XtQueryGeometry(action_area->getid(), NULL, &size); 00588 top_manager->MaxPaneSize(*action_area, size.height); 00589 top_manager->MinPaneSize(*action_area, size.height); 00590 00591 /* Manage the work area, and the paned window: */ 00592 00593 work_area->Manage(); 00594 top_manager->Manage(); 00595 shell_child->Manage(); 00596 00597 /* Pop up the shell: */ 00598 00599 XtPopup(id, XtGrabNone); 00600 00601 } 00602 00603 /* 00604 ** Method Description: 00605 ** XMCustomDialog::UnManage: 00606 ** This method unmanages a custom dialog. 00607 ** It does this by unmanaging the manager widgets and 00608 ** popping down the shell 00609 */ 00610 void 00611 XMCustomDialog::UnManage() 00612 { 00613 shell_child->UnManage(); 00614 XtPopdown(id); 00615 } 00616 00617 /* 00618 ** This page contains help texts which are defaults for the self contained 00619 ** dialog objects. 00620 */ 00621 00622 static char *prompter_help[] = { 00623 "You are being prompted for some text. Type the text in the text window.\n", 00624 " When you have edited the text to look like what you want click: \n\n", 00625 " Ok - To accept the text and remove the dialog.\n", 00626 " Apply - To accept the text and leave the dialog displayed \n", 00627 " Cancel- To cancel dismiss the dialog without accepting the text\n", 00628 " Help - To display this message\n", 00629 NULL 00630 }; 00631 00632 /* 00633 ** Functional Description: 00634 ** XMPrompter::XMPrompter: 00635 ** This method constructs a new prompter object. The object is 00636 ** selfcontained in the sense that callbacks are mapped to method 00637 ** functions. There are two instantiators that work essentially 00638 ** the same way. The only difference is whether or not the parent 00639 ** widget is an objectified widget or an Xt Widget handle. 00640 ** Formal Parameters: 00641 ** char *name: 00642 ** Name of the widget. 00643 ** XMWidget &parent 00644 ** or Widget parent: 00645 ** Identifies the parent widget for this object. 00646 ** char *prompt: 00647 ** Points to the string which specifies the prompt, if non NULL. 00648 ** XtPointer calldata: 00649 ** Optional User data which will be passed to callback routines. 00650 */ 00651 XMPrompter::XMPrompter(char *name, Widget parent, char *prompt, 00652 XtPointer calldata) : 00653 XMPromptDialog(name, parent, prompt), 00654 ok(this), 00655 apply(this), 00656 cancel(this), 00657 help(this) 00658 { 00659 /* Register the callbacks: */ 00660 00661 ok.Register(this, XmNokCallback,&XMPrompter::OkCallback, calldata); 00662 apply.Register(this, XmNapplyCallback, &XMPrompter::ApplyCallback, calldata); 00663 cancel.Register(this, XmNcancelCallback, 00664 &XMPrompter::CancelCallback, calldata); 00665 help.Register(helpbutton, XmNactivateCallback, &XMPrompter::HelpCallback, 00666 calldata); 00667 00668 /* Register the default help text: */ 00669 00670 00671 help_info.name = "Prompt_Help"; 00672 help_info.dialog = NULL; 00673 help_info.text = prompter_help; 00674 } 00675 XMPrompter::XMPrompter(char *name, XMWidget &parent, char *prompt, 00676 XtPointer calldata) : 00677 XMPromptDialog(name, parent, prompt), 00678 ok(this), 00679 apply(this), 00680 cancel(this), 00681 help(this) 00682 { 00683 /* Register the callbacks: */ 00684 00685 ok.Register(this, XmNokCallback, &XMPrompter::OkCallback, calldata); 00686 apply.Register(this, XmNapplyCallback, &XMPrompter::ApplyCallback, calldata); 00687 cancel.Register(this, XmNcancelCallback, &XMPrompter::CancelCallback, calldata); 00688 help.Register(helpbutton, XmNactivateCallback, &XMPrompter::HelpCallback, calldata); 00689 00690 /* Register the default help text: */ 00691 00692 00693 help_info.name = "Prompt_Help"; 00694 help_info.dialog = NULL; 00695 help_info.text = prompter_help; 00696 00697 /* If we have help we should enable the help button: */ 00698 00699 helpbutton->Enable(); 00700 } 00701 00702 /* 00703 ** Functional Description: 00704 ** XMPrompter::~XMPrompter: 00705 ** This method is used to destroy a prompter. All of the callbacks 00706 ** must be unregistersed, and the help widget, if it exists must 00707 ** also be deleted. 00708 */ 00709 XMPrompter::~XMPrompter() 00710 { 00711 ok.UnRegister(); 00712 apply.UnRegister(); 00713 cancel.UnRegister(); 00714 help.UnRegister(); 00715 00716 if(help_info.dialog) delete help_info.dialog; 00717 00718 } 00719 00720 /* 00721 ** Functional Description: 00722 ** XMPrompter::SetHelpText: 00723 ** This function allows the user to set a dialog specific help text 00724 ** in for the prompter object. 00725 ** Formal Parameters: 00726 ** char **newhelp 00727 ** List of null terminated text strings to display in the dialog. 00728 ** The last string pointer should be NULL. 00729 */ 00730 void XMPrompter::SetHelpText(char **new_help) 00731 { 00732 help_info.text = new_help; 00733 } 00734 /* 00735 ** Functional Description: 00736 ** XMPrompter::RevertHelpText: 00737 ** Revert to standard 'generic' help text. 00738 */ 00739 void XMPrompter::RevertHelpText() 00740 { 00741 help_info.text = prompter_help; 00742 } 00743 00744 /* 00745 ** Functional Description: 00746 ** XMPrompter::Perform: 00747 ** This function is meant to be overridden by the person specializing 00748 ** this dialog. The override should perform the application specific 00749 ** task and then return True if the task was properly performed or 00750 ** False if not. The boolean is used by the OkCallback to decide if 00751 ** it's necessary to dismiss the dialog. 00752 ** Formal Parameters: 00753 ** XMWidget *wid: 00754 ** This pointer actually. 00755 ** XtPointer userd: 00756 ** Application specific callback data. 00757 ** XtPointer calld: 00758 ** Actually points to an XmSelectionBoxCallbackStruct which 00759 ** describes what's happening. 00760 ** Returns: 00761 ** True - If action was successfully performed. 00762 ** False - If action was not successfully performed. 00763 */ 00764 Boolean XMPrompter::Perform(XMWidget *wid, XtPointer userd, XtPointer calld) 00765 { 00766 XmSelectionBoxCallbackStruct *info = (XmSelectionBoxCallbackStruct *)calld; 00767 00768 assert((info->reason == XmCR_APPLY) || 00769 (info->reason == XmCR_OK)); // This for debugging. 00770 00771 return True; // default does nothing but Ok dismisses 00772 } 00773 00774 /* 00775 ** Functional Description: 00776 ** XMPrompter::OkCallback: 00777 ** This virtual function is called in response to the 00778 ** Ok Button. In most cases, the default action should be sufficient, 00779 ** however, the function is virtual to allow easy replacement without 00780 ** worry about handling generic dialogs. The Default action is 00781 ** to call Perform to get the appropriate stuff done. If Perform 00782 ** returns True, then we unmanage ourself. 00783 ** XMPRompter::ApplyCallback: 00784 ** Virtual function called in response to the Apply button. 00785 ** Normallly the default action, to call Perform, will be sufficient. 00786 ** The function is declared virtual to allow hassle free overrides. 00787 ** Formal Parameters: 00788 ** XMWidget *wid: 00789 ** Pointer to the widget (this) 00790 ** XtPointer userd: 00791 ** User data that we're supposed to pass on to perform. 00792 ** XtPointer calld: 00793 ** Callback specific data from motif which we pass into Perform. 00794 ** It's really pointing to an XmSelectionBoxCallbackStruct. 00795 */ 00796 void XMPrompter::OkCallback(XMWidget *wid, XtPointer userd, XtPointer calld) 00797 { 00798 if(Perform(wid, userd, calld)) 00799 UnManage(); 00800 } 00801 void XMPrompter::ApplyCallback(XMWidget *wid, XtPointer userd, XtPointer calld) 00802 { 00803 Perform(wid, userd, calld); 00804 } 00805 00806 /* 00807 ** Functional description: 00808 ** XMPrompter::CancelCallback: 00809 ** This function is called for a cancel hit. Normally, the default 00810 ** action, to unmanage the dialog should be sufficient. However 00811 ** the function is virtual to allow easy override in case there are 00812 ** special requirements. 00813 ** Formal Parameters: 00814 ** As for all callbacks. 00815 */ 00816 void XMPrompter::CancelCallback(XMWidget *wind, XtPointer userd, 00817 XtPointer calld) 00818 { 00819 UnManage(); 00820 } 00821 00822 /* 00823 ** Functional Description: 00824 ** XMPrompter::HelpCallback: 00825 ** This function is called whenever the help button is struck. 00826 ** The default is to display a message/help dialog box whith the text 00827 ** that was specified in the lsat SetHelpText call or the default 00828 ** help text. 00829 */ 00830 void XMPrompter::HelpCallback(XMWidget *wind, XtPointer userd, XtPointer calld) 00831 { 00832 XM_display_help( this, &help_info, NULL); 00833 } 00834 00835 /* 00836 ** Functional Description: 00837 ** XMQuestioner::XMQuestioner: 00838 ** This method instantiates a dialog which poses a yes/no question 00839 ** The XMQuestioner class includes self contained behavior in the 00840 ** sense that the two buttons (labelled Yes and No by default) are 00841 ** associated with callback which are methods of the object. 00842 ** Formal Parameters: 00843 ** char *n: 00844 ** Name of the question dialog widget.. also shown in the title part of 00845 ** the widget banner. 00846 ** XMWidget parent: 00847 ** Widget &parent: 00848 ** Widget which is the parent of this widget. 00849 ** char *msg: 00850 ** Contains message text displayed in the dialog. This should be a 00851 ** question with a yes or no answer or the buttons should be re-labelled 00852 ** with the appropriate two answers. 00853 ** XtPointer cbd: 00854 ** Callback data which is passed to the Yes and No callback functions. 00855 ** Arglist list: 00856 ** Pointer to list of resources to override default widget resources 00857 ** Cardinal argcount: 00858 ** Number of resource entries in 'list' 00859 */ 00860 XMQuestioner::XMQuestioner(char *n, Widget parent, char *msg, XtPointer cbd, 00861 ArgList list, Cardinal argcount) : 00862 XMQuestionDialog(n, parent, msg, 00863 NULL, cbd, list, 00864 argcount) , 00865 yescallback(this) , 00866 nocallback(this) 00867 { 00868 yescallback.Register(this, XmNokCallback, &XMQuestioner::Yescb, cbd); 00869 nocallback.Register(this, XmNcancelCallback, &XMQuestioner::Nocb, cbd); 00870 00871 } 00872 XMQuestioner::XMQuestioner(char *n, XMWidget &parent, char *msg, XtPointer cbd, 00873 ArgList list, Cardinal argcount) : 00874 XMQuestionDialog(n, parent, msg, 00875 NULL, cbd, list, 00876 argcount) , 00877 yescallback(this) , 00878 nocallback(this) 00879 { 00880 yescallback.Register(this, XmNokCallback, &XMQuestioner::Yescb, cbd); 00881 nocallback.Register(this, XmNcancelCallback, &XMQuestioner::Nocb, cbd); 00882 00883 } 00884 00885 00886 /* 00887 ** Functional Description: 00888 ** XMQuestioner::~XMQuestioner: 00889 ** Destroys an instance of a questioner class. 00890 */ 00891 XMQuestioner::~XMQuestioner() 00892 { 00893 yescallback.UnRegister(); 00894 nocallback.UnRegister(); 00895 } 00896 00897 /* 00898 ** Functional Descriptions: 00899 ** XMQuestioner::Yescb: 00900 ** Virtual function called when the yes button is pressed. 00901 ** default action is to unmanage the dialog box. This function 00902 ** is usually overridden. 00903 ** XMQuestioner::Nocb: 00904 ** Virtual method called when the no button is pressed. 00905 ** default action is to unmanage the dialog box. This function 00906 ** is sometimes overridden. 00907 ** Formal Parameters: 00908 ** XMWidget *wid: 00909 ** The dialog widget itself. 00910 ** XtPointer userd: 00911 ** User data ignored by us. 00912 ** XtPointer calld: 00913 ** Callback data of the form XmAnyCallbackStruct. 00914 */ 00915 void XMQuestioner::Yescb(XMWidget *wid, XtPointer userd, XtPointer calld) 00916 { 00917 UnManage(); 00918 } 00919 00920 void XMQuestioner::Nocb(XMWidget *wid, XtPointer userd, XtPointer calld) 00921 { 00922 UnManage(); 00923 } 00924 00925 /* 00926 ** Default help text for selection box widgets.: 00927 */ 00928 00929 static char *SelectionDefaultHelp[] = { 00930 " You are being asked to select an item from the list of choices\n", 00931 "in the list box part of the widget. You can select an item either by\n", 00932 "clicking on it with the mouse or by typing it into the text input\n", 00933 "area below the list box. Once you have made your selection, you should\n", 00934 "click a button in the action area at the bottom of the dialog where: \n\n", 00935 " Ok - Will accept your choice and dismiss the dialog\n", 00936 " Apply - Will accept your choice and leave the dialog displayed\n", 00937 " Cancel - Will dismiss the dialog without any action\n", 00938 " Help - Will display this text\n", 00939 NULL 00940 }; 00941 /* 00942 ** Functional Description: 00943 ** XMSelector::XMSelector: 00944 ** This method constructs an instance of a self contained selector 00945 ** dialog. A selector dialog is used to choose one item from 00946 ** a list of choices. The user's choice can be confined to those in the 00947 ** list or expanded beyond those in the list. The selector is 00948 ** Somewhat incomplete and minimally, the client will usually need 00949 ** to supersede the SetupList and Perform methods. 00950 ** Formal Parameters: 00951 ** char *n: 00952 ** Name to be given to the dialog widget. 00953 ** Widget parent: 00954 ** XMWidget &parent: 00955 ** Identifies the parent of this dialog. 00956 ** char *prompt: 00957 ** Prompt string (put near the type-in box). 00958 ** XtPointer cbd: 00959 ** Data to pass to various callbacks. 00960 ** ArgList list: 00961 ** List of resources which override the default resource sets of the 00962 ** widget. 00963 ** Cardinal argcount: 00964 ** Number of override resource value pairs in list. 00965 */ 00966 XMSelector::XMSelector(char *name, Widget parent, char *prompt, 00967 XtPointer cbd, ArgList list, Cardinal argcount) : 00968 XMSelectionDialog(name, parent, prompt, NULL, 00969 cbd, list, argcount), 00970 okbuttonCB(this), 00971 applybuttonCB(this), 00972 cancelbuttonCB(this), 00973 helpbuttonCB(this), 00974 nomatchCB(this) 00975 { 00976 00977 /* Register the callbacks... */ 00978 00979 00980 okbuttonCB.Register(this, XmNokCallback, &XMSelector::OkCb, cbd); 00981 applybuttonCB.Register(this, XmNapplyCallback, &XMSelector::ApplyCb, cbd); 00982 cancelbuttonCB.Register(this, XmNcancelCallback, &XMSelector::CancelCb, cbd); 00983 nomatchCB.Register(this, XmNnoMatchCallback, &XMSelector::NoMatchCb, cbd); 00984 helpbuttonCB.Register(helpbutton, XmNactivateCallback, &XMSelector::HelpCb, cbd); 00985 00986 /* Set up the help button with the default help text.: */ 00987 00988 helpbutton->Enable(); 00989 helpinfo.name = "SelectionHelp"; 00990 helpinfo.dialog = (XMInformationDialog *)NULL; 00991 helpinfo.text = SelectionDefaultHelp; 00992 00993 /* Set the initial list values: */ 00994 00995 SetupList(); 00996 00997 } 00998 XMSelector::XMSelector(char *name, XMWidget &parent, char *prompt, 00999 XtPointer cbd, ArgList list, Cardinal argcount) : 01000 XMSelectionDialog(name, parent, prompt, NULL, 01001 cbd, list, argcount), 01002 okbuttonCB(this), 01003 applybuttonCB(this), 01004 cancelbuttonCB(this), 01005 helpbuttonCB(this), 01006 nomatchCB(this) 01007 { 01008 01009 /* Register the callbacks... */ 01010 01011 01012 okbuttonCB.Register(this, XmNokCallback, &XMSelector::OkCb, cbd); 01013 applybuttonCB.Register(this, XmNapplyCallback, &XMSelector::ApplyCb, cbd); 01014 cancelbuttonCB.Register(this, XmNcancelCallback, &XMSelector::CancelCb, cbd); 01015 nomatchCB.Register(this, XmNnoMatchCallback, &XMSelector::NoMatchCb, cbd); 01016 helpbuttonCB.Register(helpbutton, XmNactivateCallback, &XMSelector::HelpCb, cbd); 01017 01018 /* Set up the help button with the default help text.: */ 01019 01020 helpbutton->Enable(); 01021 helpinfo.name = "SelectionHelp"; 01022 helpinfo.dialog = (XMInformationDialog *)NULL; 01023 helpinfo.text = SelectionDefaultHelp; 01024 01025 /* Set up the initial list values: */ 01026 01027 /* This should be done by a derived class. */ 01028 01029 } 01030 /* 01031 ** Functional Description: 01032 ** XMSelector::~XMSelector: 01033 ** This method is responsible for destroying an instance of the 01034 ** selector. The main thing that we need to do is to release the 01035 ** dynamic storage associated with the callbacks by unregistering them. 01036 */ 01037 XMSelector::~XMSelector() 01038 { 01039 okbuttonCB.UnRegister(); 01040 applybuttonCB.UnRegister(); 01041 cancelbuttonCB.UnRegister(); 01042 nomatchCB.UnRegister(); 01043 helpbuttonCB.UnRegister(); 01044 01045 } 01046 01047 /* 01048 ** Functional Description: 01049 ** XMSelector::SetupList: 01050 ** This function sets up the initial display list. This is the 01051 ** default method which is intended to be overridden by the derived 01052 ** classes. The default method does nothing. 01053 */ 01054 void XMSelector::SetupList() 01055 { 01056 01057 } 01058 01059 /* 01060 ** Functional Description: 01061 ** XMSelector::SetHelpText: 01062 ** This function replaces the help text with user defineable help text 01063 ** The help text is a list of string pointers to null terminated strings 01064 ** terminated by a null pointer (see the default help text for an 01065 ** example. 01066 ** Formal Parameters: 01067 ** char **newhelp: 01068 ** New help text. 01069 */ 01070 void XMSelector::SetHelpText(char **newhelp) 01071 { 01072 helpinfo.text = newhelp; 01073 } 01074 /* 01075 ** Functional Description: 01076 ** XMSelector::RevertHelpText: 01077 ** This method restores the default help text. 01078 */ 01079 void XMSelector::RevertHelpText() 01080 { 01081 helpinfo.text = SelectionDefaultHelp; 01082 } 01083 01084 /* 01085 ** Functional Descriptions: 01086 *** XMSelector::OkCb: 01087 ** Callback for the Ok button of the dialog. 01088 ** XMSelector::NoMatchCb: 01089 ** Callback for any click with no match. 01090 ** XMSelector::ApplyCb: 01091 ** Callback for apply button. 01092 ** XMSelector::CancelCb: 01093 ** Callback for cancel button. 01094 ** XMSelector::HelpCb: 01095 ** Callback for help button. 01096 ** 01097 ** These all take relatively default actions which can be overridden by 01098 ** the deriver. Usually, the deriver will override, Perform, however 01099 ** since the other callbacks give a standardized behavior to the dialog 01100 ** widget. 01101 ** Formal Parameters: 01102 ** XMWidget *wid: 01103 ** The widget which invoked the callback. 01104 ** XtPointer userd: 01105 ** user specific call data. 01106 ** XtPointer cd: 01107 ** Callback Specific data in this case a pointer to an 01108 ** XmSelectionBoxCallbackStruct 01109 */ 01110 void XMSelector::OkCb(XMWidget *wid, XtPointer userd, XtPointer cd) 01111 { 01112 XmSelectionBoxCallbackStruct *calldata = (XmSelectionBoxCallbackStruct *)cd; 01113 01114 if(Perform(wid, userd, 01115 calldata->reason, calldata->value, calldata->length)) 01116 UnManage(); 01117 01118 } 01119 void XMSelector::ApplyCb(XMWidget *wid, XtPointer userd, XtPointer cd) 01120 { 01121 XmSelectionBoxCallbackStruct *calldata = (XmSelectionBoxCallbackStruct *)cd; 01122 01123 Perform(wid, userd, 01124 calldata->reason, calldata->value, calldata->length); 01125 } 01126 void XMSelector::NoMatchCb(XMWidget *wid, XtPointer userd, XtPointer cd) 01127 { 01128 XmSelectionBoxCallbackStruct *calldata = (XmSelectionBoxCallbackStruct *)cd; 01129 01130 if(Perform(wid, userd, 01131 calldata->reason, calldata->value, calldata->length)) 01132 UnManage(); 01133 01134 } 01135 01136 void XMSelector::CancelCb(XMWidget *wid, XtPointer cd, XtPointer ud) 01137 { 01138 UnManage(); 01139 } 01140 01141 void XMSelector::HelpCb(XMWidget *cb, XtPointer cd, XtPointer ud) 01142 { 01143 XM_display_help(cb, (XtPointer)&helpinfo, ud); 01144 } 01145 01146 /* 01147 ** Functional Description: 01148 ** XMSelector::Perform: 01149 ** This method is intended to be overridden by the deriver. 01150 ** In a typical case, the deriver will override SetupLIst and 01151 ** Perform to get everything needed to do application sensitive list 01152 ** processing. 01153 ** Formal Parameters: 01154 * XMWidget *wid: 01155 ** The widget invoking us, most often this is the object's this pointer. 01156 ** XtPointer cd: 01157 ** User supuplied call data. 01158 ** int reason: 01159 ** Why the callback is called, can be any of: 01160 ** XmCR_APPLY: 01161 ** The apply button was pressed. 01162 ** XmCR_OK: 01163 ** The Ok button was clicked. 01164 ** XmCR_NO_MATCH: 01165 ** There was an accept with no match in the field. Note that 01166 ** in this case we treat the return value the same as for an accept. 01167 ** XMString value: 01168 ** The text representing the user's choice. 01169 ** int size: 01170 ** number of characters in the user's choice. 01171 ** Return Value: 01172 ** True: 01173 ** Valid action was taken. The dialog is dismissed if OK or NO_MATCH. 01174 ** False: 01175 ** No valid action was taken, the dialog remains if OK or NO_MATCH. 01176 */ 01177 Boolean XMSelector::Perform(XMWidget *wid, XtPointer cd, 01178 int reason, XmString value, int size) 01179 { 01180 return True; 01181 } 01182 01183 /* 01184 ** The methods in the pages which follow implement the functions of the 01185 ** XMFileSelector dialog. 01186 */ 01187 01188 static char *FileSelectorHelp[] = // Default help text for file selector. 01189 { 01190 " You are being prompted a filename. If you know the complete name of\n", 01191 "the file, you can type it in at the text box at the bottom of the work\n", 01192 "area of the dialog. If you don't know the name of the file then you can\n", 01193 "use the facilities of the file selection box to browse the directory\n", 01194 "tree to hunt for a suitable file name.\n", 01195 " The left list is the set of directories one level below the current\n", 01196 "directory. There's also a ", 01197 #ifdef unix 01198 ".. for the next level up. ", 01199 #elif VMS 01200 "[-] for the next level up. ", 01201 #endif 01202 "To move into one\n", 01203 "of these directories double click on the directory name in the left box\n", 01204 " The text type-in at the top of the work area allows you to type in\n", 01205 "an arbitrary filter string. A filter string consists of a directory\n", 01206 "specification and a file search string which can contain wild card\n", 01207 "characters (and usually does to be useful). Typing in a new filter\n", 01208 "string and hitting return or clicking on the Filter button will move you\n", 01209 "to the appropriate directory and display the files matching the search\n", 01210 "string in the right hand list\n", 01211 " The right list contains the set of files in the current directory\n", 01212 "which match the search string. To select a file you can click on it\n", 01213 "Double clicking is identical to a click followed by clicking the Ok \n", 01214 "button.\n", 01215 " The buttons at the bottom of the dialog perform the following actions\n", 01216 "when clicked:\n\n", 01217 " Ok - Accepts the selection and dismisses the dialog.\n", 01218 " Filter - Re-applies the search string in the current directory\n", 01219 " Cancel - Dismisses the dialog without accepting any filename.\n", 01220 " Help - Displays this help text\n", 01221 NULL 01222 }; 01223 01224 /* 01225 ** Functional Description: 01226 ** XMFileSelector::XMFileSelector: 01227 ** This method constructs an instance of a file selector dialog. 01228 ** The file selector dialog is a self contained Motif widget which 01229 ** allows the user to choose a filename. Constructing an instance 01230 ** consists of: 01231 ** 1. Calling the constructor for XMFileListDialog to build the widget. 01232 ** 2. Calling the constructors for the callback elements to set their 01233 ** object fields. 01234 ** 3. Registering the callback functions. The callback functions are 01235 ** intended to be overridden, if necessary, by the client. 01236 ** 4. Setting up the default help text. The SetHelpText method 01237 ** allows a client to supply application specific help text. 01238 ** 01239 ** Formal Parameters: 01240 ** char *n: 01241 ** Specifies the name of the dialog widget. This will also appear 01242 ** in the banner of the dialog. 01243 ** Widget parent: 01244 ** XMWidget &parent: 01245 ** Specifies which widget or widget object will be the parent of the 01246 ** dialog widget shell. 01247 ** XtPointer ud: 01248 ** User data passed to the callback methods. This defaults to NULL. 01249 ** char *directory: 01250 ** Specifies the initial search directory. Note that if the 01251 ** search directory is not specified, then the XMFILE_DEFAULT_DIRMASK 01252 ** is used instead. This corresponds to the current working directory 01253 ** as of the time Xamine was started. 01254 ** Note: 01255 ** There is more than one constructor binding. 01256 */ 01257 01258 XMFileSelector::XMFileSelector(char *n, Widget parent, XtPointer calld, 01259 char *directory) : 01260 XMFileListDialog(n, parent, directory), 01261 okcb(this), 01262 nomatchcb(this), 01263 filtercb(this), 01264 cancelcb(this), 01265 helpcb(this) 01266 { 01267 /* Register the callbacks, note that apply is usurped for the filter 01268 ** function (Motif's decision, not mine). 01269 */ 01270 01271 okcb.Register(this, XmNokCallback, &XMFileSelector::FilterCb, calld); 01272 nomatchcb.Register(this, XmNnoMatchCallback, // Requires XmNmustMatch to be 01273 &XMFileSelector::NomatchCb, calld); // True to invoke. 01274 filtercb.Register(this, XmNapplyCallback, &XMFileSelector::FilterCb, calld); 01275 cancelcb.Register(this, XmNcancelCallback, &XMFileSelector::CancelCb, calld); 01276 helpcb.Register(this, XmNhelpCallback, &XMFileSelector::HelpCb, calld); 01277 01278 /* Set up the help info data structure */ 01279 01280 helpinfo.name = "File_Selection_Help"; 01281 helpinfo.dialog = (XMInformationDialog *)NULL; 01282 RevertHelpText(); 01283 } 01284 XMFileSelector::XMFileSelector(char *n, XMWidget &parent, 01285 XtPointer calld, 01286 char *directory) : 01287 XMFileListDialog(n, parent, directory), 01288 okcb(this), 01289 nomatchcb(this), 01290 filtercb(this), 01291 cancelcb(this), 01292 helpcb(this) 01293 { 01294 /* Register the callbacks, note that apply is usurped for the filter 01295 ** function (Motif's decision, not mine). 01296 */ 01297 01298 okcb.Register(this, XmNokCallback, &XMFileSelector::OkCb, calld); 01299 nomatchcb.Register(this, XmNnoMatchCallback, // Requires XmNmustMatch to be 01300 &XMFileSelector::NomatchCb, calld); // True to invoke. 01301 filtercb.Register(this, XmNapplyCallback, &XMFileSelector::FilterCb, calld); 01302 cancelcb.Register(this, XmNcancelCallback, &XMFileSelector::CancelCb, calld); 01303 helpcb.Register(this, XmNhelpCallback, &XMFileSelector::HelpCb, calld); 01304 01305 /* Set up the help info data structure */ 01306 01307 helpinfo.name = "File_Selection_Help"; 01308 helpinfo.dialog = (XMInformationDialog *)NULL; 01309 RevertHelpText(); 01310 01311 /* Enable the help button: */ 01312 01313 helpbutton->Enable(); 01314 } 01315 01316 /* 01317 ** Functional Description: 01318 ** XMFileSelector::~XMFileSelector: 01319 ** This method destroys the file selector widget. The only dynamic 01320 ** storage that exists is associated with the registerd callbacks. 01321 ** Therefore we unregister all callbacks. 01322 */ 01323 01324 XMFileSelector::~XMFileSelector() 01325 { 01326 okcb.UnRegister(); 01327 nomatchcb.UnRegister(); 01328 filtercb.UnRegister(); 01329 cancelcb.UnRegister(); 01330 helpcb.UnRegister(); 01331 } 01332 01333 /* 01334 ** Functional Description: 01335 ** XMFileSelector::SetHelpText: 01336 ** This function sets the help text associated with the widget. 01337 ** Formal Parameters: 01338 ** char **text: 01339 ** This is a list of character string pointers terminated by a null 01340 ** pointer. Each string itself is Null terminated. 01341 */ 01342 void XMFileSelector::SetHelpText(char **text) 01343 { 01344 helpinfo.text = text; 01345 } 01346 01347 /* 01348 ** FunctionalDescription: 01349 ** XMFileSelector::RevertHelpText: 01350 ** Reverts the help text to the default text. 01351 */ 01352 01353 void XMFileSelector::RevertHelpText() 01354 { 01355 helpinfo.text = FileSelectorHelp; 01356 } 01357 01358 01359 /* 01360 ** The functions which follow are hooked in to the callbacks. 01361 ** While they can be overridden, they provide default behavior which is 01362 ** in keeping with the Motif style guide usage of these widgets. It's best 01363 ** to only override the Perform method which is defined as a NOP so that 01364 ** the base class is testable. 01365 */ 01366 01367 /* 01368 ** Functional Description: 01369 ** Boolean Perform: 01370 ** This function takes application dependent action on accepted filenames. 01371 ** This function is normally overridden in classes derived from the 01372 ** XMFileSelector with an application specific method. 01373 ** 01374 ** Parameters: 01375 ** XMWidget *wid: 01376 ** Pointer to the widget object which invokes us...usually this dialog. 01377 ** XtPointer ud: 01378 ** User supplied data supplied at constructor time. 01379 ** char *filename: 01380 ** The name of the file which was received from the user. 01381 ** int reason: 01382 ** The callback reason which can be either of: 01383 ** XmCR_OK - Ok button was pressed. 01384 ** XmCR_NO_MATCH - Chooser in must match mode and file entered not on 01385 ** list. 01386 ** XmCR_APPLY - Is only possible if the FilterCb method is 01387 ** overridden with a method which calls Perform or 01388 ** OkCb. 01389 ** 01390 ** Returns: 01391 ** True - If the required function was performed, and the dialog 01392 ** can be dismissed if appropriate. 01393 ** False - If the client would like the dialog to remain. 01394 */ 01395 Boolean XMFileSelector::Perform(XMWidget *wid, XtPointer ud, 01396 char *filename, int reason) 01397 { 01398 return True; // Default to No-Op all done with dialog. 01399 } 01400 01401 /* 01402 ** Functional Description: 01403 ** XMFileSelector::OkCb: 01404 ** Method called when the Ok button is clicked. We repackage the 01405 ** filename string as an ASCIZ C string and call the Perform method. 01406 ** If Perform returns true, then we unmanage the dialog. The user must 01407 ** explicitly destroy the dialog since: 01408 ** a) We don't know if the dialog is dynamically allocated. 01409 ** b) Even if it is dynamic, the user may want to cache it for later use. 01410 ** Formal Parameters: 01411 ** XMWidget *wid: 01412 ** This pointer usually. 01413 ** XtPointer ud: 01414 ** User data passed to perform without interpretation. 01415 ** XtPointer cd: 01416 ** Call data which is of the form of a pointer to an 01417 ** XmFileSelectionBoxCallbackStruct (whew). Where value and length 01418 ** describe the filename. 01419 */ 01420 void XMFileSelector::OkCb(XMWidget *wid, XtPointer ud, XtPointer cd) 01421 { 01422 /* Pull the string out of the callback structure: */ 01423 01424 XmFileSelectionBoxCallbackStruct *calldata = 01425 (XmFileSelectionBoxCallbackStruct *)cd; 01426 01427 char *filename; 01428 01429 if(!XmStringGetLtoR(calldata->value, XmSTRING_DEFAULT_CHARSET, 01430 &filename)) { 01431 new XMErrorDialog("Error Message", 01432 *wid, 01433 "Unable to retrieve filename string", 01434 XMDestroyWidget); 01435 } 01436 else { 01437 if(Perform(wid, ud, filename, calldata->reason)) { 01438 UnManage(); 01439 } 01440 XtFree(filename); 01441 } 01442 } 01443 01444 /* 01445 ** Functional Description: 01446 ** XMFileSelector::NomatchCb: 01447 ** Called when the user types in a filename not in the list. 01448 ** In this case we really could just call *our* OkCb since 01449 ** that routine passes the reason from the callback data rather 01450 ** than assuming it's XmCR_OK 01451 ** Formal Parameters: 01452 ** XMWidget *wid: 01453 ** This pointer usually. 01454 ** XtPointer ud: 01455 ** User data passed to perform without interpretation. 01456 ** XtPointer cd: 01457 ** Call data which is of the form of a pointer to an 01458 ** XmFileSelectionBoxCallbackStruct (whew). Where value and length 01459 ** describe the filename. 01460 */ 01461 01462 void XMFileSelector::NomatchCb(XMWidget *wid, XtPointer ud, XtPointer cd) 01463 { 01464 XMFileSelector::OkCb(wid, ud, cd); // Make sure it's *our* OkCb that's called 01465 } 01466 01467 /* 01468 ** Functional Description: 01469 ** XMFileSelector::FilterCb: 01470 ** This function is called when the filter button is pressed. 01471 ** This function is a No-op because I believe that the filter button 01472 ** has a callback attached by motif to do the actual filtering. 01473 ** The callback is intended for any application specific processing 01474 ** that might be required. 01475 ** Formal Parameters: 01476 ** as for any callback 01477 */ 01478 01479 void XMFileSelector::FilterCb(XMWidget *wid, XtPointer ud, XtPointer cd) 01480 { 01481 } 01482 01483 /* 01484 ** Functional Description: 01485 ** XMFileSelector::CancelCb: 01486 ** This method is called when the cancel button is pressed. 01487 ** The default action is to unmanage the dialog. 01488 ** Formal Parameters: 01489 ** As for all callbacks, ignored in this case. 01490 */ 01491 01492 void XMFileSelector::CancelCb(XMWidget *wid, XtPointer ud, XtPointer cd) 01493 { 01494 UnManage(); 01495 } 01496 01497 /* 01498 ** Functional Description: 01499 ** XMFileSelector::HelpCb: 01500 ** This function is called when the help button is pressed. The 01501 ** default action is to display a help dialog described by the 01502 ** helpinfo attribute. The text in this dialog can be altered 01503 ** by clients using the SetHelpText method. Further fancier stuff 01504 ** can be done by superseding this method. 01505 ** Formal Parameters: 01506 ** XMWidget *wid: 01507 ** Usually the pointer to the help button. 01508 ** XtPointer ud: 01509 ** Userdata ignored. 01510 ** XtPointer cd: 01511 ** Call data ignored. 01512 */ 01513 01514 void XMFileSelector::HelpCb(XMWidget *wid, XtPointer ud, XtPointer cd) 01515 { 01516 XM_display_help(this, &helpinfo); 01517 } 01518 01519 01520 /* 01521 ** The following pages define the self contained custom dialog box class 01522 ** method functions. A self contained custom dialog box (XMCustomDialogBox) 01523 ** is derived from the XMCustomDialog in a manner which allows it to have 01524 ** callback methods rather than external functions as the button methods. 01525 */ 01526 01527 /* 01528 ** We provide default help text for the custom dialog box, however because 01529 ** it is really difficult to generically describe a custom dialog box, 01530 ** the user will typically have to replace this text using SetHelpText. 01531 */ 01532 static char *custom_help[] = { 01533 " This is a custom dialog box which was created by a programmer that was\n", 01534 "too lazy to supply detailed help text about what the dialog does. Since\n", 01535 "the work area of the dialog box could be almost anything, I cannot be\n", 01536 "much of a help about what to do there. What I can say, however is that\n", 01537 "after you've done what you need to do in the work area, you should select\n", 01538 "one of the following buttons from the action area:\n\n", 01539 " Ok - Generally accepts what ever you've done and removes the\n", 01540 " dialog box assuming everything was done properly\n", 01541 " Apply - Generally the same as Ok, but leaves the dialog box up.\n", 01542 " Cancel - Generally takes no action, but dismisses the dialog box\n", 01543 " Help - Causes this helpful message to appear.\n\n", 01544 "NOTE: If you know who wrote this program, then bother the hell out of \n", 01545 " that person to replace this help text with something more specific\n", 01546 " to the application\n", 01547 NULL 01548 }; 01549 01550 /* 01551 ** Functional Description: 01552 ** XMCustomDialogBox: 01553 ** These functions instantiate a custom dialog box. A custom dialog 01554 ** box is a self contained dialog box with a work area filled in by the 01555 ** box creator. Therefore this class just provides some common behavior 01556 ** and the client is expected to subclass an appropriate version for 01557 ** The desired needs. 01558 ** Formal Parameters: 01559 ** char *name: 01560 ** Name of the custom dialog box (actually top level shell name). 01561 ** XMWidget &parent: 01562 ** References the widget which will parent the widget tree that we're 01563 ** creating. 01564 ** char *title: 01565 ** The text which will be placed in the banner of the dialog. 01566 ** ArgList l: 01567 ** List of resources which will be applied at widget creation time. 01568 ** Cardinal num_args: 01569 ** Number of arguments in l. 01570 */ 01571 01572 XMCustomDialogBox::XMCustomDialogBox(char *name,XMWidget &parent, char *title, 01573 ArgList l, Cardinal num_args) : 01574 XMCustomDialog(name, parent, title, l, num_args), 01575 OkCb(this), 01576 ApplyCb(this), 01577 CancelCb(this), 01578 HelpCb(this) 01579 { 01580 SetCallbacks(); // Register the callbacks. 01581 RevertHelpText(); // And set the default help text. 01582 } 01583 01584 XMCustomDialogBox::XMCustomDialogBox(char *name, Widget parent, char *title, 01585 ArgList l, Cardinal num_args) : 01586 XMCustomDialog(name, parent, title, l, num_args), 01587 OkCb(this), 01588 ApplyCb(this), 01589 CancelCb(this), 01590 HelpCb(this) 01591 { 01592 SetCallbacks(); // Register the callbacks. 01593 InitializeHelp(); // And set the default help text. 01594 } 01595 01596 01597 /* 01598 ** Functional Description: 01599 ** XMCustomDialogBox::~XMCustomDialogBox 01600 ** This method deletes a custom dialog box. The only thing required 01601 ** is to unregister all of the callbacks. 01602 */ 01603 01604 XMCustomDialogBox::~XMCustomDialogBox() 01605 { 01606 OkCb.UnRegister(); 01607 ApplyCb.UnRegister(); 01608 CancelCb.UnRegister(); 01609 HelpCb.UnRegister(); 01610 01611 } 01612 01613 /* 01614 ** This page contains functions to manage and setup the help text in case 01615 ** the user (as they should) decides to override the default help text 01616 */ 01617 01618 /* 01619 ** Functional Description: 01620 ** XMCustomDialogBox::SetHelpText: 01621 ** Overrides the default help text. 01622 ** Formal Parameters: 01623 ** char **help: 01624 ** Points to the help text string list. 01625 */ 01626 01627 void XMCustomDialogBox::SetHelpText(char **help) 01628 { 01629 help_info.text = help; // Set new help text. 01630 } 01631 01632 /* 01633 ** Functional Description: 01634 ** XMCustomDialogBox::RevertHelpText: 01635 ** Reverts to default help text. 01636 */ 01637 01638 void XMCustomDialogBox::RevertHelpText() 01639 { 01640 help_info.text = custom_help; 01641 } 01642 01643 /* 01644 ** This page contains callback functions. As for all of the 01645 ** self contained dialogs, the Ok and Apply callbacks will call a Perform 01646 ** function which does the application specific stuff, while the 01647 ** Ok and Apply callback functions take care of widget management. 01648 ** We also supply a help callback and a cancel callback which should be 01649 ** sufficient for most of our needs. 01650 */ 01651 01652 /* 01653 ** Functional Description: 01654 ** XMCustomDialogBox::perform: 01655 ** This virtual function must be overridden by a subclasser to make the 01656 ** dialog do anything useful. Default action is to dismiss the dialog 01657 ** without taking any action (like Cancel). 01658 ** Formal Parameters: 01659 ** XMWidget *wid: 01660 ** Points to the widget that called us. This will typically be the 01661 ** appropriate button widget. 01662 ** XtPointer cli: 01663 ** This is the client data which was established on the registration of the 01664 ** callback. Currently this is one of XmCR_APPLY, if the apply button was 01665 ** hit or XmCR_OK if the OK button was the one that was hit. 01666 ** XtPointer call: 01667 ** This is the call data which in the case of this class is a pointer to 01668 ** XmPushButtonCallbackStruct. 01669 ** Returns: 01670 ** True: 01671 ** If the user's function was successfully accomplished. 01672 ** False: 01673 ** If the user's function was not accomplished. 01674 */ 01675 Boolean XMCustomDialogBox::Perform(XMWidget *wid, XtPointer cli, 01676 XtPointer call) 01677 { 01678 return True; 01679 } 01680 01681 /* 01682 ** Functional Description: 01683 ** XMCustomDialogBox::OkPressed: 01684 ** This method is called when the Ok button is pressed. It calls 01685 ** Perform() and unmanages the dialog box if Perform returns True. 01686 ** Formal Parameters: 01687 ** XMWidget *wid: 01688 ** Points to the widget that called us. This will typically be the 01689 ** appropriate button widget. 01690 ** XtPointer cli: 01691 ** This is the client data which was established on the registration of the 01692 ** callback. Currently this is one of XmCR_APPLY, if the apply button was 01693 ** hit or XmCR_OK if the OK button was the one that was hit. 01694 ** XtPointer call: 01695 ** This is the call data which in the case of this class is a pointer to 01696 ** XmPushButtonCallbackStruct. 01697 */ 01698 void XMCustomDialogBox::OkPressed(XMWidget *wid, XtPointer cli, XtPointer call) 01699 { 01700 if(Perform(wid, cli, call)) 01701 UnManage(); 01702 } 01703 01704 /* 01705 ** Functional Description: 01706 ** XMCustomDialogBox::ApplyPressed: 01707 ** Processes the Apply button. We keep the dialog box displayed 01708 ** no matter what happens. 01709 ** Formal Parameters: 01710 ** XMWidget *wid: 01711 ** Points to the widget that called us. This will typically be the 01712 ** appropriate button widget. 01713 ** XtPointer cli: 01714 ** This is the client data which was established on the registration of the 01715 ** callback. Currently this is one of XmCR_APPLY, if the apply button was 01716 ** hit or XmCR_OK if the OK button was the one that was hit. 01717 ** XtPointer call: 01718 ** This is the call data which in the case of this class is a pointer to 01719 ** XmPushButtonCallbackStruct. 01720 */ 01721 void XMCustomDialogBox::ApplyPressed(XMWidget *wid, XtPointer cli, 01722 XtPointer call) 01723 { 01724 Perform(wid, cli, call); 01725 } 01726 01727 /* 01728 ** Functional Description: 01729 ** XMCustomDialogBox::CancelPressed: 01730 ** This method is called when the cancel button was pressed. We just 01731 ** UnManage the dialog. 01732 ** Formal Parameters: 01733 ** XMWidget *wid: 01734 ** Points to the widget that called us. This will typically be the 01735 ** appropriate button widget. 01736 ** XtPointer cli: 01737 ** This is the client data which was established on the registration of the 01738 ** callback. Currently this is one of XmCR_APPLY, if the apply button was 01739 ** hit or XmCR_OK if the OK button was the one that was hit. 01740 ** XtPointer call: 01741 ** This is the call data which in the case of this class is a pointer to 01742 ** XmPushButtonCallbackStruct. 01743 */ 01744 01745 void XMCustomDialogBox::CancelPressed(XMWidget *wid, XtPointer cli, 01746 XtPointer call) 01747 { 01748 UnManage(); 01749 } 01750 01751 /* 01752 ** Functional Description: 01753 ** XMCustomDialogBox::HelpPressed: 01754 ** Called in response to the help button. We display the help text 01755 ** in a popup message dialog box. 01756 ** Formal Parameters: 01757 ** XMWidget *wid: 01758 ** Points to the widget that called us. This will typically be the 01759 ** appropriate button widget. 01760 ** XtPointer cli: 01761 ** This is the client data which was established on the registration of the 01762 ** callback. Currently this is one of XmCR_APPLY, if the apply button was 01763 ** hit or XmCR_OK if the OK button was the one that was hit. 01764 ** XtPointer call: 01765 ** This is the call data which in the case of this class is a pointer to 01766 ** XmPushButtonCallbackStruct. 01767 */ 01768 void XMCustomDialogBox::HelpPressed(XMWidget *wid, XtPointer cli, 01769 XtPointer call) 01770 { 01771 XM_display_help(this, &help_info); 01772 } 01773 01774 /* 01775 ** The functions on this page implement the private functions of the 01776 ** XMCustomDialogBox class. These functions are used by the 01777 ** constructors to provide common code paths for the typical constructor 01778 ** duties. 01779 */ 01780 01781 01782 /* 01783 ** Functional Description: 01784 ** XMCustomDialogBox::InitializeHelp: 01785 ** This function sets up the help client data for the first time. 01786 */ 01787 01788 void XMCustomDialogBox::InitializeHelp() 01789 { 01790 help_info.name = "Custom Dialog Box"; 01791 help_info.dialog = (XMInformationDialog *)NULL; 01792 help_info.text = custom_help; 01793 } 01794 01799 void 01800 XMCustomDialogBox::SetCallbacks() 01801 { 01802 OkCb.Register(Ok, XmNactivateCallback, &XMCustomDialogBox::OkPressed, 01803 (XtPointer)XmCR_OK); 01804 ApplyCb.Register(Apply, XmNactivateCallback, &XMCustomDialogBox::ApplyPressed, 01805 (XtPointer)XmCR_APPLY); 01806 CancelCb.Register(Cancel, XmNactivateCallback, &XMCustomDialogBox::CancelPressed, NULL); 01807 HelpCb.Register(Help, XmNactivateCallback, &XMCustomDialogBox::HelpPressed, NULL); 01808 }