Main Page | Class Hierarchy | Class List | File List | Class Members | File Members

# G4UIXm.cc

Go to the documentation of this file.

    00001 //
    00002 // ********************************************************************
    00003 // * License and Disclaimer                                           *
    00004 // *                                                                  *
    00005 // * The  Geant4 software  is  copyright of the Copyright Holders  of *
    00006 // * the Geant4 Collaboration.  It is provided  under  the terms  and *
    00007 // * conditions of the Geant4 Software License,  included in the file *
    00008 // * LICENSE and available at  http://cern.ch/geant4/license .  These *
    00009 // * include a list of copyright holders.                             *
    00010 // *                                                                  *
    00011 // * Neither the authors of this software system, nor their employing *
    00012 // * institutes,nor the agencies providing financial support for this *
    00013 // * work  make  any representation or  warranty, express or implied, *
    00014 // * regarding  this  software system or assume any liability for its *
    00015 // * use.  Please see the license in the file  LICENSE  and URL above *
    00016 // * for the full disclaimer and the limitation of liability.         *
    00017 // *                                                                  *
    00018 // * This  code  implementation is the result of  the  scientific and *
    00019 // * technical work of the GEANT4 collaboration.                      *
    00020 // * By using,  copying,  modifying or  distributing the software (or *
    00021 // * any work based  on the software)  you  agree  to acknowledge its *
    00022 // * use  in  resulting  scientific  publications,  and indicate your *
    00023 // * acceptance of all terms of the Geant4 Software license.          *
    00024 // ********************************************************************
    00025 //
    00026 //
    00027 // $Id: G4UIXm.cc,v 1.14 2006/06/29 19:09:49 gunter Exp $
    00028 // GEANT4 tag $Name: geant4-08-01-patch-01 $
    00029 //
    00030 // G.Barrand
    00031
    00032 //#define DEBUG
    00033
    00034 #ifdef G4UI_BUILD_XM_SESSION
    00035
    00036 #include "G4Types.hh"
    00037
    00038 #include <string.h>
    00039
    00040 #include <X11/Intrinsic.h>
    00041 #include <X11/Shell.h>
    00042 #include <X11/keysym.h>
    00043
    00044 #include <Xm/Xm.h>
    00045 #include <Xm/Command.h>
    00046 #include <Xm/RowColumn.h>
    00047 #include <Xm/Form.h>
    00048 #include <Xm/PushB.h>
    00049 #include <Xm/CascadeB.h>
    00050 #include <Xm/Text.h>
    00051
    00052 #include "G4UIXm.hh"
    00053 #include "G4UImanager.hh"
    00054 #include "G4StateManager.hh"
    00055 #include "G4UIcommandTree.hh"
    00056 #include "G4UIcommandStatus.hh"
    00057
    00058 #include "G4Xt.hh"
    00059
    00060 #include <stdlib.h>
    00061
    00062 static void XmTextAppendString (Widget,char*);
    00063
    00064 static void clearButtonCallback (Widget,XtPointer,XtPointer);
    00065
    00066 static char* XmConvertCompoundStringToString (XmString,int);
    00067 static G4bool ConvertStringToInt(const char*,int&);
    00068 static void ExecuteChangeSizeFunction(Widget);
    00069
    00070 static G4bool exitSession = true;
    00071 static G4bool exitPause = true;
    00072 static G4bool exitHelp = true;
    00073 /***************************************************************************/
    00074 G4UIXm::G4UIXm (
    00075  int argc
    00076 ,char** argv
    00077 )
    00078 :shell(NULL)
    00079 ,command(NULL)
    00080 ,menuBar(NULL)
    00081 ,text(NULL)
    00082 ,fHelp(false)
    00083 ,fHelpChoice(0)
    00084 /***************************************************************************/
    00086 {
    00087   G4UImanager* UI = G4UImanager::GetUIpointer();
    00088   if(UI!=NULL) UI->SetSession(this);
    00089
    00090   G4Xt* interactorManager = G4Xt::getInstance (argc,argv,(char*)"Xm");
    00091
    00092   Widget top = (Widget)interactorManager->GetMainInteractor();
    00093
    00094   if(getenv("XENVIRONMENT")==NULL) {
    00095     XrmDatabase database = XrmGetDatabase(XtDisplay(top));
    00096     if(database!=NULL) {
    00097       XrmPutLineResource(&database,"*topShadowColor:white");
    00098       XrmPutLineResource(&database,"*bottomShadowColor:black");
    00099       XrmPutLineResource(&database,"*foreground:black");
    00100       XrmPutLineResource(&database,"*background:lightgrey");
    00101       XrmPutLineResource(&database,"*borderColor:lightgrey");
    00102       XrmPutLineResource(&database,"*fontList:-*-helvetica-bold-r-*-*-*-120-*-*-*-*-iso8859-1");
    00103       XrmPutLineResource(&database,"*text.background:white");
    00104       XrmPutLineResource(&database,"*text.fontList:*courier*-r-*--14-*");
    00105       XrmPutLineResource(&database,"*text.maxLength:8000");
    00106     }
    00107   }
    00108
    00109   Arg args[9];
    00110   XtSetArg(args[0],XmNkeyboardFocusPolicy,XmPOINTER); // For completion.
    00111   shell = XtAppCreateShell ("G4UIXm","G4UIXm",
    00112                             topLevelShellWidgetClass,XtDisplay(top),
    00113                             args,1);
    00114   form = XmCreateForm (shell,(char*)"form",NULL,0);
    00115   XtManageChild (form);
    00116
    00117   XtSetArg(args[0],XmNtopAttachment   ,XmATTACH_FORM);
    00118   XtSetArg(args[1],XmNleftAttachment  ,XmATTACH_FORM);
    00119   XtSetArg(args[2],XmNrightAttachment ,XmATTACH_FORM);
    00120   menuBar = XmCreateMenuBar (form,(char*)"menuBar",args,3);
    00121
    00122   XtSetArg(args[0],XmNtopAttachment      ,XmATTACH_NONE);
    00123   XtSetArg(args[1],XmNleftAttachment     ,XmATTACH_FORM);
    00124   XtSetArg(args[2],XmNrightAttachment    ,XmATTACH_FORM);
    00125   XtSetArg(args[3],XmNbottomAttachment   ,XmATTACH_FORM);
    00126   command = XmCreateCommand (form,(char*)"command",args,4);
    00127   XtManageChild (command);
    00128
    00129   XtSetArg(args[0],XmNtopAttachment   ,XmATTACH_NONE);
    00130   XtSetArg(args[1],XmNleftAttachment  ,XmATTACH_FORM);
    00131   XtSetArg(args[2],XmNrightAttachment ,XmATTACH_FORM);
    00132   XtSetArg(args[3],XmNbottomAttachment,XmATTACH_WIDGET);
    00133   XtSetArg(args[4],XmNbottomWidget    ,command);
    00134   XmString cps = XmStringLtoRCreate((char*)"Clear",XmSTRING_DEFAULT_CHARSET);
    00135   XtSetArg (args[5],XmNlabelString,cps);
    00136   Widget clearButton = XmCreatePushButton(form,(char*)"clearButton",args,6);
    00137   XmStringFree (cps);
    00138   XtManageChild (clearButton);
    00139
    00140   XtSetArg(args[0],XmNtopAttachment   ,XmATTACH_WIDGET);
    00141   XtSetArg(args[1],XmNtopWidget       ,menuBar);
    00142   XtSetArg(args[2],XmNleftAttachment  ,XmATTACH_FORM);
    00143   XtSetArg(args[3],XmNrightAttachment ,XmATTACH_FORM);
    00144   XtSetArg(args[4],XmNbottomAttachment,XmATTACH_WIDGET);
    00145   XtSetArg(args[5],XmNbottomWidget    ,clearButton);
    00146   XtSetArg(args[6],XmNeditMode        ,XmMULTI_LINE_EDIT);
    00147   XtSetArg(args[7],XmNrows            ,12);
    00148   XtSetArg(args[8],XmNcolumns         ,80);
    00149   text = XmCreateScrolledText (form,(char*)"text",args,9);
    00150   XtManageChild (text);
    00151
    00152   XtAddCallback(clearButton,XmNactivateCallback,
    00153                 clearButtonCallback,(XtPointer)text);
    00154   XtAddCallback(command,XmNcommandEnteredCallback,
    00155                 commandEnteredCallback,(XtPointer)this);
    00156
    00157   Widget commandText = XmCommandGetChild(command,XmDIALOG_COMMAND_TEXT);
    00158   XtAddEventHandler(commandText,KeyPressMask,False,keyHandler,(XtPointer)this);
    00159
    00160   XtRealizeWidget(shell);
    00161   XtMapWidget(shell);
    00162
    00163   if(UI!=NULL) UI->SetCoutDestination(this);
    00164 }
    00165 /***************************************************************************/
    00166 G4UIXm::~G4UIXm(
    00167 )
    00168 /***************************************************************************/
    00170 {
    00171   G4UImanager* UI = G4UImanager::GetUIpointer();
    00172   if(UI!=NULL) {
    00173     UI->SetSession(NULL);
    00174     UI->SetCoutDestination(NULL);
    00175   }
    00176   XtDestroyWidget(shell);
    00177 }
    00178 /***************************************************************************/
    00179 G4UIsession* G4UIXm::SessionStart (
    00180 )
    00181 /***************************************************************************/
    00183 {
    00184   G4Xt* interactorManager = G4Xt::getInstance ();
    00185   Prompt("session");
    00186   exitSession = false;
    00187   interactorManager->DisableSecondaryLoop ();
    00188   void* event;
    00189   while((event = interactorManager->GetEvent())!=NULL) {
    00190     interactorManager->DispatchEvent(event);
    00191     if(exitSession==true) break;
    00192   }
    00193   interactorManager->EnableSecondaryLoop ();
    00194   return this;
    00195 }
    00196 /***************************************************************************/
    00197 void G4UIXm::Prompt (
    00198  G4String aPrompt
    00199 )
    00200 /***************************************************************************/
    00202 {
    00203   Arg args[1];
    00204   char* str = (char*)XtNewString(aPrompt.data());
    00205   XmString cps = XmStringLtoRCreate(str,XmSTRING_DEFAULT_CHARSET);
    00206   XtFree(str);
    00207   XtSetArg(args[0],XmNpromptString,cps);
    00208   XtSetValues(command,args,1);
    00209   XmStringFree(cps);
    00210 }
    00211 /***************************************************************************/
    00212 void G4UIXm::SessionTerminate (
    00213 )
    00214 /***************************************************************************/
    00216 {
    00217 }
    00218 /***************************************************************************/
    00219 void G4UIXm::PauseSessionStart (
    00220  G4String a_state
    00221 )
    00222 /***************************************************************************/
    00224 {
    00225   if(a_state=="G4_pause> ") {
    00226     SecondaryLoop ("Pause, type continue to exit this state");
    00227   }
    00228
    00229   if(a_state=="EndOfEvent") {
    00230     // Picking with feed back in event data Done here !!!
    00231     SecondaryLoop ("End of event, type continue to exit this state");
    00232   }
    00233 }
    00234 /***************************************************************************/
    00235 void G4UIXm::SecondaryLoop (
    00236  G4String a_prompt
    00237 )
    00238 /***************************************************************************/
    00240 {
    00241   G4Xt* interactorManager = G4Xt::getInstance ();
    00242   Prompt(a_prompt);
    00243   exitPause = false;
    00244   void* event;
    00245   while((event = interactorManager->GetEvent())!=NULL) {
    00246     interactorManager->DispatchEvent(event);
    00247     if(exitPause==true) break;
    00248   }
    00249   Prompt("session");
    00250 }
    00251 /***************************************************************************/
    00252 G4int G4UIXm::ReceiveG4cout (
    00253  G4String a_string
    00254 )
    00255 /***************************************************************************/
    00257 {
    00258   XmTextAppendString(text,(char*)a_string.data());
    00259   return 0;
    00260 }
    00261 /***************************************************************************/
    00262 G4int G4UIXm::ReceiveG4cerr (
    00263  G4String a_string
    00264 )
    00265 /***************************************************************************/
    00267 {
    00268   XmTextAppendString(text,(char*)a_string.data());
    00269   return 0;
    00270 }
    00271 /***************************************************************************/
    00272 G4bool G4UIXm::GetHelpChoice(
    00273  G4int& aInt
    00274 )
    00275 /***************************************************************************/
    00277 {
    00278   fHelp = true;
    00279   // SecondaryLoop :
    00280   G4Xt* interactorManager = G4Xt::getInstance ();
    00281   Prompt("Help");
    00282   exitHelp = false;
    00283   void* event;
    00284   while((event = interactorManager->GetEvent())!=NULL) {
    00285     interactorManager->DispatchEvent(event);
    00286     if(exitHelp==true) break;
    00287   }
    00288   Prompt("session");
    00289   //
    00290   if(fHelp==false) return false;
    00291   aInt = fHelpChoice;
    00292   fHelp = false;
    00293   return true;
    00294 }
    00295 /***************************************************************************/
    00296 void G4UIXm::ExitHelp(
    00297 )
    00298 /***************************************************************************/
    00300 {
    00301 }
    00302 /***************************************************************************/
    00303 void G4UIXm::AddMenu (
    00304  const char* a_name
    00305 ,const char* a_label
    00306 )
    00307 /***************************************************************************/
    00309 {
    00310   if(menuBar==NULL) return;
    00311   if(a_name==NULL) return;
    00312   if(a_label==NULL) return;
    00313   XtManageChild (menuBar);
    00314   // Pulldown menu :
    00315   Widget widget;
    00316   widget = XmCreatePulldownMenu (menuBar,(char*)a_name,NULL,0);
    00317   AddInteractor (a_name,(G4Interactor)widget);
    00318   // Cascade button :
    00319   Arg args[2];
    00320   XmString cps = XmStringLtoRCreate((char*)a_label,XmSTRING_DEFAULT_CHARSET);
    00321   XtSetArg (args[0],XmNlabelString,cps);
    00322   XtSetArg (args[1],XmNsubMenuId,widget);
    00323   widget = XmCreateCascadeButton (menuBar,(char*)a_name,args,2);
    00324   XmStringFree (cps);
    00325   XtManageChild (widget);
    00326   ExecuteChangeSizeFunction(form);
    00327 }
    00328 /***************************************************************************/
    00329 void G4UIXm::AddButton (
    00330  const char* a_menu
    00331 ,const char* a_label
    00332 ,const char* a_command
    00333 )
    00334 /***************************************************************************/
    00336 {
    00337   if(a_menu==NULL) return;
    00338   if(a_label==NULL) return;
    00339   if(a_command==NULL) return;
    00340   Widget parent = (Widget)GetInteractor(a_menu);
    00341   if(parent==NULL) return;
    00342   Widget widget = XmCreatePushButton(parent,(char*)a_label,NULL,0);
    00343   XtManageChild (widget);
    00344   XtAddCallback (widget,XmNactivateCallback,ButtonCallback,(XtPointer)this);
    00345   commands[widget] = a_command;
    00346 }
    00347 /***************************************************************************/
    00348 G4String G4UIXm::GetCommand (
    00349  Widget a_widget
    00350 )
    00351 /***************************************************************************/
    00353 {
    00354   return commands[a_widget];
    00355 }
    00356 /***************************************************************************/
    00357 /***************************************************************************/
    00358 /***************************************************************************/
    00359 void G4UIXm::commandEnteredCallback (
    00360  Widget    a_widget
    00361 ,XtPointer a_tag
    00362 ,XtPointer a_data
    00363 )
    00364 /***************************************************************************/
    00366 {
    00367   G4UIXm*  This = (G4UIXm*)a_tag;
    00368
    00369   XmString cps  = ((XmCommandCallbackStruct*)a_data)->value;
    00370   char*    ss = XmConvertCompoundStringToString(cps,0);
    00371   G4String command (ss);
    00372   XtFree   (ss);
    00373
    00374   if(This->fHelp==true) {
    00375     exitHelp = true;
    00376     This->fHelp = ConvertStringToInt(command.data(),This->fHelpChoice);
    00377   } else {
    00378     This->ApplyShellCommand (command,exitSession,exitPause);
    00379   }
    00380
    00381   a_widget = NULL;
    00382   a_tag    = NULL;
    00383 }
    00384 /***************************************************************************/
    00385 void G4UIXm::keyHandler (
    00386  Widget a_widget
    00387 ,XtPointer a_tag
    00388 ,XEvent* a_event
    00389 ,Boolean*
    00390 )
    00391 /***************************************************************************/
    00393 {
    00394   KeySym keySym;
    00395   XLookupString(&(a_event->xkey),NULL,0,&keySym,NULL);
    00396   if(keySym!=XK_Tab) return;
    00397   G4UIXm* This = (G4UIXm*)a_tag;
    00398   char* s = XmTextGetString(a_widget);
    00399   G4String ss = This->Complete(s);
    00400   XmTextSetString(a_widget,(char*)ss.data());
    00401   XtFree(s);
    00402   XmTextSetInsertionPosition(a_widget,XmTextGetLastPosition(a_widget));
    00403 }
    00404 /***************************************************************************/
    00405 void clearButtonCallback (
    00406  Widget
    00407 ,XtPointer a_tag
    00408 ,XtPointer
    00409 )
    00410 /***************************************************************************/
    00412 {
    00413   XmTextSetString((Widget)a_tag,(char*)"");
    00414 }
    00415 /***************************************************************************/
    00416 void G4UIXm::ButtonCallback (
    00417  Widget a_widget
    00418 ,XtPointer a_tag
    00419 ,XtPointer
    00420 )
    00421 /***************************************************************************/
    00423 {
    00424   G4UIXm* This = (G4UIXm*)a_tag;
    00425   if(This->fHelp==true) return; // Disabled when in help.
    00426   G4String ss = This->GetCommand (a_widget);
    00427   //printf ("debug : execute:\n%s\n",ss.data());
    00428   This->ApplyShellCommand(ss,exitSession,exitPause);
    00429 }
    00430 /***************************************************************************/
    00431 /***************************************************************************/
    00432 /***************************************************************************/
    00433 char* XmConvertCompoundStringToString (
    00434  XmString a_cps
    00435 ,int a_number
    00436 )
    00437 /***************************************************************************/
    00439 {
    00440   if(a_cps==NULL) return NULL;
    00441   char* ss = NULL;
    00442   XmStringContext context;
    00443   XmStringInitContext(&context,a_cps);
    00444   int icount = 0;
    00445   Boolean Done = False;
    00446   while(Done==False) {
    00447     char* text = NULL;
    00448     XmStringCharSet charset = NULL;
    00449     XmStringDirection direct;
    00450     Boolean sep;
    00451     if(XmStringGetNextSegment(context,&text,&charset,&direct,&sep)==True) {
    00452       XtFree(charset);
    00453       if(sep==True) Done = True;
    00454       if(icount==a_number) {
    00455         ss = text;
    00456         break;
    00457       }
    00458       icount++;
    00459       XtFree(text);
    00460     }
    00461     else
    00462       Done = True;
    00463   }
    00464   XmStringFreeContext(context);
    00465   return ss;
    00466 }
    00467 /***************************************************************************/
    00468 void XmTextAppendString (
    00469  Widget This
    00470 ,char* a_string
    00471 )
    00472 /***************************************************************************/
    00474 {
    00475   if(This==NULL) return;
    00476   if(!XtIsSubclass(This,xmTextWidgetClass)) return;
    00477   if(a_string==NULL) return;
    00478   XmTextPosition  lastpos = XmTextGetLastPosition(This);
    00479   XmTextReplace(This,lastpos,lastpos,a_string);
    00480   XmTextSetInsertionPosition(This,XmTextGetLastPosition(This));
    00481 }
    00483 G4bool ConvertStringToInt(
    00484  const char* aString
    00485 ,int& aInt
    00486 )
    00489 {
    00490   aInt = 0;
    00491   if(aString==NULL) return false;
    00492   char* s;
    00493   long value = strtol(aString,&s,10);
    00494   if(s==aString) return false;
    00495   aInt = value;
    00496   return true;
    00497 }
    00498 #include <X11/IntrinsicP.h>
    00500 void ExecuteChangeSizeFunction (
    00501  Widget aWidget
    00502 )
    00505 {
    00506   if(aWidget==NULL) return;
    00507   if(aWidget->core.widget_class->core_class.resize==NULL) return;
    00508   (aWidget->core.widget_class->core_class.resize)(aWidget);
    00509 }
    00510
    00511
    00512 #endif