TGRootIDE.cxx

Go to the documentation of this file.
00001 // @(#)root/test/RootIDE/:$Id: TGRootIDE.cxx 26165 2008-11-12 16:14:03Z bellenot $
00002 // Author: Bertrand Bellenot   20/04/2007
00003 
00004 /*************************************************************************
00005  * Copyright (C) 1995-2007, Rene Brun and Fons Rademakers.               *
00006  * All rights reserved.                                                  *
00007  *                                                                       *
00008  * For the licensing terms see $ROOTSYS/LICENSE.                         *
00009  * For the list of contributors see $ROOTSYS/README/CREDITS.             *
00010  *************************************************************************/
00011 
00012 //////////////////////////////////////////////////////////////////////////
00013 //                                                                      //
00014 //  TGRootIDE                                                           //
00015 //                                                                      //
00016 //  A simple IDE editor that uses the TGTextEdit widget.                //
00017 //  It provides all functionalities of TGTextEdit as copy, paste, cut,  //
00018 //  search, go to a given line number. In addition, it provides the     //
00019 //  possibilities for compiling, executing or interrupting a running    //
00020 //  macro.                                                              //
00021 //                                                                      //
00022 //  This class can be used in following ways:                           //
00023 //  - with file name as argument:                                       //
00024 //    new TGRootIDE("hsimple.C");                                       //
00025 //  - with a TMacro* as argument:                                       //
00026 //    TMacro *macro = new TMacro("hsimple.C");                          //
00027 //    new TGRootIDE(macro);                                             //
00028 //                                                                      //
00029 //  Basic Features:                                                     //
00030 //                                                                      //
00031 //  New Document                                                        //
00032 //                                                                      //
00033 //  To create a new blank document, select File menu / New, or click    //
00034 //  the New toolbar button. It will create a new instance of            //
00035 //  TGRootIDE.                                                          //
00036 //                                                                      //
00037 //  Open/Save File                                                      //
00038 //                                                                      //
00039 //  To open a file, select File menu / Open or click on the Open        //
00040 //  toolbar button. This will bring up the standard File Dialog for     //
00041 //  opening files.                                                      //
00042 //  If the current document has not been saved yet, you will be asked   //
00043 //  either to save or abandon the changes.                              //
00044 //  To save the file using the same name, select File menu / Save or    //
00045 //  the toolbar Save button. To change the file name use File menu /    //
00046 //  Save As... or corresponding SaveAs button on the toolbar.           //
00047 //                                                                      //
00048 //  Text Selection                                                      //
00049 //                                                                      //
00050 //  You can move the cursor by simply clicking on the desired location  //
00051 //  with the left mouse button. To highlight some text, press the mouse //
00052 //  and drag the mouse while holding the left button pressed.           //
00053 //  To select a word, double-click on it;                               //
00054 //  to select the text line - triple-click on it;                       //
00055 //  to select all  do quadruple-click.                                  //
00056 //                                                                      //
00057 //  Cut, Copy, Paste                                                    //
00058 //                                                                      //
00059 //  After selecting some text, you can cut or copy it to the clipboard. //
00060 //  A subsequent paste operation will insert the contents of the        //
00061 //  clipboard at the current cursor location.                           //
00062 //                                                                      //
00063 //  Text Search                                                         //
00064 //                                                                      //
00065 //  The editor uses a standard Search dialog. You can specify a forward //
00066 //  or backward search direction starting from the current cursor       //
00067 //  location according to the selection made of a case sensitive mode   //
00068 //  or not. The last search can be repeated by pressing F3.             //
00069 //                                                                      //
00070 //  Text Font                                                           //
00071 //                                                                      //
00072 //  You can change the text font by selecting Edit menu / Set Font.     //
00073 //  The Font Dialog pops up and shows the Name, Style, and Size of any  //
00074 //  available font. The selected font sample is shown in the preview    //
00075 //  area.                                                               //
00076 //                                                                      //
00077 //  Executing Macros                                                    //
00078 //                                                                      //
00079 //  You can execute the currently loaded macro in the editor by         //
00080 //  selecting Tools menu / Execute Macro; by clicking on the            //
00081 //  corresponding toolbar button, or by using Ctrl+F5 accelerator keys. //
00082 //  This is identical to the command ".x macro.C" in the root prompt    //
00083 //  command line.                                                       //
00084 //                                                                      //
00085 //  Compiling Macros                                                    //
00086 //                                                                      //
00087 //  The currently loaded macro can be compiled with ACLiC if you select //
00088 //  Tools menu / Compile Macro; by clicking on the corresponding        //
00089 //  toolbar button, or by using Ctrl+F7 accelerator keys.               //
00090 //  This is identical to the command ".L macro.C++" in the root prompt  //
00091 //  command line.                                                       //
00092 //                                                                      //
00093 //  Interrupting a Running Macro                                        //
00094 //                                                                      //
00095 //  You can interrupt a running macro by selecting the Tools menu /     //
00096 //  Interrupt; by clicking on the corresponding toolbar button, or by   //
00097 //  using Shift+F5 accelerator keys.                                    //
00098 //                                                                      //
00099 //  Interface to CINT Interpreter                                       //
00100 //                                                                      //
00101 //  Any command entered in the Command combo box will be passed to      //
00102 //  the CINT interpreter. This combo box will keep the commands history //
00103 //  and will allow you to re-execute the same commands during an editor //
00104 //  session.                                                            //
00105 //                                                                      //
00106 //  Keyboard Bindings                                                   //
00107 //                                                                      //
00108 //  The following table lists the keyboard shortcuts and accelerator    //
00109 //  keys.                                                               //
00110 //                                                                      //
00111 //  Key:              Action:                                           //
00112 //  ====              =======                                           //
00113 //                                                                      //
00114 //  Up                Move cursor up.                                   //
00115 //  Shift+Up          Move cursor up and extend selection.              //
00116 //  Down              Move cursor down.                                 //
00117 //  Shift+Down        Move cursor down and extend selection.            //
00118 //  Left              Move cursor left.                                 //
00119 //  Shift+Left        Move cursor left and extend selection.            //
00120 //  Right             Move cursor right.                                //
00121 //  Shift+Right       Move cursor right and extend selection.           //
00122 //  Home              Move cursor to begin of line.                     //
00123 //  Shift+Home        Move cursor to begin of line and extend selection.//
00124 //  Ctrl+Home         Move cursor to top of page.                       //
00125 //  End               Move cursor to end of line.                       //
00126 //  Shift+End         Move cursor to end of line and extend selection.  //
00127 //  Ctrl+End          Move cursor to end of page.                       //
00128 //  PgUp              Move cursor up one page.                          //
00129 //  Shift+PgUp        Move cursor up one page and extend selection.     //
00130 //  PgDn              Move cursor down one page.                        //
00131 //  Shift+PgDn        Move cursor down one page and extend selection.   //
00132 //  Delete            Delete character after cursor, or text selection. //
00133 //  BackSpace         Delete character before cursor, or text selection.//
00134 //  Ctrl+B            Move cursor left.                                 //
00135 //  Ctrl+D            Delete character after cursor, or text selection. //
00136 //  Ctrl+E            Move cursor to end of line.                       //
00137 //  Ctrl+H            Delete character before cursor, or text selection.//
00138 //  Ctrl+K            Delete characters from current position to the    //
00139 //                    end of line.                                      //
00140 //  Ctrl+U            Delete current line.                              //
00141 //                                                                      //
00142 //Begin_Html
00143 /*
00144 <img src="gif/TGRootIDE.gif">
00145 */
00146 //End_Html
00147 //                                                                      //
00148 //////////////////////////////////////////////////////////////////////////
00149 
00150 
00151 #include "TROOT.h"
00152 #include "TApplication.h"
00153 #include "TSystem.h"
00154 #include "TMacro.h"
00155 #include "TGMsgBox.h"
00156 #include "TGFileDialog.h"
00157 #include "TGFontDialog.h"
00158 #include "TGTextEdit.h"
00159 #include "TGMenu.h"
00160 #include "TGButton.h"
00161 #include "TGStatusBar.h"
00162 #include "KeySymbols.h"
00163 #include "TGToolBar.h"
00164 #include "TG3DLine.h"
00165 #include "TGLabel.h"
00166 #include "TGTextEntry.h"
00167 #include "TGTextEditDialogs.h"
00168 #include "TGRootIDE.h"
00169 #include "TGComboBox.h"
00170 #include "TGTab.h"
00171 #include "TGFSContainer.h"
00172 #include "TGListView.h"
00173 #include "TBrowser.h"
00174 #include "TFile.h"
00175 #include "TKey.h"
00176 #include "TObjString.h"
00177 #include "TRootHelpDialog.h"
00178 #include "TGSplitter.h"
00179 #include "TObjArray.h"
00180 #include "HelpText.h"
00181 #include "TGHtml.h"
00182 #include "TUrl.h"
00183 #include "TSocket.h"
00184 #include "TImage.h"
00185 #include "THtml.h"
00186 #include "TRint.h"
00187 #include "TProcessID.h"
00188 #include "Getline.h"
00189 #ifdef WIN32
00190 #include "TWin32SplashThread.h"
00191 #endif
00192 #include <string>
00193 
00194 const char *ed_filetypes[] = {
00195    "ROOT Macros",  "*.C",
00196    "Source files", "*.cxx",
00197    "Text files",   "*.txt",
00198    "All files",    "*",
00199    0, 0
00200 };
00201 
00202 const char *filters[] = {
00203    "",
00204    "*.*",
00205    "*.[C|c|h]*",
00206    "*.txt"
00207 };
00208 
00209 const char *HtmlError[] = {
00210 "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\" \"http://www.w3c.org/TR/1999/REC-html401-19991224/loose.dtd\"> ",
00211 "<HTML><HEAD><TITLE>RHTML cannot display the webpage</TITLE> ",
00212 "<META http-equiv=Content-Type content=\"text/html; charset=UTF-8\"></HEAD> ",
00213 "<BODY> ",
00214 "<TABLE cellSpacing=0 cellPadding=0 width=730 border=0> ",
00215 "  <TBODY> ",
00216 "  <TR> ",
00217 "    <TD id=infoIconAlign vAlign=top align=left width=60 rowSpan=2> ",
00218 "    <IMG src=\"info.gif\"> ",
00219 "    </TD> ",
00220 "    <TD id=mainTitleAlign vAlign=center align=left width=*> ",
00221 "      <H1 id=mainTitle>RHTML cannot display the webpage</H1></TD></TR> ",
00222 "  <TR> ",
00223 "    <TD class=errorCodeAndDivider id=errorCodeAlign align=right>&nbsp;  ",
00224 "      <DIV class=divider></DIV></TD></TR> ",
00225 "  <TR> ",
00226 "      <UL> ",
00227 "      </UL> ",
00228 "    <TD>&nbsp; </TD> ",
00229 "    <TD id=MostLikelyAlign vAlign=top align=left> ",
00230 "      <H3 id=likelyCauses>Most likely causes:</H3> ",
00231 "      <UL> ",
00232 "        <LI id=causeNotConnected>You are not connected to the Internet.  ",
00233 "        <LI id=causeSiteProblem>The website is encountering problems.  ",
00234 "        <LI id=causeErrorInAddress>There might be a typing error in the address.  ",
00235 "        <LI id=causeOtherError>  ",
00236 "        </LI></UL></TD></TR> ",
00237 "  <TR> ",
00238 "    <TD id=infoBlockAlign vAlign=top align=right>&nbsp; </TD> ",
00239 "    <TD id=moreInformationAlign vAlign=center align=left> ",
00240 "      <H4> ",
00241 "      <TABLE> ",
00242 "        <TBODY> ",
00243 "        <TR> ",
00244 "          <TD vAlign=top><SPAN id=moreInfoContainer></SPAN><ID  ",
00245 "            id=moreInformation>More information</ID> ",
00246 "      </TD></TR></TBODY></TABLE></H4> ",
00247 "      <DIV class=infoBlock id=infoBlockID> ",
00248 "      <P><ID id=errorExpl1>This problem can be caused by a variety of issues,  ",
00249 "      including:</ID>  ",
00250 "      <UL> ",
00251 "        <LI id=errorExpl2>Internet connectivity has been lost.  ",
00252 "        <LI id=errorExpl3>The website is temporarily unavailable.  ",
00253 "        <LI id=errorExpl4>The Domain Name Server (DNS) is not reachable.  ",
00254 "        <LI id=errorExpl5>The Domain Name Server (DNS) does not have a listing  ",
00255 "        for the website's domain.  ",
00256 "      <P></P> ",
00257 "      <P></P></DIV></TD></TR></TBODY></TABLE></BODY></HTML> ",
00258 0
00259 };
00260 
00261 enum ETextEditorCommands {
00262    kM_FILE_NEW, kM_FILE_CLOSE, kM_FILE_OPEN, kM_FILE_SAVE, kM_FILE_SAVEAS, kM_FILE_PRINT,
00263    kM_FILE_EXIT, kM_EDIT_CUT, kM_EDIT_COPY, kM_EDIT_PASTE, kM_EDIT_DELETE,
00264    kM_EDIT_SELECTALL, kM_SEARCH_FIND, kM_SEARCH_FINDNEXT, kM_SEARCH_GOTO,
00265    kM_TOOLS_COMPILE, kM_TOOLS_EXECUTE, kM_TOOLS_INTERRUPT, kM_TOOLS_BROWSER,
00266    kM_TOOLS_CLEAN_LOG, kM_HELP_CONTENTS, kM_HELP_ABOUT, kM_EDIT_SELFONT
00267 };
00268 
00269 ToolBarData_t fTbData[] = {
00270   { "ed_new.png",       "New File",         kFALSE, kM_FILE_NEW,         0 },
00271   { "ed_open.png",      "Open File",        kFALSE, kM_FILE_OPEN,        0 },
00272   { "ed_save.png",      "Save File",        kFALSE, kM_FILE_SAVE,        0 },
00273   { "ed_saveas.png",    "Save File As...",  kFALSE, kM_FILE_SAVEAS,      0 },
00274   { "",                 0,                  0,      -1,                  0 },
00275   { "ed_print.png",     "Print",            kFALSE, kM_FILE_PRINT,       0 },
00276   { "",                 0,                  0,      -1,                  0 },
00277   { "ed_cut.png",       "Cut selection",    kFALSE, kM_EDIT_CUT,         0 },
00278   { "ed_copy.png",      "Copy selection",   kFALSE, kM_EDIT_COPY,        0 },
00279   { "ed_paste.png",     "Paste selection",  kFALSE, kM_EDIT_PASTE,       0 },
00280   { "ed_delete.png",    "Delete selection", kFALSE, kM_EDIT_DELETE,      0 },
00281   { "",                 0,                  0,      -1,                  0 },
00282   { "ed_find.png",      "Find...",          kFALSE, kM_SEARCH_FIND,      0 },
00283   { "ed_findnext.png",  "Find next",        kFALSE, kM_SEARCH_FINDNEXT,  0 },
00284   { "ed_goto.png",      "Goto...",          kFALSE, kM_SEARCH_GOTO,      0 },
00285   { "",                 0,                  0,      -1,                  0 },
00286   { "ed_compile.png",   "Compile Macro",    kFALSE, kM_TOOLS_COMPILE,    0 },
00287   { "ed_execute.png",   "Execute Macro",    kFALSE, kM_TOOLS_EXECUTE,    0 },
00288   { "ed_interrupt.png", "Interrupt",        kFALSE, kM_TOOLS_INTERRUPT,  0 },
00289   { "",                 0,                  0,      -1,                  0 },
00290   { "ed_help.png",      "Help Contents",    kFALSE, kM_HELP_CONTENTS,    0 },
00291   { "",                 0,                  0,      -1,                  0 },
00292   { "ed_quit.png",      "Close Editor",     kFALSE, kM_FILE_EXIT,        0 },
00293   {  0,                 0,                  0,      0,                   0 }
00294 };
00295 
00296 static char *gEPrinter      = 0;
00297 static char *gEPrintCommand = 0;
00298 
00299 ClassImp(TGRootIDE)
00300 
00301 
00302 //______________________________________________________________________________
00303 TGDocument::TGDocument(const char *fname, const char *title, Int_t tabid,
00304                      TGTab *tab, TGTabElement *tabel, TGTextEdit *edit,
00305                      TObjArray *doclist) :  TNamed(fname, title)
00306 {
00307    fModified = kFALSE;
00308    fTabId    = tabid;
00309    fEditor   = edit;
00310    fTab      = tab;
00311    fTabEl    = tabel;
00312    fDocList  = doclist;
00313    Open(fname);
00314 }
00315 
00316 //______________________________________________________________________________
00317 Bool_t TGDocument::Close()
00318 {
00319    // Close the current active document.
00320 
00321    Int_t ret;
00322    if (fModified) {
00323       // the current active document has been modified
00324       // then ask the user if he wants to save it
00325       TString sfname(GetName());
00326       new TGMsgBox(gClient->GetRoot(), fTab, "TGRootIDE",
00327                    Form("%s has been modified. Do you want to save the changes?",
00328                         sfname.Data()),
00329                    kMBIconExclamation, kMBYes | kMBNo | kMBCancel, &ret);
00330       if (ret == kMBYes) {
00331          Save();
00332       }
00333       if (ret != kMBCancel) {
00334          // always keep the first two tabs
00335          if (fTab->GetNumberOfTabs() > 2) {
00336             fTab->RemoveTab(fTab->GetCurrent());
00337             fTab->Layout();
00338          }
00339          else {
00340             fEditor->Clear();
00341             fTabEl->SetText(new TGString("Untitled"));
00342             fTab->MapSubwindows();
00343             fTab->Layout();
00344          }
00345          fDocList->Remove((TObject *)this);
00346          ((TGRootIDE *)fTab->GetMainFrame())->DoTab(fTab->GetCurrent());
00347          delete this;
00348          return kTRUE;
00349       }
00350    }
00351    else {
00352       // no changes, so just close it
00353       if (fTab->GetNumberOfTabs() > 2) {
00354          // always keep the first two tabs
00355          fTab->RemoveTab(fTab->GetCurrent());
00356          fTab->Layout();
00357          fDocList->Remove((TObject *)this);
00358          ((TGRootIDE *)fTab->GetMainFrame())->DoTab(fTab->GetCurrent());
00359          delete this;
00360          return kTRUE;
00361       }
00362       else {
00363          fEditor->Clear();
00364          fTabEl->SetText(new TGString("Untitled"));
00365          fTab->MapSubwindows();
00366          fTab->Layout();
00367       }
00368       ((TGRootIDE *)fTab->GetMainFrame())->DoTab(fTab->GetCurrent());
00369       return kTRUE;
00370    }
00371    return kTRUE;
00372 }
00373 
00374 //______________________________________________________________________________
00375 Bool_t TGDocument::Open(const char *fname)
00376 {
00377    // Open file and create new document. If fname is NULL, create new Untitled 
00378    // document. Add a new tab element for this documment.
00379 
00380    TGFileInfo fi;
00381    fi.fFileTypes = ed_filetypes;
00382    if (fname == 0) {
00383       // no filename provided --> empty (untitled) document
00384       TGCompositeFrame *tf = fTab->AddTab("Untitled");
00385       tf->SetLayoutManager(new TGHorizontalLayout(tf));
00386       TGTextEdit *textEdit = new TGTextEdit(tf, 10, 10, 1);
00387       Pixel_t pxl;
00388       gClient->GetColorByName("#ccccff", pxl);
00389       textEdit->SetSelectBack(pxl);
00390       textEdit->SetSelectFore(TGFrame::GetBlackPixel());
00391       textEdit->Connect("DataChanged()", "TGDocument", this, "DataChanged()");
00392       textEdit->Connect("DataDropped(char *)", "TGDocument", this, "DataDropped(char *)");
00393       tf->AddFrame(textEdit, new TGLayoutHints(kLHintsExpandX | kLHintsExpandY));
00394       fEditor = textEdit;
00395       fEditor->Associate(fTab->GetMainFrame());
00396       fEditor->MapWindow();
00397       fTab->SetTab(fTab->GetNumberOfTabs()-1, kFALSE);
00398       fTab->MapSubwindows();
00399       fTab->Layout();
00400       fTabEl = fTab->GetTabTab(fTab->GetCurrent());
00401       fTabEl->ShowClose();
00402    }
00403    if (fname) {
00404       if ((fEditor == 0) || (fTabEl == 0) || (fEditor &&
00405            fEditor->GetText()->RowCount() > 1 &&
00406            fEditor->GetText()->ColCount() > 1)) {
00407          // if no current editor, or if current text editor already has 
00408          // text, add a new tab
00409          TGCompositeFrame *tf = fTab->AddTab(gSystem->BaseName(fname));
00410          tf->SetLayoutManager(new TGHorizontalLayout(tf));
00411          TGTextEdit *textEdit = new TGTextEdit(tf, 10, 10, 1);
00412          Pixel_t pxl;
00413          gClient->GetColorByName("#ccccff", pxl);
00414          textEdit->SetSelectBack(pxl);
00415          textEdit->SetSelectFore(TGFrame::GetBlackPixel());
00416          textEdit->Connect("DataChanged()", "TGDocument", this, "DataChanged()");
00417          textEdit->Connect("DataDropped(char *)", "TGDocument", this, "DataDropped(char *)");
00418          tf->AddFrame(textEdit, new TGLayoutHints(kLHintsExpandX | kLHintsExpandY));
00419          fEditor = textEdit;
00420          fEditor->Associate(fTab->GetMainFrame());
00421          fEditor->MapWindow();
00422          fTab->SetTab(fTab->GetNumberOfTabs()-1, kFALSE);
00423          fTab->MapSubwindows();
00424          fTab->Layout();
00425          fTabEl = fTab->GetTabTab(fTab->GetCurrent());
00426          fTabEl->ShowClose();
00427       }
00428       if (strlen(fname) == 0) {
00429          // no filename provided --> empty (untitled) document
00430          SetName("Untitled");
00431          SetTitle("Untitled");
00432          fEditor->Layout();
00433          fEditor->Connect("DataChanged()", "TGDocument", this, "DataChanged()");
00434          fEditor->Connect("DataDropped(char *)", "TGDocument", this, "DataDropped(char *)");
00435          fTabEl->SetText(new TGString("Untitled"));
00436          fTab->MapSubwindows();
00437          fTab->Layout();
00438       }
00439       else {
00440          // current tab is empty --> open document inside
00441          if (!fEditor->LoadFile(fname)) {
00442             new TGMsgBox(gClient->GetRoot(), fTab, "TGRootIDE",
00443                          Form("Error opening file \"%s\"", fname),
00444                          kMBIconExclamation, kMBOk);
00445          } else {
00446             fEditor->Layout();
00447             fTabEl->SetText(new TGString(gSystem->BaseName(fname)));
00448             fTab->MapSubwindows();
00449             fTab->Layout();
00450          }
00451       }
00452    }
00453    fEditor->Layout();
00454    fModified = kFALSE;
00455    return kTRUE;
00456 }
00457 
00458 //______________________________________________________________________________
00459 Bool_t TGDocument::Save(const char *fname)
00460 {
00461    // Save current document.
00462 
00463    TString sname;
00464    if (fname && strlen(fname) > 3) {
00465       sname = fname;
00466    }
00467    else sname = GetName();
00468    sname.Remove(TString::kLeading, '*');
00469    if (!fEditor->SaveFile(sname.Data())) {
00470       new TGMsgBox(gClient->GetRoot(), fTab, "TGRootIDE",
00471                    Form("Error saving file \"%s\"", sname.Data()),
00472                    kMBIconExclamation, kMBOk);
00473       return kFALSE;
00474    }
00475    fTabEl->SetText(new TGString(gSystem->BaseName(sname.Data())));
00476    fTabEl->Layout();
00477    fModified = kFALSE;
00478    return kTRUE;
00479 }
00480 
00481 //______________________________________________________________________________
00482 void TGDocument::DataDropped(char *fname)
00483 {
00484    // Handle drop event.
00485 
00486    if (strstr(GetName(),"Untitled")) {
00487       if (!fModified) {
00488          fTabEl->SetText(new TGString(Form("*%s", fTabEl->GetString())));
00489          fTabEl->Layout();
00490       }
00491       fModified = kTRUE;
00492    }
00493    SetName(fname);
00494    SetTitle(gSystem->BaseName(fname));
00495    fTabEl->SetText(new TGString(gSystem->BaseName(fname)));
00496    fTab->MapSubwindows();
00497    fTab->Layout();
00498 }
00499 
00500 //______________________________________________________________________________
00501 void TGDocument::DataChanged()
00502 {
00503    // Check if current document has been modified, and add or remove
00504    // a mark in front of tab name to indicate status.
00505 
00506    TList *hist = fEditor->GetHistory();
00507    if (hist->GetSize()) {
00508       if (!fModified) {
00509          fTabEl->SetText(new TGString(Form("*%s", fTabEl->GetString())));
00510          fTab->Layout();
00511       }
00512       fModified = kTRUE;
00513    }
00514    else {
00515       if (fModified) {
00516          TString sname(fTabEl->GetString());
00517          sname.Remove(TString::kLeading, '*');
00518          fTabEl->SetText(new TGString(Form("%s", sname.Data())));
00519          fTab->Layout();
00520       }
00521       fModified = kFALSE;
00522    }
00523 }
00524 
00525 //______________________________________________________________________________
00526 TGRootIDE::TGRootIDE(const char *filename, const TGWindow *p, UInt_t w,
00527                            UInt_t h) : TGMainFrame(p, w, h)
00528 {
00529    // TGRootIDE constructor with file name as first argument.
00530 
00531    Build();
00532    if (filename) {
00533       fTab->SetTab(fTab->GetNumberOfTabs()-1, kFALSE);
00534       fTab->MapSubwindows();
00535       fTab->Layout();
00536       LoadFile((char *)filename);
00537    }
00538    if (w > 0 && h > 0) {
00539       Resize(w, h > 500 ? h : 500);
00540       Layout();
00541    }
00542    MapWindow();
00543    fContents->DisplayDirectory();
00544    fContents->AddFile("..");        // up level directory
00545    fContents->SetViewMode(kLVDetails);
00546    fContents->Sort(kSortByType);
00547 }
00548 
00549 //______________________________________________________________________________
00550 TGRootIDE::TGRootIDE(TMacro *macro, const TGWindow *p, UInt_t w, UInt_t h) :
00551               TGMainFrame(p, w, h)
00552 {
00553    // TGRootIDE constructor with pointer to a TMacro as first argument.
00554 
00555    Build();
00556    if (macro) {
00557       fTab->SetTab(fTab->GetNumberOfTabs()-1, kFALSE);
00558       fTab->MapSubwindows();
00559       fTab->Layout();
00560       fMacro = macro;
00561       TIter next(macro->GetListOfLines());
00562       TObjString *obj;
00563       while ((obj = (TObjString*) next())) {
00564          fTextEdit->AddLine(obj->GetName());
00565       }
00566       fStatusBar->SetText(Form("TMacro : %s: %ld lines read.",
00567                           macro->GetName(), fTextEdit->ReturnLineCount()), 0);
00568       fFilename = macro->GetName();
00569       fFilename += ".C";
00570       SetWindowName(Form("TMacro : %s - TGRootIDE", macro->GetName()));
00571    }
00572    if (w > 0 && h > 0) {
00573       Resize(w, h > 500 ? h : 500);
00574       Layout();
00575    }
00576    MapWindow();
00577    fContents->DisplayDirectory();
00578    fContents->AddFile("..");        // up level directory
00579    fContents->SetViewMode(kLVDetails);
00580    fContents->Sort(kSortByType);
00581 }
00582 
00583 //______________________________________________________________________________
00584 TGRootIDE::~TGRootIDE()
00585 {
00586    // TGRootIDE destructor.
00587 
00588    fDocList->Delete();
00589    delete fDocList;
00590    delete fTimer;
00591 }
00592 
00593 //______________________________________________________________________________
00594 void TGRootIDE::Build()
00595 {
00596    // Build TGRootIDE widget.
00597 
00598    fDocList = new TObjArray(100);
00599    fCurrent = 0;
00600    fNbDoc   = 0;
00601    fCurrentDoc = 0;
00602    fPid = gSystem->GetPid(); //TProcessID::GetSessionProcessID();
00603    fHtml = new THtml();
00604 
00605    SetCleanup(kDeepCleanup);
00606    fMenuBarLayout = new TGLayoutHints(kLHintsTop | kLHintsExpandX, 0, 0, 1, 1);
00607    fMenuBarItemLayout = new TGLayoutHints(kLHintsTop | kLHintsLeft, 0, 4, 0, 0);
00608 
00609    fMenuFile = new TGPopupMenu(fClient->GetRoot());
00610    fMenuFile->AddEntry(" &New", kM_FILE_NEW, 0,
00611                        gClient->GetPicture("ed_new.png"));
00612    fMenuFile->AddSeparator();
00613    fMenuFile->AddEntry(" &Open...", kM_FILE_OPEN, 0,
00614                        gClient->GetPicture("ed_open.png"));
00615    fMenuFile->AddEntry(" &Close", kM_FILE_CLOSE);
00616    fMenuFile->AddEntry(" &Save", kM_FILE_SAVE, 0,
00617                        gClient->GetPicture("ed_save.png"));
00618    fMenuFile->AddEntry(" Save &As...", kM_FILE_SAVEAS, 0,
00619                        gClient->GetPicture("ed_saveas.png"));
00620    fMenuFile->AddSeparator();
00621    fMenuFile->AddEntry(" &Print...", kM_FILE_PRINT, 0,
00622                        gClient->GetPicture("ed_print.png"));
00623    fMenuFile->AddSeparator();
00624    fMenuFile->AddEntry(" E&xit", kM_FILE_EXIT, 0,
00625                        gClient->GetPicture("bld_exit.png"));
00626 
00627    fMenuEdit = new TGPopupMenu(fClient->GetRoot());
00628    fMenuEdit->AddEntry(" Cu&t             Ctrl+X", kM_EDIT_CUT, 0,
00629                        gClient->GetPicture("ed_cut.png"));
00630    fMenuEdit->AddEntry(" &Copy          Ctrl+C", kM_EDIT_COPY, 0,
00631                        gClient->GetPicture("ed_copy.png"));
00632    fMenuEdit->AddEntry(" &Paste         Ctrl+V", kM_EDIT_PASTE, 0,
00633                        gClient->GetPicture("ed_paste.png"));
00634    fMenuEdit->AddEntry(" De&lete        Del", kM_EDIT_DELETE, 0,
00635                        gClient->GetPicture("ed_delete.png"));
00636    fMenuEdit->AddSeparator();
00637    fMenuEdit->AddEntry(" Select &All   Ctrl+A", kM_EDIT_SELECTALL);
00638    fMenuEdit->AddSeparator();
00639    fMenuEdit->AddEntry(" Set &Font", kM_EDIT_SELFONT);
00640 
00641    fMenuTools = new TGPopupMenu(fClient->GetRoot());
00642    fMenuTools->AddEntry(" &Compile Macro  Ctrl+F7", kM_TOOLS_COMPILE, 0,
00643                        gClient->GetPicture("ed_compile.png"));
00644    fMenuTools->AddEntry(" &Execute Macro   Ctrl+F5", kM_TOOLS_EXECUTE, 0,
00645                        gClient->GetPicture("ed_execute.png"));
00646    fMenuTools->AddEntry(" &Interrupt              Shift+F5", kM_TOOLS_INTERRUPT, 0,
00647                        gClient->GetPicture("ed_interrupt.png"));
00648    fMenuTools->AddSeparator();
00649    fMenuTools->AddEntry(" Start &Browser", kM_TOOLS_BROWSER);
00650    fMenuTools->AddSeparator();
00651    fMenuTools->AddEntry(" Cleanup &Log Files", kM_TOOLS_CLEAN_LOG);
00652 
00653    fMenuEdit->DisableEntry(kM_EDIT_CUT);
00654    fMenuEdit->DisableEntry(kM_EDIT_COPY);
00655    fMenuEdit->DisableEntry(kM_EDIT_DELETE);
00656    fMenuEdit->DisableEntry(kM_EDIT_PASTE);
00657 
00658    fMenuSearch = new TGPopupMenu(fClient->GetRoot());
00659    fMenuSearch->AddEntry(" &Find...         Ctrl+F", kM_SEARCH_FIND, 0,
00660                        gClient->GetPicture("ed_find.png"));
00661    fMenuSearch->AddEntry(" Find &Next    F3", kM_SEARCH_FINDNEXT, 0,
00662                        gClient->GetPicture("ed_findnext.png"));
00663    fMenuSearch->AddSeparator();
00664    fMenuSearch->AddEntry(" &Goto Line... Ctrl+L", kM_SEARCH_GOTO, 0,
00665                        gClient->GetPicture("ed_goto.png"));
00666 
00667    fMenuHelp = new TGPopupMenu(fClient->GetRoot());
00668    fMenuHelp->AddEntry(" &Help Topics    F1", kM_HELP_CONTENTS, 0,
00669                        gClient->GetPicture("ed_help.png"));
00670    fMenuHelp->AddSeparator();
00671    fMenuHelp->AddEntry(" &About...", kM_HELP_ABOUT, 0,
00672                        gClient->GetPicture("about.xpm"));
00673 
00674    fMenuFile->Associate(this);
00675    fMenuEdit->Associate(this);
00676    fMenuSearch->Associate(this);
00677    fMenuTools->Associate(this);
00678    fMenuHelp->Associate(this);
00679 
00680    fMenuBar = new TGMenuBar(this, 1, 1, kHorizontalFrame);
00681    fMenuBar->SetCleanup(kDeepCleanup);
00682    fMenuBar->AddPopup("&File", fMenuFile, fMenuBarItemLayout);
00683    fMenuBar->AddPopup("&Edit", fMenuEdit, fMenuBarItemLayout);
00684    fMenuBar->AddPopup("&Search", fMenuSearch, fMenuBarItemLayout);
00685    fMenuBar->AddPopup("&Tools", fMenuTools, fMenuBarItemLayout);
00686    fMenuBar->AddPopup("&Help", fMenuHelp, new TGLayoutHints(kLHintsTop |
00687                       kLHintsRight));
00688    AddFrame(fMenuBar, fMenuBarLayout);
00689 
00690    //---- toolbar
00691 
00692    AddFrame(new TGHorizontal3DLine(this),
00693             new TGLayoutHints(kLHintsTop | kLHintsExpandX, 0,0,2,2));
00694    Int_t i,spacing = 8;
00695    fToolBar = new TGToolBar(this, 60, 20, kHorizontalFrame);
00696    fToolBar->SetCleanup(kDeepCleanup);
00697    for (i = 0; fTbData[i].fPixmap; i++) {
00698       if (strlen(fTbData[i].fPixmap) == 0) {
00699          spacing = 8;
00700          continue;
00701       }
00702       fToolBar->AddButton(this, &fTbData[i], spacing);
00703       spacing = 0;
00704    }
00705    fCommandBuf = new TGTextBuffer(256);
00706    fComboCmd   = new TGComboBox(fToolBar, "", 1);
00707    fCommand    = fComboCmd->GetTextEntry();
00708    fCommandBuf = fCommand->GetBuffer();
00709    fCommand->Associate(this);
00710    fComboCmd->Resize(200, fCommand->GetDefaultHeight());
00711    fToolBar->AddFrame(fComboCmd, new TGLayoutHints(kLHintsCenterY |
00712             kLHintsRight | kLHintsExpandX, 5, 5, 1, 1));
00713 
00714    TString defhist(Form("%s/.root_hist", gSystem->UnixPathName(gSystem->HomeDirectory())));
00715    FILE *lunin = fopen(defhist.Data(), "rt");
00716    if (lunin) {
00717       char histline[256];
00718       while (fgets(histline, 256, lunin)) {
00719          histline[strlen(histline)-1] = 0; // remove trailing "\n"
00720          fComboCmd->InsertEntry(histline, 0, -1);
00721       }
00722       fclose(lunin);
00723    }
00724 
00725    fToolBar->AddFrame(fLabel = new TGLabel(fToolBar, "Command (local):"),
00726             new TGLayoutHints(kLHintsCenterY | kLHintsRight, 5, 5, 1, 1));
00727    AddFrame(fToolBar, new TGLayoutHints(kLHintsTop | kLHintsExpandX,
00728             0, 0, 0, 0));
00729    AddFrame(new TGHorizontal3DLine(this),
00730             new TGLayoutHints(kLHintsTop | kLHintsExpandX, 0,0,2,2));
00731 
00732    fToolBar->GetButton(kM_EDIT_CUT)->SetState(kButtonDisabled);
00733    fToolBar->GetButton(kM_EDIT_COPY)->SetState(kButtonDisabled);
00734    fToolBar->GetButton(kM_EDIT_DELETE)->SetState(kButtonDisabled);
00735    fToolBar->GetButton(kM_EDIT_PASTE)->SetState(kButtonDisabled);
00736 
00737    TGHorizontalFrame *hf = new TGHorizontalFrame(this, 100, 100);
00738 
00739    TGVerticalFrame *vf3 = new TGVerticalFrame(hf, 160, 100, kSunkenFrame | kFixedWidth);
00740 
00741    fDirBuf   = new TGTextBuffer(256);
00742    fDirCombo = new TGComboBox(vf3, "");
00743    fDir      = fDirCombo->GetTextEntry();
00744    fDirBuf   = fDir->GetBuffer();
00745    fDirCombo->Resize(200, fDir->GetDefaultHeight());
00746    fDir->Connect("ReturnPressed()", "TGRootIDE", this, "DirChanged()");
00747 
00748    fDirCombo->AddEntry(gSystem->WorkingDirectory(), 1);
00749    gSystem->ChangeDirectory(gSystem->WorkingDirectory());
00750    fDir->SetText(gSystem->WorkingDirectory());
00751 
00752    fDirCombo->Select(0);
00753    fDirCombo->Connect("Selected(char *)", "TGRootIDE", this, "DirSelected(char *)");
00754 
00755    vf3->AddFrame(fDirCombo, new TGLayoutHints(kLHintsLeft | kLHintsTop | kLHintsExpandX,2,2,2,2));
00756 
00757    TGListView* lv = new TGListView(vf3, 200, 100);
00758    vf3->AddFrame(lv,new TGLayoutHints(kLHintsExpandY | kLHintsExpandX));
00759    Pixel_t white;
00760    gClient->GetColorByName("white",white);
00761    fContents = new TGFileContainer(lv, kSunkenFrame, white);
00762    fContents->Associate(this);
00763 
00764    fFileType = new TGComboBox(vf3, " All Files (*.*)");
00765    Int_t dropt = 1;
00766    fFileType->AddEntry(" All Files (*.*)", dropt++);
00767    fFileType->AddEntry(" C/C++ Files (*.c;*.cxx;*.h;...)", dropt++);
00768    fFileType->AddEntry(" Text Files (*.txt)", dropt++);
00769    fFilter = fFileType->GetTextEntry();
00770    fFileType->Resize(200, 20);
00771    vf3->AddFrame(fFileType, new TGLayoutHints(kLHintsExpandX, 1, 1, 1, 1));
00772    fFileType->Connect("Selected(Int_t)", "TGRootIDE", this, "ApplyFilter(Int_t)");
00773 
00774    hf->AddFrame(vf3, new TGLayoutHints(kLHintsLeft | kLHintsExpandY));
00775 
00776    TGVSplitter *splitter = new TGVSplitter(hf, 4);
00777    splitter->SetFrame(vf3, kTRUE);
00778    hf->AddFrame(splitter, new TGLayoutHints(kLHintsLeft | kLHintsExpandY));
00779 
00780    TGVerticalFrame *vf2 = new TGVerticalFrame(hf, 100, 100, kSunkenFrame);
00781 
00782    fTab = new TGTab(vf2, 300, 300);
00783    TGCompositeFrame *tf = fTab->AddTab("HTML");
00784    tf->SetLayoutManager(new TGHorizontalLayout(tf));
00785 
00786    // vertical frame
00787    fVerticalFrame = new TGVerticalFrame(tf,727,600,kVerticalFrame);
00788 
00789    fHorizontalFrame = new TGHorizontalFrame(fVerticalFrame,727,600);
00790 
00791    fBack = new TGPictureButton(fHorizontalFrame,
00792             gClient->GetPicture("GoBack.gif"));
00793    fBack->SetToolTipText("Go Back");
00794    fHorizontalFrame->AddFrame(fBack, new TGLayoutHints(kLHintsLeft | kLHintsTop | kLHintsCenterY,2,2,2,2));
00795    fBack->Connect("Clicked()", "TGRootIDE", this, "Back()");
00796 
00797    fForward = new TGPictureButton(fHorizontalFrame,
00798             gClient->GetPicture("GoForward.gif"));
00799    fForward->SetToolTipText("Go Forward");
00800    fHorizontalFrame->AddFrame(fForward, new TGLayoutHints(kLHintsLeft | kLHintsTop | kLHintsCenterY,2,2,2,2));
00801    fForward->Connect("Clicked()", "TGRootIDE", this, "Forward()");
00802 
00803    fReload = new TGPictureButton(fHorizontalFrame,
00804             gClient->GetPicture("ReloadPage.gif"));
00805    fReload->SetToolTipText("Reload Page");
00806    fHorizontalFrame->AddFrame(fReload, new TGLayoutHints(kLHintsLeft | kLHintsTop | kLHintsCenterY,2,2,2,2));
00807    fReload->Connect("Clicked()", "TGRootIDE", this, "Reload()");
00808 
00809    fStop = new TGPictureButton(fHorizontalFrame,
00810             gClient->GetPicture("StopLoading.gif"));
00811    fStop->SetToolTipText("Stop Loading");
00812    fHorizontalFrame->AddFrame(fStop, new TGLayoutHints(kLHintsLeft | kLHintsTop | kLHintsCenterY,2,2,2,2));
00813    fStop->Connect("Clicked()", "TGRootIDE", this, "Stop()");
00814 
00815    fHome = new TGPictureButton(fHorizontalFrame,
00816            gClient->GetPicture("GoHome.gif"));
00817    fHome->SetToolTipText("Go to ROOT HomePage\n  (http://root.cern.ch)");
00818    fHorizontalFrame->AddFrame(fHome, new TGLayoutHints(kLHintsLeft | kLHintsTop | kLHintsCenterY,2,2,2,2));
00819    fHome->Connect("Clicked()", "TGRootIDE", this, "Selected(=\"http://root.cern.ch\")");
00820 
00821    // combo box
00822    fURLBuf   = new TGTextBuffer(256);
00823    fComboBox = new TGComboBox(fHorizontalFrame, "");
00824    fURL      = fComboBox->GetTextEntry();
00825    fURLBuf   = fURL->GetBuffer();
00826    fComboBox->Resize(200, fURL->GetDefaultHeight());
00827    fURL->Connect("ReturnPressed()", "TGRootIDE", this, "URLChanged()");
00828 
00829    fComboBox->AddEntry("http://root.cern.ch", 1);
00830    fComboBox->AddEntry("http://root.cern.ch/root/htmldoc/ClassIndex.html", 2);
00831    fURL->SetText("http://root.cern.ch/root/htmldoc/ClassIndex.html");
00832 
00833    fComboBox->Select(0);
00834    fComboBox->Connect("Selected(char *)", "TGRootIDE", this, "Selected(char *)");
00835 
00836    fHorizontalFrame->AddFrame(fComboBox, new TGLayoutHints(kLHintsLeft | kLHintsCenterY | kLHintsExpandX,2,2,2,2));
00837 
00838    fVerticalFrame->AddFrame(fHorizontalFrame, new TGLayoutHints(kLHintsLeft | kLHintsTop | kLHintsExpandX,2,2,2,2));
00839 
00840    // embedded canvas
00841    fGuiHtml = new TGHtml(fVerticalFrame, 10, 10, -1);
00842    fVerticalFrame->AddFrame(fGuiHtml, new TGLayoutHints(kLHintsLeft | kLHintsTop | kLHintsExpandX | kLHintsExpandY,2,2,2,2));
00843 
00844    tf->AddFrame(fVerticalFrame, new TGLayoutHints(kLHintsLeft | kLHintsTop | kLHintsExpandX | kLHintsExpandY,2,2,2,2));
00845 
00846    fGuiHtml->Connect("MouseOver(char *)", "TGRootIDE", this, "MouseOver(char *)");
00847    fGuiHtml->Connect("MouseDown(char *)", "TGRootIDE", this, "MouseDown(char *)");
00848    Selected("http://root.cern.ch/root/htmldoc/ClassIndex.html");
00849    fGuiHtml->Layout();
00850 
00851    tf = fTab->AddTab("Untitled");
00852    tf->SetLayoutManager(new TGHorizontalLayout(tf));
00853    fTextEdit = new TGTextEdit(tf, 10, 10, 1);
00854    fTextEdit->Associate(this);
00855    TGTabElement *tabel = fTab->GetTabTab(1);
00856    tabel->ShowClose();
00857 
00858    // set selected text colors
00859    Pixel_t pxl;
00860    gClient->GetColorByName("#ccccff", pxl);
00861    fTextEdit->SetSelectBack(pxl);
00862    fTextEdit->SetSelectFore(TGFrame::GetBlackPixel());
00863    fCurrentDoc = new TGDocument("", "", 1, fTab,
00864                   fTab->GetTabTab(1),
00865                   fTextEdit, fDocList);
00866    fDocList->Add((TObject *)fCurrentDoc);
00867    tf->AddFrame(fTextEdit, new TGLayoutHints(kLHintsExpandX | kLHintsExpandY));
00868 
00869    vf2->AddFrame(fTab, new TGLayoutHints(kLHintsExpandX | kLHintsExpandY));
00870    fTab->Connect("Selected(Int_t)", "TGRootIDE", this, "DoTab(Int_t)");
00871    fTab->Connect("CloseTab(Int_t)", "TGRootIDE", this, "CloseTab(Int_t)");
00872 
00873    hf->AddFrame(vf2, new TGLayoutHints(kLHintsExpandX | kLHintsExpandY));
00874    AddFrame(hf, new TGLayoutHints(kLHintsExpandX | kLHintsExpandY));
00875 
00876    gClient->GetColorByName("#ccccff", pxl);
00877    fTextView = new TGTextView(this, 10, 100, 1);
00878    fTextView->SetSelectBack(pxl);
00879    fTextView->SetSelectFore(TGFrame::GetBlackPixel());
00880    fTextView->Associate(this);
00881    fTextView->ChangeOptions(fTextView->GetOptions() | kFixedHeight);
00882 
00883    TGHSplitter *hsplitter = new TGHSplitter(this, 4);
00884    hsplitter->SetFrame(fTextView, kFALSE);
00885    AddFrame(hsplitter, new TGLayoutHints(kLHintsLeft | kLHintsExpandX));
00886 
00887    AddFrame(fTextView, new TGLayoutHints(kLHintsExpandX));
00888 
00889    Int_t parts[] = { 75, 25 };
00890    fStatusBar = new TGStatusBar(this);
00891    fStatusBar->SetCleanup(kDeepCleanup);
00892    fStatusBar->SetParts(parts, 2);
00893    AddFrame(fStatusBar, new TGLayoutHints(kLHintsBottom | kLHintsExpandX, 0, 0, 3, 0));
00894 
00895    SetClassHints("TGRootIDE", "TGRootIDE");
00896    SetWindowName("Untitled - TGRootIDE");
00897 
00898    fMacro = 0;
00899    fFilename = "Untitled";
00900    fStatusBar->SetText(fFilename.Data(), 0);
00901 
00902    MapSubwindows();
00903    Resize(GetDefaultWidth() + 50, GetDefaultHeight() > 500 ? GetDefaultHeight() : 500);
00904    Layout();
00905 
00906    gVirtualX->GrabKey(fId, gVirtualX->KeysymToKeycode(kKey_F3), 0, kTRUE);
00907 
00908    AddInput(kKeyPressMask | kEnterWindowMask | kLeaveWindowMask |
00909             kFocusChangeMask | kStructureNotifyMask);
00910 
00911    fTimer = new TTimer(this, 250);
00912    fTimer->Reset();
00913    fTimer->TurnOn();
00914 
00915    fExiting = kFALSE;
00916    fTextChanged = kFALSE;
00917 }
00918 
00919 //______________________________________________________________________________
00920 void TGRootIDE::LoadFile(char *fname)
00921 {
00922    // Load a file into the editor. If fname is 0, a TGFileDialog will popup.
00923 
00924    TGFileInfo fi;
00925    fi.fFileTypes = ed_filetypes;
00926    if (fname == 0) {
00927       new TGFileDialog(fClient->GetDefaultRoot(), this, kFDOpen, &fi);
00928       if (fi.fFilename && strlen(fi.fFilename)) {
00929          fname = fi.fFilename;
00930       }
00931    }
00932    if (fname) {
00933       const char *p = fTab->GetTabTab(fTab->GetCurrent())->GetString();
00934       if (!strcmp(p, "HTML")) {
00935          TString filename(fname);
00936          if (filename.EndsWith(".htm") ||
00937              filename.EndsWith(".html")) {
00938             Selected(Form("file://%s", filename.Data()));
00939          }
00940          else {
00941             TString pathtmp = Form("%s/%s.html",
00942                gSystem->UnixPathName(gSystem->TempDirectory()),
00943                gSystem->BaseName(fname));
00944             fHtml->Convert(fname, fname,
00945                gSystem->UnixPathName(gSystem->TempDirectory()),
00946                gSystem->UnixPathName(gSystem->TempDirectory()));
00947             Selected(Form("file://%s", pathtmp.Data()));
00948          }
00949          //gSystem->Unlink(pathtmp.Data());
00950       }
00951       else {
00952          TGDocument *doc = new TGDocument(fname, gSystem->BaseName(fname),
00953                                         fTab->GetNumberOfTabs()+1, fTab,
00954                                         0, 0, fDocList);
00955          fDocList->Add((TObject *)doc);
00956          fCurrent = fTab->GetCurrent();
00957          fCurrentDoc = doc;
00958          fFilename = fCurrentDoc->GetName();
00959          fTextEdit = fCurrentDoc->GetTextEdit();
00960          fTextEdit->SetFocus();
00961       }
00962    }
00963 }
00964 
00965 //______________________________________________________________________________
00966 void TGRootIDE::SaveFile(const char *fname)
00967 {
00968    // Save the edited text in the file "fname".
00969 
00970    char *p;
00971    if (!fCurrentDoc) return;
00972    fCurrentDoc->Save(fname);
00973    if ((p = (char *)strrchr(fname, '/')) == 0) {
00974       p = (char *)fname;
00975    } else {
00976       ++p;
00977    }
00978    fStatusBar->SetText(Form("%s: %ld lines written.", p,
00979                        fTextEdit->ReturnLineCount()), 0);
00980    SetWindowName(Form("%s - TGRootIDE", p));
00981    fTextChanged = kFALSE;
00982 }
00983 
00984 //______________________________________________________________________________
00985 Bool_t TGRootIDE::SaveFileAs()
00986 {
00987    // Save the edited text in a file selected with TGFileDialog.
00988    // Shouldn't we create a backup file?
00989 
00990    if (!fCurrentDoc) return kFALSE;
00991    static TString dir(".");
00992    static Bool_t overwr = kFALSE;
00993    TGFileInfo fi;
00994    fi.fFileTypes = ed_filetypes;
00995    fi.fIniDir    = StrDup(dir);
00996    fi.fOverwrite = overwr;
00997    new TGFileDialog(fClient->GetDefaultRoot(), this, kFDSave, &fi);
00998    overwr = fi.fOverwrite;
00999    if (fi.fFilename && strlen(fi.fFilename)) {
01000       fCurrentDoc->Save(fi.fFilename);
01001       fFilename = fi.fFilename;
01002       return kTRUE;
01003    }
01004    return kFALSE;
01005 }
01006 
01007 //______________________________________________________________________________
01008 Int_t TGRootIDE::IsSaved()
01009 {
01010    // Check if file has to be saved in case of modifications.
01011 
01012    Int_t ret;
01013    TGDocument *doc = 0;
01014    TIter next(fDocList);
01015    while ((doc = (TGDocument *)next())) {
01016       if (doc->IsModified()) {
01017          TString sfname(doc->GetName());
01018          new TGMsgBox(fClient->GetRoot(), this, "TGRootIDE",
01019                       Form("%s has been modified. Do you want to save the changes?",
01020                            sfname.Data()),
01021                       kMBIconExclamation, kMBYes | kMBNo | kMBCancel, &ret);
01022          if (ret == kMBYes) {
01023             doc->Save();
01024          }
01025       }
01026    }
01027    return kMBNo; //ret;
01028 }
01029 
01030 //______________________________________________________________________________
01031 void TGRootIDE::PrintText()
01032 {
01033    // Open the print dialog and send current buffer to printer.
01034 
01035    Int_t ret = 0;
01036    if (!gEPrinter) {
01037       gEPrinter = StrDup("892_2_cor"); // use gEnv
01038       gEPrintCommand = StrDup("xprint");
01039    }
01040    new TGPrintDialog(fClient->GetDefaultRoot(), this, 400, 150,
01041                      &gEPrinter, &gEPrintCommand, &ret);
01042    if (ret) {
01043       fTextEdit->Print();
01044       fStatusBar->SetText(Form("Printed: %s", fFilename.Data()), 0);
01045    }
01046 }
01047 
01048 //______________________________________________________________________________
01049 void TGRootIDE::CloseWindow()
01050 {
01051    // Close TGRootIDE window.
01052 
01053    if (fExiting) {
01054       return;
01055    }
01056    fExiting = kTRUE;
01057    if (IsSaved() == kMBCancel) {
01058       fExiting = kFALSE;
01059       return;
01060    }
01061    fExiting = kFALSE;
01062    Cleanup();
01063 #ifdef WIN32
01064    gSystem->Exec(Form("del %s\\*.html", gSystem->TempDirectory()));
01065    gSystem->Exec(Form("del %s\\*.C", gSystem->TempDirectory()));
01066 #else
01067    gSystem->Exec(Form("rm -f %s/*.html", gSystem->TempDirectory()));
01068    gSystem->Exec(Form("rm -f %s/*.C", gSystem->TempDirectory()));
01069 #endif
01070    delete this;
01071    gApplication->Terminate(0);
01072 }
01073 
01074 //______________________________________________________________________________
01075 Bool_t TGRootIDE::HandleKey(Event_t *event)
01076 {
01077    // Keyboard event handler.
01078 
01079    char   input[10];
01080    Int_t  n;
01081    UInt_t keysym;
01082 
01083    if (event->fType == kGKeyPress) {
01084       gVirtualX->LookupString(event, input, sizeof(input), keysym);
01085       n = strlen(input);
01086 
01087       switch ((EKeySym)keysym) {   // ignore these keys
01088          case kKey_Shift:
01089          case kKey_Control:
01090          case kKey_Meta:
01091          case kKey_Alt:
01092          case kKey_CapsLock:
01093          case kKey_NumLock:
01094          case kKey_ScrollLock:
01095             return kTRUE;
01096          case kKey_F1:
01097             SendMessage(this, MK_MSG(kC_COMMAND, kCM_MENU),
01098                         kM_HELP_CONTENTS, 0);
01099             return kTRUE;
01100          case kKey_F3:
01101             Search(kTRUE);
01102             return kTRUE;
01103          default:
01104             break;
01105       }
01106       if (event->fState & kKeyControlMask) {   // Ctrl key modifier pressed
01107          switch((EKeySym)keysym) {
01108             case kKey_F4:
01109             case kKey_W:
01110                SendMessage(this, MK_MSG(kC_COMMAND, kCM_MENU),
01111                            kM_FILE_CLOSE, 0);
01112                return kTRUE;
01113             case kKey_F5:
01114                ExecuteMacro();
01115                return kTRUE;
01116             case kKey_F7:
01117                CompileMacro();
01118                return kTRUE;
01119             case kKey_Tab:
01120                if (fTab->GetCurrent() == fTab->GetNumberOfTabs()-1)
01121                   fTab->SetTab(0);
01122                else
01123                   fTab->SetTab(fTab->GetCurrent()+1);
01124                break;
01125             default:
01126                break;
01127          }
01128       }
01129       if (event->fState & kKeyShiftMask) {   // Shift key modifier pressed
01130          switch((EKeySym)keysym) {
01131             case kKey_F5:
01132                InterruptMacro();
01133                return kTRUE;
01134             default:
01135                break;
01136          }
01137       }
01138    }
01139    return TGMainFrame::HandleKey(event);
01140 }
01141 
01142 //______________________________________________________________________________
01143 void TGRootIDE::ClearText()
01144 {
01145    // Clear text edit widget.
01146 
01147    fTextEdit->Clear();
01148    fMacro = 0;
01149    fFilename = "Untitled";
01150    SetWindowName("Untitled - TGRootIDE");
01151    fStatusBar->SetText("New File", 0);
01152    fTextChanged = kFALSE;
01153    fTab->GetTabTab(fTab->GetCurrent())->SetText(new TGString("Untitled"));
01154    fTab->MapSubwindows();
01155    fTab->Layout();
01156 }
01157 
01158 //______________________________________________________________________________
01159 void TGRootIDE::Search(Bool_t again)
01160 {
01161    // Invokes search dialog, or just search previous string if again is true.
01162 
01163    if (again) {
01164       SendMessage(fTextEdit, MK_MSG(kC_COMMAND, kCM_MENU),
01165                   TGTextEdit::kM_SEARCH_FINDAGAIN, 0);
01166    }
01167    else {
01168       fTextEdit->Search(kFALSE);
01169    }
01170 }
01171 
01172 //______________________________________________________________________________
01173 void TGRootIDE::Goto()
01174 {
01175    // Invokes goto dialog, and go to the specified line.
01176 
01177    Long_t ret;
01178 
01179    new TGGotoDialog(fClient->GetDefaultRoot(), this, 400, 150, &ret);
01180 
01181    if (ret >= 0)
01182       fTextEdit->Goto(ret-1);
01183 }
01184 
01185 //______________________________________________________________________________
01186 void TGRootIDE::CompileMacro()
01187 {
01188    // Save the edited text in a temporary macro, then compile it.
01189 
01190    if (fTextEdit->ReturnLineCount() < 3)
01191       return;
01192    if ((fMacro) || (fFilename.Contains("Untitled"))) {
01193       if (!SaveFileAs())
01194          return;
01195    }
01196    TString pathtmp = Form("%s/ride.%d.log", gSystem->TempDirectory(), fPid);
01197    gSystem->RedirectOutput(pathtmp.Data(), "a");
01198 
01199    char *tmpfile = gSystem->ConcatFileName(gSystem->TempDirectory(),
01200                                 gSystem->BaseName(fFilename.Data()));
01201    fTextEdit->SaveFile(tmpfile, kFALSE);
01202    gSystem->CompileMacro(tmpfile);
01203    gSystem->Unlink(tmpfile);
01204    delete tmpfile;
01205 
01206    gSystem->RedirectOutput(0);
01207    fTextView->LoadFile(pathtmp.Data());
01208    if (fTextView->ReturnLineCount() > 7)
01209       fTextView->SetVsbPosition(fTextView->ReturnLineCount());
01210 }
01211 
01212 //______________________________________________________________________________
01213 void TGRootIDE::ExecuteMacro()
01214 {
01215    // Save the edited text in a temporary macro, execute it, and then delete
01216    // the temporary file.
01217 
01218    if (fTextEdit->ReturnLineCount() < 3)
01219       return;
01220    if (fMacro) {
01221       fMacro->Exec();
01222       return;
01223    }
01224    if (fTextChanged) {
01225       Int_t ret;
01226       new TGMsgBox(fClient->GetRoot(), this, "TGRootIDE",
01227             "The text has been modified. Do you want to save the changes?",
01228             kMBIconExclamation, kMBYes | kMBNo | kMBCancel, &ret);
01229       if (ret == kMBYes) {
01230          if (fFilename.Contains("Untitled"))
01231             SaveFileAs();
01232          else
01233             SaveFile(fFilename.Data());
01234          fTextChanged = kFALSE;
01235       }
01236       if (ret == kMBCancel)
01237          return;
01238    }
01239    if (fFilename.Contains("Untitled")) {
01240       if (!SaveFileAs())
01241          return;
01242    }
01243    TString pathtmp = Form("%s/ride.%d.log", gSystem->TempDirectory(), fPid);
01244    gSystem->RedirectOutput(pathtmp.Data(), "a");
01245 
01246    char *tmpfile = gSystem->ConcatFileName(gSystem->TempDirectory(),
01247                                 gSystem->BaseName(fFilename.Data()));
01248    gROOT->SetExecutingMacro(kTRUE);
01249    fTextEdit->SaveFile(tmpfile, kFALSE);
01250    gROOT->Macro(tmpfile);
01251    gSystem->Unlink(tmpfile);
01252    delete tmpfile;
01253    gROOT->SetExecutingMacro(kFALSE);
01254    gSystem->RedirectOutput(0);
01255    fTextView->LoadFile(pathtmp.Data());
01256    if (fTextView->ReturnLineCount() > 7)
01257       fTextView->SetVsbPosition(fTextView->ReturnLineCount());
01258 }
01259 
01260 //______________________________________________________________________________
01261 void TGRootIDE::InterruptMacro()
01262 {
01263    // Interrupt execution of a macro.
01264 
01265    gROOT->SetInterrupt(kTRUE);
01266 }
01267 
01268 //______________________________________________________________________________
01269 void TGRootIDE::About()
01270 {
01271    // Display ROOT splash screen.
01272 
01273 #ifdef R__UNIX
01274    TString rootx;
01275 # ifdef ROOTBINDIR
01276    rootx = ROOTBINDIR;
01277 # else
01278    rootx = gSystem->Getenv("ROOTSYS");
01279    if (!rootx.IsNull()) rootx += "/bin";
01280 # endif
01281    rootx += "/root -a &";
01282    gSystem->Exec(rootx);
01283 #else
01284 #ifdef WIN32
01285    new TWin32SplashThread(kTRUE);
01286 #else
01287    char str[32];
01288    sprintf(str, "About ROOT %s...", gROOT->GetVersion());
01289    TRootHelpDialog *hd = new TRootHelpDialog(this, str, 600, 400);
01290    hd->SetText(gHelpAbout);
01291    hd->Popup();
01292 #endif
01293 #endif
01294 }
01295 
01296 //______________________________________________________________________________
01297 Bool_t TGRootIDE::HandleTimer(TTimer *t)
01298 {
01299    // Handle timer event.
01300 
01301    if (t != fTimer) return kTRUE;
01302    // check if some text is available in the clipboard
01303    if ((gVirtualX->InheritsFrom("TGX11")) &&
01304       (gVirtualX->GetPrimarySelectionOwner() == kNone)) {
01305       fMenuEdit->DisableEntry(kM_EDIT_PASTE);
01306       fToolBar->GetButton(kM_EDIT_PASTE)->SetState(kButtonDisabled);
01307    }
01308    else {
01309       fMenuEdit->EnableEntry(kM_EDIT_PASTE);
01310       if (fToolBar->GetButton(kM_EDIT_PASTE)->GetState() == kButtonDisabled)
01311          fToolBar->GetButton(kM_EDIT_PASTE)->SetState(kButtonUp);
01312    }
01313    // check if text is selected in the editor
01314    if (fTextEdit && fTextEdit->IsMarked()) {
01315       fMenuEdit->EnableEntry(kM_EDIT_CUT);
01316       fMenuEdit->EnableEntry(kM_EDIT_COPY);
01317       fMenuEdit->EnableEntry(kM_EDIT_DELETE);
01318       if (fToolBar->GetButton(kM_EDIT_CUT)->GetState() == kButtonDisabled) {
01319          fToolBar->GetButton(kM_EDIT_CUT)->SetState(kButtonUp);
01320          fToolBar->GetButton(kM_EDIT_COPY)->SetState(kButtonUp);
01321          fToolBar->GetButton(kM_EDIT_DELETE)->SetState(kButtonUp);
01322       }
01323    }
01324    else {
01325       fMenuEdit->DisableEntry(kM_EDIT_CUT);
01326       fMenuEdit->DisableEntry(kM_EDIT_COPY);
01327       fMenuEdit->DisableEntry(kM_EDIT_DELETE);
01328       if (fToolBar->GetButton(kM_EDIT_CUT)->GetState() == kButtonUp) {
01329          fToolBar->GetButton(kM_EDIT_CUT)->SetState(kButtonDisabled);
01330          fToolBar->GetButton(kM_EDIT_COPY)->SetState(kButtonDisabled);
01331          fToolBar->GetButton(kM_EDIT_DELETE)->SetState(kButtonDisabled);
01332       }
01333    }
01334    // get cursor position
01335    if (fTextEdit) {
01336       TGLongPosition pos = fTextEdit->GetCurrentPos();
01337       fStatusBar->SetText(Form("Ln %ld, Ch %ld", pos.fY, pos.fX), 1);
01338    }
01339    fTimer->Reset();
01340    return kTRUE;
01341 }
01342 
01343 //______________________________________________________________________________
01344 Bool_t TGRootIDE::ProcessMessage(Long_t msg, Long_t parm1, Long_t)
01345 {
01346    // Handle menu and other command generated by the user.
01347 
01348    TRootHelpDialog *hd;
01349 
01350    switch(GET_MSG(msg)) {
01351       case kC_CONTAINER:
01352          switch (GET_SUBMSG(msg)) {
01353             case kCT_ITEMDBLCLICK:
01354                if (parm1==kButton1) OnDoubleClick((TGLVEntry*)fContents->GetLastActive(), parm1);
01355                break;
01356          }
01357          break;
01358       case kC_COMMAND:
01359          switch(GET_SUBMSG(msg)) {
01360             case kCM_BUTTON:
01361             case kCM_MENU:
01362                switch (parm1) {
01363                   // "File" menu related events
01364                   case kM_FILE_NEW:
01365                      {
01366                         fDocList->Add((TObject *)new TGDocument(0, 0,
01367                            fTab->GetNumberOfTabs(), fTab, 0, 0, fDocList));
01368                      }
01369                      break;
01370                   case kM_FILE_CLOSE:
01371                      if (fCurrentDoc) {
01372                         fCurrentDoc->Close();
01373                      }
01374                      fTab->Layout();
01375                      break;
01376                   case kM_FILE_OPEN:
01377                      LoadFile();
01378                      break;
01379                   case kM_FILE_SAVE:
01380                      if (fFilename.Contains("Untitled"))
01381                         SaveFileAs();
01382                      else
01383                         SaveFile(fFilename.Data());
01384                      break;
01385                   case kM_FILE_SAVEAS:
01386                      SaveFileAs();
01387                      break;
01388                   case kM_FILE_PRINT:
01389                      PrintText();
01390                      break;
01391                   case kM_FILE_EXIT:
01392                      CloseWindow();
01393                      break;
01394 
01395                   // "Edit" menu related events
01396                   case kM_EDIT_CUT:
01397                      fTextEdit->Cut();
01398                      break;
01399                   case kM_EDIT_COPY:
01400                      fTextEdit->Copy();
01401                      break;
01402                   case kM_EDIT_PASTE:
01403                      fTextEdit->Paste();
01404                      break;
01405                   case kM_EDIT_DELETE:
01406                      fTextEdit->Delete();
01407                      break;
01408                   case kM_EDIT_SELECTALL:
01409                      fTextEdit->SelectAll();
01410                      if (fTextEdit->IsMarked()) {
01411                         fMenuEdit->EnableEntry(kM_EDIT_CUT);
01412                         fMenuEdit->EnableEntry(kM_EDIT_COPY);
01413                         fMenuEdit->EnableEntry(kM_EDIT_DELETE);
01414                         if (fToolBar->GetButton(kM_EDIT_CUT)->GetState() == kButtonDisabled) {
01415                            fToolBar->GetButton(kM_EDIT_CUT)->SetState(kButtonUp);
01416                            fToolBar->GetButton(kM_EDIT_COPY)->SetState(kButtonUp);
01417                            fToolBar->GetButton(kM_EDIT_DELETE)->SetState(kButtonUp);
01418                         }
01419                      }
01420                      break;
01421                   case kM_EDIT_SELFONT:
01422                      {
01423                         Int_t count;
01424                         char fontname[256];
01425                         TGFontDialog::FontProp_t prop;
01426                         new TGFontDialog(fClient->GetRoot(), this, &prop);
01427                         if (prop.fName != "") {
01428                            sprintf(fontname,"-*-%s-%s-%c-*-*-%d-*-*-*-*-*-*-*",
01429                                    prop.fName.Data(), prop.fBold ? "bold" : "medium",
01430                                    prop.fItalic ? 'i' : 'r',
01431                                    prop.fSize);
01432                            if (!gVirtualX->ListFonts(fontname, 10, count)) {
01433                               sprintf(fontname,"-*-%s-%s-%c-*-*-%d-*-*-*-*-*-*-*",
01434                                       prop.fName.Data(), prop.fBold ? "bold" : "medium",
01435                                       prop.fItalic ? 'o' : 'r',
01436                                       prop.fSize);
01437                            }
01438                            TGFont *font = fClient->GetFont(fontname);
01439                            if (font) {
01440                               FontStruct_t editorfont = font->GetFontStruct();
01441                               fTextEdit->SetFont(editorfont);
01442                               fTextEdit->Update();
01443                            }
01444                         }
01445                      }
01446                      break;
01447 
01448                   // "Tools" menu related events
01449                   case kM_TOOLS_COMPILE:
01450                      CompileMacro();
01451                      break;
01452                   case kM_TOOLS_EXECUTE:
01453                      ExecuteMacro();
01454                      break;
01455                   case kM_TOOLS_INTERRUPT:
01456                      InterruptMacro();
01457                      break;
01458                   case kM_TOOLS_BROWSER:
01459                      new TBrowser();
01460                      break;
01461                   case kM_TOOLS_CLEAN_LOG:
01462 #ifdef WIN32
01463                      gSystem->Exec(Form("del %s\\ride.*.log", gSystem->TempDirectory()));
01464 #else
01465                      gSystem->Exec(Form("rm -f %s/ride.*.log", gSystem->TempDirectory()));
01466 #endif
01467                      break;
01468 
01469                   // "Search" menu related events
01470                   case kM_SEARCH_FIND:
01471                      Search(kFALSE);
01472                      break;
01473                   case kM_SEARCH_FINDNEXT:
01474                      Search(kTRUE);
01475                      break;
01476                   case kM_SEARCH_GOTO:
01477                      Goto();
01478                      break;
01479 
01480                   // "Help" menu related events
01481                   case kM_HELP_CONTENTS:
01482                      hd = new TRootHelpDialog(this, "Help on Editor...", 600, 400);
01483                      hd->SetText(gHelpTextEditor);
01484                      hd->Popup();
01485                      break;
01486                   case kM_HELP_ABOUT:
01487                      About();
01488                      break;
01489                }
01490                break;
01491          }
01492          break;
01493       case kC_TEXTENTRY:
01494          switch (GET_SUBMSG(msg)) {
01495             case kTE_ENTER:
01496                if (parm1 == 1) {
01497                   // here copy the string from text buffer to return variable
01498                   const char *string = fCommandBuf->GetString();
01499                   if (strlen(string) > 1) {
01500                      // form temporary file path
01501                      TString pathtmp = Form("%s/ride.%d.log", gSystem->TempDirectory(),
01502                                              fPid);
01503                      TString sPrompt = ((TRint*)gROOT->GetApplication())->GetPrompt();
01504                      FILE *lunout = fopen(pathtmp.Data(), "a+t");
01505                      if (lunout) {
01506                         fputs(Form("%s%s\n",sPrompt.Data(), string), lunout);
01507                         fclose(lunout);
01508                      }
01509                      gSystem->RedirectOutput(pathtmp.Data(), "a");
01510                      gApplication->SetBit(TApplication::kProcessRemotely);
01511                      gROOT->ProcessLine(string);
01512                      //fComboCmd->ReturnPressed();
01513                      fComboCmd->InsertEntry(string, 0, -1);
01514                      Gl_histadd((char *)string);
01515                      gSystem->RedirectOutput(0);
01516                      fTextView->LoadFile(pathtmp.Data());
01517                      if (fTextView->ReturnLineCount() > 7)
01518                         fTextView->SetVsbPosition(fTextView->ReturnLineCount());
01519                      CheckRemote(string);
01520                      fCommand->Clear();
01521                   }
01522                }
01523                break;
01524             default:
01525                break;
01526          }
01527          break;
01528 
01529       default:
01530          break;
01531    }
01532    return kTRUE;
01533 }
01534 
01535 //______________________________________________________________________________
01536 void TGRootIDE::DisplayFile(const TString &fname)
01537 {
01538    // Display content of ROOT file.
01539 
01540    TFile file(fname);
01541    fContents->RemoveAll();
01542    fContents->AddFile(gSystem->WorkingDirectory());
01543    fContents->SetPagePosition(0,0);
01544    fContents->SetColHeaders("Name","Title");
01545 
01546    TIter next(file.GetListOfKeys());
01547    TKey *key;
01548 
01549    while ((key=(TKey*)next())) {
01550       TString cname = key->GetClassName();
01551       TString name = key->GetName();
01552       TGLVEntry *entry = new TGLVEntry(fContents,name,cname);
01553       entry->SetSubnames(key->GetTitle());
01554       fContents->AddItem(entry);
01555 
01556       // user data is a filename
01557       entry->SetUserData((void*)StrDup(fname));
01558    }
01559    fContents->Sort(kSortByType);
01560    Resize();
01561 }
01562 
01563 //______________________________________________________________________________
01564 void TGRootIDE::DisplayDirectory(const TString &fname)
01565 {
01566    // Display content of directory.
01567 
01568    fContents->SetDefaultHeaders();
01569    gSystem->ChangeDirectory(fname);
01570    fContents->ChangeDirectory(fname);
01571    fContents->DisplayDirectory();
01572    fContents->AddFile("..");  // up level directory
01573    fContents->Sort(kSortByType);
01574    Resize();
01575    fDir->SetText(gSystem->WorkingDirectory());
01576    if (!fDirCombo->FindEntry(gSystem->WorkingDirectory()))
01577       fDirCombo->AddEntry(gSystem->WorkingDirectory(),
01578                           fDirCombo->GetNumberOfEntries()+1);
01579 }
01580 
01581 //______________________________________________________________________________
01582 void TGRootIDE::DisplayObject(const TString& fname, const TString& name)
01583 {
01584    // Display object located in file.
01585 
01586    TDirectory *sav = gDirectory;
01587 
01588    static TFile *file = 0;
01589    if (file) delete file;     // close
01590    file = new TFile(fname);   // reopen
01591 
01592    TObject* obj = file->Get(name);
01593    if (obj) {
01594       if (!obj->IsFolder()) {
01595          obj->Browse(0);
01596       } else obj->Print();
01597    }
01598    gDirectory = sav;
01599 }
01600 
01601 //______________________________________________________________________________
01602 static Bool_t IsTextFile(const char *candidate)
01603 {
01604    // Returns true if given a text file
01605    // Uses the specification given on p86 of the Camel book
01606    // - Text files have no NULLs in the first block
01607    // - and less than 30% of characters with high bit set
01608 
01609    Int_t i;
01610    Int_t nchars;
01611    Int_t weirdcount = 0;
01612    char buffer[512];
01613    FILE *infile;
01614    FileStat_t buf;
01615 
01616    gSystem->GetPathInfo(candidate, buf);
01617    if (!(buf.fMode & kS_IFREG))
01618       return kFALSE;
01619 
01620    infile = fopen(candidate, "r");
01621    if (infile) {
01622       // Read a block
01623       nchars = fread(buffer, 1, 512, infile);
01624       fclose (infile);
01625       // Examine the block
01626       for (i = 0; i < nchars; i++) {
01627          if (buffer[i] & 128)
01628             weirdcount++;
01629          if (buffer[i] == '\0')
01630             // No NULLs in text files
01631             return kFALSE;
01632       }
01633       if ((nchars > 0) && ((weirdcount * 100 / nchars) > 30))
01634          return kFALSE;
01635    } else {
01636       // Couldn't open it. Not a text file then
01637       return kFALSE;
01638    }
01639    return kTRUE;
01640 }
01641 
01642 //______________________________________________________________________________
01643 void TGRootIDE::OnDoubleClick(TGLVEntry* f, Int_t btn)
01644 {
01645    // Handle double click in TGListView.
01646 
01647    if (btn!=kButton1) return;
01648    gVirtualX->SetCursor(fContents->GetId(),gVirtualX->CreateCursor(kWatch));
01649 
01650    TString name(f->GetTitle());
01651    const char* fname = (const char*)f->GetUserData();
01652 
01653    if (IsTextFile(name.Data())) {
01654       LoadFile((char *)name.Data());
01655    }
01656    else if (fname) {
01657       DisplayObject(fname,name);
01658    } else if (name.EndsWith(".root")) {
01659       DisplayFile(name);
01660    } else {
01661       DisplayDirectory(name);
01662    }
01663    fContents->Sort(kSortByType);
01664    gVirtualX->SetCursor(fContents->GetId(),gVirtualX->CreateCursor(kPointer));
01665 }
01666 
01667 //______________________________________________________________________________
01668 void TGRootIDE::DoTab(Int_t id)
01669 {
01670    // Handle Tab navigation.
01671 
01672    fCurrentDoc = 0;
01673    fFilename = "";
01674    //fTextEdit = 0;
01675    TGDocument *doc = 0;
01676    TIter next(fDocList);
01677    while ((doc = (TGDocument *) next())) {
01678       if (doc->GetTabEl() == fTab->GetTabTab(id)) {
01679          fCurrentDoc = doc;
01680          fFilename = fCurrentDoc->GetName();
01681          fTextEdit = fCurrentDoc->GetTextEdit();
01682          break;
01683       }
01684    }
01685    const char *p = fTab->GetTabTab(id)->GetString();
01686    fFilename = p;
01687    SetWindowName(Form("%s - TGRootIDE", p));
01688    fCurrent = id;
01689 }
01690 
01691 //______________________________________________________________________________
01692 void TGRootIDE::CloseTab(Int_t id)
01693 {
01694    // Close tab "id".
01695 
01696    if (fCurrentDoc) {
01697       fCurrentDoc->Close();
01698    }
01699    else if (fTab->GetNumberOfTabs() > 2) {
01700       fTab->RemoveTab(id);
01701    }
01702    fTab->Layout();
01703 }
01704 
01705 //______________________________________________________________________________
01706 void TGRootIDE::ApplyFilter(Int_t id)
01707 {
01708    // Apply filter selected in combo box to the file list view.
01709 
01710    fContents->SetFilter(filters[id]);
01711    fContents->DisplayDirectory();
01712    fContents->AddFile("..");        // up level directory
01713    fContents->Sort(kSortByType);
01714 }
01715 
01716 //______________________________________________________________________________
01717 void TGRootIDE::DirSelected(const char *uri)
01718 {
01719    // A directory has been selected in the navigation history.
01720 
01721    fDir->SetText(uri);
01722    if (!fDirCombo->FindEntry(uri))
01723       fDirCombo->AddEntry(uri, fDirCombo->GetNumberOfEntries()+1);
01724    DisplayDirectory(uri);
01725 }
01726 
01727 //______________________________________________________________________________
01728 void TGRootIDE::DirChanged()
01729 {
01730    // A directory has been typed in the text entry of the navigation history.
01731 
01732    const char *string = fDir->GetText();
01733    if (string) {
01734       DirSelected(StrDup(string));
01735    }
01736 }
01737 
01738 //______________________________________________________________________________
01739 static char *ReadRemote(const char *url)
01740 {
01741    // Temporary function to read remote pictures
01742 
01743    static char *buf = 0;
01744    TUrl fUrl(url);
01745 
01746    TString msg = "GET ";
01747    msg += fUrl.GetProtocol();
01748    msg += "://";
01749    msg += fUrl.GetHost();
01750    msg += ":";
01751    msg += fUrl.GetPort();
01752    msg += "/";
01753    msg += fUrl.GetFile();
01754    msg += "\r\n";
01755 
01756    TString uri(url);
01757    if (!uri.BeginsWith("http://"))
01758       return 0;
01759    TSocket s(fUrl.GetHost(), fUrl.GetPort());
01760    if (!s.IsValid())
01761       return 0;
01762    if (s.SendRaw(msg.Data(), msg.Length()) == -1)
01763       return 0;
01764    Int_t size = 1024*1024;
01765    buf = (char *)calloc(size, sizeof(char));
01766    if (s.RecvRaw(buf, size) == -1) {
01767       free(buf);
01768       return 0;
01769    }
01770    return buf;
01771 }
01772 
01773 //______________________________________________________________________________
01774 void TGRootIDE::Selected(const char *uri)
01775 {
01776    // A URL has been selected, either by a click on a link or by the
01777    // navigation buttons, or by history combobox / text entry.
01778 
01779    char *buf = 0;
01780    FILE *f;
01781 
01782    gVirtualX->SetCursor(fGuiHtml->GetId(), gVirtualX->CreateCursor(kWatch));
01783    TString surl(gSystem->UnixPathName(uri));
01784    // if url does not contains "http://", prepend "file://" (local navigation)
01785    if (!surl.BeginsWith("http://") && !surl.BeginsWith("file://"))
01786       surl.Prepend("file://");
01787    if (surl.EndsWith(".root")) {
01788       // Open Root files directly and open a Root browser.
01789       TFile *f = TFile::Open(surl.Data());
01790       if (f && !f->IsZombie()) {
01791          f->Browse(new TBrowser());
01792       }
01793       gVirtualX->SetCursor(fGuiHtml->GetId(), gVirtualX->CreateCursor(kPointer));
01794       return;
01795    }
01796    TUrl url(surl.Data());
01797    if ((!strcmp(url.GetProtocol(), "http"))) {
01798       // web file...
01799       buf = ReadRemote(url.GetUrl());
01800       if (buf) {
01801          // display html page
01802          fGuiHtml->Clear();
01803          fGuiHtml->Layout();
01804          fGuiHtml->SetBaseUri(url.GetUrl());
01805          fGuiHtml->ParseText(buf);
01806          free(buf);
01807          fURL->SetText(surl.Data());
01808          if (!fComboBox->FindEntry(surl.Data()))
01809             fComboBox->AddEntry(surl.Data(), fComboBox->GetNumberOfEntries()+1);
01810       }
01811       else {
01812          // something went wrong --> display error
01813          fGuiHtml->Clear();
01814          fGuiHtml->Layout();
01815          fGuiHtml->SetBaseUri("");
01816          for (int i=0; HtmlError[i]; i++) {
01817             fGuiHtml->ParseText((char *)HtmlError[i]);
01818          }
01819       }
01820    }
01821    else {
01822       // local file...
01823       f = fopen(url.GetFile(), "r");
01824       if (f) {
01825          // file is opened (and valid)
01826          fGuiHtml->Clear();
01827          fGuiHtml->Layout();
01828          fGuiHtml->SetBaseUri("");
01829          buf = (char *)calloc(4096, sizeof(char));
01830          while (fgets(buf, 4096, f)) {
01831             fGuiHtml->ParseText(buf);
01832          }
01833          free(buf);
01834          fclose(f);
01835          fURL->SetText(surl.Data());
01836          if (!fComboBox->FindEntry(surl.Data()))
01837             fComboBox->AddEntry(surl.Data(), fComboBox->GetNumberOfEntries()+1);
01838       }
01839       else {
01840          // something went wrong --> display error
01841          fGuiHtml->Clear();
01842          fGuiHtml->Layout();
01843          fGuiHtml->SetBaseUri("");
01844          for (int i=0; HtmlError[i]; i++) {
01845             fGuiHtml->ParseText((char *)HtmlError[i]);
01846          }
01847       }
01848    }
01849    gVirtualX->SetCursor(fGuiHtml->GetId(), gVirtualX->CreateCursor(kPointer));
01850    fGuiHtml->Layout();
01851 }
01852 
01853 //______________________________________________________________________________
01854 void TGRootIDE::URLChanged()
01855 {
01856    // The text entry of navigation history has changed.
01857 
01858    const char *string = fURL->GetText();
01859    if (string) {
01860       Selected(StrDup(gSystem->UnixPathName(string)));
01861    }
01862 }
01863 
01864 //______________________________________________________________________________
01865 void TGRootIDE::Back()
01866 {
01867    // Handle "Back" navigation button.
01868 
01869    Int_t index = 0;
01870    const char *string = fURL->GetText();
01871    TGLBEntry * lbe1 = fComboBox->FindEntry(string);
01872    if (lbe1)
01873       index = lbe1->EntryId();
01874    if (index > 0) {
01875       fComboBox->Select(index - 1, kTRUE);
01876       TGTextLBEntry *entry = (TGTextLBEntry *)fComboBox->GetSelectedEntry();
01877       if (entry) {
01878          const char *string = entry->GetTitle();
01879          if (string)
01880             Selected(string);
01881       }
01882    }
01883 }
01884 
01885 //______________________________________________________________________________
01886 void TGRootIDE::Forward()
01887 {
01888    // Handle "Forward" navigation button.
01889 
01890    Int_t index = 0;
01891    const char *string = fURL->GetText();
01892    TGLBEntry * lbe1 = fComboBox->FindEntry(string);
01893    if (lbe1)
01894       index = lbe1->EntryId();
01895    if (index < fComboBox->GetNumberOfEntries()) {
01896       fComboBox->Select(index + 1, kTRUE);
01897       TGTextLBEntry *entry = (TGTextLBEntry *)fComboBox->GetSelectedEntry();
01898       if (entry) {
01899          const char *string = entry->GetTitle();
01900          if (string)
01901             Selected(string);
01902       }
01903    }
01904 }
01905 
01906 //______________________________________________________________________________
01907 void TGRootIDE::Reload()
01908 {
01909    // Handle "Reload" navigation button.
01910 
01911    const char *string = fURL->GetText();
01912    if (string)
01913       Selected(string);
01914 }
01915 
01916 //______________________________________________________________________________
01917 void TGRootIDE::Stop()
01918 {
01919    // Handle "Stop Loading" navigation button.
01920    // Not active for the time being.
01921 
01922 }
01923 
01924 //______________________________________________________________________________
01925 void TGRootIDE::MouseOver(char *url)
01926 {
01927    // Handle MouseOver signal from TGHtml widget.
01928 
01929    fStatusBar->SetText(url, 0);
01930 }
01931 
01932 //______________________________________________________________________________
01933 void TGRootIDE::MouseDown(char *url)
01934 {
01935    // Handle MouseDown signal from TGHtml widget.
01936 
01937    Selected(url);
01938 }
01939 
01940 //______________________________________________________________________________
01941 void TGRootIDE::CheckRemote(const char * /*str*/)
01942 {
01943    // Check if actual ROOT session is a remote one or a local one.
01944 
01945    Pixel_t pxl;
01946    TString sPrompt = ((TRint*)gROOT->GetApplication())->GetPrompt();
01947    Int_t end = sPrompt.Index(":root [", 0);
01948    if (end > 0 && end != kNPOS) {
01949       // remote session
01950       sPrompt.Remove(end);
01951       gClient->GetColorByName("#ff0000", pxl);
01952       fLabel->SetTextColor(pxl);
01953       fLabel->SetText(Form("Command (%s):", sPrompt.Data()));
01954    }
01955    else {
01956       // local session
01957       gClient->GetColorByName("#000000", pxl);
01958       fLabel->SetTextColor(pxl);
01959       fLabel->SetText("Command (local):");
01960    }
01961    fToolBar->Layout();
01962 }
01963 
01964 

Generated on Tue Jul 5 15:15:11 2011 for ROOT_528-00b_version by  doxygen 1.5.1