GSI Object Oriented Online Offline (Go4) GO4-6.4.0
Loading...
Searching...
No Matches
TGo4MainWindow.cpp
Go to the documentation of this file.
1// $Id$
2//-----------------------------------------------------------------------
3// The GSI Online Offline Object Oriented (Go4) Project
4// Experiment Data Processing at EE department, GSI
5//-----------------------------------------------------------------------
6// Copyright (C) 2000- GSI Helmholtzzentrum fuer Schwerionenforschung GmbH
7// Planckstr. 1, 64291 Darmstadt, Germany
8// Contact: http://go4.gsi.de
9//-----------------------------------------------------------------------
10// This software can be used under the license agreements as stated
11// in Go4License.txt file which is part of the distribution.
12//-----------------------------------------------------------------------
13
14#include "TGo4MainWindow.h"
15
16#include <QtCore/QString>
17#include <QtCore/QDateTime>
18#include <QtCore/QTimer>
19#include <QtCore/QProcess>
20#include <QtCore/QHash>
21#include <QtCore/QDir>
22
23#include <QApplication>
24#include <QMenuBar>
25#include <QDockWidget>
26#include <QToolBar>
27#include <QAction>
28#include <QActionGroup>
29#include <QStatusBar>
30#include <QStyleFactory>
31#include <QColor>
32#include <QMessageBox>
33#include <QColorDialog>
34#include <QFileDialog>
35#include <QFontDialog>
36#include <QInputDialog>
37#include <QMdiSubWindow>
38#include <QMimeData>
39#include <QDesktopServices>
40#include <QUrl>
41
43#include "TSystem.h"
44#include "TROOT.h"
45#include "TMath.h"
46#include "TStyle.h"
47#include "TH1.h"
48#include "TClass.h"
49#include "TCanvas.h"
50
52#include "TGo4Version.h"
53#include "TGo4Log.h"
54#include "TGo4LockGuard.h"
55#include "TGo4Parameter.h"
56#include "TGo4Condition.h"
57#include "TGo4MdiArea.h"
58#include "TGo4Fitter.h"
59#include "TGo4FitPanel.h"
60#include "TGo4DynamicEntry.h"
61#include "TGo4AnalysisStatus.h"
62
63#include "TGo4ObjectManager.h"
64#include "TGo4ObjectProxy.h"
65#include "TGo4BrowserProxy.h"
66#include "TGo4DabcProxy.h"
67#include "TGo4AnalysisProxy.h"
68#include "TGo4WidgetProxy.h"
69
71#include "TGo4QSettings.h"
72#include "TGo4TreeViewer.h"
73#include "TGo4Browser.h"
74#include "TGo4BrowserOptions.h"
75#include "TGo4Style.h"
76#include "TGo4ViewPanel.h"
78#include "TGo4AnalysisWindow.h"
79#include "TGo4StartClient.h"
80#include "TGo4HisDrawOptions.h"
82#include "TGo4ScaleOptions.h"
83#include "TGo4DividePad.h"
87#include "TGo4ConditionInfo.h"
88#include "TGo4HistogramInfo.h"
89#include "TGo4EventInfo.h"
90#include "TGo4LoadedLibraries.h"
91#include "TGo4EditDynEntry.h"
92#include "TGo4ParaEdit.h"
94#include "TGo4ConditionEditor.h"
95#include "TGo4LogSettings.h"
96#include "TGo4LogInfo.h"
98#include "TGo4ConnectServer.h"
99#include "TGo4MBSViewer.h"
100#include "TGo4SetScaleValues.h"
101#include "TGo4CommandLine.h"
102#include "TGo4MarkerSettings.h"
103#include "TGo4OptStatsSettings.h"
104#include "TGo4HttpProxy.h"
105
106#include "TGo4UserCommands.h"
107
108#include "TGo4Script.h"
109
111
112using namespace Qt;
113
115 QMainWindow(),
116 fApp(app)
117{
118 // setDockWindowsMovable(true);
119 // statusBar();
120 resize( 1152, 864 );
121
122 setWindowIcon(QIcon(":/icons/go4logo2_big.png"));
123 // setRightJustification( true );
124 // setUsesTextLabel(true);
125 // setOpaqueMoving(false);
126
127 fxOM = new TGo4ObjectManager("GUI_OM","Gui object manager");
128 fOMDataPath = "data";
129 fOMBrowserPath = "gui";
130 fOMEditorsPath = "editors";
131
132 fNewWidgetX = 0;
133 fNewWidgetY = 0;
134
135 fKillCommand = "";
136 fLastPassword = "";
137 fLastFileDir = QDir::currentPath();
138
139 fCloseCounter = 0;
141 fConnectingHttp = "";
142
143 fbGetAnalysisConfig = true;
144
145 fbPanelTimerActive = false;
146
147 fbFullScreen = false;
148
149
150 // create mount point for all data sources
151 fxOM->MakeFolder(fOMDataPath.toLatin1().constData());
152
153 // create entry for browser
154 TGo4BrowserProxy *br = new TGo4BrowserProxy(fOMDataPath.toLatin1().constData(), fOMEditorsPath.toLatin1().constData(), kFALSE);
155 fxOM->AddProxy("", br, fOMBrowserPath.toLatin1().constData(), "Place for gui slots");
156 br->CreateMemoryFolder();
157
158 auto h1 = new TH1I("histo1","histo title", 100, -10., 10.);
159 h1->FillRandom("gaus",10000);
160 h1->SetDirectory(nullptr);
161 br->SaveToMemory("", h1, kTRUE);
162
163 new TGo4Script(this);
164
165 gStyle->SetPalette(1);
166 gStyle->SetCanvasColor(10); // no effect, can be set in settings
167 gStyle->SetPadColor(10); // no effect
168 gStyle->SetFrameFillColor(10); // works if not 0
169 gStyle->SetStatColor(0); // works
170
171 //gStyle->SetOptStat(11111111);
172 gStyle->SetOptStat(go4sett->getOptStat());
173
174 fxMdiArea = new TGo4MdiArea(this);
175 fxMdiArea->setHorizontalScrollBarPolicy(Qt::ScrollBarAsNeeded);
176 fxMdiArea->setVerticalScrollBarPolicy(Qt::ScrollBarAsNeeded);
177 setCentralWidget(fxMdiArea);
178 fxMdiArea->setFocus();
179
180 menuBar()->setNativeMenuBar(go4sett->getNativeMenuBar());
181
182 AddFileMenu();
184
185 AddToolsMenu();
186 AddToolsBar();
187
190
192
193 QDockWidget* BrowserDockWin = new QDockWidget("Browser", this);
194 BrowserDockWin->setObjectName("BrowserDock");
195 TGo4Browser* browser = new TGo4Browser(BrowserDockWin,"Browser");
196 browser->setWindowFlags(Qt::Widget);
197 ConnectGo4Widget(browser);
198 browser->StartWorking();
199 BrowserDockWin->setFeatures(QDockWidget::DockWidgetMovable | QDockWidget::DockWidgetClosable);
200 BrowserDockWin->setWidget(browser);
201 BrowserDockWin->setAllowedAreas(Qt::LeftDockWidgetArea | Qt::RightDockWidgetArea);
202 addDockWidget(Qt::LeftDockWidgetArea, BrowserDockWin);
203
204 QAction* BrowserDockAction = BrowserDockWin->toggleViewAction();
205 BrowserDockAction->setShortcut(QKeySequence("F6"));
206
207 QDockWidget* LogDockWin = new QDockWidget("Log window", this);
208 LogDockWin->setObjectName("LogInfoDock");
209 TGo4LogInfo* loginfo = new TGo4LogInfo(this, "LogInfo");
210 ConnectGo4Widget(loginfo);
211 LogDockWin->setFeatures(QDockWidget::DockWidgetMovable | QDockWidget::DockWidgetClosable);
212 LogDockWin->setWidget(loginfo);
213 LogDockWin->setAllowedAreas(Qt::TopDockWidgetArea | Qt::BottomDockWidgetArea);
214 addDockWidget(Qt::BottomDockWidgetArea, LogDockWin);
215
216 QAction* LogDockWinAction=LogDockWin->toggleViewAction();
217 LogDockWinAction->setShortcut(QKeySequence("F7"));
218
219 QDockWidget* MBSDockWin = new QDockWidget("MBS monitor", this);
220 MBSDockWin->setObjectName("MbsViewerDock");
221 TGo4MBSViewer* mbs = new TGo4MBSViewer(MBSDockWin, "MBSViewer");
222 mbs->setWindowFlags(Qt::Widget);
223 ConnectGo4Widget(mbs);
224 MBSDockWin->setFeatures(QDockWidget::DockWidgetMovable | QDockWidget::DockWidgetClosable);
225 MBSDockWin->setWidget(mbs);
226 MBSDockWin->setAllowedAreas(Qt::TopDockWidgetArea | Qt::BottomDockWidgetArea);
227 addDockWidget(Qt::BottomDockWidgetArea, MBSDockWin);
228
229 QAction* MBSDockAction=MBSDockWin->toggleViewAction();
230 MBSDockAction->setShortcut(QKeySequence("F8"));
231
232 QToolBar* DividePanelBar = addToolBar("Canvas Tools");
233 DividePanelBar->setObjectName("DividePadDock");
234 TGo4DividePad* dividepanel = new TGo4DividePad(this, "DividePad");
235 DividePanelBar->addWidget(dividepanel);
236
237 QToolBar* stylebar = addToolBar("Color Tools");
238 stylebar->setObjectName("Go4StyleDock");
239 fxStyle = new TGo4Style(this, "Go4Style");
240 stylebar->addWidget(fxStyle);
241
242 QToolBar* BrowserOptionsPanel = addToolBar("Browser Options");
243 BrowserOptionsPanel->setObjectName("BrowserOptionsDock");
244 TGo4BrowserOptions* bropt = new TGo4BrowserOptions(this, "BrowserOptions");
245 ConnectGo4Widget(bropt);
246 BrowserOptionsPanel->addWidget(bropt);
247 bropt->StartWorking();
248
249 QToolBar* DrawOptionPanel = addToolBar("Draw Options");
250 DrawOptionPanel->setObjectName("DrawOptionsDock");
251 TGo4HisDrawOptions* drawopt = new TGo4HisDrawOptions(this, "DrawOptions");
252 DrawOptionPanel->addWidget(drawopt);
253 DrawOptionPanel->adjustSize();
254
255 QToolBar* DrawOptionShortPanel = addToolBar("Hist Draw Options");
256 DrawOptionShortPanel->setObjectName("HisDrawOptionsDock");
257 TGo4HisDrawOptionsShort* drawopts = new TGo4HisDrawOptionsShort(this, "HisDrawOptions");
258 DrawOptionShortPanel->addWidget(drawopts);
259 DrawOptionShortPanel->adjustSize();
260
261 QToolBar* ScaleOptionBar = addToolBar("Zoom Tools");
262 ScaleOptionBar->setObjectName("ScaleOptionsDock");
263 TGo4ScaleOptions* scopt = new TGo4ScaleOptions(this, "ScaleOptions");
264 ConnectGo4Widget(scopt);
265 ScaleOptionBar->addWidget(scopt);
266 ScaleOptionBar->adjustSize();
267
268 QToolBar* commandlinebar = addToolBar("Go4 Command Line");
269 commandlinebar->setObjectName("CommandLineDock");
270 TGo4CommandLine* cli = new TGo4CommandLine(this, "CommandLine");
271 ConnectGo4Widget(cli);
272 commandlinebar->addWidget(cli);
273
274 QToolBar* tviewerdock = addToolBar("Tree viewer");
275 tviewerdock->setObjectName("TreeViewerDock");
276 TGo4TreeViewer* tviewer = new TGo4TreeViewer(this, "TreeViewer");
277 ConnectGo4Widget(tviewer);
278 tviewerdock->addWidget(tviewer);
279
280 AddAnalysisMacrosBar(); // new 2016
281
282
283 // test: can we implement shortcuts to enable specific dock windows JAM?
284// QMenu* dockMenu = menuBar()->addMenu("&Docks");
285// dockMenu->addAction(BrowserDockAction);
286// dockMenu->addAction(LogDockWinAction);
287// dockMenu->addAction(MBSDockAction);
288// do not need this, since shortcuts also work in default dock menu :)
289
290 // make it here while only here exists all toolbars and dock widgets
292
293 windowsMenu = menuBar()->addMenu("&Windows");
294 QObject::connect(windowsMenu, &QMenu::aboutToShow, this, &TGo4MainWindow::windowsMenuAboutToShow);
295 // need to create menu item with F11
297
298 menuBar()->addSeparator();
299
300 QMenu* helpMenu = menuBar()->addMenu("&Help");
301 helpMenu->addAction("&Introduction (user manual)", this, &TGo4MainWindow::IntroHelpSlot)->setShortcut(Qt::Key_F1);
302 helpMenu->addAction("&Reference manual", this, &TGo4MainWindow::RefHelpSlot);
303 helpMenu->addAction("&Fit Tutorial", this, &TGo4MainWindow::FitHelpSlot);
304 helpMenu->addSeparator();
305 helpMenu->addAction("About &Qt", this, &TGo4MainWindow::aboutQt)->setShortcut(Qt::Key_F2);
306 helpMenu->addAction("About R&OOT", this, &TGo4MainWindow::aboutROOT)->setShortcut(Qt::Key_F3);
308 helpMenu->addAction("About &DABC", this, &TGo4MainWindow::aboutDABC);
309 helpMenu->addAction("About &Go4", this, &TGo4MainWindow::about)->setShortcut(Qt::Key_F4);
310
311 const char *libs = gSystem->Getenv("GO4USERLIBRARY");
312
313 if (libs) {
314#if QT_VERSION < QT_VERSION_CHECK(5,14,0)
315 QStringList LibList = QString(libs).split(":", QString::SkipEmptyParts);
316#else
317 QStringList LibList = QString(libs).split(":", Qt::SkipEmptyParts);
318#endif
319
320 for (auto &lib : LibList)
321 gSystem->Load(lib.toLatin1().constData());
322 }
323
324 go4sett->restoreMainWindowState(this);
325
326 QApplication::setStyle(go4sett->getAppStyle());
327
328 faSuperimpose->setChecked(go4sett->getPadSuperimpose());
329 faCrosshair->setChecked(go4sett->getPadCrosshair());
330 faEventstatus->setChecked(go4sett->getPadEventStatus());
331
332 go4sett->getBasicSettings();
333 go4sett->getAppFont();
334
335 // start mbs monitoring only after browser etc. is fully there:
336 if(go4sett->getMbsMonitorMonitorActive()) mbs->TimerStart();
337
338 std::cout <<"Using Qt settings at "<< go4sett->GetSettLoaction().toLatin1().constData() << std::endl;
339
340 statusBar()->showMessage("Ready");
341 statusBar()->setSizeGripEnabled(true);
342
343 QString sfmt = go4sett->getGStyleStatFormat();
344 if (!sfmt.isEmpty()) gStyle->SetStatFormat(sfmt.toLatin1().constData());
345}
346
353
355{
356 return fLastPassword.toLatin1().constData();
357}
358
359void TGo4MainWindow::ShowAboudDialog(const QString &title, const QString &text, const QString &icon)
360{
361 QMessageBox AboutDialog(QMessageBox::NoIcon, title, text, QMessageBox::Ok, this);
362 AboutDialog.setIconPixmap(QPixmap(icon));
363 AboutDialog.setTextFormat(Qt::RichText);
364 AboutDialog.exec();
365}
366
368{
369 QString GO4STR("Go4 ");
370 GO4STR.append ( __GO4RELEASE__);
371 QString GO4STR1 = GO4STR;
372 GO4STR1.append("<br>");
373 GO4STR1.append("The Go4 (GSI Object Oriented On-line Off-line system) is based on ROOT<br> with the specific requirements of the low and medium energy nuclear and atomic<br> physics experiments implemented as extensions.<br> See <a href='http://go4.gsi.de'>http://go4.gsi.de</a> for more information");
374
375 ShowAboudDialog(GO4STR, GO4STR1, ":/icons/go4logo2_big.png");
376}
377
379{
380 QMessageBox::aboutQt(this, "Qt");
381}
382
384{
385 QString mestring("This Go4 uses ROOT ");
386 mestring.append(gROOT->GetVersion());
387 mestring.append("<br> ROOT is an object-oriented framework <br>for large scale scientific <br>data analysis and data mining.<br> It has been developed at CERN<br> See <a href='http://root.cern.ch'>http://root.cern.ch</a> for more information");
388 ShowAboudDialog("ROOT", mestring, ":/icons/root.png");
389}
390
392{
393 QString mestring("This Go4 uses DABC ");
395 mestring.append(TGo4DabcProxy::GetDabcVersion());
396 else
397 mestring.append("<undef>");
398 mestring.append("<br>DABC (Data Acquisition Backbone Core) is <br> framework to build multi-threaded multi-node DAQ applications.<br> It is developed in GSI.<br> See <a href='http://dabc.gsi.de'>http://dabc.gsi.de</a> for more information");
399 ShowAboudDialog("DABC", mestring, ":/icons/dabc.png");
400}
401
403{
404 QMenu* settMenu = menuBar()->addMenu("&Settings");
405
406 QMenu* sub = createPopupMenu();
407 sub->setTitle("Sh&ow/hide");
408 settMenu->addMenu(sub);
409
410 settMenu->addAction("&Font...", this, &TGo4MainWindow::ChangeFontSlot);
411
412 QMenu *styleMenu = settMenu->addMenu("St&yle");
413
414 QMenu* prefMenu = settMenu->addMenu("&Gui preferences");
415
416 QObject::connect(QGo4Widget::CreateChkAction(prefMenu, "Fetch when drawing", go4sett->getFetchDataWhenDraw()),
417 &QAction::toggled, this, &TGo4MainWindow::ChangeFetchWhenDrawSlot);
418
419 QObject::connect(QGo4Widget::CreateChkAction(prefMenu, "Fetch when copying", go4sett->getFetchDataWhenCopy()),
420 &QAction::toggled, this, &TGo4MainWindow::ChangeFetchWhenCopySlot);
421
422 QObject::connect(QGo4Widget::CreateChkAction(prefMenu, "Fetch when saving", go4sett->getFetchDataWhenSave()),
423 &QAction::toggled, this, &TGo4MainWindow::ChangeFetchWhenSaveSlot);
424
425 QObject::connect(QGo4Widget::CreateChkAction(prefMenu, "Hide TGo4EventElement", go4sett->getHideTGo4EventElement()),
426 &QAction::toggled, this, &TGo4MainWindow::ChangeHideEventElement);
427
428 QObject::connect(QGo4Widget::CreateChkAction(prefMenu, "Draw item once", go4sett->getDrawOnceFlag()),
429 &QAction::toggled, this, &TGo4MainWindow::ChangeDrawOnceSlot);
430
431 QObject::connect(QGo4Widget::CreateChkAction(prefMenu, "Rubberband when moving windows", go4sett->getMoveSubwindowRubberBand()),
432 &QAction::toggled, this, &TGo4MainWindow::ChangeWindowRubberBandSlot);
433
434 prefMenu->addAction("GUI HighDPI Scale factor...", this, &TGo4MainWindow::ScaleFactorSlot);
435
436 QObject::connect(QGo4Widget::CreateChkAction(prefMenu, "Native menu bar", go4sett->getNativeMenuBar()),
437 &QAction::toggled, this, &TGo4MainWindow::ChangeNativeMenuBarSlot);
438
439 QMenu* panelMenu = settMenu->addMenu("&Panel defaults");
440
441 panelMenu->addAction("&Canvas color...", this, &TGo4MainWindow::CanvasColorSlot);
442
443 QObject::connect(QGo4Widget::CreateChkAction(panelMenu, "White canvas for saved images", go4sett->getSavePadWhiteBackground()),
444 &QAction::toggled, this, &TGo4MainWindow::ChangeSaveWhiteBackgroundSlot);
445
446 panelMenu->addAction("Marker labels...", this, &TGo4MainWindow::MarkerSettingsSlot);
447 panelMenu->addAction("Statistics box...", this, &TGo4MainWindow::OptStatsSlot);
448
449 faSuperimpose = QGo4Widget::CreateChkAction(panelMenu, "&Superimpose mode", go4sett->getPadSuperimpose());
450 QObject::connect(faSuperimpose, &QAction::toggled, this, &TGo4MainWindow::SuperimposeSlot);
451
452 faCrosshair = QGo4Widget::CreateChkAction(panelMenu, "Cross(&X)hair mode", go4sett->getPadCrosshair());
453 QObject::connect(faCrosshair, &QAction::toggled, this, &TGo4MainWindow::CrosshairSlot);
454
455 faEventstatus = QGo4Widget::CreateChkAction(panelMenu, "Show Event Status", go4sett->getPadEventStatus());
456 QObject::connect(faEventstatus, &QAction::toggled, this, &TGo4MainWindow::EventStatusSlot);
457
458 QObject::connect(QGo4Widget::CreateChkAction(panelMenu, "Objects cloning", go4sett->getCloneFlag()),
459 &QAction::toggled, this, &TGo4MainWindow::ChangeCloneFlagSlot);
460
461 faDrawTime = QGo4Widget::CreateChkAction(panelMenu, "Draw time", go4sett->getDrawTimeFlag(), go4sett->getCloneFlag());
462 QObject::connect(faDrawTime, &QAction::toggled, this, &TGo4MainWindow::ChangeDrawTimeFlagSlot);
463
464 faDrawDate = QGo4Widget::CreateChkAction(panelMenu, "Draw date", go4sett->getDrawDateFlag(), go4sett->getCloneFlag());
465 QObject::connect(faDrawDate, &QAction::toggled, this, &TGo4MainWindow::ChangeDrawDateFlagSlot);
466
467 faDrawItem = QGo4Widget::CreateChkAction(panelMenu, "Draw item name", go4sett->getDrawItemFlag(), go4sett->getCloneFlag());
468 QObject::connect(faDrawItem, &QAction::toggled, this, &TGo4MainWindow::ChangeDrawItemFlagSlot);
469
470 panelMenu->addAction("Draw line &width ...", this, &TGo4MainWindow::DrawLineWidthSlot);
471 panelMenu->addAction("Draw fill color ...", this, &TGo4MainWindow::DrawFillColorSlot);
472 panelMenu->addAction("Draw fill style ...", this, &TGo4MainWindow::DrawFillStyleSlot);
473 panelMenu->addAction("TH1 draw opt ...", this, &TGo4MainWindow::TH1DrawOptSlot);
474 panelMenu->addAction("TH2 draw opt ...", this, &TGo4MainWindow::TH2DrawOptSlot);
475 panelMenu->addAction("TH3 draw opt ...", this, &TGo4MainWindow::TH3DrawOptSlot);
476 panelMenu->addAction("TGraph draw opt ...", this, &TGo4MainWindow::TGraphDrawOptSlot);
477 panelMenu->addAction("Printf format ...", this, &TGo4MainWindow::GStyleStatFormatSlot);
478 panelMenu->addAction("Palette settings ...", this, &TGo4MainWindow::PaletteSettingsSlot);
479
480
481 settMenu->addAction("&Log actions...", this, &TGo4MainWindow::LogSettingsSlot);
482 QMenu* termMenu = settMenu->addMenu("&Terminal");
483 QObject::connect(QGo4Widget::CreateChkAction(termMenu, "Print timestamps", go4sett->getTermShowTimestamp()), &QAction::toggled, this, &TGo4MainWindow::ChangeTerminalTimeStampSlot);
484 termMenu->addAction("&Timestamp Format...", this, &TGo4MainWindow::ChangeTerminalTimeStampFormatSlot);
485 termMenu->addAction("&History...", this, &TGo4MainWindow::InputTerminalParametersSlot);
486 termMenu->addAction("&Font...", this, &TGo4MainWindow::ChangeTerminalFontSlot);
487
488
489 settMenu->addAction("Generate &hotstart", this, &TGo4MainWindow::CreateGUIScriptSlot);
490 settMenu->addAction("&Break hotstart execution", this, &TGo4MainWindow::StopGUIScriptSlot);
491
492
493 settMenu->addAction("&Save settings", this, &TGo4MainWindow::SaveSettingsSlot);
494
495 QActionGroup *ag = new QActionGroup(this);
496 ag->setExclusive(true);
497
498 QStringList list = QStyleFactory::keys();
499 list.sort();
500 QHash<QString, int> stylesDict;
501 for (auto styleStr : list) {
502 QString styleAccel = styleStr;
503 if ( stylesDict[styleAccel.left(1)] ) {
504 for (int i = 0; i < styleAccel.length(); i++ ) {
505 if ( !stylesDict[styleAccel.mid( i, 1 )] ) {
506 stylesDict.insert(styleAccel.mid( i, 1 ), 1);
507 styleAccel = styleAccel.insert( i, '&' );
508 break;
509 }
510 }
511 } else {
512 stylesDict.insert(styleAccel.left(1), 1);
513 styleAccel = "&"+styleAccel;
514 }
515 QAction *act = new QAction(styleAccel, this);
516 act->setCheckable(true);
517 act->setChecked(go4sett->getAppStyle() == styleStr);
518
519 QObject::connect(act, &QAction::triggered, [&, styleStr]() { SetStyleSlot(styleStr); });
520
521 ag->addAction(act);
522 styleMenu->addAction(act);
523 }
524}
525
526#define CtrlKey(key) ((int)Qt::CTRL | key)
527
528
530{
531 QMenu* fileMenu = menuBar()->addMenu("&File");
532
533 fileMenu->addAction(QIcon( ":/icons/open.png" ), "&Open...",
534 this, &TGo4MainWindow::OpenFileSlot)->setShortcut(CtrlKey(Qt::Key_O));
535 fileMenu->addAction(QIcon( ":/icons/network.png" ), "Open &Remote...",
536 this, &TGo4MainWindow::OpenRemoteFileSlot)->setShortcut(CtrlKey(Qt::Key_R) );
538 fileMenu->addAction(QIcon( ":/icons/dabc.png" ), "Connect &DABC...",
540 fileMenu->addAction(QIcon( ":/icons/http.png" ), "Connect &HTTP...",
542 fileMenu->addAction(QIcon( ":/icons/histserv.png" ), "Open HIST &Server...",
544 fileMenu->addAction(QIcon( ":/icons/hiscre.png" ), "&Import histograms...",
546
547 fileMenu->addAction(QIcon( ":/icons/filesave.png" ), "Save memor&y...",
548 this, &TGo4MainWindow::SaveFileSlot)->setShortcut(CtrlKey(Qt::Key_Y) );
549 fileMenu->addAction(QIcon( ":/icons/close.png" ),"Close all files",
550 this, &TGo4MainWindow::CloseAllFilesSlot)->setShortcut(CtrlKey(Qt::Key_Q));
551 fileMenu->addAction(QIcon( ":/icons/exit.png" ), "E&xit",
552 this, &TGo4MainWindow::close)->setShortcut(CtrlKey(Qt::Key_X));
553}
554
556{
557 QToolBar *FileBar = addToolBar( "File Toolbar" );
558 FileBar->setObjectName("FileToolBar");
559
560 FileBar->addAction( QIcon( ":/icons/open.png" ), "Open a local file from disk",
562
563 FileBar->addAction( QIcon( ":/icons/network.png" ), "Open a remote file from server",
565
567 FileBar->addAction( QIcon( ":/icons/dabc.png" ), "Connect to DABC server",
569
570 FileBar->addAction( QIcon( ":/icons/http.png" ), "Connect to HTTP server",
572
573 FileBar->addAction( QIcon( ":/icons/histserv.png" ), "Connect to running histogram server",
575
576 FileBar->addAction( QIcon( ":/icons/filesave.png" ), "Save the content of the browser to a root file",
578
579 FileBar->addAction( QIcon( ":/icons/close.png" ), "Close all root files in file browser",
581
582 FileBar->addAction( QIcon( ":/icons/exit.png" ), "Exit the Go4",
583 this, &TGo4MainWindow::close);
584}
585
587{
588 QMenu* toolMenu = menuBar()->addMenu("&Tools");
589
590 toolMenu->addAction(QIcon(":/icons/chart.png" ), "&View panel",
591 [this]() { MakeNewPanel(); })->setShortcut(CtrlKey(Qt::Key_V) );
592 toolMenu->addAction(QIcon(":/icons/fitpanel.png" ), "&Fit panel...",
593 [this]() { StartFitPanel(); })->setShortcut(CtrlKey(Qt::Key_F) );
594 toolMenu->addAction(QIcon(":/icons/hislist.png" ),"&Histogram properties...",
596 toolMenu->addAction(QIcon(":/icons/hiscre.png" ), "Create New H&istogram...",
597 [this]() { CreateNewHist(); })->setShortcut(CtrlKey(Qt::Key_I) );
598 toolMenu->addAction(QIcon(":/icons/condlist.png" ),"C&ondition properties...",
600 toolMenu->addAction(QIcon(":/icons/condcre.png" ),"Create new &condition...",
601 [this]() { CreateNewCondition(); });
602 toolMenu->addAction(QIcon(":/icons/zoom.png" ),"&Event printout...",
604 toolMenu->addAction(QIcon(":/icons/dynlist.png" ),"Create &dyn. list entry ...",
605 [this]() { CreateNewDynEntry(); })->setShortcut(CtrlKey(Qt::Key_D) );
606 toolMenu->addAction(QIcon(":/icons/dllicon.png" ), "Load li&braries ...",
607 this, &TGo4MainWindow::LoadLibrarySlot)->setShortcut(CtrlKey(Qt::Key_B) );
608 toolMenu->addAction(QIcon(":/icons/user.png" ), "&User GUI ...",
609 this, &TGo4MainWindow::UserPanelSlot)->setShortcut(CtrlKey(Qt::Key_U));
610}
611
613{
614 QToolBar *ToolBar = addToolBar("Go4 tools");
615 ToolBar->setObjectName("Go4ToolsBar");
616
617 ToolBar->addAction( QIcon( ":/icons/chart.png" ), "Create a new view panel",
618 [this]() { MakeNewPanel(); });
619
620 ToolBar->addAction( QIcon( ":/icons/fitpanel.png" ), "Show/hide the Go4 Fit Panel",
621 [this]() { StartFitPanel(); });
622
623 ToolBar->addAction( QIcon( ":/icons/hislist.png" ), "Show histogram properties window",
625
626 ToolBar->addAction( QIcon( ":/icons/hiscre.png" ), "Create new ROOT Histogram",
628
629 ToolBar->addAction( QIcon( ":/icons/condlist.png" ), "Show condition properties window",
631
632 ToolBar->addAction( QIcon( ":/icons/condcre.png" ), "Create new condition in analysis",
633 [this]() { CreateNewCondition(); });
634
635 ToolBar->addAction( QIcon( ":/icons/zoom.png" ), "Event printout and examination window",
637
638 ToolBar->addAction( QIcon( ":/icons/dynlist.png" ), "Create new Dynamic list entry",
639 [this]() { CreateNewDynEntry(); });
640
641 ToolBar->addAction( QIcon( ":/icons/dllicon.png" ), "Load Libraries",
643
644 ToolBar->addAction( QIcon( ":/icons/user.png" ), "Start user panel",
646}
647
649{
650 QMenu* anMenu = menuBar()->addMenu("&Analysis");
651
653 anMenu->addAction(QIcon(":/icons/launchanal.png"), "Lau&nch analysis...", [this]() { LaunchClient(); });
654 faLaunchAnal->setShortcut(CtrlKey(Qt::Key_N));
656 anMenu->addAction(QIcon(":/icons/connect.png"), "&Connect to running server...", [this]() { ConnectServer(); });
657 faConnectAnal->setShortcut(CtrlKey(Qt::Key_C));
658
659 faPrepareAnal = anMenu->addAction(QIcon(":/icons/connect.png"), "&Prepare for client connection...",
660 [this]() { PrepareForClientConnection(); });
661
662 faDisconnectAnal = anMenu->addAction(QIcon(":/icons/disconnect.png"), "Disconnect from analysis",
663 [this]() { DisconnectAnalysis(); });
664 faDisconnectAnal->setShortcut(CtrlKey(Qt::Key_M));
665
666 faShutdownAnal = anMenu->addAction(QIcon(":/icons/shutanal.png"), "Shutdown analysis",
667 [this]() { ShutdownAnalysis(); });
668 faShutdownAnal->setShortcut(CtrlKey(Qt::Key_M));
669
671 anMenu->addAction(QIcon(":/icons/restart.png"), "Submit+S&tart", this, &TGo4MainWindow::SubmitStartAnalysisSlot);
672 faSumbStartAnal->setShortcut(CtrlKey(Qt::Key_T));
673
674 faStartAnal = anMenu->addAction(QIcon(":/icons/start.png"), "&Start", this, &TGo4MainWindow::StartAnalysisSlot);
675 faStartAnal->setShortcut(CtrlKey(Qt::Key_S));
676
677 faStopAnal = anMenu->addAction(QIcon(":/icons/Stop.png"), "Stop (&Halt)", this, &TGo4MainWindow::StopAnalysisSlot);
678 faStopAnal->setShortcut(CtrlKey(Qt::Key_H));
679
680 faAnalConfig = anMenu->addAction(QIcon(":/icons/control.png"), "Confi&guration...", this,
682 faAnalConfig->setShortcut(CtrlKey(Qt::Key_G));
683
684 faAnalTermin = anMenu->addAction(QIcon(":/icons/analysiswin.png"), "Analysis &Window", this,
686 faAnalTermin->setShortcut(CtrlKey(Qt::Key_W));
687}
688
690{
691 QToolBar *AnalBar = addToolBar("Analysis Toolbar");
692 AnalBar->setObjectName("AnalysisToolBar");
693 AnalBar->setToolTip("Analysis related tool buttons");
694
695 AnalBar->addAction(faLaunchAnal);
696 AnalBar->addAction(faConnectAnal);
697 AnalBar->addAction(faDisconnectAnal);
698 AnalBar->addAction(faShutdownAnal);
699
700 AnalBar->addAction(faSumbStartAnal);
701
702 AnalBar->addAction(faStartAnal);
703
704 AnalBar->addAction(faStopAnal);
705 AnalBar->addAction(faAnalConfig);
706 AnalBar->addAction(faAnalTermin);
707}
708
710{
711 windowsMenu->clear();
712
713 bool on = ! fxMdiArea->subWindowList().isEmpty();
714
715 windowsMenu->addAction("Ca&scade", fxMdiArea, &TGo4MdiArea::cascadeSubWindows)->setEnabled(on);
716 windowsMenu->addAction("&Tile", fxMdiArea, &TGo4MdiArea::tileSubWindows)->setEnabled(on);
717 windowsMenu->addAction("&Close all", fxMdiArea, &TGo4MdiArea::closeAllSubWindows)->setEnabled(on);
718 windowsMenu->addAction("&Minimize all", this, &TGo4MainWindow::MinAllWindows)->setEnabled(on);
719
720 windowsMenu->addAction((fbFullScreen ? "&Normal window" : "&Full screen"), this, &TGo4MainWindow::ToggleFullScreenSlot)->setShortcut(Qt::Key_F11);
721
722 windowsMenu->addSeparator();
723
724 auto loginfo = (TGo4LogInfo *) FindGo4Widget("LogInfo", false);
725 if (loginfo) {
726 windowsMenu->addAction("Save L&ogwindow", loginfo, &TGo4LogInfo::SaveLogInfo);
727 windowsMenu->addAction("Clear &Logwindow", loginfo, &TGo4LogInfo::ClearLogInfo);
728 } else {
729 windowsMenu->addAction("Save L&ogwindow")->setEnabled(false);
730 windowsMenu->addAction("Clear &Logwindow")->setEnabled(false);
731 }
732
733 auto anw = FindAnalysisWindow();
734 if (anw) {
735 windowsMenu->addAction("Save &Analysis window", anw, &TGo4AnalysisWindow::SaveAnalysisOutput);
736 windowsMenu->addAction("Clear Analysis &window", anw, &TGo4AnalysisWindow::ClearAnalysisOutput);
737 } else {
738 windowsMenu->addAction("Save &Analysis window")->setEnabled(false);
739 windowsMenu->addAction("Clear Analysis &window")->setEnabled(false);
740 }
741
742 windowsMenu->addSeparator();
743
744 QList<QMdiSubWindow *> windows = fxMdiArea->subWindowList();
745 for (int i = 0; i < windows.count(); i++) {
746 QAction *act = new QAction(windows.at(i)->widget()->windowTitle(), this);
747 act->setCheckable(true);
748 act->setChecked(fxMdiArea->activeSubWindow() == windows.at(i));
749
750 windowsMenu->addAction(act);
751
752 QObject::connect(act, &QAction::triggered, [this, i]() { WindowActivated(i); });
753 }
754}
755
757{
758 QList<QMdiSubWindow *> windows = fxMdiArea->subWindowList();
759 for ( int i = 0; i < windows.count(); i++ )
760 windows.at(i)->widget()->showMinimized();
761}
762
764{
765 QList<QMdiSubWindow *> windows = fxMdiArea->subWindowList();
766
767 int x(15),y(15);
768
769 for ( int i = 0; i < windows.count(); i++ ) {
770 windows.at(i)->move(x, y);
771 x+=25; y+=25;
772 }
773}
774
776{
777 if (fbFullScreen) showNormal();
778 else showFullScreen();
780}
781
783{
784 QList<QMdiSubWindow *> windows = fxMdiArea->subWindowList();
785 if ((id >= 0) && (id < windows.count())) {
786 windows.at(id)->widget()->showNormal();
787 windows.at(id)->widget()->setFocus();
788 }
789}
790
791typedef void *(*TStartUserGuiFunc)(QWidget *parent);
792
793bool TGo4MainWindow::startUserGUI(const char *usergui)
794{
795 QString dirname, libname;
796
797 bool result = false;
798
799 if (usergui && (strlen(usergui) > 0)) {
800 QFileInfo info(usergui);
801 if (info.exists()) {
802 if (info.isFile()) {
803 dirname = info.path();
804 libname = info.fileName();
805 } else if (info.isDir()) {
806 dirname = usergui;
807 }
808 }
809 if ((dirname.length()>0) && (dirname[dirname.length()-1]!='/')) dirname+="/";
810 }
811
812 bool defaultnames = libname.isEmpty();
813 if (defaultnames)
814 libname = "libGo4UserGui";
815
816 TStartUserGuiFunc startfunc = nullptr;
817
818 libname = dirname + libname;
819
820 std::cout << "Try usergui: " << libname.toLatin1().constData() << std::endl;
821
822 bool loaded = false;
823
824 if (gSystem->Load(libname.toLatin1().constData()) >= 0) {
825 loaded = true;
826 startfunc = (TStartUserGuiFunc) gSystem->DynFindSymbol(libname.toLatin1().constData(), "StartUserPanel");
827 }
828
829 if (startfunc) {
830 QGo4Widget* userpanel = (QGo4Widget*) startfunc(fxMdiArea);
831 if (userpanel) {
832 userpanel->setObjectName("UserPanel");
833
834 QMdiSubWindow* sub = fxMdiArea->AddGo4SubWindow(userpanel);
836 ConnectGo4Widget(userpanel);
837 userpanel->ensurePolished();
838 sub->show();
839 result = true;
840 } else
841 StatusMessage("StartUserPanel() function did not create user widget");
842 }
843
844 if (result) {
845 std::cout << "Start user GUI from ";
846 if (dirname.length()>0)
847 std::cout << dirname.toLatin1().constData() << std::endl;
848 else
849 std::cout << "$LD_LIBRARY_PATH=" << gSystem->Getenv("LD_LIBRARY_PATH") << std::endl;
850 } else {
851 if (loaded) gSystem->Unload(libname.toLatin1().constData());
852 }
853
854 return result;
855}
856
858{
859 QGo4Widget* userpanel = FindGo4Widget("UserPanel", true);
860 if (userpanel) return;
861
862 // check GO4USERGUI variable
863 if (gSystem->Getenv("GO4USERGUI"))
864 if (startUserGUI(gSystem->Getenv("GO4USERGUI"))) return;
865
866 // check from standard LD_LIBRARY_PATHS
867 if (startUserGUI(nullptr)) return;
868
869 TString usergui;
870
871 if (go4sett->getWebBasedCanvas())
872 usergui = TGo4Log::subGO4SYS("qt4/WebUserGUI");
873 else
874 usergui = TGo4Log::subGO4SYS("qt4/Go4UserGUI");
875
876 if (startUserGUI(usergui.Data())) return;
877
878 QMessageBox::critical(this,"Starting user GUI", "No suitable libraries found");
879}
880
882{
883 QString name;
884
885 TGo4Slot *edslot = fxOM->GetSlot(fOMEditorsPath.toLatin1().constData());
886
887 int n = 0;
888 do {
889 n++;
890 name = QString("Panel") + QString::number(n);
891 } while (edslot && edslot->FindChild(name.toLatin1().constData()));
892
893 TGo4ViewPanel *panel = new TGo4ViewPanel(fxMdiArea, name.toLatin1().constData());
894 QMdiSubWindow* sub = fxMdiArea->AddGo4SubWindow(panel); // warning: Qt may exchange the winId here!
895 // panel->GetQCanvas()->performResize(); // may register new winId for TCanvas here
896
897
898 sub->resize(go4sett->lastPanelSize("ViewPanel"));
899
901
902 ConnectGo4Widget(panel);
903 panel->update();
904 panel->show();
905 panel->ensurePolished();
906 panel->CompleteInitialization();
907
908 if(ndiv>1) {
909
910 int DivX = 1, DivY = 1;
911
912 TGo4DividePad* divpad = findChild<TGo4DividePad*>("DividePad");
913
914 if (divpad) {
915 DivX = divpad->SpinBoxX->value();
916 DivY = divpad->SpinBoxY->value();
917 }
918 if (DivX * DivY < ndiv) {
919 DivX = (int) TMath::Sqrt(ndiv*1.);
920 DivY = DivX;
921 while (DivX*DivY<ndiv) DivY++;
922 }
923 panel->Divide(DivX, DivY);
924 }
925
926 return panel;
927}
928
930{
931 //if ((sub->x() + sub->width() < fxMdiArea->viewport()->width()) &&
932 //(sub->y() + sub->height() < fxMdiArea->viewport()->height())) return;
933
934 int newx = fNewWidgetX;
935 int newy = fNewWidgetY;
936 if (newx + sub->width() > fxMdiArea->width()) newx = 0;
937 if (newy + sub->height() > fxMdiArea->height()) newy = 0;
938 sub->move(newx, newy);
939 fNewWidgetX = sub->x() + 30;
940 fNewWidgetY = sub->y() + 30;
941}
942
943
944void TGo4MainWindow::closeEvent(QCloseEvent *ce)
945{
946 if (fCloseCounter != 0) return;
947
948 if(QMessageBox::question( this, "Go4 GUI", "Really Exit Go4?",
949 QMessageBox::Yes | QMessageBox::No, QMessageBox::Yes) != QMessageBox::Yes) {
950 ce->ignore();
951 return;
952 }
953
954 TGo4FitPanel* panel = (TGo4FitPanel*) FindGo4Widget("FitPanel", false);
955 if (panel) panel->close();
956
957 //fxMdiArea->closeAllSubWindows();
958
960 fxMdiArea->closeAllSubWindows();
962
963 bool realshutdown = false;
964
965 // TODO: terminate HTTP server running in Qt window
967 if (an && an->TerminateOnClose()) realshutdown = true;
968
970 int waitsecs = 180;
971 if(!RemoveAnalysisProxy(waitsecs, realshutdown)) {
972 fCloseCounter = (waitsecs+10) *10; // was 100 gui waits about 10 second to close analysis
973 statusBar()->showMessage("Exit.... please wait");
974 QApplication::setOverrideCursor(Qt::WaitCursor);
975 QTimer::singleShot(100, this, &TGo4MainWindow::ForseCloseSlot);
976 ce->ignore();
977 } else {
978 statusBar()->showMessage("Closing GUI...");
979 // JAM: due to problems with Qt5, we just use delayed exit here
980 // note that calling directly gSystem->Exit gives crash in ROOT object/pad cleanup...
981 // probably because fxMdiArea->closeAllSubWindows() will have effect only after this event handler returns
982 QTimer::singleShot(100, this, &TGo4MainWindow::ForseCloseSlot);
983 ce->ignore();
984 }
985}
986
988{
989 // if (!RemoveAnalysisProxy(30) && (fCloseCounter>0)) {
990
991 if (Browser()->FindServer()) {
992
993 if (fCloseCounter>0) {
995 QTimer::singleShot(100, this, &TGo4MainWindow::ForseCloseSlot);
996 return;
997 }
998
999 QMessageBox box(QMessageBox::Critical, "Exit GUI", "Analysis is not (yet) shutdown correctly");
1000 auto wait_btn = box.addButton("Wait 10 s more", QMessageBox::AcceptRole);
1001 auto kill_btn = box.addButton("Kill analysis", QMessageBox::DestructiveRole);
1002 auto exit_btn = box.addButton("Exit immediately", QMessageBox::DestructiveRole);
1003 auto cancel_btn = box.addButton("Cancel quit", QMessageBox::RejectRole);
1004 box.setDefaultButton(wait_btn);
1005
1006 box.exec();
1007
1008 if (box.clickedButton() == wait_btn) {
1009 fCloseCounter = 100;
1010 QTimer::singleShot(100, this, &TGo4MainWindow::ForseCloseSlot);
1011 return;
1012 }
1013
1014 if ((box.clickedButton() == cancel_btn) || !box.clickedButton()) {
1015 std::cout << "Keep GUI running, press exit once again" << std::endl;
1016 return;
1017 }
1018
1019 if (box.clickedButton() == kill_btn) {
1020 std::cout << "Killing analysis" << std::endl;
1021 TerminateAnalysis(false);
1022 }
1023
1024 if (box.clickedButton() == exit_btn) {
1025 std::cout << "GUI closed with analysis still running - may lead to analysis task running forever" << std::endl;
1026 std::cout << "Please check running processes with \"ps\" and probably, kill analysis with \"killall go4analysis\" command" << std::endl;
1027 }
1028 }
1029 std::cout << "----- Exiting Go4 GUI now -----" << std::endl;
1030 gSystem->Exit(0);
1031}
1032
1034{
1035 QFileDialog fd( this,
1036 "Select a ROOT file to open it in the Go4 Disk Browser",
1038 QString("Root files (*.root);;Root xml files (*.xml);;All files (*.*)"));
1039
1040 fd.setFileMode( QFileDialog::ExistingFiles);
1041
1042 if (fd.exec() != QDialog::Accepted) return;
1043
1044 QStringList list = fd.selectedFiles();
1045 for (auto &fileName : list) {
1046 fLastFileDir = QFileInfo(fileName).absolutePath();
1047 Browser()->OpenFile(fileName.toLatin1().constData());
1048 }
1049}
1050
1051
1053{
1054 QFileDialog fd(this,
1055 "Select a file for importing histogram objects",
1057 QString("ASCII/Go4 (*.hdat);;Ortec MCA (*.Spe);;All files (*.*)"));
1058
1059 fd.setFileMode(QFileDialog::ExistingFiles);
1060 if (fd.exec() != QDialog::Accepted)
1061 return;
1062
1063 QStringList list = fd.selectedFiles();
1064 for(auto &fileName : list) {
1065 fLastFileDir = QFileInfo(fileName).absolutePath();
1066 Browser()->ImportObjectFromFile(fileName.toLatin1().constData(),
1067 QFileInfo(fileName).absolutePath().toLatin1().constData(),
1068 fd.selectedNameFilter().toLatin1().constData());
1069 }
1070}
1071
1072
1074{
1075 TGo4OpenRemoteDialog fd(this);
1076 if (fd.exec() != QDialog::Accepted)
1077 return;
1078
1079 QString ftype = fd.GetFileType();
1080 QString host = fd.GetServer();
1081
1082 QString urlpath;
1083 if(ftype.contains("root:"))
1084 urlpath = "root://" + host + "/";
1085 else
1086 if (ftype.contains("rfio:")) {
1087 if(!host.isEmpty())
1088 urlpath="rfio:" + host + ":/";
1089 else
1090 urlpath="rfio:/";
1091 } else
1092 if (ftype.contains("http:")) {
1093 if(!host.isEmpty())
1094 urlpath="http://" + host + "/";
1095 else
1096 urlpath="http://";
1097 }
1098
1099 QString fileName = fd.GetFileName();
1100
1101 if(!fileName.isEmpty() && !fileName.contains(".root"))
1102 fileName.append(".root");
1103
1104 fileName = urlpath + fileName;
1105
1106 fxOM->AddFile(fOMDataPath.toLatin1().constData(), fileName.toLatin1().constData());
1107}
1108
1110{
1111 bool ok = false;
1112 QString dabcnode = QInputDialog::getText(
1113 this, "Establish connection with DABC", "Provide dabc server name",
1114 QLineEdit::Normal, QString(), &ok);
1115 if (!ok) return;
1116
1117 if (!Browser()->ConnectDabc(dabcnode.toLatin1().constData()))
1118 QMessageBox::warning(this, "DABC server", "Cannot connect to DABC server");
1119}
1120
1125
1126TGo4ServerProxy *TGo4MainWindow::ConnectHttpServer(const char *addr, const char *user, const char *pass, bool with_qt_process, bool get_analysis_config)
1127{
1128 QString httpaddr;
1129
1130 if (!addr) {
1131 bool ok = false;
1132 QString portstring;
1133 QString fulladdress = go4sett->getClientNode().append(QString(":")).append(portstring.setNum(go4sett->getClientPort()));
1134 httpaddr = QInputDialog::getText(
1135 this, "Establish connection with HTTP", "Provide http server name",
1136 QLineEdit::Normal, fulladdress, &ok);
1137 if (!ok) return nullptr;
1138 QStringList nameportlist = httpaddr.split(":");
1139 int nameindex = 0;
1140 int portindex = 1;
1141 if(nameportlist.at(0).contains("http")) {
1142 nameindex = 1;
1143 portindex = 2;
1144 }
1145 // first check here if we have valid port number:
1146 if(nameportlist.size()<portindex+1 || nameportlist.at(portindex).isEmpty()){
1147 QMessageBox::warning(this, "HTTP server connection", "Could not connect. Please specify port number!");
1148 return nullptr;
1149 }
1150 QString host = nameportlist.at(nameindex);
1151 QStringList hostnamelist = nameportlist.at(nameindex).split("//");
1152 if(hostnamelist.size()>1) host = hostnamelist.at(1); // get rid of optional leading // of full http address
1153 go4sett->setClientNode(host);
1154 go4sett->setClientPort(nameportlist.at(portindex).toInt());
1155 go4sett->setClientConnectMode(1);
1156
1157 } else {
1158 httpaddr = addr;
1159 }
1160
1162
1163 if (!exec) return nullptr;
1164
1165 TGo4ServerProxy *serv = exec->ConnectHttp(httpaddr.toLatin1().constData(), user, pass);
1166
1167 if (serv) StatusMessage(QString("Connect with http server %1 %2").arg(httpaddr).arg(serv->IsGo4Analysis() ? " as GO4 analysis" : ""));
1168
1169 if (serv && serv->IsGo4Analysis()) {
1171 if (!serv->IsViewer())
1172 EstablishAnalysisConfiguration(get_analysis_config ? 3 : 2);
1173
1174 TGo4LogInfo* loginfo = (TGo4LogInfo*) FindGo4Widget("LogInfo", false);
1175 if (loginfo) loginfo->WorkWithInfo(serv->LoginfoSlot());
1176
1177 if (!with_qt_process) EstablishAnalysisWindowForHttp();
1178 }
1179
1180 return serv;
1181}
1182
1184{
1185 TGo4HServerConnection dlg( this, "Connect to remote HServer", true );
1186
1187 dlg.ServerName->setText(go4sett->getHServName());
1188 dlg.BaseName->setText(go4sett->getHServBase());
1189 dlg.FilterList->setText(go4sett->getHServFilter());
1190 dlg.PortNumberSpin->setValue(go4sett->getHServPort());
1191
1192 if (dlg.exec() != QDialog::Accepted) return;
1193
1194 go4sett->setHServName(dlg.ServerName->text());
1195 go4sett->setHServBase(dlg.BaseName->text());
1196 go4sett->setHServFilter(dlg.FilterList->text());
1197 go4sett->setHServPort(dlg.PortNumberSpin->value());
1198
1199 if (!Browser()->ConnectHServer(dlg.ServerName->text().toLatin1().constData(),
1200 dlg.PortNumberSpin->value(),
1201 dlg.BaseName->text().toLatin1().constData(),
1202 dlg.UserPassEdt->text().toLatin1().constData(),
1203 dlg.FilterList->text().toLatin1().constData()))
1204 QMessageBox::warning(this, "HServer", "Cannot connect to histogram server");
1205}
1206
1208{
1209 QFileDialog fd(this,
1210 go4sett->getFetchDataWhenSave() ?
1211 "Select root file to fetch and export all browser objects" :
1212 "Select root file to export all local browser objects",
1213 fLastFileDir, "ROOT (*.root)");
1214
1215 fd.setFileMode( QFileDialog::AnyFile);
1216 fd.setAcceptMode(QFileDialog::AcceptSave);
1217 fd.selectFile("export.root");
1218
1219 if (fd.exec() != QDialog::Accepted) return;
1220
1221 QStringList flst = fd.selectedFiles();
1222 if (flst.isEmpty()) return;
1223
1224 QString fname = flst[0];
1225 fLastFileDir = fd.directory().path();
1226 if (fname.indexOf(".root", 0, Qt::CaseInsensitive)<0) fname += ".root";
1227
1228 if (!Browser()->SaveBrowserToFile(fname.toLatin1().constData(), go4sett->getFetchDataWhenSave()))
1229 QMessageBox::warning(this, "Save data to file", "Specified file can not be created");
1230}
1231
1233{
1234 fxOM->CloseFiles(fOMDataPath.toLatin1().constData());
1235}
1236
1238{
1239 int size = go4sett->getTermHistorySize();
1240
1241 bool ok = false;
1242
1243 size = QInputDialog::getInt(this,
1244 "Analysis terminal history size in bytes (minimum 10000 bytes)",
1245 "Input 0 if full analysis history should be preserved",
1246 size, 0, 100000000, 10000, &ok);
1247
1248 if ((size > 0) && (size < 10000)) size = 10000;
1249
1250 if (ok) {
1251 go4sett->setTermHistorySize(size);
1253 if (anw)
1254 anw->SetHistorySize(size);
1255 }
1256}
1257
1259{
1260 TGo4LogSettings dlg;
1261 if (dlg.exec() != QDialog::Accepted) return;
1262
1263 if(dlg.LogfileWrite->isChecked())
1264 TGo4Log::OpenLogfile(dlg.LogfileName->text().toLatin1().constData(), "Logfile for Go4 GUI", true);
1265
1266 TGo4Log::LogfileEnable(dlg.LogfileWrite->isChecked());
1267 TGo4Log::OutputEnable(dlg.LogfilePrint->isChecked());
1268 TGo4Log::SetIgnoreLevel(dlg.IgnoreCombo->currentIndex());
1269 TGo4Log::AutoEnable(dlg.ModeCombo->currentIndex());
1270}
1271
1272void TGo4MainWindow::HelpWindow(const char *filename, const char *msg)
1273{
1274 QApplication::setOverrideCursor( Qt::WaitCursor );
1275
1276 QString surl = TGo4Log::subGO4SYS(filename).Data();
1277
1278 bool result = QDesktopServices::openUrl(QUrl::fromLocalFile(surl));
1279
1280 if(result)
1281 StatusMessage(msg ? QString(msg) : QString("Show ") + filename);
1282 else
1283 StatusMessage(QString("Fail to display ") + filename);
1284
1285 QApplication::restoreOverrideCursor();
1286}
1287
1289{
1290 HelpWindow("docs/Go4Introduction.pdf", "Show Go4 Introduction manual...");
1291}
1292
1294{
1295 HelpWindow("docs/Go4Reference.pdf", "Show Go4 Reference manual...");
1296}
1297
1299{
1300 HelpWindow("docs/Go4FitTutorial.pdf", "Show Go4 Fit tutorial...");
1301}
1302
1304{
1305 go4sett->setBasicSettings();
1306 go4sett->setAppFont(QApplication::font());
1307
1308 go4sett->setAppStyle(QApplication::style()->objectName());
1309
1310 go4sett->storeMainWindowState(this);
1311
1312 go4sett->Store();
1313
1314 std::cout << "Save Qt settings to " << go4sett->GetSettLoaction().toLatin1().constData() << std::endl;
1315}
1316
1318{
1319 bool ok = false;
1320 QFont font= QFontDialog::getFont(&ok, QApplication::font(), this);
1321 if (!ok) return;
1322
1323 go4sett->setAppFont(font);
1324
1325 QApplication::setFont(font);
1326}
1327
1329{
1330 bool ok = false;
1331 QFont font= QFontDialog::getFont(&ok, go4sett->getTermFont(), this);
1332 if (!ok) return;
1333
1334 go4sett->setTermFont(font);
1335
1337 if (anw) anw->setFont(font);
1338}
1339
1340
1342{
1343 go4sett->setTermShowTimestamp(flag);
1345 if (anw)
1346 anw->UpdateTimeStampFormat();
1347}
1348
1350{
1351 bool ok = false;
1352 QString str = QInputDialog::getText(this, "Analysis terminal timestamp format",
1353 "Time format (empty resets to yyyy-MM-dd hh:mm:ss.zzz)",
1354 QLineEdit::Normal, go4sett->getTermTimeFormat(), &ok);
1355 if (ok) {
1356 if (str.isEmpty())
1357 str = "yyyy-MM-dd hh:mm:ss.zzz";
1358 go4sett->setTermTimeFormat(str);
1360 if (anw)
1361 anw->UpdateTimeStampFormat();
1362 }
1363}
1364
1365void TGo4MainWindow::SetStyleSlot(const QString &style)
1366{
1367 // save settings anyway
1368 go4sett->setAppStyle(style);
1369 go4sett->Store();
1370
1371 QApplication::setStyle(style);
1372}
1373
1374void TGo4MainWindow::StatusMessage(const QString& mess)
1375{
1376 QString output = QDateTime::currentDateTime().toString(Qt::ISODate);
1377 output.append(": ");
1378 output.append(mess);
1379 statusBar()->showMessage(output, 0); // JAM2016: do not clear message after 3s. ratemeter will clear message on each update.
1381 TGo4Log::Message(1, "%s", output.toLatin1().constData());
1382}
1383
1385{
1386 // JAM note this function is called by update timer from TGo4Browser each second
1387 TGo4ServerProxy *root_serv = Browser()->FindServer(nullptr, kFALSE);
1388 TGo4ServerProxy *go4_serv = Browser()->FindServer();
1389 TGo4AnalysisProxy *pr = dynamic_cast<TGo4AnalysisProxy *>(go4_serv);
1390 TGo4HttpProxy *ht = dynamic_cast<TGo4HttpProxy *>(go4_serv);
1391
1392 QString capt = "Go4 ";
1393 capt += __GO4RELEASE__;
1394 capt += " @";
1395 capt += gSystem->HostName();
1396 if (go4_serv && go4_serv->IsConnected() ) {
1397 capt += " <";
1398 capt += go4_serv->GetContainedObjectInfo();
1399 capt += ">";
1400 }
1401 setWindowTitle(capt);
1402
1403 bool flag = false;
1404 if (!pr) flag = !ht ? true: false;
1405 faLaunchAnal->setEnabled(flag);
1406 // JAM here check again ratemeter connection, if http server was disconnected by browser popup close item:
1407 EstablishRatemeter(flag ? 0: 1);
1408 // need to check if the controller role has switched to another HTTP server here:
1409 static TGo4HttpProxy *oldhttp = nullptr;
1410 if (ht) {
1411 // check for server names may not be unique if connected twice by chance, better use proxy pointers!
1412 if(ht != oldhttp) {
1413 oldhttp = ht;
1416 }
1417 }
1418
1419 if (!pr)
1420 flag = !ht ? true : false;
1421 else
1422 flag = (fConnectingCounter <= 0) && pr->IsAnalysisServer() && !pr->IsConnected();
1423 faConnectAnal->setEnabled(flag);
1424
1425 faPrepareAnal->setEnabled(flag);
1426
1427 if (!pr)
1428 flag = !ht ? false : true;
1429 else
1430 flag = pr->IsAnalysisServer() && (pr->IsConnected() || (fConnectingCounter <= 0));
1431 faDisconnectAnal->setEnabled(flag);
1432
1433 flag = false;
1434 if (go4_serv)
1435 flag = !go4_serv->IsAnalysisServer() || (go4_serv->IsConnected() && go4_serv->IsAdministrator());
1436 faShutdownAnal->setEnabled(flag);
1437
1438 bool iscontrolling = false, issubmit = false;
1439 if (go4_serv) {
1440 iscontrolling = go4_serv->IsConnected() && (go4_serv->IsAdministrator() || go4_serv->IsController());
1441 if (iscontrolling)
1442 issubmit = go4_serv->CanSubmitObjects();
1443 }
1444
1445 faSumbStartAnal->setEnabled(issubmit);
1446
1447 faStartAnal->setEnabled(iscontrolling);
1448
1449 faStopAnal->setEnabled(iscontrolling);
1450
1451 faAnalConfig->setEnabled(iscontrolling);
1452
1453 faAnalTermin->setEnabled(FindAnalysisWindow() != nullptr);
1454
1455 if (!go4_serv && root_serv) {
1456 faStartAnal->setEnabled(root_serv->FindCommand("Start").Length()>0);
1457 faStopAnal->setEnabled(root_serv->FindCommand("Stop").Length()>0);
1458 }
1459}
1460
1462{
1463 go4sett->setFetchDataWhenDraw(flag);
1464}
1465
1467{
1468 go4sett->setFetchDataWhenCopy(flag);
1469}
1470
1472{
1473 go4sett->setFetchDataWhenSave(flag);
1474}
1475
1477{
1478 go4sett->setHideTGo4EventElement(flag);
1479 UpdateBrowser();
1480}
1481
1483{
1484 go4sett->setDrawOnceFlag(flag);
1485}
1486
1488{
1489 go4sett->setMoveSubwindowRubberBand(flag);
1490}
1491
1493{
1494 go4sett->setNativeMenuBar(flag);
1495 menuBar()->setNativeMenuBar(flag);
1497#ifdef Darwin
1498 QMessageBox::information(this, "Change menu type",
1499 "On platforms like MacOS changing of menu type may require restart of application");
1500#endif
1501}
1502
1504{
1505 QColor c = QColorDialog::getColor();
1506 if (c.isValid())
1507 go4sett->setCanvasColor(c.red(), c.green(), c.blue());
1508}
1509
1511{
1512 TGo4MarkerSettings mset;
1513 if (mset.exec() != QDialog::Accepted) return;
1514 // all work is done inside dialog.
1515}
1516
1518{
1520 stset.exec();
1521 // all work is done inside dialog.
1522}
1523
1525{
1526 go4sett->setPadSuperimpose(flag);
1527}
1528
1530{
1531 go4sett->setPadCrosshair(flag);
1532}
1533
1535{
1536 go4sett->setPadEventStatus(flag);
1537}
1538
1540{
1541 faDrawTime->setEnabled(flag);
1542 faDrawDate->setEnabled(flag);
1543 faDrawItem->setEnabled(flag);
1544 go4sett->setCloneFlag(flag);
1545}
1546
1548{
1549 go4sett->setDrawTimeFlag(flag);
1550}
1551
1553{
1554 go4sett->setDrawItemFlag(flag);
1555}
1556
1558{
1559 go4sett->setDrawDateFlag(flag);
1560}
1561
1563{
1564 go4sett->setSavePadWhiteBackground(flag);
1565}
1566
1568{
1569 int w = go4sett->getDrawLineWidth();
1570
1571 bool ok = false;
1572
1573 w = QInputDialog::getInt(this,
1574 "Default line width for object drawing",
1575 "Input 1 to preserve default value",
1576 w, 1, 10, 1, &ok);
1577
1578 if (ok) go4sett->setDrawLineWidth(w);
1579}
1580
1581
1583{
1584 int w = go4sett->getDrawFillColor();
1585
1586 bool ok = false;
1587
1588 w = QInputDialog::getInt(this,
1589 "Default fill color for 1D objects (histogram and graph) drawing",
1590 "Input 0 for no fill",
1591 w, 0, 50, 1, &ok);
1592
1593 if (ok) go4sett->setDrawFillColor(w);
1594}
1595
1597{
1598 int w = go4sett->getDrawFillStyle();
1599
1600 bool ok = false;
1601
1602 w = QInputDialog::getInt(this,
1603 "Default fill style for 1D objects (histogram and graph) drawing",
1604 "Input 1001 for solid fill",
1605 w, 0, 4000, 1, &ok);
1606
1607 if (ok) go4sett->setDrawFillStyle(w);
1608}
1609
1610
1612{
1613 bool ok = false;
1614 QString str = QInputDialog::getText(this,
1615 "Default draw options for TH1 class",
1616 "Input draw options",
1617 QLineEdit::Normal, go4sett->getTH1DrawOpt(), &ok);
1618 if (ok) go4sett->setTH1DrawOpt(str);
1619}
1620
1622{
1623 bool ok = false;
1624 QString str = QInputDialog::getText(this,
1625 "Default draw options for TH2 class",
1626 "Input draw options",
1627 QLineEdit::Normal, go4sett->getTH2DrawOpt(), &ok);
1628 if (ok) go4sett->setTH2DrawOpt(str);
1629}
1630
1632{
1633 bool ok = false;
1634 QString str = QInputDialog::getText(this,
1635 "Default draw options for TH3 class",
1636 "Input draw options",
1637 QLineEdit::Normal, go4sett->getTH3DrawOpt(), &ok);
1638 if (ok) go4sett->setTH3DrawOpt(str);
1639}
1640
1642{
1643 bool ok = false;
1644 QString str = QInputDialog::getText(this,
1645 "Default draw options for TGraph class",
1646 "Input draw options",
1647 QLineEdit::Normal, go4sett->getTGraphDrawOpt(), &ok);
1648 if (ok)
1649 go4sett->setTGraphDrawOpt(str);
1650}
1651
1652
1654{
1655 bool ok = false;
1656 QString s0 = go4sett->getGStyleStatFormat();
1657 if (s0.isEmpty()) s0 = gStyle->GetStatFormat();
1658
1659 QString str = QInputDialog::getText(this,
1660 "Printf argument for float values - gStyle->GetStatFormat()",
1661 "Input format string like 6.4g (empty - ROOT default)",
1662 QLineEdit::Normal, s0, &ok);
1663 if (ok) {
1664 go4sett->setGStyleStatFormat(str);
1665 if (str.isEmpty())
1666 gStyle->SetStatFormat();
1667 else
1668 gStyle->SetStatFormat(str.toLatin1().constData());
1669 }
1670}
1671
1672
1674{
1675 // JAM: later we might put some elaborate input dialog here. for the moment keep on with parsing a string-
1676 bool ok = false;
1677 int min = 0, def = 0, max = 0;
1678 go4sett->getPaletteOpt(min, def, max);
1679 QString palvals = QString("%1:%2:%3").arg(min).arg(def).arg(max);
1680 QString str = QInputDialog::getText(this,
1681 "Default Palette options",
1682 "Input - MinIndex:DefaultIndex:MaxIndex",
1683 QLineEdit::Normal, palvals, &ok);
1684 if (ok) {
1685 QStringList parts=str.split(":");
1686 min=parts[0].toInt();
1687 def=parts[1].toInt();
1688 max=parts[2].toInt();
1689// std::cout <<"PaletteSettingsSlot has "<<min<<":"<<def<<":"<<max <<std::endl;
1690 go4sett->setPaletteOpt(min,def,max);
1691 // activate settings immediately, do not need to restart go4
1692 fxStyle->SetPaletteRange(min,def,max);
1693 }
1694}
1695
1696
1698{
1699 double w = go4sett->getScreenScaleFactor();
1700
1701 bool ok = false;
1702
1703 w = QInputDialog::getDouble(this, "HighDPI scaling", "Please set scale factor. Restart GUI to apply!", w, 0, 50, 1,
1704 &ok);
1705 if (ok)
1706 go4sett->setScreenScaleFactor(w);
1707}
1708
1709void TGo4MainWindow::LaunchClient(bool interactive)
1710{
1712 if (anal) {
1713 QMessageBox::warning(this, "Launch analysis", "Please disconnect analysis first");
1714 return;
1715 }
1716
1717 if (interactive) {
1718 TGo4StartClient dlg;
1719 if (dlg.exec()!=QDialog::Accepted) return;
1720 dlg.getResults();
1721 }
1722
1723 int shellmode = go4sett->getClientShellMode();
1724 int termmode = go4sett->getClientTermMode();
1725 int isserver = go4sett->getClientIsServer();
1726
1727 TString launchcmd, killcmd;
1728 Bool_t res = kFALSE;
1729
1730 QString workdir = go4sett->getClientDir();
1731
1732 if (isserver==2) {
1733 // first handle http connection
1734
1735 QString addr = QString("%1:%2").arg(go4sett->getClientNode()).arg(go4sett->getClientPort());
1736
1737 // first verify that http server already running with such address
1738 // need to request analysis status anyway
1739 if (ConnectHttpServer(addr.toLatin1().constData(), nullptr, nullptr, false, true)) {
1740 StatusMessage("Connected to existing analysis webserver!"); // JAM tell user that this is no analysis restart!
1741 std::cout<< "!!! Connected to existing analysis webserver "<<addr.toLatin1().constData()<< "!!! "<<std::endl; // status message is shadowed by ratemeter ....
1742 return;
1743 }
1744
1745 res = TGo4ServerProxy::GetLaunchString(launchcmd, killcmd,
1746 2, shellmode, termmode,
1747 go4sett->getClientName().toLatin1().constData(),
1748 go4sett->getClientNode().toLatin1().constData(),
1749 workdir.toLatin1().constData(),
1750 go4sett->getClientExec().toLatin1().constData(),
1751 go4sett->getClientPort(),
1752 go4sett->getClientExeMode(),
1753 go4sett->getClientArgs().toLatin1().constData());
1754
1755 if (!res) return;
1756
1757 fKillCommand = killcmd.Data();
1758
1759 if ((termmode==2) || (termmode==3)) {
1760 gSystem->Exec(launchcmd.Data());
1761 } else {
1762 TGo4AnalysisWindow* anw = EstablishAnalysisWindow(true, true, true);
1763 anw->StartAnalysisShell(launchcmd.Data(), (shellmode == 0) ? workdir.toLatin1().constData() : nullptr, true);
1764 }
1765
1766 fConnectingCounter = 100; // try next 10 seconds connect with the server
1767 fConnectingHttp = addr;
1768 fbGetAnalysisConfig = true; // pass to timer that we want to have analysis config window when ready JAM
1769 QTimer::singleShot(100, this, &TGo4MainWindow::CheckConnectingCounterSlot);
1770
1771 return;
1772 }
1773
1774 if (isserver == 0) {
1775 TGo4AnalysisProxy *anal = AddAnalysisProxy(false, (termmode==1));
1776 if (anal)
1777 res = anal->LaunchAsClient(launchcmd, killcmd,
1778 shellmode,
1779 termmode,
1780 go4sett->getClientName().toLatin1().constData(),
1781 go4sett->getClientNode().toLatin1().constData(),
1782 workdir.toLatin1().constData(),
1783 go4sett->getClientExec().toLatin1().constData(),
1784 go4sett->getClientExeMode(),
1785 go4sett->getClientArgs().toLatin1().constData());
1787 if (res && anw && (termmode==1)) {
1788 anw->StartAnalysisShell(launchcmd.Data(), (shellmode == 0) ? workdir.toLatin1().constData() : nullptr, false);
1789 }
1790 if (res && anal) anal->SetAnalysisLaunched(termmode==1 ? 2 : 1);
1791 } else {
1792 res = TGo4AnalysisProxy::LaunchAsServer(launchcmd, killcmd,
1793 shellmode,
1794 termmode,
1795 go4sett->getClientName().toLatin1().constData(),
1796 go4sett->getClientNode().toLatin1().constData(),
1797 go4sett->getClientPort(),
1798 workdir.toLatin1().constData(),
1799 go4sett->getClientExec().toLatin1().constData(),
1800 go4sett->getClientExeMode(),
1801 go4sett->getClientArgs().toLatin1().constData());
1802 }
1803
1804 if (res)
1805 fKillCommand = killcmd.Data();
1806 else
1807 fKillCommand = "";
1808
1809 StatusMessage("Starting Analysis.... Please wait");
1810
1811 if ((isserver == 1) && interactive) {
1812 fbGetAnalysisConfig = true; // pass to timer that we want to have analysis config window when ready JAM
1813 ConnectServer(true, "");
1814 }
1815}
1816
1818{
1819 TGo4AnalysisProxy *ana = AddAnalysisProxy(false, false);
1820 if (ana && interactive)
1821 QMessageBox::information(this, "Prepare for client connection",
1822 QString("Now you can start client from other shell (node) and connect to port ") + QString::number(ana->ConnectorPort()));
1823}
1824
1825TGo4AnalysisWindow* TGo4MainWindow::EstablishAnalysisWindow(bool needoutput, bool withkillbnt, bool force_recreate)
1826{
1828 if (anw)
1829 if (force_recreate || (anw->HasOutput() && !needoutput)) {
1830 delete anw;
1831 anw = nullptr;
1832 }
1833
1834 if (!anw) {
1835 if (needoutput) {
1836 anw = new TGo4AnalysisWindow(fxMdiArea, "AnalysisWindow", true);
1837 QMdiSubWindow* sub = fxMdiArea->AddGo4SubWindow(anw);
1838 sub->resize(go4sett->lastPanelSize("AnalysisWindow", 700, 500));
1839 CascadeMdiPosition(sub);
1840 ConnectGo4Widget(anw);
1841 anw->ensurePolished();
1842 sub->show();
1843 } else {
1844 QToolBar* dock = addToolBar("Analysis control");
1845 dock->setObjectName("AnalysisControlBar");
1846 anw = new TGo4AnalysisWindow(this, "AnalysisWindow", false, withkillbnt || fKillCommand.length()>0);
1847 ConnectGo4Widget(anw);
1848 dock->addWidget(anw);
1849 }
1850 }
1851
1852 return anw;
1853}
1854
1856{
1857 // used together with http server connection
1858 // analysis window only created when not exists and http proxy is available
1859
1860 auto serv = Browser()->FindServer();
1861 if (!serv || (dynamic_cast<TGo4AnalysisProxy *>(serv) != nullptr) || (serv->DebugOutputSlot() == nullptr)) return;
1862
1863 auto anw = FindAnalysisWindow();
1864
1865 if (anw) {
1866 if (anw->HasLink()) return;
1867 delete anw;
1868 anw = nullptr;
1869 }
1870
1871 anw = EstablishAnalysisWindow(true, false);
1872 if (anw) anw->WorkWithDebugOutput(serv->DebugOutputSlot());
1873 serv->ResetDebugOutputRequests();
1874}
1875
1876
1878{
1879 const char *analisysitem = "Analysis";
1880
1881 TGo4Slot *analslot = Browser()->DataSlot(analisysitem);
1882
1883 if (!analslot) {
1884 TGo4AnalysisProxy *anal = new TGo4AnalysisProxy(isserver);
1885 fxOM->AddProxy(fOMDataPath.toLatin1().constData(), anal, analisysitem, "Analysis proxy");
1886 analslot = Browser()->DataSlot(analisysitem);
1887 anal->SetDefaultReceiver(fxOM, TString("gui/") + analisysitem + "/");
1888 }
1889
1890 TGo4AnalysisProxy *anal = !analslot ? nullptr :
1891 dynamic_cast<TGo4AnalysisProxy *> (analslot->GetProxy());
1892
1893 if (!anal) return nullptr;
1894
1895 anal->SetAnalysisReady(kFALSE);
1896
1897 TGo4LogInfo *loginfo = (TGo4LogInfo *) FindGo4Widget("LogInfo", false);
1898 if (loginfo)
1899 loginfo->WorkWithInfo(anal->LoginfoSlot());
1900
1901 if (anal->IsAnalysisServer())
1902 EstablishRatemeter(anal->IsConnected() ? 2 : 0);
1903 else
1905
1907
1909
1910 auto anw = FindAnalysisWindow();
1911 if (anw)
1912 if (anw->HasOutput() && !needoutput) {
1913 delete anw;
1914 anw = nullptr;
1915 }
1916
1917 if(!anw) {
1918 if (needoutput) {
1919 anw = EstablishAnalysisWindow(true);
1920 if (anw) anw->WorkWithUpdateObjectCmd(anal->UpdateObjectSlot());
1921 } else {
1923 }
1924 }
1925
1926 return anal;
1927}
1928
1929bool TGo4MainWindow::RemoveAnalysisProxy(int waittime, bool servershutdown)
1930{
1931 // Browser()->ToggleMonitoring(0);
1934
1935 // TGo4AnalysisProxy *anal = Browser()->FindAnalysis();
1937 if (srv) {
1938 srv->DisconnectAnalysis(waittime, servershutdown);
1939 }
1940 // TGo4Slot *slot = Browser()->FindServerSlot(kTRUE, 1);
1941 // it is allowed to delete slot directly
1942 //if (slot) delete slot;
1943
1944 return !Browser()->FindServer();
1945}
1946
1948{
1951
1952 if (anw && anw->HasOutput()) return;
1953
1954 bool shouldexists = false;
1955 if (anal) {
1956 if (anal->IsAnalysisServer()) {
1957 if (anal->IsConnected() && (anal->IsController() || anal->IsAdministrator()))
1958 shouldexists = true;
1959 } else {
1960 shouldexists = true;
1961 }
1962 }
1963
1964 if (shouldexists && !anw) {
1965 anw = EstablishAnalysisWindow(false, !anal->IsAnalysisServer());
1966 if (anw) anw->WorkWithUpdateObjectCmd(anal->UpdateObjectSlot());
1967 }
1968}
1969
1971{
1972 // level = 0 - delete
1973 // level = 1 - as is
1974 // level = 2 - create
1976 dynamic_cast<TGo4AnalysisStatusMonitor*>
1977 (FindGo4Widget("AnalysisStatusMonitor", false));
1978
1979 if (level == 2) {
1980 if (!status) {
1981 status = new TGo4AnalysisStatusMonitor(statusBar(), "AnalysisStatusMonitor");
1982 ConnectGo4Widget(status);
1983 statusBar()->addWidget(status);
1984 TGo4ServerProxy *serv = Browser()->FindServer();
1985 if (serv)
1986 status->WorkWithRatemeter(serv->RatemeterSlot());
1987 }
1988 } else if (level == 0) {
1989 if (status) {
1990 status->RemoveLink("Ratemeter",true); // JAM: need to remove the update link before deleting!
1991 statusBar()->removeWidget(status);
1992 delete status;
1993 }
1994 status = nullptr;
1995 }
1996
1997 if (status)
1998 status->show();
1999
2000 return status;
2001}
2002
2004{
2005 // level: 0 - delete, 1 - keep as is, 2 - create, 3 - create + request status
2006
2008
2009 if (level == 0) {
2010 if (conf) {
2011 delete conf->parentWidget();
2012 conf = nullptr;
2013 }
2014 } else if (level >= 2) {
2015 if (!conf) {
2016 conf = new TGo4AnalysisConfiguration(fxMdiArea, "AnalysisConfiguration");
2017 QMdiSubWindow* sub = fxMdiArea->AddGo4SubWindow(conf);
2018 CascadeMdiPosition(sub);
2019 ConnectGo4Widget(conf);
2020 // ! do not show configuration window before analysis settings requested
2021 // conf->ensurePolished();
2022 // sub->show();
2023 }
2024 TGo4ServerProxy *anal = Browser()->FindServer();
2025 if (anal) {
2026 conf->WorkWithAnalysis(anal);
2027 if (level > 2) anal->RequestAnalysisSettings();
2028 }
2029 }
2030
2031 return conf;
2032}
2033
2034
2035void TGo4MainWindow::ConnectServer(bool interactive, const char *password)
2036{
2037 if (fConnectingCounter > 0) return;
2039 if (anal) {
2040 if (anal->IsConnected() || !anal->IsAnalysisServer()) {
2041 if (interactive)
2042 QMessageBox::warning(this, "Connect client", "Analysis task is already connected");
2043 return;
2044 }
2045 }
2046
2047 QString pass = password;
2048 if (interactive) {
2050 if (fLastPassword.length() > 0)
2051 dlg.setPassword(fLastPassword.toLatin1().constData());
2052 if (dlg.exec()!=QDialog::Accepted) return;
2053 pass = dlg.getInput();
2054 }
2055 // here check if we want web server or regular connection:
2056
2057 if(go4sett->getClientConnectMode() == 0) {
2058 if (!anal) anal = AddAnalysisProxy(true, false);
2059 bool def = go4sett->getClientDefaultPass();
2060 if (!def) fLastPassword = pass;
2061
2062 if (anal)
2063 anal->ConnectToServer(go4sett->getClientNode().toLatin1().constData(),
2064 go4sett->getClientPort(),
2065 go4sett->getClientControllerMode(),
2066 def ? nullptr : pass.toLatin1().constData());
2067 StatusMessage("Connecting running analysis.... Please wait");
2068
2069 // wait about 4 sec that analysis is connected
2070 fConnectingCounter = 41;
2073 } else {
2074 QString fulladdress = go4sett->getClientNode();
2075 if ((go4sett->getClientPort() > 0) && (go4sett->getClientPort() != 80)) {
2076 QString portstring;
2077 portstring.setNum(go4sett->getClientPort());
2078 fulladdress.append(":");
2079 fulladdress.append(portstring);
2080 }
2081 QString msg("Connecting analysis http server at ");
2082 msg.append(fulladdress).append(QString(", Please wait"));
2083 StatusMessage(msg);
2084 ConnectHttpServer(fulladdress.toLatin1().constData(),
2085 go4sett->getClientAccountName().toLatin1().constData(),
2086 pass.toLatin1().constData(), false, false);
2088 }
2089}
2090
2092{
2093 if (fConnectingHttp.length() > 0) {
2094 TGo4ServerProxy *serv =
2095 ConnectHttpServer(fConnectingHttp.toLatin1().constData(), nullptr, nullptr, go4sett->getClientTermMode() == 1, fbGetAnalysisConfig);
2096 if (serv) {
2097 serv->SetAnalysisLaunched(go4sett->getClientTermMode()==1 ? 2 : 1);
2098 fConnectingHttp = "";
2100 fbGetAnalysisConfig=false;
2101 return;
2102 }
2103 if (--fConnectingCounter <= 0) {
2104 StatusMessage(fConnectingHttp + " refused connection. Try again");
2105 fConnectingHttp = "";
2107 fbGetAnalysisConfig=false;
2108 return;
2109 }
2110 } else {
2112 if (!anal || anal->IsConnected() || (--fConnectingCounter <= 0)) {
2113 if (fConnectingCounter <= 0)
2114 StatusMessage("Analysis refused connection. Try again");
2116 EstablishRatemeter(anal && anal->IsConnected() ? 2 : 0);
2117 int level = 0;
2118 if (anal && anal->IsConnected() && (anal->IsController() || anal->IsAdministrator())) {
2119 if (fbGetAnalysisConfig) {
2120 level = 3;
2121 fbGetAnalysisConfig = false;
2122 } else {
2123 level = 2;
2124 }
2125 }
2129 if (anal && !anal->IsConnected()) RemoveAnalysisProxy(1);
2130 return;
2131 }
2132 }
2133 QTimer::singleShot(100, this, &TGo4MainWindow::CheckConnectingCounterSlot);
2134}
2135
2137{
2138 TGo4ServerProxy *serv = Browser()->FindServer();
2139 if (!serv) return;
2140
2141 bool shutdown = serv->IsAnalysisLaunched() > 1;
2142
2143 if (interactive) {
2144
2145 if (shutdown) {
2146
2147 QMessageBox msgBox(QMessageBox::Warning,
2148 "Disconnect from analysis",
2149 "Analysis runs inside go4 widget.\n"
2150 "If one only disconnects from the analysis,\n"
2151 "it remains invisible and difficult to stop.\n"
2152 "To shutdown it later, one need to reconnect with go4 gui again.\n"
2153 "It is recommended to shutdown analysis now");
2154
2155 auto btnShutdown = msgBox.addButton("Shutdown", QMessageBox::DestructiveRole);
2156 auto btnDisconnect = msgBox.addButton("Disconnect", QMessageBox::ActionRole);
2157 auto btnCancel = msgBox.addButton("Cancel", QMessageBox::RejectRole);
2158 msgBox.setDefaultButton(btnShutdown);
2159
2160 msgBox.exec();
2161 if (msgBox.clickedButton() == btnCancel)
2162 return;
2163 else if (msgBox.clickedButton() == btnShutdown)
2164 shutdown = true;
2165 else if (msgBox.clickedButton() == btnDisconnect)
2166 shutdown = false;
2167 } else {
2168 QMessageBox msgBox(QMessageBox::Question, "Disconnect analysis", "Really disconnect from analysis task?");
2169
2170 auto btnDisconnect = msgBox.addButton("Disconnect", QMessageBox::DestructiveRole);
2171 auto btnCancel = msgBox.addButton("Cancel", QMessageBox::RejectRole);
2172 msgBox.setDefaultButton(btnDisconnect);
2173
2174 msgBox.exec();
2175 if (msgBox.clickedButton() == btnCancel)
2176 return;
2177 }
2178 }
2179 RemoveAnalysisProxy(30, shutdown);
2180 StatusMessage("Disconnect analysis");
2181}
2182
2184{
2185 if (interactive) {
2186 QMessageBox msgBox(QMessageBox::Question, "Shutdown analysis", "Really shutdown analysis task?");
2187
2188 auto btnShutdown = msgBox.addButton("Shutdown", QMessageBox::DestructiveRole);
2189 auto btnCancel = msgBox.addButton("Cancel", QMessageBox::RejectRole);
2190 msgBox.setDefaultButton(btnShutdown);
2191
2192 msgBox.exec();
2193 if (msgBox.clickedButton() == btnCancel)
2194 return;
2195 }
2196 TGo4ServerProxy *serv = Browser()->FindServer();
2197 if (!serv) return;
2198 bool realshutdown = false;
2199 TGo4AnalysisProxy *anal = dynamic_cast<TGo4AnalysisProxy *>(serv);
2200 TGo4HttpProxy *http = dynamic_cast<TGo4HttpProxy *>(serv);
2201 if (anal)
2202 realshutdown = anal->IsAnalysisServer() &&
2203 anal->IsConnected() &&
2204 anal->IsAdministrator();
2205 else if (http)
2206 realshutdown = http->IsConnected() && http->IsAdministrator();
2207
2208 RemoveAnalysisProxy(30, realshutdown);
2209 StatusMessage("Shutdown analysis");
2210}
2211
2213{
2214 TGo4ServerProxy *serv = Browser()->FindServer();
2215 if (!serv) return false;
2216
2217 if (serv->IsConnected() && serv->CanSubmitObjects() &&
2218 (serv->IsAdministrator() || serv->IsController())) {
2219 serv->SubmitAnalysisSettings();
2220 serv->RefreshNamesList();
2221 StatusMessage("Press Ctrl+S or choose Analysis->Start from the Menu to start the analysis");
2222 return true;
2223 }
2224
2225 return false;
2226}
2227
2233
2235{
2236 TGo4ServerProxy *go4_serv = Browser()->FindServer();
2237 if (go4_serv) {
2238 go4_serv->StartAnalysis();
2239 go4_serv->RefreshNamesList();
2240 go4_serv->DelayedRefreshNamesList(4);
2242 } else {
2243 TGo4ServerProxy *root_serv = Browser()->FindServer(nullptr, kFALSE);
2244 if (root_serv) {
2245 TString cmd = root_serv->FindCommand("Start");
2246 if (cmd.Length() > 0) {
2247 root_serv->SubmitCommand(cmd);
2248 StatusMessage(TString::Format("Submit %s command to the server", cmd.Data()).Data());
2249 }
2250 }
2251 }
2252}
2253
2255{
2256 TGo4ServerProxy *go4_serv = Browser()->FindServer();
2257 if (go4_serv) {
2258 go4_serv->StopAnalysis();
2259 } else {
2260 TGo4ServerProxy *root_serv = Browser()->FindServer(nullptr, kFALSE);
2261 if (root_serv) {
2262 TString cmd = root_serv->FindCommand("Stop");
2263 if (cmd.Length()>0) {
2264 root_serv->SubmitCommand(cmd);
2265 StatusMessage(TString::Format("Submit %s command to the server", cmd.Data()).Data());
2266 }
2267 }
2268 }
2269}
2270
2272{
2273 if (interactive) {
2274 QMessageBox msgBox(QMessageBox::Question, "Kill analysis process",
2275 QString("Kill analysis by shell command: ") +fKillCommand + " ?");
2276
2277 auto btnKill = msgBox.addButton("Kill", QMessageBox::DestructiveRole);
2278 auto btnCancel = msgBox.addButton("Cancel", QMessageBox::RejectRole);
2279 msgBox.setDefaultButton(btnKill);
2280
2281 msgBox.exec();
2282 if (msgBox.clickedButton() == btnCancel)
2283 return;
2284 }
2285
2287 if (anw) anw->TerminateAnalysisProcess();
2288
2289 // proxy will be deleted after 7 seconds
2290 //RemoveAnalysisProxy(7);
2291
2292 anw = FindAnalysisWindow();
2293 if (anw)
2294 anw->AppendOutputBuffer(QString("\nKilling analysis client: \n ")+fKillCommand, 2);
2295 else
2296 StatusMessage(QString("Killing analysis client with: ")+fKillCommand);
2297
2298 if (fKillCommand.length() > 0) {
2299 QProcess* killprocess = new QProcess;
2300 QStringList args;
2301 QString progname = fKillCommand;
2303 killprocess->start(progname, args);
2304 QTimer::singleShot(10000, killprocess, &QProcess::deleteLater);
2305 } else
2306 StatusMessage("Can not kill analysis. Do it by OS commands");
2307
2309
2311}
2312
2313QGo4Widget* TGo4MainWindow::FindGo4Widget(const char *name, bool activate)
2314{
2315 if (!fxOM) return nullptr;
2316
2317 TGo4Slot *slot = fxOM->GetSlot(fOMEditorsPath.toLatin1().constData());
2318
2319 TGo4Slot *widgslot = !slot ? nullptr : slot->FindChild(name);
2320 if (!widgslot) return nullptr;
2321
2322 TGo4WidgetProxy *wproxy = (TGo4WidgetProxy*) widgslot->GetProxy();
2323
2324 QGo4Widget *widg = wproxy->GetWidget();
2325 if (widg && activate) {
2326 if(!widg->isVisible()){
2327 widg->raise();
2328 widg->show();
2329 widg->setFocus();
2330 }
2331 }
2332
2333 return widg;
2334}
2335
2337{
2338 TGo4FitPanel *fitpanel = (TGo4FitPanel*) FindGo4Widget("FitPanel", true);
2339
2340 if (!fitpanel) {
2341 fitpanel = new TGo4FitPanel(fxMdiArea,"FitPanel");
2342 QMdiSubWindow* sub = fxMdiArea->AddGo4SubWindow(fitpanel);
2343 CascadeMdiPosition(sub);
2344 ConnectGo4Widget(fitpanel);
2345 fitpanel->ensurePolished();
2346 sub->show();
2347 } else {
2348 fitpanel->parentWidget()->showNormal();
2349 fitpanel->setFocus();
2350 }
2351 return fitpanel;
2352}
2353
2355{
2356 TGo4HistogramInfo* hinfo = (TGo4HistogramInfo*) FindGo4Widget("HistogramInfo", true);
2357 if (!hinfo) {
2358 hinfo = new TGo4HistogramInfo(fxMdiArea, "HistogramInfo");
2359 QMdiSubWindow* sub = fxMdiArea->AddGo4SubWindow(hinfo);
2360 CascadeMdiPosition(sub);
2361 ConnectGo4Widget(hinfo);
2362 hinfo->ensurePolished();
2363 hinfo->adjustSize();
2364 sub->show();
2365 }
2366 return hinfo;
2367}
2368
2370{
2371 TGo4ConditionInfo* cinfo = (TGo4ConditionInfo*) FindGo4Widget("ConditionInfo", true);
2372 if (!cinfo) {
2373 cinfo = new TGo4ConditionInfo(fxMdiArea, "ConditionInfo");
2374 QMdiSubWindow* sub = fxMdiArea->AddGo4SubWindow(cinfo);
2375 CascadeMdiPosition(sub);
2376 ConnectGo4Widget(cinfo);
2377 cinfo->ensurePolished();
2378 cinfo->adjustSize();
2379 sub->show();
2380 }
2381 return cinfo;
2382}
2383
2385{
2386 TGo4LoadedLibraries llib(this);
2387 llib.exec();
2388
2389 UpdateBrowser();
2390}
2391
2393{
2394 TGo4Browser* br = (TGo4Browser*) FindGo4Widget("Browser", false);
2395 if (br) br->ShootUpdateTimer();
2396}
2397
2399{
2400 TGo4ParaEdit* pedit = (TGo4ParaEdit*) FindGo4Widget("ParaEdit", true);
2401
2402 if (itemname) {
2403 TClass *cl = Browser()->ItemClass(itemname);
2404 if (cl)
2405 if (!cl->IsLoaded()) {
2406 QMessageBox::warning(nullptr, "Parameter editor", QString("Cannot start parameter editor for incomplete class ") + cl->GetName());
2407 return pedit;
2408 }
2409 }
2410
2411 if (!pedit) {
2412 pedit = new TGo4ParaEdit(fxMdiArea, "ParaEdit");
2413 QMdiSubWindow* sub = fxMdiArea->AddGo4SubWindow(pedit);
2414 ConnectGo4Widget(pedit);
2415 pedit->ensurePolished();
2416 sub->show();
2417 CascadeMdiPosition(sub);
2418 }
2419
2420 if (itemname)
2421 pedit->WorkWithParameter(itemname, false);
2422
2423 return pedit;
2424}
2425
2427{
2428 TGo4EditDynEntry* dedit = (TGo4EditDynEntry*) FindGo4Widget("EditDynEntry", true);
2429
2430 if (!dedit) {
2431 dedit = new TGo4EditDynEntry(fxMdiArea, "EditDynEntry");
2432 QMdiSubWindow* sub = fxMdiArea->AddGo4SubWindow(dedit);
2433 CascadeMdiPosition(sub);
2434 ConnectGo4Widget(dedit);
2435 dedit->ensurePolished();
2436 sub->show();
2437 }
2438
2439 return dedit;
2440}
2441
2443{
2444 TGo4ConditionEditor* wedit = (TGo4ConditionEditor*) FindGo4Widget("ConditionEditor", true);
2445 if (!wedit) {
2446 wedit = new TGo4ConditionEditor(fxMdiArea, "ConditionEditor");
2447 QMdiSubWindow* sub = fxMdiArea->AddGo4SubWindow(wedit);
2448 CascadeMdiPosition(sub);
2449 ConnectGo4Widget(wedit);
2450 wedit->ensurePolished();
2451 sub->show();
2452 }
2453 return wedit;
2454}
2455
2457{
2458 TGo4EventInfo* einfo = (TGo4EventInfo*) FindGo4Widget("EventInfo", true);
2459
2460 if (!einfo) {
2461 einfo = new TGo4EventInfo(fxMdiArea, "EventInfo");
2462 QMdiSubWindow* sub = fxMdiArea->AddGo4SubWindow(einfo);
2463 CascadeMdiPosition(sub);
2464 ConnectGo4Widget(einfo);
2465 einfo->ensurePolished();
2466 sub->show();
2467 }
2468
2469 return einfo;
2470}
2471
2476
2478{
2480 QWidget *mdi = conf ? conf->parentWidget() : nullptr;
2481
2482 if (!mdi)
2483 return;
2484
2485 if (mdi->isVisible()) {
2486 mdi->hide();
2487 } else {
2488 if (conf->GetNumSteps() == 0) {
2489 // this can happen when gui connected to server without requesting the setup. Do it when user wants to see
2490 // config:
2491 TGo4ServerProxy *anal = Browser()->FindServer();
2492 if (anal)
2494 }
2495 mdi->raise();
2496 mdi->show();
2497 if (mdi->isMinimized())
2498 mdi->showNormal();
2499 }
2500}
2501
2503{
2504 return (TGo4AnalysisWindow *) FindGo4Widget("AnalysisWindow", false);
2505}
2506
2508{
2510 if (!anw) return;
2511
2512 if (anw->HasOutput()) {
2513 QWidget *mdi = anw->parentWidget();
2514
2515 if (mdi->isVisible()) {
2516 mdi->hide();
2517 } else {
2518 mdi->raise();
2519 mdi->show();
2520 if (mdi->isMinimized()) mdi->showNormal();
2521 }
2522 } else {
2523 QToolBar* dock = dynamic_cast<QToolBar*> (anw->parentWidget());
2524 if (dock->isVisible())
2525 dock->hide();
2526 else
2527 dock->show();
2528 }
2529}
2530
2532{
2534
2535 if (anw) {
2536 if (anw->HasOutput()) {
2537 anw->parentWidget()->close();
2538 } else {
2539 QToolBar* bar = dynamic_cast<QToolBar*> (anw->parentWidget());
2540 removeToolBar(bar);
2541 delete bar;
2542 }
2543 }
2544
2545 // try to reestablish window for other server
2546 QTimer::singleShot(250, [this]() { EstablishAnalysisWindowForHttp(); });
2547}
2548
2549
2550void TGo4MainWindow::ToggleMbsMonitor(const char *nodename)
2551{
2552 TGo4MBSViewer *mbs = dynamic_cast<TGo4MBSViewer *>(FindGo4Widget("MBSViewer", false));
2553 if (!mbs)
2554 return;
2555 if (mbs->parentWidget()->isVisible()) {
2556 mbs->parentWidget()->hide();
2557 } else {
2558 mbs->SetNode(nodename);
2559 mbs->parentWidget()->show();
2560 }
2561}
2562
2564{
2565 TGo4SetScaleValues* scl = nullptr;
2566
2567 QList<QMdiSubWindow *> windows = fxMdiArea->subWindowList();
2568 for (int i = 0; i < windows.count(); ++i) {
2569 scl = dynamic_cast<TGo4SetScaleValues *>(windows.at(i)->widget());
2570 if (scl) break;
2571 }
2572
2573 if (!scl) {
2574 scl = new TGo4SetScaleValues(fxMdiArea, "ScaleValues", Qt::WindowStaysOnTopHint);
2575 QMdiSubWindow* sub = fxMdiArea->AddGo4SubWindow(scl);
2576 CascadeMdiPosition(sub);
2577 scl->ensurePolished();
2578 sub->show();
2579 } else {
2580 scl->parentWidget()->close();
2581 scl = nullptr;
2582 }
2583 return scl;
2584}
2585
2587{
2588 TGo4CreateNewHistogram dlg(this);
2590
2591 dlg.SetAnalysisAvaliable((isremote != 0) && an && an->IsAnalysisSettingsReady());
2592 dlg.SetLocalAvaliable(isremote != 1);
2593
2594 if (dlg.exec() != QDialog::Accepted) return;
2595 TH1 *h1 = dlg.MakeHistogram();
2596 if (!h1) return;
2597
2599
2600 if (dlg.GetSelectedCmd()==1) {
2601 TString newitem = Browser()->SaveToMemory("", h1, kTRUE);
2602
2603 if (newitem.Length()>0)
2606 newitem.Data(), h1->IsA());
2607 h1 = nullptr;
2608 } else
2609 if ((dlg.GetSelectedCmd() == 2) && an) {
2610 h1->SetBit(TGo4Status::kGo4CanDelete);
2611 an->UpdateAnalysisObject("", h1);
2612 if (anw) anw->WaitForNewObject(isremote==1);
2613 else an->RefreshNamesList();
2614 }
2615 if (h1) delete h1;
2616}
2617
2618void TGo4MainWindow::CreateNewCondition(bool forothereditor)
2619{
2621 if (!an || !an->IsAnalysisSettingsReady()) {
2622 QMessageBox::information(this,"Create new condition","Cannot create new condition before analysis setup");
2623 return;
2624 }
2625
2626 TGo4CreateNewCondition dlg(this);
2627
2628 if (dlg.exec() != QDialog::Accepted) return;
2629
2630 TGo4Condition *cond = dlg.MakeCondition();
2631 if (!cond) return;
2632
2633 cond->SetBit(TGo4Status::kGo4CanDelete);
2634 an->UpdateAnalysisObject("", cond);
2635 delete cond;
2636
2638 if(anw) anw->WaitForNewObject(forothereditor);
2639 else an->RefreshNamesList();
2640}
2641
2642void TGo4MainWindow::CreateNewDynEntry(bool forothereditor)
2643{
2645 if (!an || !an->IsAnalysisSettingsReady()) {
2646 QMessageBox::information(this,"Create new dynamic entry","Cannot create new entry before analysis setup");
2647 return;
2648 }
2649
2650 TGo4CreateNewDynEntry dlg(this);
2651
2652 if (dlg.exec() != QDialog::Accepted) return;
2653
2654 TGo4DynamicEntry *entry = dlg.MakeEntry();
2655 if (!entry) return;
2656
2657 entry->SetBit(TGo4Status::kGo4CanDelete);
2658 an->UpdateAnalysisObject("", entry);
2659 delete entry;
2660
2662 if (anw) anw->WaitForNewObject(forothereditor);
2663 else an->RefreshNamesList();
2664}
2665
2667{
2668 if (!editor) return;
2669 QObject::connect(editor, &QGo4Widget::widgetService, this, &TGo4MainWindow::editorServiceSlot);
2670 GetWidgetTopSlot(editor, true);
2671}
2672
2673TGo4ViewPanel *TGo4MainWindow::DisplayBrowserItem(const char *itemname, TGo4ViewPanel *panel, TPad *pad, bool activate, int updatelevel, const char *drawopt)
2674{
2675 TGo4BrowserProxy *br = Browser();
2676 if (!br || !itemname || strlen(itemname) == 0) return nullptr;
2677
2678 TGo4Slot *guislot = br->BrowserSlot(itemname);
2679
2680 if (!guislot) return nullptr;
2681 if (!guislot->GetProxy()) {
2682 std::cerr << " Problem with gui slots" << std::endl;
2683 return nullptr;
2684 }
2685
2686 if (!panel) {
2687 panel = MakeNewPanel();
2688 pad = panel->GetCanvas();
2689 } else if (!pad)
2690 pad = panel->GetActivePad();
2691
2692 if (!panel->AddDrawObject(pad, TGo4ViewPanel::kind_Link, itemname, nullptr, false, drawopt)) return nullptr;
2693
2694 if (activate) {
2695 panel->SetActivePad(pad);
2696 panel->ShootRepaintTimer();
2697 }
2698
2699 if (updatelevel < 0) {
2700 if (go4sett->getFetchDataWhenDraw())
2701 updatelevel = 2;
2702 else
2703 updatelevel = 1;
2704 }
2705
2706 br->GetBrowserObject(itemname, updatelevel);
2707
2708 return panel;
2709}
2710
2711bool TGo4MainWindow::SaveBrowserItemToFile(const char *itemname, const char *subfolder)
2712{
2713 TGo4BrowserProxy *br = Browser();
2714 if (!br || !itemname) return false;
2715
2716 TString fileslotname;
2717 const char *filepath = nullptr;
2718
2719 bool res = false;
2720
2721 if (br->DefineFileObject(itemname, fileslotname, &filepath)) {
2722 QMessageBox msgBox(QMessageBox::Question, "Writing object to file",
2723 QString("Overwrite ") + filepath + " in file " + fileslotname.Data());
2724 auto btnOverwrite = msgBox.addButton("Overwrite", QMessageBox::ActionRole);
2725 /* auto btnOther = */ msgBox.addButton("Save to other file", QMessageBox::ActionRole);
2726 auto btnCancel = msgBox.addButton("Cancel", QMessageBox::RejectRole);
2727 msgBox.setDefaultButton(btnOverwrite);
2728 msgBox.exec();
2729 if (msgBox.clickedButton() == btnCancel)
2730 return false;
2731 if (msgBox.clickedButton() == btnOverwrite)
2732 res = br->UpdateObjectInFile(itemname, fileslotname.Data(), filepath);
2733 }
2734
2735 if (!res) {
2736 QString root_fmt = "ROOT (*.root)";
2737 QString xml_fmt = "ROOT XML (*.xml)";
2738
2739 QFileDialog fd(this, QString("Save ") + itemname + " in root file", fLastFileDir);
2740 fd.setFileMode(QFileDialog::AnyFile);
2741 fd.setAcceptMode(QFileDialog::AcceptSave);
2742 fd.setNameFilters(QStringList() << root_fmt << xml_fmt);
2743
2744 if (fd.exec() == QDialog::Accepted) {
2745 QStringList flst = fd.selectedFiles();
2746 if (!flst.isEmpty()) {
2747 QString filename = flst[0];
2748 if (fd.selectedNameFilter()==xml_fmt) {
2749 if (!filename.endsWith(".xml")) filename.append(".xml");
2750 } else {
2751 if (!filename.endsWith(".root")) filename.append(".root");
2752 }
2753 res = br->SaveItemToFile(itemname, filename.toLatin1().constData(), subfolder);
2754 fLastFileDir = fd.directory().path();
2755 }
2756 }
2757 }
2758
2759 return res;
2760}
2761
2763{
2764 if (!panel) return;
2765
2766 TCanvas *can = panel->GetCanvas();
2767
2768 QFileDialog fd( this, QString("Save ") + panel->objectName() + " As", fLastFileDir);
2769 fd.setFileMode( QFileDialog::AnyFile );
2770 fd.setAcceptMode(QFileDialog::AcceptSave);
2771
2772 QString PS = "Post Script (*.ps)";
2773 QString PS_Portrait = "Post Script Portrait (*.ps)";
2774 QString PS_Landscape = "Post Script Landscape (*.ps)";
2775 QString EPS = "Encapsulated Post Script (*.eps)";
2776 QString EPS_Preview = "Encapsulated Post Script preview (*.eps)";
2777 QString GIF = "GIF format (*.gif)";
2778 QString PDF = "PDF format (*.pdf)";
2779 QString SVG = "SVG format (*.svg)";
2780 QString XPM = "XPM format (*.xpm)";
2781 QString PNG = "PNG format (*.png)";
2782 QString JPG = "JPG format (*.jpg)";
2783 QString TIFF = "TIFF format (*.tiff)";
2784
2785 QString CXXM = "C++ Macro (*.C)";
2786 QString JSONM = "json file (*.json)";
2787 QString ROOTM = "root file (*.root)";
2788
2789 QStringList flt;
2790
2791 flt << PNG;
2792 flt << PDF;
2793 flt << JPG;
2794 flt << SVG;
2795 flt << CXXM;
2796 flt << ROOTM;
2797 flt << GIF;
2798
2799 flt << PS;
2800 flt << PS_Portrait;
2801 flt << PS_Landscape;
2802 flt << EPS;
2803 flt << EPS_Preview;
2804
2805 flt << XPM;
2806 flt << TIFF;
2807
2808 flt << JSONM;
2809
2810 fd.setNameFilters(flt);
2811
2812 QString filename0 = panel->objectName();
2813
2814 fd.selectFile(filename0 + ".png");
2815
2816 QObject::connect(&fd, &QFileDialog::filterSelected, [filename0, &fd](const QString &fltr) {
2817 QStringList flst = fd.selectedFiles();
2818 if (flst.size() > 1)
2819 return;
2820 if ((flst.size() == 1) && (flst[0].indexOf(filename0 + ".") != 0))
2821 return;
2822
2823 auto p = fltr.indexOf("(*."), p2 = fltr.lastIndexOf(")");
2824 fd.selectFile(filename0 + fltr.mid(p + 2, p2 - p - 2));
2825 });
2826
2827
2828 if (fd.exec() != QDialog::Accepted) return;
2829
2830 bool blankbg = go4sett->getSavePadWhiteBackground();
2831 if(blankbg) {
2832 can = (TCanvas *) panel->GetCanvas()->Clone();
2833 can->SetName("PrintoutPad");
2834 }
2835 QStringList flst = fd.selectedFiles();
2836 if (flst.isEmpty()) return;
2837
2838 QString filename = flst[0];
2839 QString filter = fd.selectedNameFilter();
2840
2841 fLastFileDir = fd.directory().path();
2842
2843 const char *opt = "ps";
2844
2845 if (filter == EPS) {
2846 opt = "eps";
2847 if (!filename.endsWith(".eps"))
2848 filename.append(".eps");
2849 } else if (filter == EPS_Preview) {
2850 opt = "Preview";
2851 if (!filename.endsWith(".eps"))
2852 filename.append(".eps");
2853 } else if (filter == PS) {
2854 opt = "ps";
2855 if (!filename.endsWith(".ps"))
2856 filename.append(".ps");
2857 } else if (filter == PS_Portrait) {
2858 opt = "Portrait";
2859 if (!filename.endsWith(".ps"))
2860 filename.append(".ps");
2861 } else if (filter == PS_Landscape) {
2862 opt = "Landscape";
2863 if (!filename.endsWith(".ps"))
2864 filename.append(".ps");
2865 } else if (filter == GIF) {
2866 opt = "gif";
2867 if (!filename.endsWith(".gif"))
2868 filename.append(".gif");
2869 } else if (filter == PDF) {
2870 opt = "pdf";
2871 if (!filename.endsWith(".pdf"))
2872 filename.append(".pdf");
2873 } else if (filter == SVG) {
2874 opt = "svg";
2875 if (!filename.endsWith(".svg"))
2876 filename.append(".svg");
2877 } else if (filter == XPM) {
2878 opt = "xpm";
2879 if (!filename.endsWith(".xpm"))
2880 filename.append(".xpm");
2881 } else if (filter == PNG) {
2882 opt = "png";
2883 if (!filename.endsWith(".png"))
2884 filename.append(".png");
2885 } else if (filter == JPG) {
2886 opt = "jpg";
2887 if (!filename.endsWith(".jpg"))
2888 filename.append(".jpg");
2889 } else if (filter == TIFF) {
2890 opt = "tiff";
2891 if (!filename.endsWith(".tiff"))
2892 filename.append(".tiff");
2893 } else if (filter == CXXM) {
2894 opt = "cxx";
2895 if (!filename.endsWith(".C"))
2896 filename.append(".C");
2897 } else if (filter == JSONM) {
2898 opt = "json";
2899 if (!filename.endsWith(".json"))
2900 filename.append(".json");
2901 } else if (filter == ROOTM) {
2902 opt = "root";
2903 if (!filename.endsWith(".root"))
2904 filename.append(".root");
2905 }
2906
2907 if(blankbg) {
2908 panel->ResetPadFillColors(can,0);
2909 gROOT->SetBatch(kTRUE); // force ROOT to make memory print of canvas instead of using actual window display for image formats.
2910 }
2911
2912 can->Print(filename.toLatin1().constData(), opt);
2913
2914 if(blankbg) {
2915 gROOT->SetBatch(kFALSE);
2916 delete can;
2917 }
2918}
2919
2921{
2922 return fxOM;
2923}
2924
2926{
2927 return (TGo4BrowserProxy *) fxOM->GetProxy(fOMBrowserPath.toLatin1().constData());
2928}
2929
2931{
2932 if (!widget) return nullptr;
2933
2934 QString EditorName = widget->objectName();
2935
2936 QString editorslotname = fOMEditorsPath;
2937 editorslotname += "/";
2938 editorslotname += EditorName;
2939 TGo4Slot *edslot = fxOM->GetSlot(editorslotname.toLatin1().constData());
2940 if (!edslot && force) {
2941 fxOM->AddProxy(fOMEditorsPath.toLatin1().constData(), new TGo4WidgetProxy(widget), EditorName.toLatin1().constData(), "Links for Go4 widget");
2942 edslot = fxOM->GetSlot(editorslotname.toLatin1().constData());
2943 }
2944 return edslot;
2945}
2946
2948{
2949 // block monitoring when start panel updates
2951
2952 fbPanelTimerActive = false;
2953
2954 // first check if active viewpanel need update its content
2955 TGo4ViewPanel *actpanel = fxMdiArea->GetActivePanel();
2956 if (actpanel && actpanel->IsRepaintTimerActive())
2957 actpanel->checkRepaintSlot();
2958
2959 if (fbPanelTimerActive) return;
2960
2961 // now check if any other panel should be repainted
2962 TGo4Slot *topslot = fxOM->GetSlot(fOMEditorsPath.toLatin1().constData());
2963 for (int n = 0; n < topslot->NumChilds(); n++) {
2964 TGo4Slot *subslot = topslot->GetChild(n);
2965
2966 TGo4WidgetProxy *wproxy =
2967 dynamic_cast<TGo4WidgetProxy*> (subslot->GetProxy());
2968 if (!wproxy) continue;
2969
2970 TGo4ViewPanel *panel =
2971 dynamic_cast<TGo4ViewPanel *> (wproxy->GetWidget());
2972
2973 if (panel && (panel != actpanel))
2974 if (panel->IsRepaintTimerActive()) {
2975 panel->checkRepaintSlot();
2976 if (fbPanelTimerActive) return;
2977 }
2978 }
2979
2980 // enable monitoring only when all drawing are finished
2982}
2983
2984void TGo4MainWindow::editorServiceSlot(QGo4Widget* editor, int serviceid, const char *str, void *par)
2985{
2986 if (!editor) return;
2987
2988 TGo4LockGuard lock;
2989
2990 TGo4Slot *edslot = GetWidgetTopSlot(editor, false);
2991 if (!edslot) return;
2992
2993 switch (serviceid) {
2995 QDragMoveEvent *event = (QDragMoveEvent *) par;
2996 if (!event || !event->mimeData()->hasText()) return;
2997
2998 QString eventstr = event->mimeData()->text();
2999
3000 bool accept = false;
3001 if (event->source() == FindGo4Widget("Browser",false)) {
3002 int kind = Browser()->ItemKind(eventstr.toLatin1().constData());
3003 TClass *cl = Browser()->ItemClass(eventstr.toLatin1().constData());
3004 accept = editor->IsAcceptDrag(eventstr.toLatin1().constData(), cl, kind);
3005 }
3006
3007 if (accept) event->acceptProposedAction();
3008 break;
3009 }
3010
3012 QDropEvent *event = (QDropEvent *) par;
3013
3014 if (!event || !event->mimeData()->hasText()) return;
3015
3016 QString eventstr = event->mimeData()->text();
3017 event->acceptProposedAction();
3018
3019 if (event->source() == FindGo4Widget("Browser",false)) {
3020 int kind = Browser()->ItemKind(eventstr.toLatin1().constData());
3021 TClass *cl = Browser()->ItemClass(eventstr.toLatin1().constData());
3022
3023 auto panel = dynamic_cast<TGo4ViewPanel *>(editor);
3024 auto fitpanel = dynamic_cast<TGo4FitPanel *>(editor);
3025 if (panel)
3026 panel->DropOnPad((TPad *)str, eventstr.toLatin1().constData(), cl, kind);
3027 else if (fitpanel)
3028 fitpanel->DropOnPanel(event, eventstr.toLatin1().constData(), cl, kind);
3029 else
3030 editor->DropItem(eventstr.toLatin1().constData(), cl, kind);
3031 }
3032 break;
3033 }
3034
3036 TClass *cl = (TClass *) par;
3037 int id = str ? QString(str).toInt() : 0;
3038 if (cl) {
3039 if (cl->InheritsFrom(TH1::Class()))
3040 CreateNewHist(id);
3041 else if (cl->InheritsFrom(TGo4Condition::Class()) && (id != 0))
3042 CreateNewCondition(id==1);
3043 else if (cl->InheritsFrom(TGo4DynamicEntry::Class()) && (id != 0))
3044 CreateNewDynEntry(id==1);
3045 }
3046 break;
3047 }
3049 void ** res = (void **) par;
3050 res[0] = DisplayBrowserItem(str, (TGo4ViewPanel *) res[0], (TPad *) res[1], *((bool *)res[2]), *((int *) res[3]), nullptr);
3051 break;
3052 }
3053
3055 TGo4ViewPanel **res = (TGo4ViewPanel **) par;
3056 *res = nullptr;
3057 TGo4Slot *topslot = fxOM->GetSlot(fOMEditorsPath.toLatin1().constData());
3058 for (int n = 0; n < topslot->NumChilds(); n++) {
3059 TGo4Slot *subslot = topslot->GetChild(n);
3060
3061 TGo4WidgetProxy *wproxy =
3062 dynamic_cast<TGo4WidgetProxy *> (subslot->GetProxy());
3063 if (!wproxy) continue;
3064
3065 TGo4ViewPanel *panel =
3066 dynamic_cast<TGo4ViewPanel *> (wproxy->GetWidget());
3067
3068 if (panel)
3069 if (panel->FindPadWithItem(str)) {
3070 *res = panel;
3071 break;
3072 }
3073 }
3074 break;
3075 }
3076
3078 TGo4Slot *topslot = fxOM->GetSlot(fOMEditorsPath.toLatin1().constData());
3079
3080 for (int n = 0; n < topslot->NumChilds(); n++) {
3081 TGo4Slot *subslot = topslot->GetChild(n);
3082
3083 auto wproxy = dynamic_cast<TGo4WidgetProxy *> (subslot->GetProxy());
3084 if (!wproxy) continue;
3085
3086 auto panel = dynamic_cast<TGo4ViewPanel *> (wproxy->GetWidget());
3087 if (panel)
3088 panel->UndrawItemOnPanel(str);
3089 }
3090
3091 break;
3092 }
3093
3095 TClass *cl = Browser()->ItemClass(str);
3096 Int_t kind = Browser()->ItemKind(str);
3097
3098 if (kind == TGo4Access::kndGo4Param) {
3099 StartParaEdit(str);
3100 break;
3101 } else if (kind==TGo4Access::kndTreeLeaf) {
3102 TGo4TreeViewer* tviewer =
3103 dynamic_cast<TGo4TreeViewer*> (FindGo4Widget("TreeViewer", false));
3104 if (tviewer) {
3105 tviewer->WorkWithLeaf(str);
3106 tviewer->parentWidget()->show();
3107 }
3108 break;
3109 }
3110
3111 if (!cl) return;
3112
3113 if (cl->InheritsFrom(TGo4Fitter::Class())) {
3114 TGo4FitPanel *fitpanel = StartFitPanel();
3115 TGo4ViewPanel *panel = dynamic_cast<TGo4ViewPanel *> (editor);
3116 fitpanel->WorkWithFitter(str, panel, !panel ? nullptr : panel->GetActivePad());
3117 } else if (cl->InheritsFrom(TGo4Parameter::Class())) {
3118 StartParaEdit(str);
3119 } else if (cl->InheritsFrom(TH1::Class())) {
3120 auto hinfo = StartHistogramInfo();
3121 hinfo->WorkWithHistogram(str);
3122 } else if (cl->InheritsFrom(TGo4Condition::Class())) {
3123 auto wedit = StartConditionEditor();
3124 wedit->WorkWithCondition(str);
3125 } else if (cl->InheritsFrom(TGo4DynamicEntry::Class())) {
3126 auto dedit = StartEditDynEntry();
3127 dedit->WorkWithEntry(str);
3128 } else if (cl->InheritsFrom(TGo4AnalysisStatus::Class())) {
3129 // use central editor, later can control many analysis at once
3131 }
3132
3133 break;
3134 }
3135
3137 TClass *cl = Browser()->ItemClass(str);
3138 int kind = Browser()->ItemKind(str);
3139 if (kind == TGo4Access::kndEventElement) {
3140 TGo4EventInfo* einfo = StartEventInfo();
3141 einfo->WorkWithEvent(str);
3142 break;
3143 }
3144 if (!cl) return;
3145 if (cl->InheritsFrom(TH1::Class())) {
3147 hinfo->WorkWithHistogram(str);
3148 } else if (cl->InheritsFrom(TGo4Condition::Class())) {
3150 cinfo->WorkWithCondition(str);
3151 }
3152 break;
3153 }
3154
3156 TGo4Slot *slot = (TGo4Slot *) par;
3157 if (!slot) break;
3158 TObject *obj = slot->GetAssignedObject();
3159 if (!obj) break;
3160 if (obj->InheritsFrom(TGo4Fitter::Class())) {
3161 TGo4FitPanel* fitpanel = StartFitPanel();
3162 fitpanel->WorkWithFitterInSlot(slot);
3163 }
3164 break;
3165 }
3166
3168 const char *subfolder = (const char *) par;
3169 bool res = SaveBrowserItemToFile(str, subfolder);
3170 *((char *) par) = res ? 1 : 0;
3171 break;
3172 }
3173
3175 TObject **obj = (TObject **) par;
3176 Bool_t res = Browser()->UpdateAnalysisItem(str, *obj);
3177 *obj = res ? (TObject *) 1 : nullptr;
3178 break;
3179 }
3180
3182 StatusMessage(str);
3183 break;
3184 }
3185
3187 TGo4ViewPanel **res = (TGo4ViewPanel **) par;
3188 *res = MakeNewPanel(QString(str).toInt());
3189 break;
3190 }
3191
3193 bool* res = (bool*) par;
3194 *res = Browser()->IsItemRemote(str);
3195 break;
3196 }
3197
3199 TGo4BrowserProxy **res = (TGo4BrowserProxy **) par;
3200 *res= Browser();
3201 break;
3202 }
3203
3205 TObject **obj = (TObject **) par;
3206 TString itemname = Browser()->SaveToMemory(str, *obj, true);
3207 QString **res = (QString **) par;
3208 *res = nullptr;
3209 if (itemname.Length() > 0)
3210 *res = new QString(itemname.Data());
3211 break;
3212 }
3213
3215 TGo4ServerProxy ** res = (TGo4ServerProxy **) par;
3216 *res = Browser()->FindServer(str);
3217 break;
3218 }
3219
3221 TGo4Slot *brslot = Browser()->BrowserSlot((const char *)par);
3222
3223 QByteArray ba = editor->objectName().toLatin1();
3224
3225 if (!str) str = ba.constData();
3226
3227 TGo4Slot *link = fxOM->AddLink(brslot, edslot->GetFullName(),
3228 str, "link to browser item");
3229 if (link)
3230 editor->SetLinkedName(link, (const char *)par);
3231
3232 break;
3233 }
3234
3236 QByteArray ba = editor->objectName().toLatin1();
3237 if (!str) str = ba.constData();
3238 TGo4Slot *slot = (TGo4Slot *) par;
3239 if (slot)
3240 fxOM->AddLink(slot, edslot->GetFullName(), str, "direct link to OM slot");
3241 break;
3242 }
3243
3245 TGo4Slot **res = (TGo4Slot **) par;
3246
3247 TGo4Slot *parent = *res;
3248 *res = nullptr;
3249 if (!parent) parent = edslot;
3250 TGo4Slot *brslot = Browser()->BrowserSlot(str);
3251
3252 if (brslot) {
3253 *res = fxOM->AddLink(brslot, parent->GetFullName(),
3254 brslot->GetName(), "link in specific subfolder");
3255 if (*res)
3256 editor->SetLinkedName(*res, str);
3257 }
3258 break;
3259 }
3260
3262 TGo4Slot **res = (TGo4Slot **) par;
3263 *res = edslot;
3264 break;
3265 }
3266
3268 TGo4Slot *objslot = edslot->FindChild(str);
3269
3270 if (!objslot)
3271 objslot = fxOM->MakeObjSlot(edslot->GetFullName(), str, "Place for editor object");
3272 if (objslot)
3273 objslot->SetProxy(new TGo4ObjectProxy);
3274
3275 TGo4Slot **res = (TGo4Slot **)par;
3276 *res = objslot;
3277 break;
3278 }
3279
3282 break;
3283 }
3284
3286 if (!edslot) return;
3287 const char **res = (const char **) par;
3288 *res = TGo4BrowserProxy::GetLinkedName(edslot->FindChild(str));
3289 break;
3290 }
3291
3293 void ** res = (void **) par;
3294 TGo4Slot *link = (TGo4Slot *) *res;
3295 *res = (void *) TGo4BrowserProxy::GetLinkedName(link);
3296 break;
3297 }
3298
3302 if (!edslot) return;
3303 TGo4Slot *link = edslot->FindChild(str);
3304 if (!link) return;
3305 const char *itemname = TGo4BrowserProxy::GetLinkedName(link);
3306 TObject **res = (TObject **) par;
3307 int updatelevel = serviceid - QGo4Widget::service_GetLinked0;
3308 if (itemname)
3309 *res = Browser()->GetBrowserObject(itemname, updatelevel);
3310 else
3311 *res = link->GetAssignedObject();
3312 break;
3313 }
3314
3316 if (!edslot) return;
3317 TGo4Slot *link = edslot->FindChild(str);
3318 if (link) link->Delete();
3319 break;
3320 }
3321
3323 if (!str || (strcmp(str,"complete") != 0))
3324 edslot->DeleteChilds(str);
3325 else
3326 edslot->Delete();
3327 break;
3328 }
3329
3331 TGo4Slot *slot = fxOM->GetSlot(fOMEditorsPath.toLatin1().constData());
3332 for (int n = 0; n < slot->NumChilds(); n++) {
3333 TGo4Slot *subslot = slot->GetChild(n);
3334 if (edslot == subslot)
3335 continue;
3336
3337 TGo4WidgetProxy *wproxy = dynamic_cast<TGo4WidgetProxy *>(subslot->GetProxy());
3338
3339 if (wproxy)
3340 wproxy->GetWidget()->ObjectCreatedByWidget(str, (TClass *)par);
3341 }
3342 break;
3343 }
3344
3346 if (!edslot) break;
3347
3348 TGo4WidgetProxy* proxy =
3349 dynamic_cast<TGo4WidgetProxy *> (edslot->GetProxy());
3350 if (proxy)
3351 proxy->ConnectPad((TPad *) par);
3352 break;
3353 }
3354
3356 TGo4ViewPanel **res = (TGo4ViewPanel **) par;
3357 *res = fxMdiArea->GetActivePanel();
3358 break;
3359 }
3360
3362 if (strcmp(str,"CloseAnalysisWindow") == 0) {
3363 // we should postpone window closing, while it is called from inside window itself
3364 // and it is create problem in sequence,
3365 QTimer::singleShot(100, this, &TGo4MainWindow::CloseAnalysisWindow);
3366 } else if (strcmp(str,"PrintAnalysisHistograms") == 0) {
3367 auto anw = FindAnalysisWindow();
3368 if (anw) anw->PrintHistograms();
3369 } else if (strcmp(str,"PrintAnalysisConditions") == 0) {
3370 auto anw = FindAnalysisWindow();
3371 if (anw) anw->PrintConditions();
3372 } else if (strcmp(str,"DisplayMbsMonitor") == 0) {
3373 ToggleMbsMonitor((const char *) par);
3374 } else if (strcmp(str,"SubmitAnalysisSettings") == 0) {
3376 } else if (strcmp(str,"CloseAnalysisSettings") == 0) {
3377 auto anal = Browser()->FindServer();
3378 if (anal) {
3379 anal->CloseAnalysisSettings();
3380 anal->RefreshNamesList();
3381 }
3382 } else if (strcmp(str,"SubmitStartAnalysis") == 0) {
3384 } else if (strcmp(str,"StartAnalysis") == 0) {
3386 } else if (strcmp(str,"StopAnalysis") == 0) {
3388 } else if (strcmp(str,"TerminateAnalysis") == 0) {
3389 TerminateAnalysis(true);
3390 } else if (strcmp(str,"UpdateGuiLayout") == 0) {
3392 } else if (strcmp(str, "StartEventInfo") == 0) {
3394 } else if(strcmp(str, "ActivateConditionEditor") == 0) {
3396 (TGo4ConditionEditor*) FindGo4Widget("ConditionEditor", true);
3397 if (w) {
3398 w->setFocus();
3399 w->RefreshWidget(true);
3400 }
3401 } else if (strcmp(str, "SavePanelCanvas") == 0) {
3402 SavePanelCanvas(dynamic_cast<TGo4ViewPanel *>(editor));
3403 } else if (strcmp(str, "ToggleScaleValues") == 0) {
3405 } else if (strcmp(str, "GetFitterFromFitPanel") == 0) {
3406 TGo4FitPanel *panel = (TGo4FitPanel *) FindGo4Widget("FitPanel", false);
3407 TGo4Fitter **res = (TGo4Fitter **) par;
3408 if (panel && res)
3409 *res = panel->GetFitter();
3410 } else if (strcmp(str, "CloneFitterFromFitPanel") == 0) {
3411 auto panel = (TGo4FitPanel *) FindGo4Widget("FitPanel", false);
3412 TGo4Fitter **res = (TGo4Fitter **) par;
3413 if (panel && res)
3414 *res = panel->CloneFitter();
3415 }
3416
3417 break;
3418 }
3419
3421 // TGo4ViewPanel *panel = (TGo4ViewPanel *) editor;
3422 if (!fbPanelTimerActive) {
3423 fbPanelTimerActive = true;
3424 QTimer::singleShot(0, this, &TGo4MainWindow::checkPanelRepaintSlot);
3425 }
3426
3427 break;
3428 }
3429
3431 HelpWindow(str, (const char *) par);
3432 break;
3433 }
3434
3436 HotStart(str);
3437 break;
3438 }
3439
3446 TGo4ViewPanel *panel = (TGo4ViewPanel *) editor;
3447 TPad *pad = (TPad *) par;
3448 fxMdiArea->ResponseOnPanelEvent(serviceid, panel, pad);
3449 break;
3450 }
3451
3452 }
3453}
3454
3455// ******************** hot start functions *********************
3456
3457void TGo4MainWindow::HotStart(const char *fname)
3458{
3459 if (!fname) return;
3460
3462 if(!exec) return;
3463
3464 if (!exec->StartScriptExecution(fname)) return;
3465
3467}
3468
3470{
3472 if (!exec) return;
3473
3474 Bool_t res = kTRUE;
3475 do {
3476 res = exec->ContinueExecution();
3477 } while(res && !exec->IsWaitSomething());
3478
3479 if (res) {
3481 if (!QApplication::overrideCursor())
3482 QApplication::setOverrideCursor(Qt::WaitCursor);
3483 } else {
3484 exec->FinishExecution();
3485 StatusMessage("Script execution done");
3486 QApplication::restoreOverrideCursor();
3487 }
3488}
3489
3491{
3493 if (exec) exec->FinishExecution();
3494}
3495
3497{
3499 QString fileName =
3500 QFileDialog::getSaveFileName(this,
3501 "Create GUI script dialog",
3503 QString("GUI hotstart script (*") + ext + ")");
3504 if (fileName.isEmpty()) return;
3505
3506 int pos = fileName.indexOf(ext);
3507
3508 if ((pos<0) || (pos!=fileName.length()-ext.length()))
3509 fileName+=ext;
3510
3511 StatusMessage(QString("Generate script ")+fileName);
3512
3513 TGo4Script::ProduceScript(fileName.toLatin1().constData(), this);
3514}
3515
3517{
3518 QToolBar* AnalysisMacroBar = addToolBar("Analysis Command Buttons");
3519 AnalysisMacroBar->setObjectName("AnalysisCommandToolBar");
3520
3521 // new: everything is in dedicated class
3522 TGo4UserCommands* companel = new TGo4UserCommands(this, "UserCommands");
3523 ConnectGo4Widget(companel);
3524 AnalysisMacroBar->addWidget(companel);
3525 AnalysisMacroBar->adjustSize();
3526}
3527
3529{
3530 if (fApp) fApp->processEvents(QEventLoop::AllEvents, TGo4AbstractInterface::DelayMillisec());
3531}
3532
3534{
3535 if (!name || !*name) return nullptr;
3536
3537 TGo4ViewPanel *panel = dynamic_cast<TGo4ViewPanel *> (FindGo4Widget(name, false));
3538
3539 if (panel) return panel;
3540
3541 TGo4Slot *slot = fxOM->GetSlot(fOMEditorsPath.toLatin1().constData());
3542
3543 for (Int_t n = 0; n < slot->NumChilds(); n++) {
3544 TGo4Slot *widgslot = slot->GetChild(n);
3545 TGo4WidgetProxy *wproxy = !widgslot ? nullptr : dynamic_cast<TGo4WidgetProxy *>(widgslot->GetProxy());
3546 panel = !wproxy ? nullptr : dynamic_cast<TGo4ViewPanel *>(wproxy->GetWidget());
3547
3548 if (panel)
3549 if (strcmp(panel->GetPanelName(), name) == 0)
3550 return panel;
3551 }
3552
3553 return nullptr;
3554}
void *(* TStartUserGuiFunc)(QWidget *parent)
#define CtrlKey(key)
TGo4QSettings * go4sett
#define __GO4RELEASE__
Definition TGo4Version.h:25
void widgetService(QGo4Widget *editor, int serviceid, const char *str, void *par)
@ service_WhereItemDrawn
Definition QGo4Widget.h:84
@ service_UndrawItem
Definition QGo4Widget.h:85
@ service_UpdateAnalysisItem
Definition QGo4Widget.h:61
@ service_PanelTimer
Definition QGo4Widget.h:87
@ service_ShowInfo
Definition QGo4Widget.h:58
@ service_GetLinked2
Definition QGo4Widget.h:78
@ service_EditItem
Definition QGo4Widget.h:57
@ service_HotStart
Definition QGo4Widget.h:89
@ service_CreateViewPanel
Definition QGo4Widget.h:63
@ service_Browser
Definition QGo4Widget.h:65
@ service_EditInSlot
Definition QGo4Widget.h:59
@ service_General
Definition QGo4Widget.h:86
@ service_GetLinked0
Definition QGo4Widget.h:76
@ service_AddDirectLink
Definition QGo4Widget.h:69
@ service_RemoveLink
Definition QGo4Widget.h:79
@ panel_PadDeleted
Definition QGo4Widget.h:94
@ service_GetLinked1
Definition QGo4Widget.h:77
@ service_SaveToMemory
Definition QGo4Widget.h:66
@ panel_Activated
Definition QGo4Widget.h:90
@ service_HelpWindow
Definition QGo4Widget.h:88
@ service_GetTopSlot
Definition QGo4Widget.h:71
@ service_ConnectPad
Definition QGo4Widget.h:82
@ service_LastActivePanel
Definition QGo4Widget.h:83
@ service_AddLinkInSlot
Definition QGo4Widget.h:70
@ service_DropEvent
Definition QGo4Widget.h:54
@ service_SetLinkedName
Definition QGo4Widget.h:73
@ service_BrowserItemRemote
Definition QGo4Widget.h:64
@ service_CreateItem
Definition QGo4Widget.h:55
@ service_AddEditorSlot
Definition QGo4Widget.h:72
@ service_DrawItem
Definition QGo4Widget.h:56
@ service_GetLinkedName2
Definition QGo4Widget.h:75
@ service_GetAnalysis
Definition QGo4Widget.h:67
@ service_GetLinkedName
Definition QGo4Widget.h:74
@ service_SaveItem
Definition QGo4Widget.h:60
@ service_StatusMessage
Definition QGo4Widget.h:62
@ service_RemoveAllLinks
Definition QGo4Widget.h:80
@ service_AddEditorLink
Definition QGo4Widget.h:68
@ panel_ActiveUpdated
Definition QGo4Widget.h:93
@ service_ObjectCreated
Definition QGo4Widget.h:81
@ service_DragEnter
Definition QGo4Widget.h:53
static QAction * CreateChkAction(QMenu *menu, const QString &text, bool checked, bool enabled=true)
virtual bool IsAcceptDrag(const char *itemname, TClass *cl, int kind)
void SetLinkedName(TGo4Slot *slot, const char *itemname)
set name of item, which was linked by this slot
virtual void DropItem(const char *itemname, TClass *cl, int kind)
void ObjectCreatedByWidget(const char *itemname, TClass *cl)
void RemoveLink(const char *linkname, bool blockreset=true)
static Int_t DelayMillisec()
Default delay during hotstart file extension.
static const char * FileExtension()
Returns default hotstart file extension.
static void DeleteInstance()
Delete instance of interface class.
@ kndEventElement
Definition TGo4Proxy.h:41
virtual void WorkWithAnalysis(TGo4ServerProxy *anal)
Bool_t IsAdministrator() const override
Bool_t IsConnected() const override
Bool_t ConnectToServer(const char *remotehost, Int_t remoteport, Int_t ascontroller, const char *accesspass)
TGo4Slot * UpdateObjectSlot()
Bool_t IsAnalysisServer() const override
Bool_t LaunchAsClient(TString &launchcmd, TString &killcmd, Int_t shellkind, Int_t konsole, const char *name, const char *remotehost, const char *remotedir, const char *remoteexe, Int_t exe_kind=0, const char *exeargs=nullptr)
static Bool_t LaunchAsServer(TString &launchcmd, TString &killcmd, Int_t shellkind, Int_t konsole, const char *name, const char *remotehost, Int_t remoteport, const char *remotedir, const char *remoteexe, Int_t exe_kind=0, const char *exeargs=nullptr)
Bool_t IsController() const override
void SetDefaultReceiver(TGo4ObjectManager *rcv, const char *path)
Set receiver for object envelopes, which coming from analysis without request.
virtual void WorkWithRatemeter(TGo4Slot *slot)
static void ExtractProgArgs(QString &prog, QStringList &args)
bool TerminateOnClose() const
void AppendOutputBuffer(const QString &value, int prio=0)
void WorkWithUpdateObjectCmd(TGo4Slot *slot)
void WaitForNewObject(bool isobjectforeditor)
void StartAnalysisShell(const char *cmd, const char *workdir=nullptr, bool aschildprocess=false)
virtual void StartWorking()
void ImportObjectFromFile(const char *filename, const char *filedir, const char *format)
Bool_t SaveItemToFile(const char *itemname, const char *filename, const char *subfolder=nullptr)
TGo4AnalysisProxy * FindAnalysis(const char *itemname=nullptr)
static void SetLinkedName(TGo4Slot *slot, const char *itemname)
TGo4Slot * BrowserSlot(const char *item=nullptr)
TObject * GetBrowserObject(const char *name, Int_t update=0)
void ToggleMonitoring(Int_t period)
void CreateMemoryFolder(const char *foldername=nullptr)
TString SaveToMemory(const char *pathname, TObject *obj, Bool_t ownership, Bool_t overwrite=kFALSE)
Int_t ItemKind(const char *name)
TGo4Slot * DataSlot(const char *item)
Bool_t DefineFileObject(const char *itemname, TString &filedataslot, const char **filepath)
TGo4ServerProxy * FindServer(const char *itemname=nullptr, Bool_t asanalysis=kTRUE)
void SetMonitorBlockingFlag(Bool_t blocked=kFALSE)
Bool_t UpdateAnalysisItem(const char *itemname, TObject *obj=nullptr)
Bool_t IsItemRemote(const char *name)
static const char * GetLinkedName(TGo4Slot *slot)
TClass * ItemClass(const char *name)
void OpenFile(const char *fname)
Bool_t UpdateObjectInFile(const char *itemname, const char *fileslotname, const char *filepath)
void ShootUpdateTimer()
void StartWorking()
virtual void RefreshWidget(bool checkindex)
virtual void WorkWithCondition(const char *itemname)
Go4 condition class.
void setPassword(const char *pass)
TGo4DynamicEntry * MakeEntry()
static const char * GetDabcVersion()
ABC for all entries that can be kept in a dynamic list.
void WorkWithEvent(const char *itemname)
virtual void WorkWithFitter(const char *itemname, TGo4ViewPanel *panel, TPad *pad)
virtual void DropOnPanel(QDropEvent *event, const char *itemname, TClass *cl, int kind)
virtual TGo4Fitter * GetFitter()
virtual void WorkWithFitterInSlot(TGo4Slot *slot)
Central class of Go4Fit package.
Definition TGo4Fitter.h:38
virtual void WorkWithHistogram(const char *itemname)
Here Go4/ROOT-specific functionality of HttpProxy.
Bool_t IsAdministrator() const override
Bool_t IsConnected() const override
virtual void ClearLogInfo()
void WorkWithInfo(TGo4Slot *slot)
virtual void SaveLogInfo()
static TString subGO4SYS(const char *subdir)
Return subdirectory in the GO4SYS.
Definition TGo4Log.cxx:189
static Bool_t IsAutoEnabled()
get current user boolean
Definition TGo4Log.cxx:378
static const char * Message(Int_t prio, const char *text,...) GO4_PRINTF2_ARGS
Display a message.
Definition TGo4Log.cxx:206
static void SetIgnoreLevel(Int_t level)
Define threshold for output.
Definition TGo4Log.cxx:332
static void LogfileEnable(Bool_t on=kTRUE)
switch writing to logfile on or off
Definition TGo4Log.cxx:363
static void AutoEnable(Bool_t on=kTRUE)
set boolean for user action
Definition TGo4Log.cxx:373
static void OutputEnable(Bool_t on=kTRUE)
switch output on or off
Definition TGo4Log.cxx:353
static void OpenLogfile(const char *name=nullptr, const char *headercomment=nullptr, Bool_t appendmode=kFALSE)
Open file of name for logmessage output.
Definition TGo4Log.cxx:383
virtual void TimerStart()
virtual void SetNode(const QString &txt)
TGo4AnalysisWindow * EstablishAnalysisWindow(bool needoutput, bool withkillbnt=false, bool force_recreate=false)
TGo4BrowserProxy * Browser()
void CheckConnectingCounterSlot()
TGo4AnalysisConfiguration * FindAnalysisConfiguration()
void HotStart(const char *fname)
QAction * faDrawTime
bool RemoveAnalysisProxy(int waittime=30, bool servershutdown=false)
void SetStyleSlot(const QString &)
TGo4Style * fxStyle
TGo4FitPanel * StartFitPanel()
void StatusMessage(const QString &mess)
void ShowAboudDialog(const QString &title, const QString &text, const QString &icon)
void PrepareForClientConnection(bool interactive=true)
void ChangeDrawItemFlagSlot(bool)
QAction * faSuperimpose
TGo4EventInfo * StartEventInfo()
void ChangeNativeMenuBarSlot(bool)
void LaunchClient(bool interactive=true)
void TerminateAnalysis(bool interactive=true)
void CreateNewHist(int isremote=-1)
TGo4EditDynEntry * StartEditDynEntry()
QAction * faAnalTermin
void ChangeCloneFlagSlot(bool)
QAction * faDrawDate
virtual ~TGo4MainWindow()
TGo4ObjectManager * fxOM
TGo4MdiArea * fxMdiArea
QAction * faCrosshair
QAction * faConnectAnal
QGo4Widget * FindGo4Widget(const char *name, bool activate)
TGo4ViewPanel * FindViewPanel(const char *name)
QAction * faAnalConfig
TGo4HistogramInfo * StartHistogramInfo()
void DisconnectAnalysis(bool interactive=true)
TGo4AnalysisConfiguration * EstablishAnalysisConfiguration(int level)
void EstablishAnalysisWindowForHttp()
void ChangeFetchWhenSaveSlot(bool)
TGo4ParaEdit * StartParaEdit(const char *itemname=nullptr)
TGo4AnalysisStatusMonitor * EstablishRatemeter(int level)
QApplication * fApp
QAction * faPrepareAnal
void windowsMenuAboutToShow()
QAction * faEventstatus
void ChangeDrawDateFlagSlot(bool)
void ChangeWindowRubberBandSlot(bool)
void CreateNewDynEntry(bool forothereditor=false)
const char * LastTypedPassword() const
void CascadeMdiPosition(QWidget *sub)
void ChangeSaveWhiteBackgroundSlot(bool)
TGo4ConditionEditor * StartConditionEditor()
void ChangeDrawTimeFlagSlot(bool)
void CreateNewCondition(bool forothereditor=false)
void EventStatusSlot(bool)
void ChangeDrawOnceSlot(bool)
QAction * faStopAnal
QAction * faSumbStartAnal
void ConnectGo4Widget(QGo4Widget *editor)
TGo4ViewPanel * DisplayBrowserItem(const char *itemname, TGo4ViewPanel *panel, TPad *pad, bool activate, int updatelevel, const char *drawopt)
void ChangeFetchWhenCopySlot(bool)
void InputTerminalParametersSlot()
bool startUserGUI(const char *)
void UpdateDockAnalysisWindow()
QAction * faLaunchAnal
void HelpWindow(const char *filename, const char *msg=nullptr)
void SavePanelCanvas(TGo4ViewPanel *panel)
QAction * faShutdownAnal
TGo4Slot * GetWidgetTopSlot(QGo4Widget *widget, bool force)
TGo4ConditionInfo * StartConditionInfo()
void closeEvent(QCloseEvent *ce) override
QAction * faStartAnal
void SuperimposeSlot(bool)
void ChangeTerminalTimeStampSlot(bool)
TGo4ViewPanel * MakeNewPanel(int div=0)
TGo4MainWindow(QApplication *)
void WindowActivated(int id)
void ConnectServer(bool interactive=true, const char *password="")
bool SaveBrowserItemToFile(const char *itemname, const char *subfolder)
TGo4AnalysisProxy * AddAnalysisProxy(bool isserver, bool needoutput)
void ToggleMbsMonitor(const char *nodename)
void ChangeTerminalTimeStampFormatSlot()
TGo4ServerProxy * ConnectHttpServer(const char *addr=nullptr, const char *user=nullptr, const char *pass=nullptr, bool with_qt_process=false, bool get_analysis_config=false)
void ChangeFetchWhenDrawSlot(bool)
TGo4SetScaleValues * ToggleScaleValues()
QAction * faDisconnectAnal
void ShutdownAnalysis(bool interactive=true)
void editorServiceSlot(QGo4Widget *editor, int serviceid, const char *str, void *par)
QString fConnectingHttp
TGo4ObjectManager * OM()
TGo4AnalysisWindow * FindAnalysisWindow()
QAction * faDrawItem
void ChangeHideEventElement(bool)
void CrosshairSlot(bool)
void ToggleAnalysisConfiguration()
const QString & GetFileName()
const QString & GetFileType()
virtual void WorkWithParameter(const char *itemname, bool isrefresh)
Bool_t ContinueExecution()
static void ProduceScript(const char *filename, TGo4MainWindow *main)
TGo4ServerProxy * ConnectHttp(const char *servername, const char *account=nullptr, const char *pass=nullptr) override
Connect to HTTP server.
Bool_t IsWaitSomething() const
static TGo4Script * ScriptInstance()
Bool_t StartScriptExecution(const char *fname)
void FinishExecution()
special base class for remote data servers like DABC, HTTP, hist server
const char * GetContainedObjectInfo() override
Bool_t IsAnalysisSettingsReady() const
TGo4Slot * LoginfoSlot()
virtual Bool_t CanSubmitObjects() const
virtual Bool_t IsConnected() const
virtual void StartAnalysis()
virtual void StopAnalysis()
virtual Bool_t IsGo4Analysis() const
void SetAnalysisReady(Bool_t on=kTRUE)
virtual void RequestAnalysisSettings()
virtual Bool_t UpdateAnalysisObject(const char *objectname, TObject *obj)
Int_t IsAnalysisLaunched() const
virtual void DisconnectAnalysis(Int_t waittime=30, Bool_t servershutdown=kFALSE)
Close connection to analysis and destroys proxy with correspondent slot.
virtual Bool_t SubmitCommand(const char *name, Int_t waitres=-1, const char *arg1=nullptr, const char *arg2=nullptr, const char *arg3=nullptr)
void SetAnalysisLaunched(Int_t on=1)
virtual Bool_t DelayedRefreshNamesList(Int_t delay_sec)
TGo4Slot * RatemeterSlot()
virtual Bool_t IsAnalysisServer() const
virtual Bool_t IsController() const
virtual void SubmitAnalysisSettings()
virtual Bool_t IsAdministrator() const
virtual TString FindCommand(const char *name)
static Bool_t GetLaunchString(TString &launchcmd, TString &killcmd, Int_t serverkind, Int_t shellkind, Int_t konsole, const char *name, const char *remotehost, const char *remotedir, const char *remoteexe, Int_t guiport, Int_t exe_kind=0, const char *exeargs=nullptr)
virtual Bool_t RefreshNamesList()
virtual Bool_t IsViewer() const
TString GetFullName(TGo4Slot *toparent=nullptr)
Definition TGo4Slot.cxx:274
TGo4Proxy * GetProxy() const
Definition TGo4Slot.h:93
void SetProxy(TGo4Proxy *cont)
Definition TGo4Slot.cxx:296
Int_t NumChilds() const
Definition TGo4Slot.h:76
TGo4Slot * FindChild(const char *name) const
Definition TGo4Slot.cxx:245
void DeleteChilds(const char *startedwith=nullptr)
Definition TGo4Slot.cxx:202
TObject * GetAssignedObject()
Definition TGo4Slot.cxx:356
void Delete(Option_t *opt="") override
Definition TGo4Slot.cxx:171
TGo4Slot * GetChild(Int_t n) const
Definition TGo4Slot.h:77
virtual void WorkWithLeaf(const char *itemname)
virtual void ShootRepaintTimer()
virtual void Divide(int numX, int numY)
virtual bool IsRepaintTimerActive()
virtual void checkRepaintSlot()
virtual TPad * FindPadWithItem(const char *itemname)
virtual TPad * GetActivePad()
virtual void CompleteInitialization()
virtual const char * GetPanelName()
virtual void UndrawItemOnPanel(const char *itemname)
virtual void ResetPadFillColors(TPad *pad, int col, TPad *backup=nullptr)
virtual void SetActivePad(TPad *pad)
virtual TCanvas * GetCanvas()
virtual TGo4Slot * AddDrawObject(TPad *pad, int kind, const char *itemname, TObject *obj, bool owner, const char *drawopt)
QGo4Widget * GetWidget() const