00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016 #include "TGo4AnalysisWindow.h"
00017
00018 #include "TSystem.h"
00019 #include "Riostream.h"
00020
00021 #include "qmime.h"
00022 #include "qlayout.h"
00023 #include "qtooltip.h"
00024 #include "qimage.h"
00025 #include "qpixmap.h"
00026 #include "qtimer.h"
00027 #include "qlabel.h"
00028 #include "qfiledialog.h"
00029 #include "qmessagebox.h"
00030 #include "qprocess.h"
00031 #include "qtextedit.h"
00032 #include "qpushbutton.h"
00033 #include "qtoolbutton.h"
00034
00035 #include "TGo4QSettings.h"
00036 #include "TGo4AnalysisProxy.h"
00037 #include "TGo4BrowserProxy.h"
00038 #include "TGo4AnalysisObjectResult.h"
00039 #include "QGo4CommandsHistory.h"
00040
00041
00042
00043 TGo4AnalysisWindow::TGo4AnalysisWindow(QWidget* parent, const char* name, bool needoutput, bool needkillbtn)
00044 : QGo4Widget( parent, name)
00045 {
00046
00047 setCanDestroyWidget(false);
00048 setAcceptDrops(FALSE);
00049
00050 fAnalysisProcess = 0;
00051 fxOutput = 0;
00052 outputBuffer = "";
00053 fiMaxOuputSize = 0;
00054 fxCmdHist = 0;
00055
00056 fNewObjectForEditor = true;
00057
00058 setCaption("Analysis Terminal");
00059
00060 if (needoutput) {
00061
00062 resize(700, 400);
00063 setIcon(QPixmap::fromMimeSource("analysiswin.png"));
00064 QGridLayout* layout = new QGridLayout( this, 1, 1, 11, 6, "layout");
00065 fxOutput = new QTextEdit(this, "output");
00066 fxOutput->setUndoRedoEnabled(FALSE);
00067 fxOutput->setAutoFormatting(QTextEdit::AutoNone);
00068 fxOutput->setWordWrap(QTextEdit::NoWrap);
00069 fxOutput->setReadOnly(TRUE);
00070 layout->addWidget( fxOutput, 0, 0 );
00071
00072 fiMaxOuputSize = go4sett->getTermHistorySize();
00073
00074 QHBoxLayout *box1 = new QHBoxLayout(layout);
00075 box1->addWidget(new QLabel("Press enter to execute.", this), 1);
00076 CreateCmdLine(box1);
00077
00078 QHBoxLayout *box2 = new QHBoxLayout(layout);
00079 CreateButtons(box2, needkillbtn);
00080
00081 updateTerminalOutput();
00082 } else {
00083
00084 QHBoxLayout *box = new QHBoxLayout(this, 0, 3);
00085
00086 CreateButtons(box, needkillbtn);
00087
00088 CreateCmdLine(box);
00089
00090 adjustSize();
00091 }
00092 }
00093
00094 void TGo4AnalysisWindow::CreateCmdLine(QHBoxLayout* box)
00095 {
00096 fxCmdHist = new QGo4CommandsHistory(this, "commandslist");
00097 QToolTip::add(fxCmdHist, "CINT command for analysis process. Note: '@' means 'TGo4Analysis::Instance()->' .");
00098 connect(fxCmdHist, SIGNAL(activated(const QString&)), this, SLOT(HistActivated(const QString&)));
00099 fxCmdHist->setMinimumSize( QSize( 220, 25 ) );
00100
00101 box->addWidget(fxCmdHist, HasOutput() ? 3 : 1);
00102
00103 QToolButton* MacroSearch = new QToolButton( this, "MacroSearch" );
00104 MacroSearch->setSizePolicy( QSizePolicy( (QSizePolicy::SizeType)0, (QSizePolicy::SizeType)0, 0, 0, MacroSearch->sizePolicy().hasHeightForWidth() ) );
00105 MacroSearch->setMinimumSize( QSize( 30, 25 ) );
00106 MacroSearch->setMaximumSize( QSize( 30, 25 ) );
00107 MacroSearch->setPixmap( QPixmap::fromMimeSource( "" ) );
00108 MacroSearch->setIconSet( QIconSet( QPixmap::fromMimeSource( "findfile.png" ) ) );
00109 QToolTip::add(MacroSearch, trUtf8( "Search root macro on disk." ) );
00110 connect(MacroSearch, SIGNAL(clicked()), this, SLOT(FileDialog_Macro()));
00111 box->addWidget(MacroSearch,1);
00112 }
00113
00114 void TGo4AnalysisWindow::CreateButtons(QHBoxLayout* box, bool needkillbtn)
00115 {
00116 if (needkillbtn) {
00117 QToolButton* KillProcess= new QToolButton(this,"KillProcess");
00118 KillProcess->setSizePolicy( QSizePolicy( (QSizePolicy::SizeType)0, (QSizePolicy::SizeType)0, 0, 0, KillProcess->sizePolicy().hasHeightForWidth() ) );
00119 KillProcess->setMinimumSize( QSize( 30, 25 ) );
00120 KillProcess->setMaximumSize( QSize( 30, 25 ) );
00121 KillProcess->setPixmap( QPixmap::fromMimeSource( "" ) );
00122 KillProcess->setIconSet( QIconSet( QPixmap::fromMimeSource( "killanal.png" ) ) );
00123 QToolTip::add( KillProcess, trUtf8( "Apply Ctrl+C in the analysis terminal." ) );
00124 connect(KillProcess, SIGNAL(clicked()), this, SLOT(RequestTerminate()));
00125 box->addWidget(KillProcess);
00126 }
00127
00128 if (HasOutput()) {
00129 QToolButton* ClearButton = new QToolButton( this, "ClearButton" );
00130 ClearButton->setSizePolicy( QSizePolicy( (QSizePolicy::SizeType)0, (QSizePolicy::SizeType)0, 0, 0, ClearButton->sizePolicy().hasHeightForWidth() ) );
00131 ClearButton->setMinimumSize( QSize( 30, 25 ) );
00132 ClearButton->setMaximumSize( QSize( 30, 25 ) );
00133 ClearButton->setPixmap( QPixmap::fromMimeSource( "" ) );
00134 ClearButton->setIconSet( QIconSet( QPixmap::fromMimeSource( "clear.png" ) ) );
00135 QToolTip::add(ClearButton, trUtf8( "Clear Terminal Window." ) );
00136 connect(ClearButton, SIGNAL(clicked()), this, SLOT(ClearAnalysisOutput()));
00137 box->addItem(new QSpacerItem(1,1));
00138 box->addWidget(ClearButton,1);
00139 }
00140
00141 QToolButton* PrintHistoButton = new QToolButton( this, "PrintHistoButton" );
00142 PrintHistoButton->setSizePolicy( QSizePolicy( (QSizePolicy::SizeType)0, (QSizePolicy::SizeType)0, 0, 0, PrintHistoButton->sizePolicy().hasHeightForWidth() ) );
00143 PrintHistoButton->setMinimumSize( QSize( 30, 25 ) );
00144 PrintHistoButton->setMaximumSize( QSize( 30, 25 ) );
00145 PrintHistoButton->setPixmap( QPixmap::fromMimeSource( "" ) );
00146 PrintHistoButton->setIconSet( QIconSet( QPixmap::fromMimeSource( "hislist.png" ) ) );
00147 QToolTip::add(PrintHistoButton, trUtf8( "Print list of all histograms." ) );
00148 connect(PrintHistoButton, SIGNAL(clicked()), this, SLOT(PrintHistograms()));
00149 box->addWidget(PrintHistoButton,1);
00150
00151 QToolButton* PrintConnyButton = new QToolButton( this, "PrintConnyButton" );
00152 PrintConnyButton->setSizePolicy( QSizePolicy( (QSizePolicy::SizeType)0, (QSizePolicy::SizeType)0, 0, 0, PrintConnyButton->sizePolicy().hasHeightForWidth() ) );
00153 PrintConnyButton->setMinimumSize( QSize( 30, 25 ) );
00154 PrintConnyButton->setMaximumSize( QSize( 30, 25 ) );
00155 PrintConnyButton->setPixmap( QPixmap::fromMimeSource( "" ) );
00156 PrintConnyButton->setIconSet( QIconSet( QPixmap::fromMimeSource( "condlist.png" ) ) );
00157 QToolTip::add(PrintConnyButton, trUtf8( "Print list of all conditions." ) );
00158 connect(PrintConnyButton, SIGNAL(clicked()), this, SLOT(PrintConditions()));
00159 box->addWidget(PrintConnyButton,1);
00160
00161 QToolButton* PrintEventButton = new QToolButton( this, "PrintEventButton" );
00162 PrintEventButton->setSizePolicy( QSizePolicy( (QSizePolicy::SizeType)0, (QSizePolicy::SizeType)0, 0, 0, PrintEventButton->sizePolicy().hasHeightForWidth() ) );
00163 PrintEventButton->setMinimumSize( QSize( 30, 25 ) );
00164 PrintEventButton->setMaximumSize( QSize( 30, 25 ) );
00165 PrintEventButton->setPixmap( QPixmap::fromMimeSource( "" ) );
00166 PrintEventButton->setIconSet( QIconSet( QPixmap::fromMimeSource( "zoom.png" ) ) );
00167 QToolTip::add(PrintEventButton, trUtf8( "Start Event Inspection panel" ) );
00168 connect(PrintEventButton, SIGNAL(clicked()), this, SLOT(PrintEvent()));
00169 box->addWidget(PrintEventButton,1);
00170 }
00171
00172 TGo4AnalysisWindow::~TGo4AnalysisWindow()
00173 {
00174
00175 if (Browser()!=0)
00176 Browser()->ToggleMonitoring(0);
00177 }
00178
00179 bool TGo4AnalysisWindow::HasOutput()
00180 {
00181 return fxOutput!=0;
00182 }
00183
00184
00185 void TGo4AnalysisWindow::SetHistorySize(int sz)
00186 {
00187 fiMaxOuputSize = sz;
00188 }
00189
00190 void TGo4AnalysisWindow::updateTerminalOutput()
00191 {
00192 if (fxOutput==0) return;
00193
00194 unsigned int buflen = outputBuffer.length();
00195
00196 if (fiMaxOuputSize>0) {
00197
00198
00199 unsigned int cutlength = fiMaxOuputSize / 2;
00200
00201 if (buflen > 0) {
00202 unsigned int outlen = fxOutput->length();
00203 if (buflen + outlen < fiMaxOuputSize)
00204 fxOutput->append(outputBuffer);
00205 else
00206 if (buflen>=cutlength) {
00207 outputBuffer.remove(0, buflen-cutlength);
00208 fxOutput->setText(outputBuffer);
00209 fxOutput->moveCursor(QTextEdit::MoveEnd, FALSE);
00210 } else {
00211 QString curr = fxOutput->text();
00212 curr.remove(0, cutlength - buflen);
00213 curr+=outputBuffer;
00214 fxOutput->setText(curr);
00215 fxOutput->moveCursor(QTextEdit::MoveEnd, FALSE);
00216 }
00217 }
00218 } else
00219 if (buflen>0)
00220 fxOutput->append(outputBuffer);
00221
00222 outputBuffer = "";
00223 QTimer::singleShot(100, this, SLOT(updateTerminalOutput()));
00224 }
00225
00226 void TGo4AnalysisWindow::readFromStdout()
00227 {
00228 if (fAnalysisProcess!=0) {
00229 QByteArray ba = fAnalysisProcess->readStdout();
00230 QString buf(ba);
00231 AppendOutputBuffer(buf);
00232 }
00233 }
00234
00235
00236 void TGo4AnalysisWindow::readFromStderr()
00237 {
00238 if (fAnalysisProcess!=0) {
00239 QByteArray ba = fAnalysisProcess->readStderr();
00240 QString buf(ba);
00241 AppendOutputBuffer(buf);
00242 }
00243 }
00244
00245 void TGo4AnalysisWindow::AppendOutputBuffer(const QString& value)
00246 {
00247 outputBuffer.append(value);
00248 }
00249
00250
00251 void TGo4AnalysisWindow::scrollToTop()
00252 {
00253 if (fxOutput!=0)
00254 fxOutput->setContentsPos( 0, 0 );
00255 }
00256
00257 void TGo4AnalysisWindow::StartAnalysisShell(const char* text)
00258 {
00259 if (fAnalysisProcess!=0) delete fAnalysisProcess;
00260
00261 fAnalysisProcess = new QProcess();
00262 connect(fAnalysisProcess, SIGNAL(readyReadStdout()), this, SLOT(readFromStdout()));
00263 connect(fAnalysisProcess, SIGNAL(readyReadStderr()), this, SLOT(readFromStderr()));
00264
00265
00266 fAnalysisProcess->setArguments(QStringList::split(" ", text));
00267 if (!fAnalysisProcess->start()) {
00268 cerr << "Fatal error. Could not start the Analysis" << endl;
00269 TerminateAnalysisProcess();
00270 }
00271 }
00272
00273 void TGo4AnalysisWindow::RequestTerminate()
00274 {
00275 ServiceCall("TerminateAnalysis");
00276 }
00277
00278 void TGo4AnalysisWindow::TerminateAnalysisProcess()
00279 {
00280 if (fAnalysisProcess==0) return;
00281 AppendOutputBuffer("\nTerminate process ... \n\n");
00282 fAnalysisProcess->tryTerminate();
00283 if (fAnalysisProcess->isRunning()) fAnalysisProcess->kill();
00284 delete fAnalysisProcess;
00285 fAnalysisProcess = 0;
00286 }
00287
00288 void TGo4AnalysisWindow::ClearAnalysisOutput()
00289 {
00290 if (fxOutput!=0)
00291 fxOutput->clear();
00292 }
00293
00294 void TGo4AnalysisWindow::SaveAnalysisOutput()
00295 {
00296 if (fxOutput==0) return;
00297 QFileDialog fd(this, "Save analysis terminal output", TRUE);
00298 fd.setMode( QFileDialog::AnyFile );
00299 fd.setFilter( "Plain text (*.txt)" );
00300 fd.setName( "Save analysis output");
00301 fd.setCaption( "Save analysis terminal output");
00302 if (fd.exec() != QDialog::Accepted) return;
00303
00304 QString fileName = fd.selectedFile();
00305 if(!fileName.endsWith(".txt")) fileName.append(".txt");
00306 QFile NewFile(fileName);
00307 NewFile.open( IO_ReadWrite | IO_Append );
00308 QTextStream t( &NewFile );
00309 t << fxOutput->text() << endl;
00310 NewFile.close();
00311 }
00312
00313 void TGo4AnalysisWindow::HistActivated(const QString& str)
00314 {
00315 if (fxCmdHist->EnterPressed() && (str!="")) {
00316 fxCmdHist->ResetEnterPressed();
00317 int pos = -1;
00318 for (int i=0;i<fxCmdHist->count();i++)
00319 if (fxCmdHist->text(i)=="") pos = i;
00320
00321 if (pos>0) fxCmdHist->removeItem(pos);
00322 if (pos!=0) fxCmdHist->insertItem("", 0);
00323
00324 if (fxCmdHist->currentItem()!=0)
00325 fxCmdHist->setCurrentItem(0);
00326
00327 TGo4AnalysisProxy* anal = GetAnalysis();
00328 if (anal!=0)
00329 anal->ExecuteLine(str.latin1());
00330 }
00331 }
00332
00333 void TGo4AnalysisWindow::FileDialog_Macro()
00334 {
00335 QFileDialog fd( this, "search macro", true);
00336 fd.setCaption("Select ROOT macro for analysis task");
00337 fd.setMode( QFileDialog::ExistingFile);
00338 fd.setName( "Select/Enter root macro");
00339 fd.setFilter( "CINT Macro (*.C)" );
00340
00341 if (fd.exec() != QDialog::Accepted) return;
00342
00343 QString cmd = QString(".x ") + fd.selectedFile();
00344 if(!cmd.endsWith(".C")) cmd.append(".C");
00345 fxCmdHist->insertItem(cmd, 0);
00346 }
00347
00348 void TGo4AnalysisWindow::PrintHistograms()
00349 {
00350 const QString com="@PrintHistograms()";
00351 fxCmdHist->insertItem(com,0);
00352 fxCmdHist->SetEnterPressed(1);
00353 HistActivated(com);
00354 fxCmdHist->SetEnterPressed(0);
00355 }
00356
00357 void TGo4AnalysisWindow::PrintConditions()
00358 {
00359 const QString com="@PrintConditions()";
00360 fxCmdHist->insertItem(com,0);
00361 fxCmdHist->SetEnterPressed(1);
00362 HistActivated(com);
00363 fxCmdHist->SetEnterPressed(0);
00364 }
00365
00366 void TGo4AnalysisWindow::PrintEvent()
00367 {
00368 ServiceCall("StartEventInfo");
00369 }
00370
00371 void TGo4AnalysisWindow::WorkWithUpdateObjectCmd(TGo4Slot* slot)
00372 {
00373
00374 AddLink(slot, "ObjectUpdateCmd");
00375 }
00376
00377 void TGo4AnalysisWindow::WaitForNewObject(bool isobjectforeditor)
00378 {
00379 fNewObjectForEditor = isobjectforeditor;
00380 }
00381
00382 void TGo4AnalysisWindow::linkedObjectUpdated(const char* linkname, TObject* obj)
00383 {
00384 if (strcmp(linkname, "ObjectUpdateCmd")!=0) return;
00385 TGo4AnalysisObjectResult* res = dynamic_cast<TGo4AnalysisObjectResult*>(obj);
00386 if (res==0) return;
00387 Browser()->SyncBrowserSlots();
00388 const char* itemname = res->GetObjectFullName();
00389 TClass* cl = Browser()->ItemClass(itemname);
00390 if (cl!=0) InformThatObjectCreated(itemname, cl);
00391 if (!fNewObjectForEditor) EditItem(itemname);
00392 fNewObjectForEditor = true;
00393 }
00394
00395 void TGo4AnalysisWindow::linkedObjectRemoved(const char* linkname)
00396 {
00397 if (!HasOutput())
00398 ServiceCall("CloseAnalysisWindow");
00399 }
00400
00401