Back to home page

sPhenix code displayed by LXR

 
 

    


File indexing completed on 2025-08-03 08:22:02

0001 // $Id: RDBCform.C,v 1.1.1.1 2004/02/18 20:58:02 dave Exp $
0002 //
0003 //     This file is part of the RDBC
0004 //     Author: Valeriy Onuchin <onuchin@sirius.ihep.su>
0005 /////////////////////////////////////////////////////////////////////
0006 //
0007 // An example of Simple Form used for browsing of tables
0008 //
0009 //////////////////////////////////////////////////////////////////////
0010 //
0011 // Usage:
0012 //  
0013 // root[0] gSystem->Load("libRDBC");      // load library
0014 // root[1] .L RDBCform.C                  // load macro
0015 //    or
0016 // root[1] .L RDBCform.C++                // compile and load macro
0017 //
0018 // root[2]  new DbForm();                 // create form  
0019 //
0020 //////////////////////////////////////////////////////////////////////
0021 //
0022 // To compile standalone executable program use:
0023 //
0024 // 1. Compile shared lib module RDBCform_C.so by:
0025 //
0026 //       root[0] gSystem->Load("libRDBC");
0027 //       root[1] .L RDBCform.C++
0028 //
0029 // 2. Comiple executable by:
0030 //
0031 //    $ g++ -O -o RDBCform RDBCform.C `root-config --cflags --glibs` -lRDBC -DSTANDALONE 
0032 //
0033 //  Check the main() code at the bottom of this script
0034 //
0035 // 3. Run it (RDBCform_C.so should be in current dir):
0036 // 
0037 //    $ ./RDBCform&
0038 //
0039 //////////////////////////////////////////////////////////////////////
0040 //
0041 // Warnings:
0042 //
0043 //   - this macro uses TGxxx classes which don't work with win32
0044 //   - some tables ( for example Oracle system tables) can
0045 //     be browsed only with forward_only cursor. 
0046 //     Use DbForm::SetForwardOnly() method to force this
0047 //     setting.
0048 //
0049 //Begin_Html
0050 /*
0051 <img src="oform.gif">
0052 */
0053 //End_Html
0054 
0055 #include <RDBC/TSQLConnection.h>
0056 #include <RDBC/TSQLStatement.h>
0057 #include <RDBC/TSQLDriverManager.h>
0058 #include <RDBC/TSQLResultSet.h>
0059 #include <RDBC/TSQLResultSetMetaData.h>
0060 #include <RDBC/TSQLDatabaseMetaData.h>
0061 
0062 #include <TTimer.h>
0063 #include <TGCanvas.h>
0064 #include <TGToolBar.h>
0065 #include <TGStatusBar.h>
0066 #include <TGMsgBox.h>
0067 #include <TVirtualX.h>
0068 #include <TROOT.h>
0069 #include <TInterpreter.h>
0070 #include <TGMenu.h>
0071 #include <TG3DLine.h>
0072 #include <RQ_OBJECT.h>
0073 #include <TSystem.h>
0074 #include <TGTextEntry.h>
0075 #include <TGButton.h>
0076 #include <TGFrame.h>
0077 #include <TGLabel.h>
0078 
0079 
0080 class DbForm* gForm = 0; // db form available from interpreter 
0081 
0082 ////////////////////////////////////////////////////////////////
0083 //
0084 //  Password Dialog widget used for entering 
0085 //  Data Source Name, User Name and Password 
0086 //
0087 ///////////////////////////////////////////////////////////////   
0088 class PasswordDialog 
0089 {
0090 RQ_OBJECT()
0091 
0092 private:
0093    TGMainFrame*   fMain;
0094    TGTextEntry*   fDSNEntry;  // data source name text entry
0095    TGTextEntry*   fUserEntry; // username text entry
0096    TGTextEntry*   fPswdEntry; // password text entry 
0097    TGTextButton*  fOKButton;        // OK button
0098    TGTextButton*  fCancelButton;    // Cancel button
0099    TGLabel*       fDSNLabel; 
0100    TGLabel*       fPswLabel;   
0101    TGLabel*       fUsrLabel;
0102    TGLabel*       fInfoLabel;
0103    TString        fDSN;  // last entered DSN
0104    TString        fUsername;  // last entered username
0105    TString        fPassword;  // last enterd password
0106         
0107 public:
0108    PasswordDialog();
0109    ~PasswordDialog(); 
0110    
0111    void Hide();
0112    void Show();
0113    void Clear();
0114     
0115    TGMainFrame* GetMainFrame() const { return fMain; }
0116    TString GetDSN() const { return fDSN; }
0117    TString GetUsername() const { return fUsername; }
0118    TString GetPassword() const { return fPassword; }
0119    
0120    void Print(Option_t* opt="") const;      
0121    void Entered( const Text_t* dsn=0,
0122                  const Text_t* pwd=0,
0123                  const Text_t* usr=0 );     // *SIGNAL*
0124 
0125    // slots
0126    void  DSNEntered();
0127    void  PasswordEntered();
0128    void  UsernameEntered();
0129 };
0130 
0131 //____________________________________________________________________
0132 PasswordDialog::PasswordDialog()
0133 {
0134    // constructor
0135 
0136    fMain = new TGMainFrame(gClient->GetRoot(),500,200);
0137    fMain->SetWMSizeHints(500,200,500,200,0,0);
0138    fMain->SetWindowName("Enter DSN, Password, User Name");
0139    fMain->SetIconName("Enter DSN, Password ,User Name");
0140    
0141     // create username text entry
0142    fDSNEntry = new TGTextEntry(fMain,"");
0143    fDSNEntry->Resize(350,20);
0144    fDSNEntry->Move(100,50);
0145    fDSNLabel = new TGLabel(fMain,"DSN:");
0146    fDSNLabel->Move(30,52);
0147    
0148    fUserEntry = new TGTextEntry(fMain,"");
0149    fUserEntry->Resize(350,20);
0150    fUserEntry->Move(100,90);
0151    fUserEntry->SetMaxLength(20);  // maximum 20 symbols
0152    fUsrLabel = new TGLabel(fMain,"User Name:");
0153    fUsrLabel->Move(30,92);
0154       
0155    // create password text entry
0156    fPswdEntry = new TGTextEntry(fMain,"");
0157    fPswdEntry->Resize(350,20);
0158    fPswdEntry->Move(100,130);
0159    fPswdEntry->SetMaxLength(20);  // maximum 20 symbols
0160    
0161    // set password echo mode
0162    fPswdEntry->SetEchoMode(TGTextEntry::kPassword);    
0163   
0164    fPswLabel = new TGLabel(fMain,"Password:");
0165    fPswLabel->Move(30,132); 
0166    
0167    fInfoLabel =  new TGLabel(fMain,
0168                 "Type DSN, Username and Password to log on");
0169    
0170    fInfoLabel->Move(30,20);
0171     
0172    fOKButton = new TGTextButton(fMain,"OK");
0173    fOKButton->Move(200,170);
0174    fOKButton->Resize(50,20);
0175          
0176    fCancelButton = new TGTextButton(fMain,"Cancel");
0177    fCancelButton->Move(300,170);
0178    fCancelButton->Resize(50,20);
0179     
0180    fMain->MapSubwindows();
0181    fMain->MapRaised();
0182    fMain->SetWMPosition(300,300);
0183    fMain->ChangeOptions(fMain->GetOptions() | kFixedSize);
0184           
0185    //*** Make connections between signals and  handlers
0186 
0187    fDSNEntry->Connect("ReturnPressed()","PasswordDialog",
0188                        this,"DSNEntered");
0189      
0190    // Connects TGTextEntry's signal "ReturnPressed" from 
0191    // fUserEntry to PasswordDialog::UsernameEntered() method 
0192    // of "this" object         
0193    
0194    fUserEntry->Connect("ReturnPressed()","PasswordDialog",
0195                         this,"UsernameEntered");
0196    
0197    // Connects TGTextEntry's signal "ReturnPressed" from
0198    // fPswdEntry to PasswordDialog::UsernameEntered() method 
0199    // of "this" object.
0200           
0201    fPswdEntry->Connect( "ReturnPressed()","PasswordDialog",
0202                         this,"PasswordEntered()");
0203   
0204    fCancelButton->Connect("Pressed()","PasswordDialog",
0205                            this,"Hide()");
0206 
0207    fCancelButton->Connect("Pressed()","PasswordDialog",
0208                            this,"Clear()");   
0209   
0210    fOKButton->Connect("Released()","PasswordDialog",
0211                            this,"PasswordEntered()");
0212    
0213    fDSNEntry->Connect("CursorOutDown()","TGTextEntry",fUserEntry,"SetFocus()");
0214    fUserEntry->Connect("CursorOutDown()","TGTextEntry",fPswdEntry,"SetFocus()");
0215    fUserEntry->Connect("CursorOutUp()","TGTextEntry",fDSNEntry,"SetFocus()");
0216    fPswdEntry->Connect("CursorOutUp()","TGTextEntry",fUserEntry,"SetFocus()");
0217 }
0218 
0219 //____________________________________________________________________
0220 void PasswordDialog::Show()
0221 { 
0222    // 
0223    
0224    fMain->MapRaised();
0225 }
0226 
0227 //____________________________________________________________________
0228 void PasswordDialog::Hide()
0229 { 
0230    //
0231    
0232    fMain->UnmapWindow();
0233 }
0234 
0235 //____________________________________________________________________
0236 void PasswordDialog::Clear()
0237 { 
0238    // 
0239    
0240    fDSNEntry->Clear();
0241    fPswdEntry->Clear();
0242    fUserEntry->Clear();
0243 }
0244 
0245 //____________________________________________________________________
0246 PasswordDialog::~PasswordDialog()
0247 { 
0248    // destructor 
0249  
0250    delete fDSNEntry;
0251    delete fDSNLabel;
0252    delete fUserEntry;
0253    delete fPswdEntry;
0254    delete fPswLabel;
0255    delete fUsrLabel;
0256    delete fInfoLabel;
0257    delete fOKButton;
0258    delete fCancelButton;
0259    delete fMain;     
0260 }
0261 
0262 //____________________________________________________________________
0263 void PasswordDialog::Entered(const Text_t* dsn,const Text_t* usr,
0264                              const Text_t* pwd)
0265 {
0266    // This signal is emitted when username and password entered.
0267  
0268    TString DSN = dsn;   
0269    TString USR = usr;        
0270    TString PWD = pwd;
0271    
0272       // User can add some validation procedure below
0273    if( DSN==fDSN && USR==fUsername && PWD==fPassword ) return;
0274    if( !DSN.IsNull() && !USR.IsNull()  ) {
0275      
0276       long args[3];
0277       
0278       args[0] = (long)DSN.Data();
0279       args[1] = (long)USR.Data();
0280       args[2] = (long)PWD.Data();
0281       
0282       fDSN = DSN;    // copy dsn
0283       fUsername = USR;    // copy username 
0284       fPassword = PWD;    // copy password 
0285          
0286       Emit("Entered(Text_t*,Text_t*,Text_t*)",args);
0287    }
0288 }
0289    
0290 //____________________________________________________________________
0291 void PasswordDialog::DSNEntered()
0292 {
0293    // Handles ReturnPressed signal from dsn text entry.
0294    // ... just move keyboard focus to username text entry.
0295    
0296    // move keyboard focus to password text entry
0297    fUserEntry->SetFocus();   
0298    
0299    // select text in the password text entry   
0300    fUserEntry->SelectAll();  
0301 }
0302    
0303 //____________________________________________________________________
0304 void PasswordDialog::UsernameEntered()
0305 {
0306    // Handles ReturnPressed signal from username  text entry.
0307    // ... just move keyboard focus to password text entry.
0308    
0309    // move keyboard focus to password text entry
0310    fPswdEntry->SetFocus();   
0311    
0312    // select text in the password text entry   
0313    fPswdEntry->SelectAll();  
0314 }
0315 
0316 //____________________________________________________________________
0317 void PasswordDialog::PasswordEntered()
0318 {
0319    // Handles ReturnPressed signal from password text entry 
0320 
0321    TString dsn = fDSNEntry->GetText();   
0322    TString usr = fUserEntry->GetText();        
0323    TString pwd = fPswdEntry->GetText();
0324    
0325    Clear();
0326    fDSNEntry->SetFocus();  // move back keyboard focus to username entry  
0327    Entered(dsn.Data(),usr.Data(),pwd.Data());   // emit  signal
0328    fDSN="";
0329    fUsername="";
0330    fPassword="";      
0331 }
0332 
0333 //____________________________________________________________________
0334 void PasswordDialog::Print(Option_t*) const
0335 {
0336    // Prints entered dsn, username and password
0337    
0338    printf("\nDSN: %s",fDSN.Data());
0339    printf("\nUsername: %s\n",fUsername.Data());
0340    printf("Password: %s\n",fPassword.Data());   
0341 }
0342     
0343 ///////////////////////////////////////////////////////////////////
0344 class DbFormEntry
0345 {
0346 RQ_OBJECT()
0347 
0348 private:
0349    TGLabel* fLabel;  // column name
0350    TGTextEntry* fEntry; // column value as text
0351    TGCompositeFrame* fMain;  // 
0352    TGLayoutHints* fLayoutHints1; // hints for text
0353    TGLayoutHints* fLayoutHints2;  // hints for label
0354    Int_t fColumnIndex; // column index
0355    TString fColumnName; // column name
0356    TString fColumnValue;  // column value 
0357 
0358 public:
0359    DbFormEntry(TGWindow* p,Int_t index,
0360                const TString& value, const TString& name);
0361    ~DbFormEntry();
0362    
0363    void Updated(Int_t index,const Text_t* value); //*SIGNAL*
0364    void SetColumnValue(const TString& value) 
0365       { fColumnValue = value; fEntry->SetText(value.Data()); }
0366    
0367    TGCompositeFrame* GetMain() const { return fMain; }
0368 };
0369 
0370 //____________________________________________________________________
0371 DbFormEntry::DbFormEntry(TGWindow* p,Int_t index,
0372                         const TString& value,const TString& name)
0373 {  
0374    // ctor
0375    
0376    fMain = new TGCompositeFrame(p,32, 32,kHorizontalFrame);
0377    fLayoutHints1 = new TGLayoutHints( kLHintsRight | kLHintsExpandX,
0378                                    5, 100, 5, 5);
0379    fLayoutHints2 = new TGLayoutHints( kLHintsNormal,
0380                                      100, 5, 5, 5);
0381    
0382    fColumnIndex = index;
0383    fColumnValue = value;
0384    fColumnName = name;
0385    
0386    fLabel = new TGLabel(fMain,fColumnName.Data());
0387    fEntry = new TGTextEntry(fMain,fColumnValue.Data());
0388    fEntry->SetEnabled(kFALSE); // disable
0389    fMain->AddFrame(fLabel,fLayoutHints2); 
0390    fMain->AddFrame(fEntry,fLayoutHints1);
0391    
0392    fEntry->Connect("ReturnPressed()","DbFormEntry",this,
0393                    "Updated(Int_t,Text_t*)");
0394 
0395 }      
0396 
0397 //____________________________________________________________________
0398 DbFormEntry::~DbFormEntry()
0399 {  
0400    // dtor with sanity check
0401    
0402    if(fLabel) fLabel->UnmapWindow();
0403    if(fEntry) fEntry->UnmapWindow();   
0404    if(fLabel) delete fLabel;
0405    if(fEntry) delete fEntry;
0406    if(fLayoutHints1) delete fLayoutHints1;
0407    if(fLayoutHints2) delete fLayoutHints2;
0408    if(fMain) delete fMain;
0409 }
0410 
0411 //____________________________________________________________________
0412 void DbFormEntry::Updated(Int_t index,const Text_t* value)
0413 {  
0414    // emit signal when text changed in the text entry 
0415    // (not used so far)
0416    
0417    long args[2];
0418    
0419    TString newValue = fEntry->GetText();
0420           
0421    if(fColumnValue!=newValue) {
0422       args[0] = (long)fColumnIndex;
0423       args[1] = (long)newValue.Data();
0424       Emit("Updated(Int_t,Text_t*)",args); 
0425    }
0426 }
0427 
0428 typedef DbFormEntry* DbFormEntryPtr; 
0429          
0430 ///////////////////////////////////////////////////////////////////   
0431 class DbForm
0432 {
0433 RQ_OBJECT()
0434 
0435 private:
0436    enum EFile { kConnect,kDisconnect,kExit };
0437    enum EGo { kPrev,kNext,kFirst,kLast,kAbsolute };
0438    enum EHelp { kAbout };
0439    
0440    // GUI part
0441    TGMainFrame*  fMain;   // main frame
0442    TGPopupMenu*  fFileMenu; // file popup menu
0443    TGPopupMenu*  fGotoMenu; // go popup menu
0444    TGPopupMenu*  fHelpMenu; // help menu
0445    TGTextEntry*  fQueryTextEntry;  // SQL query text entry
0446    TGTextButton* fExecuteQueryButton; // excute query button
0447    TGTextButton* fCancelQueryButton; // cancel query button
0448    TGTextButton* fNextButton;  // next button
0449    TGTextButton* fPrevButton;  // prev button
0450    TGTextButton* fLastButton;  // last button
0451    TGTextButton* fFirstButton; // first button
0452    TTimer* fNextButtonTimer; // auotorepeat timer for next button
0453    TTimer* fPrevButtonTimer; // auotorepeat timer for prev button
0454    TGCompositeFrame* fButtonGroup; // button group for next,prev,first,last bttns
0455    TGStatusBar*   fStatusBar; // status bar 
0456    TGMenuBar*     fMenuBar;  // menu bar 
0457    TGLayoutHints* fMenuBarLayout;   //  layout hints 
0458    TGLayoutHints* fMenuBarItemLayout; // layout hints 
0459    TGLayoutHints* fMenuBarHelpLayout; // layout hints 
0460    TGHorizontal3DLine* fToolBarSep; // separator
0461    TGToolBar*     fToolBar;   // composite rame for execute query text entry and bttns
0462    TGLayoutHints* fBarLayout; // layout hints 
0463    TGLayoutHints* fQueryTextLayout; // layout for query text entry
0464    TGCanvas* fCanvasWindow; // window with sliders
0465    TGCompositeFrame* fContainer; //
0466    DbFormEntry** fEntries;  // form entries
0467    PasswordDialog* fPD; // password dialog used to enter dsn,uid,pwd
0468             
0469   // db part
0470    Bool_t fConnected; // kTRUE if connected to db
0471    TString fDSN;    // dsn name 
0472    Int_t fRstype; // result set type
0473    Int_t fRsconc; // result set concurrency   
0474    TSQLConnection* fConnection; // connection to db
0475    TSQLStatement* fStatement; // latest statement
0476    TSQLResultSet* fResultSet; // latest result set
0477    TSQLResultSetMetaData* fResultSetMetaData; // result set meta data 
0478  
0479    void DisplayResults();
0480    void UpdateColumn(Int_t index,const Text_t* value);
0481    void ClearCanvas();
0482 
0483 public:
0484    DbForm();
0485    ~DbForm();
0486    
0487    TSQLConnection* GetConnection() const { return fConnection; }
0488    void SetForwardOnly();
0489    void SetConnection(TSQLConnection* con) { fConnection=con; HandleConnect(); }
0490    void SetStatement(TSQLStatement* stmt) 
0491          { SetConnection(stmt->GetConnection()); HandleExecuteQuery(); }
0492 
0493    void Hide() { fMain->UnmapWindow(); }
0494    void Show() { fMain->MapRaised(); }
0495    TGMainFrame* GetMainFrame() const { return fMain; }  
0496 
0497    // slots 
0498    void HandleFileMenu(Int_t id);
0499    void HandleGotoMenu(Int_t id);
0500    void HandleDisconnect();
0501    void HandleConnect();
0502    void HandleExecuteQuery();
0503    void First();
0504    void Last();
0505    void Next();
0506    void Prev();
0507    void AcceleratePrevButton();
0508    void AccelerateNextButton();
0509    void Connect(const Text_t* dsn, const Text_t* uid, const Text_t* pwd);    
0510 
0511 };
0512       
0513 /////////////////////////// DbForm implementation ////////////////////
0514 //____________________________________________________________________
0515 DbForm::DbForm()
0516 {
0517    // constructor
0518       
0519    TGLayoutHints *lo = 0;
0520 
0521    fConnection = 0; // connection to db
0522    fStatement = 0; // latest statement
0523    fResultSet = 0; // latest result set
0524    fResultSetMetaData = 0; // result set meta data 
0525    fConnected = kFALSE;   
0526 
0527    if(gForm) gInterpreter->DeleteGlobal(gForm); //delete gForm;
0528        
0529    fMain = new TGMainFrame(gClient->GetRoot(),500,500);
0530    fMain->SetWMSizeHints(500,500,500,500,0,0);
0531    fMain->SetWindowName("Simple Database Form");
0532    fMain->SetIconName("Simple of Database Form");   
0533    fMain->SetClassHints("DbForm", "DbForm");
0534    fMain->SetMWMHints(kMWMDecorAll, kMWMFuncAll, kMWMInputModeless);
0535    
0536    fFileMenu = new TGPopupMenu(gClient->GetRoot());
0537    fFileMenu->AddEntry("&Connect",kConnect);
0538    fFileMenu->AddEntry("&Disconnect",kDisconnect);
0539    fFileMenu->AddSeparator();
0540    fFileMenu->AddEntry("&Exit",kExit);
0541 
0542    fGotoMenu = new TGPopupMenu(gClient->GetRoot());
0543    fGotoMenu->AddEntry("&First",kFirst);   
0544    fGotoMenu->AddEntry("&Prev",kPrev);   
0545    fGotoMenu->AddEntry("&Next",kNext);
0546    fGotoMenu->AddEntry("&Last",kLast);
0547    
0548    fHelpMenu = new TGPopupMenu(gClient->GetRoot());
0549    fHelpMenu->AddEntry("&About",kAbout);
0550    
0551    fMenuBarLayout = new TGLayoutHints( kLHintsTop | 
0552                                        kLHintsLeft | 
0553                                        kLHintsExpandX,5,5,3,1);
0554    
0555    fMenuBarItemLayout = new TGLayoutHints(kLHintsTop | 
0556                                           kLHintsLeft,0,20,3,1);
0557    
0558    fMenuBarHelpLayout = new TGLayoutHints(kLHintsTop | 
0559                                           kLHintsRight,0,5,3,1);
0560       
0561    fMenuBar = new TGMenuBar(fMain,1,1,kHorizontalFrame);
0562    fMenuBar->AddPopup("&File",fFileMenu, fMenuBarItemLayout);
0563    fMenuBar->AddPopup("&Go",fGotoMenu, fMenuBarItemLayout);
0564    fMenuBar->AddPopup("&Help",fHelpMenu, fMenuBarHelpLayout);
0565    fMain->AddFrame(fMenuBar, fMenuBarLayout);
0566   
0567    fToolBarSep = new TGHorizontal3DLine(fMain);
0568    fBarLayout = new TGLayoutHints(kLHintsTop | kLHintsExpandX);
0569    fMain->AddFrame(fToolBarSep,fBarLayout);
0570 
0571    fToolBar = new TGToolBar(fMain,60,20, kHorizontalFrame);
0572    fMain->AddFrame(fToolBar,fBarLayout);
0573     
0574    fQueryTextEntry = new TGTextEntry(fToolBar,"");
0575    fToolBar->AddFrame(fQueryTextEntry,fMenuBarLayout);
0576    
0577    fExecuteQueryButton = new TGTextButton(fToolBar,"Query");
0578    fCancelQueryButton = new TGTextButton(fToolBar,"Cancel");
0579 
0580    fToolBar->AddFrame(fCancelQueryButton,fMenuBarHelpLayout);
0581    fToolBar->AddFrame(fExecuteQueryButton,fMenuBarHelpLayout);
0582 
0583    fStatusBar = new TGStatusBar(fMain, 60, 10);
0584    int parts[] = { 25, 75 };
0585    fStatusBar->SetParts(parts, 2);
0586    lo = new TGLayoutHints(kLHintsBottom | kLHintsExpandX, 0, 0, 3, 0);
0587    fMain->AddFrame(fStatusBar,lo);
0588    fButtonGroup = new TGCompositeFrame(fMain,60,10,kHorizontalFrame);
0589    fMain->AddFrame(fButtonGroup,lo);
0590    
0591    fFirstButton = new TGTextButton(fButtonGroup,"First",kFirst);
0592    fPrevButton = new TGTextButton(fButtonGroup,"Prev",kPrev);
0593    fNextButton = new TGTextButton(fButtonGroup,"Next",kNext);
0594    fLastButton = new TGTextButton(fButtonGroup,"Last",kLast);
0595 
0596    fButtonGroup->AddFrame(fFirstButton,fMenuBarLayout);
0597    fButtonGroup->AddFrame(fPrevButton,fMenuBarLayout);
0598    fButtonGroup->AddFrame(fNextButton,fMenuBarLayout);
0599    fButtonGroup->AddFrame(fLastButton,fMenuBarLayout);
0600 
0601    fCanvasWindow = new TGCanvas(fMain, 200, 400);
0602    lo = new TGLayoutHints( kLHintsBottom | 
0603                            kLHintsExpandX | 
0604                            kLHintsExpandY, 3, 3, 3, 3);
0605    fMain->AddFrame(fCanvasWindow,lo);
0606 
0607    fContainer = new TGCompositeFrame(fCanvasWindow->GetViewPort(), 10, 10,
0608                                      kHorizontalFrame);
0609    
0610    fContainer->SetLayoutManager(new TGVerticalLayout(fContainer));
0611    fCanvasWindow->SetContainer(fContainer);
0612 
0613    fMain->MapSubwindows();
0614    fMain->SetWMPosition(300,300);
0615    fMain->Layout();
0616    fMain->MapRaised();
0617 
0618    TSQL::SetHandler("Catch(TSQLException*)");
0619    HandleDisconnect();
0620 
0621    // connect signals  
0622    TQObject::Connect(fCancelQueryButton,"Pressed()","TGTextEntry",
0623                      fQueryTextEntry,"Clear()");
0624 
0625    fFileMenu->Connect("Activated(Int_t)","DbForm",this,
0626                       "HandleFileMenu(Int_t)");
0627 
0628    fGotoMenu->Connect("Activated(Int_t)","DbForm",this,
0629                       "HandleGotoMenu(Int_t)");
0630 
0631    fExecuteQueryButton->Connect("Released()","DbForm",this,
0632                       "HandleExecuteQuery()");
0633    
0634    fQueryTextEntry->Connect("ReturnPressed()","DbForm",this,
0635                       "HandleExecuteQuery()");   
0636    
0637    fNextButtonTimer = new TTimer(250); 
0638    fPrevButtonTimer = new TTimer(250); 
0639 
0640    fFirstButton->Connect("Released()","DbForm",this,"First()");
0641    fLastButton->Connect("Released()","DbForm",this,"Last()");
0642  
0643    // create accelerating autorepeat effect for Next/Prev buttons 
0644    fNextButton->Connect("Pressed()","TTimer",fNextButtonTimer,"TurnOn()");
0645    fNextButton->Connect("Released()","TTimer",fNextButtonTimer,"TurnOff()");   
0646    fNextButton->Connect("Released()","TTimer",fNextButtonTimer,"SetTime(=250)");   
0647    fNextButtonTimer->Connect("Timeout()","DbForm",this,"Next()");  //
0648    fNextButtonTimer->Connect("Timeout()","DbForm",this,"AccelerateNextButton()");  //
0649 
0650    fPrevButton->Connect("Pressed()","TTimer",fPrevButtonTimer,"TurnOn()");
0651    fPrevButton->Connect("Released()","TTimer",fPrevButtonTimer,"TurnOff()");
0652    fPrevButton->Connect("Released()","TTimer",fPrevButtonTimer,"SetTime(=250)");    
0653    fPrevButtonTimer->Connect("Timeout()","DbForm",this,"Prev()");
0654    fPrevButtonTimer->Connect("Timeout()","DbForm",this,"AcceleratePrevButton()");  //
0655 
0656    gForm = this;
0657    fPD = 0;
0658 }
0659 
0660 //____________________________________________________________________
0661 void DbForm::AccelerateNextButton()
0662 {
0663    // accelerator
0664 
0665    Long_t nt = fNextButtonTimer->GetTime();
0666    fNextButtonTimer->SetTime(nt-10);
0667 }
0668 
0669 //____________________________________________________________________
0670 void DbForm::AcceleratePrevButton()
0671 {
0672    // accelerator
0673 
0674    Long_t pt = fPrevButtonTimer->GetTime();
0675    fPrevButtonTimer->SetTime(pt-10);
0676 }
0677 
0678 //____________________________________________________________________
0679 DbForm::~DbForm()
0680 {
0681    // destructor
0682 
0683    delete fNextButtonTimer;
0684    delete fPrevButtonTimer;
0685    delete fContainer;
0686    delete fCanvasWindow;
0687    delete fQueryTextLayout;
0688    delete fBarLayout;
0689    delete fToolBar;
0690    delete fToolBarSep;
0691    delete fMenuBarHelpLayout;
0692    delete fMenuBarItemLayout;
0693    delete fMenuBarLayout;
0694    delete fMenuBar;
0695    delete fStatusBar;
0696    delete fButtonGroup;
0697    delete fFirstButton;
0698    delete fLastButton;
0699    delete fPrevButton;
0700    delete fNextButton;
0701    delete fCancelQueryButton;
0702    delete fExecuteQueryButton;
0703    delete fQueryTextEntry;
0704    delete fHelpMenu;
0705    delete fGotoMenu;
0706    delete fFileMenu;  
0707    HandleDisconnect();
0708    delete fPD;
0709    delete fMain;
0710 }
0711 
0712 //____________________________________________________________________
0713 void DbForm::UpdateColumn(Int_t index,const Text_t* value)
0714 {
0715    // handler method used when column was updated 
0716    // (not used yet)
0717   
0718    TString str=value;
0719 
0720    if( fResultSet &&
0721        !fResultSet->IsBeforeFirst() && 
0722        !fResultSet->IsAfterLast() ) fResultSet->UpdateString(index,str);
0723 }
0724    
0725 //____________________________________________________________________
0726 void DbForm::First()
0727 {  
0728    // scroll to first row
0729    
0730    fResultSet->First();
0731    DisplayResults();
0732 }
0733 
0734 //____________________________________________________________________
0735 void DbForm::Last()
0736 {  
0737    // scroll to last row
0738       
0739    fResultSet->Last();
0740    DisplayResults();
0741 }
0742 
0743 //____________________________________________________________________
0744 void DbForm::Next()
0745 {  
0746    // scroll to next row
0747    
0748    fResultSet->Next();
0749    DisplayResults();
0750 }
0751 
0752 //____________________________________________________________________
0753 void DbForm::Prev()
0754 {
0755    // scroll to previous row
0756     
0757    fResultSet->Previous();
0758    DisplayResults();  
0759 }
0760 
0761 //____________________________________________________________________
0762 void DbForm::DisplayResults()
0763 {
0764    // display new row
0765    
0766    char rowstr[15];
0767    Int_t row = fResultSet->GetRow();
0768    sprintf(rowstr,"Row: %d",row);
0769    fStatusBar->SetText(rowstr,0);
0770    
0771    if(fResultSet->IsAfterLast()) {
0772      fGotoMenu->DisableEntry(kNext);
0773      fNextButton->SetState(kButtonDisabled);
0774    } else {
0775      fGotoMenu->EnableEntry(kNext);
0776      if(fNextButton->GetState()==kButtonDisabled) fNextButton->SetState(kButtonUp);
0777    }
0778      
0779    if(fResultSet->IsBeforeFirst()) {
0780      fGotoMenu->DisableEntry(kPrev);
0781      fPrevButton->SetState(kButtonDisabled);
0782    } else {
0783      fGotoMenu->EnableEntry(kPrev);
0784      if(fPrevButton->GetState()==kButtonDisabled) fPrevButton->SetState(kButtonUp);
0785    }
0786    
0787    if(fRstype == kTYPE_FORWARD_ONLY)  SetForwardOnly();  
0788         
0789    Int_t ncollumns = fResultSetMetaData->GetColumnCount();
0790 
0791    TString value; 
0792           
0793    for( int i=1; i <= ncollumns; ++i ) {
0794       if(!fResultSet->IsBeforeFirst() && !fResultSet->IsAfterLast()) {
0795          value = fResultSet->GetString(i);         
0796       } else {
0797          value = "";
0798       }
0799       fEntries[i-1]->SetColumnValue(value); 
0800    }   
0801 }
0802 
0803 //____________________________________________________________________
0804 void DbForm::HandleFileMenu(Int_t id)
0805 {
0806    // handler for File menu popup actions
0807 
0808    switch(id) {
0809    case kConnect:
0810       fConnected = kFALSE;
0811             
0812       if(!fPD) {
0813          fPD = new PasswordDialog();
0814          fPD->Connect("Entered(Text_t*,Text_t*,Text_t*)",
0815                                "DbForm",this,
0816                                "Connect(Text_t*,Text_t*,Text_t*)");
0817       } else {
0818          fPD->Show();
0819       }   
0820       break;   
0821    case kDisconnect:
0822       HandleDisconnect();
0823       break;
0824    case kExit:
0825       HandleDisconnect();
0826       gSystem->Exit(0);
0827       break;
0828    default:
0829       break;       
0830    }
0831 }      
0832 
0833 //____________________________________________________________________
0834 void DbForm::HandleGotoMenu(Int_t id)
0835 {
0836    // handler for Go menu popup actions
0837 
0838    switch(id) {
0839       case kFirst:
0840          First();
0841          break;   
0842       case kLast:
0843          Last();
0844          break;
0845       case kPrev:
0846          Prev();
0847          break;
0848       case kNext:
0849          Next();
0850          break;   
0851       default:
0852          break;       
0853    }
0854 }      
0855 
0856 //____________________________________________________________________
0857 void DbForm::ClearCanvas()
0858 {
0859    // clear canvas
0860 
0861    Int_t ncollumns;
0862    
0863    if(fResultSetMetaData) { // clear canvas window 
0864       TGCompositeFrame* cont = (TGCompositeFrame*)fCanvasWindow->GetContainer();
0865       TList* list = cont->GetList();
0866       ncollumns = fResultSetMetaData->GetColumnCount();
0867 
0868       for( int i=1; i <= ncollumns; ++i ) {
0869          delete fEntries[i-1];
0870       }
0871 
0872       list->Clear();
0873       cont->MapSubwindows();
0874       cont->Layout();
0875    }   
0876 }
0877    
0878 //____________________________________________________________________
0879 void DbForm::HandleExecuteQuery()
0880 {
0881    // handler for use to execute SQL query
0882    
0883    TString sql = fQueryTextEntry->GetText();
0884    Int_t ncollumns;
0885    char rowstr[15];
0886         
0887    if(sql.IsNull()) return;    // validate sql
0888      
0889    ClearCanvas();
0890     
0891    if(fStatement) delete fStatement;
0892    fStatement = fConnection->CreateStatement(fRstype,fRsconc);   
0893    
0894    if(!fStatement) {
0895       return;
0896    }
0897       
0898    fResultSet = fStatement->ExecuteQuery(sql);
0899    
0900    if(fResultSet) { 
0901       fStatusBar->SetText(sql.Data(),1);
0902       fResultSetMetaData = fResultSet->GetMetaData(); // new metadata
0903       if(fRstype != kTYPE_FORWARD_ONLY) fGotoMenu->EnableEntry(kFirst);
0904       if(fRstype != kTYPE_FORWARD_ONLY) fGotoMenu->EnableEntry(kPrev);
0905       fGotoMenu->EnableEntry(kNext);
0906       fGotoMenu->EnableEntry(kLast);
0907       if(fRstype != kTYPE_FORWARD_ONLY) fFirstButton->SetState(kButtonUp);
0908       if(fRstype != kTYPE_FORWARD_ONLY) fPrevButton->SetState(kButtonUp);
0909       fNextButton->SetState(kButtonUp);
0910       fLastButton->SetState(kButtonUp);
0911        
0912       Int_t row = fResultSet->GetRow();
0913       sprintf(rowstr,"Row: %d",row);
0914       fStatusBar->SetText(rowstr,0);
0915    
0916       ncollumns = fResultSetMetaData->GetColumnCount();
0917       Int_t type;
0918       
0919       fEntries = new DbFormEntryPtr[ncollumns];
0920       
0921       for( int i=1; i <= ncollumns; ++i ) {
0922          type = fResultSetMetaData->GetColumnType(i);
0923          fEntries[i-1] = new DbFormEntry(fCanvasWindow->GetContainer(),i,
0924                               TString(""),fResultSetMetaData->GetColumnName(i));
0925 
0926          fCanvasWindow->AddFrame(fEntries[i-1]->GetMain(), fMenuBarLayout);
0927 
0928 //         fEntries[i-1]->Connect("Updated(Int_t,Text_t*)",
0929 //                        "DbForm",this,"UpdateColumn(Int_t,Text_t*)");
0930       }
0931       
0932       if(fRstype == kTYPE_FORWARD_ONLY)  SetForwardOnly();  
0933       fMain->MapSubwindows();
0934       fMain->Layout();
0935    } else {
0936       sql = "Failed to execute " + sql;
0937       fStatusBar->SetText(sql.Data(),1);
0938       fGotoMenu->DisableEntry(kFirst);
0939       fGotoMenu->DisableEntry(kPrev);
0940       fGotoMenu->DisableEntry(kNext);
0941       fGotoMenu->DisableEntry(kLast);
0942       fFirstButton->SetState(kButtonDisabled);
0943       fPrevButton->SetState(kButtonDisabled);
0944       fNextButton->SetState(kButtonDisabled);
0945       fLastButton->SetState(kButtonDisabled);
0946       fQueryTextEntry->SetFocus();
0947       fStatusBar->SetText("",0); 
0948    }
0949 }
0950       
0951 //____________________________________________________________________
0952 void DbForm::HandleDisconnect()
0953 {
0954    // handler for disconnect from db 
0955    
0956    ClearCanvas();   
0957    if(fConnection) fConnection->Close();
0958    fConnection = 0;
0959    fConnected = kFALSE;
0960    fGotoMenu->DisableEntry(kFirst);
0961    fGotoMenu->DisableEntry(kPrev);
0962    fGotoMenu->DisableEntry(kNext);
0963    fGotoMenu->DisableEntry(kLast);
0964    fFirstButton->SetState(kButtonDisabled);
0965    fPrevButton->SetState(kButtonDisabled);
0966    fNextButton->SetState(kButtonDisabled);
0967    fLastButton->SetState(kButtonDisabled);
0968    fExecuteQueryButton->SetState(kButtonDisabled);
0969    fCancelQueryButton->SetState(kButtonDisabled);
0970    fFileMenu->DisableEntry(kDisconnect);
0971    fQueryTextEntry->SetEnabled(kFALSE);
0972    fQueryTextEntry->Clear(); 
0973    fStatusBar->SetText("Disconnected",1);  
0974    fStatusBar->SetText("",0);
0975    fResultSetMetaData=0;  
0976    fResultSet=0;  
0977    fStatement=0;
0978 }
0979 
0980 //____________________________________________________________________
0981 void DbForm::HandleConnect()
0982 {
0983    // handler used to connect to db 
0984    
0985    fExecuteQueryButton->SetState(kButtonUp);
0986    fCancelQueryButton->SetState(kButtonUp);
0987    fFileMenu->EnableEntry(kDisconnect);
0988    
0989    TString info = "Connected to DSN - ";
0990    info += fDSN;  
0991    fStatusBar->SetText(info.Data(),1);
0992    
0993    TSQLDatabaseMetaData* md = fConnection->GetMetaData();
0994 
0995    if(md->SupportsResultSetType(kTYPE_SCROLL_INSENSITIVE)) {
0996       fRstype = kTYPE_SCROLL_INSENSITIVE;
0997    } else if(md->SupportsResultSetType(kTYPE_SCROLL_SENSITIVE)) {
0998       fRstype = kTYPE_SCROLL_SENSITIVE;
0999    } else {
1000       SetForwardOnly();
1001    }
1002 
1003    if(md->SupportsResultSetConcurrency(fRstype,kCONCUR_READ_ONLY)) {
1004       fRsconc = kCONCUR_READ_ONLY;
1005    } else {
1006       fRsconc = kCONCUR_UPDATABLE;
1007    }
1008 
1009    fQueryTextEntry->SetEnabled(kTRUE);
1010    fQueryTextEntry->SetFocus();      
1011 }      
1012 
1013 //____________________________________________________________________
1014 void DbForm::Connect(const Text_t* dsn,const Text_t* uid,const Text_t* pwd)
1015 {
1016    // password dialog 
1017    
1018    HandleDisconnect();
1019    
1020    fConnection = TSQLDriverManager::GetConnection(dsn,uid,pwd);
1021    fConnected = fConnection != 0;
1022    
1023    if(fConnected) {
1024       fDSN = dsn;
1025       fPD->Hide();
1026       HandleConnect();
1027    }
1028 }
1029 
1030 //____________________________________________________________________
1031 void DbForm::SetForwardOnly()
1032 {
1033    // 
1034        
1035    fRstype = kTYPE_FORWARD_ONLY;
1036    fPrevButton->SetState(kButtonDisabled);
1037    fFirstButton->SetState(kButtonDisabled);  
1038    fLastButton->SetState(kButtonDisabled);   
1039    fGotoMenu->DisableEntry(kFirst);
1040    fGotoMenu->DisableEntry(kPrev);
1041    fGotoMenu->DisableEntry(kLast);   
1042 }
1043       
1044 //____________________________________________________________________
1045 void Catch(TSQLException* e)
1046 {
1047    // exception handling function
1048    // can be switched off by TSQL::UnsetHandler()
1049 
1050    EMsgBoxIcon icontype = kMBIconExclamation; 
1051    Int_t buttons = 0; 
1052    Int_t retval;
1053 
1054    TString str  = e->GetMessage();
1055    TGMsgBox* errb;
1056 
1057    if(gForm) {   
1058       errb = new TGMsgBox(gClient->GetRoot(),gForm->GetMainFrame(),
1059                           "Error", str.Data(),icontype, buttons, &retval);
1060    } else  {
1061       printf("%s\n",str.Data());
1062    }      
1063 }
1064 
1065 ///////////////////////////////////////////////////////////////////////////////
1066 void RDBCform()
1067 {
1068    new DbForm();
1069 }
1070 
1071 //////////////////////////// Main program ////////////////////////////////////
1072 #ifdef STANDALONE
1073 
1074 #include <TROOT.h>
1075 #include <TApplication.h>
1076 #include <TSystem.h>
1077 #include <TInterpreter.h>
1078 
1079 //---- Main program ------------------------------------------------------------
1080 
1081 TROOT root("RDBCform", "GUI form for table browsing");
1082 
1083 int main(int argc, char **argv)
1084 {
1085    TApplication theApp("App", &argc, argv);
1086 
1087    if (gROOT->IsBatch()) {
1088       fprintf(stderr, "%s: cannot run in batch mode\n", argv[0]);
1089       return 1;
1090    }
1091    gDebug =1;
1092    gSystem->Load("libRDBC");
1093    gSystem->Load("./RDBCform_C");
1094    gInterpreter->ProcessLine("gForm = new DbForm();");
1095    theApp.Run();
1096    return 0;
1097 }
1098 #endif