Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | File List | Class Members | File Members | Related Pages

XMDialogs.cpp

Go to the documentation of this file.
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 }   

Generated on Thu Jan 6 16:58:42 2005 for Spectrodaq External Event Framework by  doxygen 1.3.9.1