ATLAS Offline Software
Loading...
Searching...
No Matches
VP1MainWindow.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2026 CERN for the benefit of the ATLAS collaboration
3*/
4
6// //
7// Implementation of class VP1MainWindow //
8// //
9// Author: Thomas Kittelmann <Thomas.Kittelmann@cern.ch> //
10// //
11// Initial version: April 2007 //
12//
13// Updates:
14// - Riccardo.Maria.Bianchi@cern.ch
15// //
17
19
29
30#ifdef BUILDVP1LIGHT
35#endif
36
38
40#include "VP1Base/IVP1System.h"
41#include "VP1Base/VP1Msg.h"
42#include "VP1Base/VP1Settings.h"
43#include "VP1Base/VP1QtUtils.h"
44
45
46#include <QMessageBox>
47#include <QImageWriter>
48#include <QFileInfo>
49#include <QInputDialog>
50#include <QLabel>
51#include <QCloseEvent>
52#include <QFileDialog>
53#include <QDir>
54#include <QTimer>
55#include <QSettings>
56#include <QComboBox>
57#include <QPainter>
58#include <QPrinter>
59#include <QPrintDialog>
60#include <QProgressBar>
61#include <QStyleFactory>
62#include <QDateTime>
63#include <QTimeZone>
64#include <QMutex>
65#include <QDesktopServices>
66#include <QUrl>
67#include <QProcess>
68#include <QGraphicsView>
69#include <QGraphicsScene>
70#include <QtGui>
71#include <QScrollBar>
72
73
74
75/* FIXME: LCG does not ship QWebEngine with Qt5 at the moment,
76 * but later you want to put it back again!
77 */
78/*
79#include <QtGlobal>
80#if QT_VERSION > QT_VERSION_CHECK(5, 5, 0)
81 #include <QWebEngineView> // Qt 5.6
82#else
83 #include <QtWebKit>
84#endif
85*/
86
87#include <cassert>
88#include <iostream>
89
90namespace {
91
92bool saveSnapshot(QWidget *parent, const QPixmap& snapshot, const QString& filename)
93{
94 QString error;
95 if (snapshot.isNull()) {
96 error = QStringLiteral("VP1 could not render the snapshot. No image was saved.\n\n"
97 "Offscreen OpenGL rendering may be unavailable on this display. "
98 "Check the terminal for Coin/GLX errors.");
99 } else {
100 QImageWriter writer(filename);
101 if (!writer.write(snapshot.toImage())) {
102 error = QStringLiteral("Could not write the snapshot:\n%1").arg(writer.errorString());
103 } else {
104 const QFileInfo output(filename);
105 if (!output.isFile() || output.size() == 0)
106 error = QStringLiteral("The image writer reported success, but no non-empty output file was found.");
107 }
108 }
109 if (error.isEmpty())
110 return true;
111
112 const QString message = error + QStringLiteral("\n\nOutput file: ") + filename;
113 VP1Msg::message(QStringLiteral("ERROR - Snapshot failed: ") + message);
114 QMessageBox dialog(QMessageBox::Critical, QStringLiteral("Snapshot failed"), message,
115 QMessageBox::Ok, parent);
116 dialog.setTextFormat(Qt::PlainText);
117 dialog.exec();
118 return false;
119}
120
121QString eventTimeUTC(unsigned timestamp)
122{
123 return QDateTime::fromSecsSinceEpoch(timestamp, Qt::UTC)
124 .toString(QStringLiteral("yyyy-MM-dd HH:mm:ss 'UTC'"));
125}
126
127QString eventTimeCERN(unsigned timestamp)
128{
129 const QTimeZone cernTimeZone("Europe/Zurich");
130 return QDateTime::fromSecsSinceEpoch(timestamp, Qt::UTC)
131 .toTimeZone(cernTimeZone)
132 .toString(QStringLiteral("yyyy-MM-dd HH:mm:ss t"));
133}
134
135}
136
137
138//_________________________________________________________________________________
140: QMainWindow(parent),
141 m_runnumber(-1),
142 m_eventnumber(-1),
143 m_betweenevents(true),
144 m_mustquit(false),
145 m_dummyemptycontroller(new QWidget(0)),
146 m_scheduler(sched),
147 m_availEvents(ae),
148 m_settingsfile(QDir::homePath()+QDir::separator()+".atlasvp1"),
149 m_userRequestedExit(false),
151 m_mutex(new QMutex()),
152 m_edEditor(0)
153{
154 setupUi(this); // this sets up the GUI
155
157 //
158 #if defined BUILDVP1LIGHT
159 bool checkShowAllCruiseAndEventControls = VP1QtUtils::expertSettingIsSet("expert","ExpertSettings/VP1_DEVEL_SHOW_ALL_CRUISE_AND_EVENT_CONTROLS");
160 #else
161 bool checkShowAllCruiseAndEventControls = VP1QtUtils::environmentVariableIsOn("VP1_DEVEL_SHOW_ALL_CRUISE_AND_EVENT_CONTROLS");
162 #endif
163
164 if (!checkShowAllCruiseAndEventControls) {
165 pushButton_eventseek->setVisible(false);
166 groupBox_cruise->setVisible(false);
167 }
168
169 if (m_availEvents) {
170 connect(m_availEvents,SIGNAL(message(const QString&)),this,SLOT(helperAddToMessageBox(const QString&)));
171 connect(m_availEvents,SIGNAL(freshEventsChanged()),this,SLOT(updateEventControls()));
172 }
173
174 // File menu
175 if(!m_availEvents) {
176 QMenu* menu_file = new QMenu(menubar);
177 menu_file->setObjectName("menu_file");
178 menu_file->setTitle("&File");
179 menubar->addAction(menu_file->menuAction());
180 m_action_addEventFile = menu_file->addAction("&Add event file ...");
181
182 connect(m_action_addEventFile,SIGNAL(triggered(bool)),this,SLOT(addEventFile()));
183 }
184
185 #ifndef BUILDVP1LIGHT
186 pushButton_previousevent->setVisible(false);
187 pushButton_eventselect->setVisible(false);
188 #else
189 pushButton_eventselect->setVisible(true);
190 pushButton_eventselect->setText("Event: 0/0");
191 pushButton_eventselect->setEnabled(false);
192 pushButton_previousevent->setEnabled(false);
193 //Disable all controls that are not available in VP1Light
194 // pushButton_quicksetup_3dcocktail->setEnabled(false);
195 // pushButton_quicksetup_3dcocktail->setToolTip("Not available in VP1Light");
196 pushButton_quicksetup_trackingstudies->setEnabled(false);
197 pushButton_quicksetup_trackingstudies->setToolTip("Not available in VP1Light");
198 pushButton_quicksetup_calostudies->setEnabled(false);
199 pushButton_quicksetup_calostudies->setToolTip("Not available in VP1Light");
200 action_quicklaunch_Tracking_studies->setEnabled(false);
201 action_quicklaunch_Tracking_studies->setToolTip("Not available in VP1Light");
202 action_quicklaunch_Calo_studies->setEnabled(false);
203 action_quicklaunch_Calo_studies->setToolTip("Not available in VP1Light");
204 action_quicklaunch_Storegate_browser->setEnabled(false);
205 action_quicklaunch_Storegate_browser->setToolTip("Not available in VP1Light");
206 action_quicklaunch_trackcalo_commis->setEnabled(false);
207 action_quicklaunch_trackcalo_commis->setToolTip("Not available in VP1Light");
208 m_action_addEventFile->setEnabled(false);
209 #endif
210
212 //Do we need a menu for multiple input directories?
213
214 VP1AvailEvtsLocalDir* availLocal = dynamic_cast<VP1AvailEvtsLocalDir*>(m_availEvents);
215
216 QStringList inputdirs;
217 if (availLocal)
218 inputdirs = availLocal->availableSourceDirectories();
219
220 if (availLocal&&!inputdirs.isEmpty()) {
221
222 QString currentdir = availLocal->currentSourceDir();
223 if (currentdir.endsWith("/"))
224 currentdir.chop(1);
225 m_currentStream = QDir(currentdir).dirName();
226 QMenu * menu_inputdir = new QMenu(menubar);
227 menu_inputdir->setObjectName("menu_inputdir");
228 menu_inputdir->setTitle("&Stream");
229
230 menubar->addAction(menu_inputdir->menuAction());
231
232 QActionGroup * inputdir_actiongroup = new QActionGroup(menu_inputdir);
233 QAction*action_inputdir_current(0);
234 for (QString inputdir : inputdirs) {
235 if (inputdir.endsWith("/"))
236 inputdir.chop(1);
237 QString dirname = QDir(inputdir).dirName();
238 QAction * action_inputdir = new QAction(this);
239 action_inputdir->setObjectName("action_inputdir_"+dirname);
240 action_inputdir->setData(inputdir);
241 action_inputdir->setStatusTip("Get input files from: "+inputdir);
242 action_inputdir->setCheckable(true);
243
244 if (currentdir==inputdir)
245 action_inputdir_current = action_inputdir;
246 menu_inputdir->addAction(action_inputdir);
247 inputdir_actiongroup->addAction(action_inputdir);
248 m_inputdiractions << action_inputdir;
249 connect(action_inputdir,SIGNAL(triggered(bool)),this,SLOT(inputDirectoryActionTriggered()));
250 }
251 if (action_inputdir_current) {
252 action_inputdir_current->blockSignals(true);
253 action_inputdir_current->setChecked(true);
254 action_inputdir_current->blockSignals(false);
255 }
256
257 // Populate inputdirstatuses
258 for(QAction* action : m_inputdiractions)
259 m_inputdirstatuses[action] = VP1DirStatusData(action->data().toString(),
260 QString(),
261 true,
262 false);
263
265 m_streamMenuUpdater->start();
266
267 //Fixme: start timer which every minute checks the status of these directories
268 QTimer *timer = new QTimer(this);
269 connect(timer, SIGNAL(timeout()), this, SLOT(updateInputDirectoriesStatus()));
270 timer->start(5000);//update this menu rather often (this is only for P1 anyway)
271 }
272
273 //.......
274
276 m_tabmanager = new VP1TabManager(this,tabWidget_central,m_channelmanager);
277 stackedWidget_customcontrols->addWidget(m_dummyemptycontroller);
278
279 //Final touches to instructions page:
280
281 // Remove any margins added by the layouts in the stacked
282 // widget. This really ought to be the default for stacked widgets!
283 for (int i=0;i<stackedWidget_central->count();++i)
284 stackedWidget_central->widget(i)->layout()->setContentsMargins(0,0,0,0);
285
286 frame_instructions->setStyleSheet("QFrame#frame_instructions { "+VP1DockWidget::highlightStyle()+" } ");
287 frame_instructions->setFrameShape(QFrame::StyledPanel);
288 // textBrowser_intro1->setStyleSheet("QTextBrowser#textBrowser_intro1 { background-color: rgba(0, 0, 0, 0%) } ");
289 // textBrowser_intro2->setStyleSheet("QTextBrowser#textBrowser_intro2 { background-color: rgba(0, 0, 0, 0%) } ");
290 #ifndef BUILDVP1LIGHT
291 connect(pushButton_quicksetup_3dcocktail,SIGNAL(clicked()),this,SLOT(quickSetupTriggered()));
292 #else
293 connect(pushButton_quicksetup_3dcocktail,SIGNAL(clicked()),this,SLOT(quickSetupTriggered()));
294 #endif
295 connect(pushButton_quicksetup_trackingstudies,SIGNAL(clicked()),this,SLOT(quickSetupTriggered()));
296 connect(pushButton_quicksetup_calostudies,SIGNAL(clicked()),this,SLOT(quickSetupTriggered()));
297 connect(pushButton_quicksetup_geometrystudies,SIGNAL(clicked()),this,SLOT(quickSetupTriggered()));
298 connect(pushButton_quicksetup_analysisstudies,SIGNAL(clicked()),this,SLOT(quickSetupTriggered()));
299
300 //Default application font:
301 m_defaultfont = QApplication::font();
305 else
307
308 //Tabs:
309 connect(m_tabmanager,SIGNAL(tabListChanged(QStringList)),this,SLOT(tabListChanged(QStringList)));
310 connect(tabWidget_central,SIGNAL(currentChanged(int)),this,SLOT(updateCentralStackWidget()));
312
313 //Channels:
314
315 connect(pushButton_saveAllChannels,SIGNAL(clicked()),this,SLOT(saveAllCurrentChannels()));
316 connect(pushButton_makeEventDisplay,SIGNAL(clicked()),this,SLOT(makeAllChannelsEventDisplay()));
317
318 connect(pushButton_3D,SIGNAL(clicked()),this,SLOT(launch3DstereoEditor()));
319
320 connect(pushButton_channelfullscreen,SIGNAL(clicked()),m_tabmanager,SLOT(showCurrentChannelFullScreen()));
321 connect(pushButton_channelinformation,SIGNAL(clicked()),this,SLOT(request_channelInformation()));
322 connect(pushButton_printchannel,SIGNAL(clicked()),this,SLOT(request_printChannel()));
323 connect(pushButton_savesnapshotchannel,SIGNAL(clicked()),this,SLOT(request_saveChannelSnapshot()));
325
326 //Menu:
327 //Quick start:
328 connect(action_quicklaunch_Tracking_studies,SIGNAL(triggered(bool)),this,SLOT(quickSetupTriggered()));
329 connect(action_quicklaunch_Calo_studies,SIGNAL(triggered(bool)),this,SLOT(quickSetupTriggered()));
330 connect(action_quicklaunch_Geometry_studies,SIGNAL(triggered(bool)),this,SLOT(quickSetupTriggered()));
331 connect(action_quicklaunch_analysisstudies,SIGNAL(triggered(bool)),this,SLOT(quickSetupTriggered()));
332 connect(action_quicklaunch_Storegate_browser,SIGNAL(triggered(bool)),this,SLOT(quickSetupTriggered()));
333 connect(action_quicklaunch_3dcocktail,SIGNAL(triggered(bool)),this,SLOT(quickSetupTriggered()));
334 connect(action_quicklaunch_trackcalo_commis,SIGNAL(triggered(bool)),this,SLOT(quickSetupTriggered()));
335 connect(action_exit_VP1,SIGNAL(triggered(bool)),this,SLOT(close()));
336
337 //Configuration
338 m_menu_loadConfFile = menuConfiguration->addMenu ( "&Load tab configuration from file" );
339 m_menu_loadConfFile->setStatusTip("Select .vp1 config file to load");
340 connect(m_menu_loadConfFile,SIGNAL(aboutToShow()),this,SLOT(showMenu_loadConfFile()));
341 menuConfiguration->addSeparator();
342 //plugins:
343 m_menu_loadPlugin = menuConfiguration->addMenu ( "&Load plugin" );
344 m_menu_loadPlugin->setStatusTip("Select plugin to load");
345 // m_action_infoAboutLoadedPlugins = menuPlugins->addAction ( "&Info about loaded plugins" );
346 // m_action_infoAboutLoadedPlugins->setStatusTip("Get information about the presently loaded plugins");
347 // m_action_infoAboutLoadedPlugins->setEnabled(false);
348 connect(m_menu_loadPlugin,SIGNAL(aboutToShow()),this,SLOT(showMenu_loadPlugin()));
349 //Style
350 m_menu_changeStyle = menu_Style->addMenu ( "&Style" );
351 QActionGroup * styleGroup = new QActionGroup(this);
352 QAction * laststyleact(0);
353 bool foundplastique=false;
354 QSettings s(m_settingsfile,QSettings::IniFormat);
355 QString defaultstyle=s.value("style/defaultstyle", "Fusion").toString();
356 for (QString style : QStyleFactory::keys() ) {
357 QAction * act = m_menu_changeStyle->addAction(style);
358 act->setStatusTip("Change application style to "+style);
359 connect(act,SIGNAL(triggered(bool)),this,SLOT(changeStyleActionTriggered()));
360 act->setCheckable(true);
361 styleGroup->addAction(act);
362 laststyleact=act;
363 if (act->text()==defaultstyle) {
364 act->setChecked(true);
365 QApplication::setStyle(QStyleFactory::create(act->text()));
366 foundplastique=true;
367 }
368 }
369 if (!foundplastique) {
370 laststyleact->setChecked(true);
371 QApplication::setStyle(QStyleFactory::create(laststyleact->text()));
372 }
373 //Fonts:
374 int savedgoal = 0;
376 savedgoal = s.value("font/pixelsize_diff", 0).toInt();
377 else
378 savedgoal = s.value("font/pointsize_relativepercent", 0).toInt();
379
380 m_menu_changeFontSize = menu_Style->addMenu ( "&Font size" );
381 QList<int> fontoptions;
383 fontoptions <<15<<10<<+5<<+3<<+2<<+1<<0<<-1<<-2<<-3<<-5<<-10<<-20<<-30;
384 else
385 fontoptions <<150<<100<<50<<30<<20<<10<<5<<0<<-5<<-10<<-20<<-30<<-50;
386
387 QActionGroup * fontGroup = new QActionGroup(this);
388 bool foundsavedgoal(false);
389 QAction * normalfontact(0);
390 for (int fontopt : fontoptions) {
392 continue;
393 QString text = (fontopt==0?"normal": (fontopt>0?"+":"")+QString::number(fontopt)+(m_defaultfont_pointsize < 0.0? " pixels" : "%"));
394 QAction * act = m_menu_changeFontSize->addAction(text);
395 act->setStatusTip("Change overall font size of application to "+text);
396 act->setData(fontopt);
397 act->setCheckable(true);
398 fontGroup->addAction(act);
399 connect(act,SIGNAL(triggered(bool)),this,SLOT(changeFontSizeActionTriggered()));
400 if (fontopt==0)
401 normalfontact=act;
402 if (savedgoal==fontopt) {
403 act->setChecked(true);
404 changeFontSize(fontopt);
405 foundsavedgoal=true;
406 }
407 }
408 if (!foundsavedgoal) {
409 normalfontact->setChecked(true);
410 }
411
412 //
413 m_actionSave_current_tabs = menuConfiguration->addAction ( "&Save current tab configuration to file" );
414 m_actionSave_current_tabs->setStatusTip("Save current tab/channel layout to .vp1 config file");
415 menuConfiguration->addSeparator();
416 m_actionAdd_empty_tab = menuConfiguration->addAction ( "&Add empty tab" );
417 m_actionAdd_empty_tab->setStatusTip("Add empty tab to the current tab list");
418 connect(m_actionAdd_empty_tab,SIGNAL(triggered(bool)),this,SLOT(request_addEmptyTab()));
419 connect(m_actionSave_current_tabs,SIGNAL(triggered(bool)),this,SLOT(request_saveasConfig()));
420
421 //ExpertSettings
422 #ifdef BUILDVP1LIGHT
423 menuConfiguration->addSeparator();
424 m_actionEnableExpertSettings = menuConfiguration->addAction ( "&Settings" );
425 m_actionEnableExpertSettings->setStatusTip("Open additional settings");
426 connect(m_actionEnableExpertSettings, &QAction::triggered, this, &VP1MainWindow::request_expertSettings);
427 #endif
428
429 //Event navigation:
430 connect(pushButton_nextevent,SIGNAL(clicked()),this,SLOT(goToNextEvent()));
431 #ifdef BUILDVP1LIGHT
432 connect(pushButton_previousevent,SIGNAL(clicked()),this,SLOT(goToPreviousEvent()));
433 connect(pushButton_eventselect,SIGNAL(clicked()),this,SLOT(chooseEvent()));
434 #endif
435
436 //Listen for external requests:
438 listenOnTcp();
439 // updateTcpIcon();
440 connect(&m_tcpserver,SIGNAL(listenStateChanged(bool)),this,SLOT(updateTcpIcon()));
443 m_blockallmessages=false;
445
446 //Cruise:
447 connect(pushButton_cruise,SIGNAL(clicked()),this,SLOT(request_cruisemodechange()));
448 connect(radioButton_cruise_event,SIGNAL(clicked()),this,SLOT(request_cruisemodechange()));
449 connect(radioButton_cruise_tab,SIGNAL(clicked()),this,SLOT(request_cruisemodechange()));
450 connect(radioButton_cruise_both,SIGNAL(clicked()),this,SLOT(request_cruisemodechange()));
451
452 // Help menu
453 QMenu* menu_help = new QMenu(menubar);
454 menu_help->setObjectName("menu_help");
455 menu_help->setTitle("&Help");
456 menubar->addAction(menu_help->menuAction());
457 m_action_openVP1Site = menu_help->addAction("VP1 &Web Site");
458 m_action_openUsersGuide = menu_help->addAction("VP1 &User's Guide");
459 m_action_openUsersSupport = menu_help->addAction("VP1 User's &Support (in the system browser)");
460 menu_help->addSeparator();
461 m_action_openAbout = menu_help->addAction("&About VP1");
462
463 QTimer::singleShot(0, this, SLOT(postInitUpdates()));
466
467 connect(m_action_openUsersGuide,SIGNAL(triggered(bool)),this,SLOT(help_openUserGuide()));
468 connect(m_action_openVP1Site,SIGNAL(triggered(bool)),this,SLOT(help_openVP1WebSite()));
469 connect(m_action_openUsersSupport,SIGNAL(triggered(bool)),this,SLOT(help_openUserSupport()));
470 connect(m_action_openAbout,SIGNAL(triggered(bool)),this,SLOT(help_openAbout()));
471
472 // FIXME: enabling menubar again. It's part of a quickfix, described here: https://its.cern.ch/jira/browse/ATLASVPONE-120
473 #ifndef BUILDVP1LIGHT
474 menubar->setEnabled(false);
475 #endif
476}
477
478//_________________________________________________________________________________
480{
481 VP1Msg::messageDebug("VP1MainWindow::launch3DstereoEditor()");
482 m_tabmanager->launchStereoEditorCurrentTab();
483
484}
485
486//_________________________________________________________________________________
488 /*
489 * Open the online help from a web url location
490 * with the default system web browser
491 */
492 VP1Msg::messageDebug("VP1MainWindow::help_openUserGuide()");
493 // we use here the default system browser
494 QDesktopServices::openUrl(QUrl("http://atlas-vp1.web.cern.ch/atlas-vp1/doc/"));
495 return;
496}
497
498//_________________________________________________________________________________
500 /*
501 * Open the online page with links to the JIRA issue collectors
502 * with the default system web browser
503 */
504 VP1Msg::messageDebug("VP1MainWindow::help_openUserSupport()");
505 // we use here the default system browser
506 QDesktopServices::openUrl(QUrl("http://atlas-vp1.web.cern.ch/atlas-vp1/vp1_users_support/"));
507 return;
508}
509
510//_________________________________________________________________________________
512 /*
513 * Open the online help from a web url location
514 * with the default system web browser
515 */
516 VP1Msg::messageDebug("VP1MainWindow::help_openVP1WebSite()");
517 // we use here the default system browser
518 QDesktopServices::openUrl(QUrl("http://atlas-vp1.web.cern.ch/atlas-vp1/"));
519 return;
520}
521
522
523//_________________________________________________________________________________
525 /*
526 * open the online help
527 */
528 VP1Msg::messageDebug("VP1MainWindow::help_openAbout()");
529 // we use here the default system browser
530 QDesktopServices::openUrl(QUrl("https://atlas-vp1.web.cern.ch/atlas-vp1/doc_new/about_vp1/CREDITS.html"));
531 return;
532}
533
534
535//_________________________________________________________________________________
537
538 //Make sure that the splitters give maximum space for the tab area.
539
540 int sum1 = splitter_tabwidget_messagebox->sizes().at(0) + splitter_tabwidget_messagebox->sizes().at(1);
541 QList<int> sizes1; sizes1 << sum1 << 0;
542 splitter_tabwidget_messagebox->setSizes ( sizes1 );
543 int bottom = 1;
544 while (splitter_tabwidget_messagebox->sizes().at(1)==0&&bottom<50000) {
545 QList<int> sizes2; sizes2 << sum1-bottom << bottom;
546 splitter_tabwidget_messagebox->setSizes ( sizes2 );
547 ++bottom;
548 }
549
550 int sum2 = splitter_leftright->sizes().at(0) + splitter_leftright->sizes().at(1);
551 int left = 300;
552 QList<int> sizes3; sizes3 << left << sum2-left;
553 splitter_leftright->setSizes ( sizes3 );
554 while (splitter_leftright->sizes().at(0)==0&&left<50000) {
555 QList<int> sizes4; sizes4 << left << sum2-left;
556 splitter_leftright->setSizes ( sizes4 );
557 ++left;
558 }
559
560 int prefwidths = std::max<int>(left,widget_controlsContainer->sizeHint().width());
561 prefwidths = std::max<int>(prefwidths,groupBox_channelcontrols->sizeHint().width());
562 prefwidths = std::max<int>(prefwidths,groupBox_cruise->sizeHint().width());
563 prefwidths = std::max<int>(prefwidths,groupBox_event->sizeHint().width());
564 prefwidths = std::max<int>(prefwidths,stackedWidget_customcontrols->sizeHint().width());
565 widget_controlsContainer->setMaximumWidth(50+prefwidths);
566 // int h1(textBrowser_intro1->viewport()->sizeHint().height());
567 // textBrowser_intro1->setMaximumHeight(h1+2);
568 if (m_availEvents)
569 m_availEvents->init();
571}
572
573//_________________________________________________________________________________
575 progressbar = new QProgressBar();
576 progressbar->setMinimum(0);
577 progressbar->reset();
578 progressbar->setOrientation(Qt::Horizontal);
579 statusBar()->addPermanentWidget(progressbar);
580 m_statusbarlabel = new QLabel();
581 //Turn off ugly box around items in statusbar:
582 statusBar()->setStyleSheet("QStatusBar::item { border-width: 0 }");
583 statusBar()->addPermanentWidget(m_statusbarlabel);
584 progressbar->hide();
585}
586
587//_________________________________________________________________________________
589{
590 if (m_edEditor) {
591 VP1Msg::messageDebug("deleting the editor");
592 delete m_edEditor;
593 }
594 VP1Msg::messageDebug("deleting the tab manager");
595 delete m_tabmanager;
596 VP1Msg::messageDebug("deleting the channel manager");
597 delete m_channelmanager;
598 VP1Msg::messageDebug("deleting the events");
599 delete m_availEvents;
600
602 VP1Msg::messageDebug("deleting the streamupdater");
603 m_streamMenuUpdater->quit();
604 m_streamMenuUpdater->deleteLater();
605 }
606
607 VP1Msg::messageDebug("deleting the mutex");
608 delete m_mutex;
609
610 VP1Msg::messageDebug("deleting the view");
611}
612
613//_________________________________________________________________________________
615 return m_mustquit;
616}
617
618
619//_________________________________________________________________________________
621{
622 bool l = m_tcpserver.isListening();
623 m_statusbarlabel->setPixmap(QIcon(l?":/vp1/icons/icons/network_64x64.png":":/vp1/icons/icons/network_disconnect_64x64.png")
624 .pixmap(progressbar->height(),progressbar->height(),QIcon::Normal,QIcon::On));
625 m_statusbarlabel->setToolTip(l?"Listening on port "+QString::number(m_tcpserver.port())+" for incoming messsages"
626 :"VP1 is presently NOT listening for incoming messages");
627
628}
629
630//_________________________________________________________________________________
631void VP1MainWindow::loadPluginFile(const QString& filename)
632{
633 VP1Msg::messageDebug("loadPluginFile()");
634
635 QString err = m_channelmanager->loadPluginFile(filename);
636 if (!err.isEmpty()) {
637 QMessageBox::critical(0, "Error - could not load plugin file: "+filename,
638 "Could not load plugin file: "
639 +filename+"\n\nReason: "+err,QMessageBox::Ok,QMessageBox::Ok);
640 VP1Msg::message("Could not load plugin file: "+filename+"\n\nReason: "+err);
641 }
642 //Fixme: Error message here is hardcoded to be the same as in loadPluginFile method!!
643}
644
645//_________________________________________________________________________________
647 bool ok;
648 QString newtabname = QInputDialog::getText( 0, "New Tab Name","New tab name:",
649 QLineEdit::Normal, m_tabmanager->suggestNewTabName("My Tab"), &ok );
650 if (!ok||newtabname.isEmpty())
651 return;
652 m_tabmanager->addNewTab(newtabname);
653}
654
655//_________________________________________________________________________________
656void VP1MainWindow::tabListChanged(const QStringList& l) {
658 if (l.count()) {
659 m_actionSave_current_tabs->setEnabled(true);
660 groupBox_cruise->setEnabled(true);
661 } else {
662 m_actionSave_current_tabs->setEnabled(false);
663 groupBox_cruise->setEnabled(false);
664 }
665 if (l.count()>1) {
666 radioButton_cruise_tab->setEnabled(true);
667 radioButton_cruise_both->setEnabled(true);
668 } else {
669 if (radioButton_cruise_tab->isChecked()||radioButton_cruise_both->isChecked())
670 radioButton_cruise_event->setChecked(true);
671 radioButton_cruise_tab->setEnabled(false);
672 radioButton_cruise_both->setEnabled(false);
673 }
674}
675
676//_________________________________________________________________________________
677void VP1MainWindow::addChannelIconsToComboBox(QComboBox* cb, const bool& isbasenames) {
678 int n= cb->count();
679 for (int i = 0; i<n; ++i) {
680 QString icontext = m_channelmanager->getIconLocation(cb->itemText(i), isbasenames);
681 if (!icontext.isEmpty())
682 cb->setItemIcon ( i, QIcon(icontext) );
683 }
684}
685
686//_________________________________________________________________________________
688{
689 VP1Msg::messageDebug("VP1MainWindow::selectedChannelChanged()");
690
691 //Controls box:
692 if (cw) {
693 groupBox_channelcontrols->setTitle("Controls: "+cw->unique_name());
694 groupBox_channelcontrols->setEnabled(true);
695 QWidget* controller = m_channelmanager->getController(cw);
696 if (!controller) {
697 stackedWidget_customcontrols->setCurrentWidget(m_dummyemptycontroller);
698 } else {
699 if (stackedWidget_customcontrols->indexOf(controller)==-1)
700 stackedWidget_customcontrols->addWidget(controller);
701 stackedWidget_customcontrols->setCurrentWidget(controller);
702 }
703 } else {
704 groupBox_channelcontrols->setTitle("Controls: no channel selected");
705 groupBox_channelcontrols->setEnabled(false);
706 stackedWidget_customcontrols->setCurrentWidget(m_dummyemptycontroller);
707 }
708
709 // FIXME: enabling menubar again. It's part of a quickfix, described here: https://its.cern.ch/jira/browse/ATLASVPONE-120
710 menubar->setEnabled(true);
711
712 // FIXME: enabling menubar again. It's part of a quickfix, described here: https://its.cern.ch/jira/browse/ATLASVPONE-120
713 menubar->setEnabled(true);
714}
715
716//_________________________________________________________________________________
718
719 QString filename = QFileDialog::getSaveFileName(this, "Select configuration file to save",
721 "VP1 Configuration files (*.vp1)",0,QFileDialog::DontResolveSymlinks);
722 if(filename.isEmpty())
723 return;
724
725 if (!filename.endsWith(".vp1"))
726 filename += ".vp1";
727
728 m_tabmanager->saveConfigurationToFile(filename,false/*Since the filedialog already asks*/);
729 m_currentconfigfile=filename;
730}
731
732//_________________________________________________________________________________
734{
735 if (m_currentconfigfile.isEmpty()) {
737 return;
738 }
739 m_tabmanager->saveConfigurationToFile(m_currentconfigfile,false);
740}
741
742//_________________________________________________________________________________
744{
745 QString filename = QFileDialog::getOpenFileName(this, "Select configuration file to load",
747 "VP1 configuration files (*.vp1)",0,QFileDialog::DontResolveSymlinks);
748 if(filename.isEmpty())
749 return;
750 m_tabmanager->loadConfigurationFromFile(filename,availablePluginFiles());
751 m_currentconfigfile=filename;
752}
753
754//_________________________________________________________________________________
756{
757#ifdef __APPLE__
758 QString sharedlibsuffix = "dylib";
759#else
760 QString sharedlibsuffix = "so";
761#endif
762 qDebug() << "VP1MainWindow::request_loadPlugin()"<<m_currentloadpluginpath;
763
764 QString filename = QFileDialog::getOpenFileName(this, "Select plugin file to load",
766 "VP1 plugin files (*VP1*."+sharedlibsuffix+")",0,QFileDialog::DontResolveSymlinks);
767 if(filename.isEmpty())
768 return;
769 m_currentloadpluginpath = QFileInfo(filename).dir().absolutePath();
770 loadPluginFile(filename);
771}
772
773//_________________________________________________________________________________
774QMap<QString,QString> VP1MainWindow::availableFiles(const QString& extension,
775 const QString& pathvar,//LD_LIBRARY_PATH or DATAPATH
776 const QString& instareasubdir,
777 const QString& extradirenvvar,
778 bool currentdir ) const
779{
780
781 qDebug() << "VP1MainWindow::availableFiles()";
782 qDebug() << "extension:" << extension << "pathvar:" << pathvar << "instareasubdir:" << instareasubdir << "extradirenvvar:" << extradirenvvar << "currentdir:" << currentdir;
783
784
785 //Add directories from extradirenvvar (e.g. $VP1PLUGINPATH)
786 QStringList vp1pluginpath =
787 extradirenvvar.isEmpty() ?
788 QStringList() :
789 QString(::getenv(extradirenvvar.toStdString().c_str())) .
790#if QTCORE_VERSION >= 0x050E00
791 split(":",Qt::SkipEmptyParts);
792#else
793 split(":",QString::SkipEmptyParts);
794#endif
795 if(VP1Msg::debug()){
796 qDebug() << "extradirenvvar:" << extradirenvvar;
797 qDebug() << "vp1pluginpath:" << vp1pluginpath;
798 }
799
800 #ifdef BUILDVP1LIGHT
801 //Add dir from Expert Settings
802 if(VP1QtUtils::expertSettingValue("expert","ExpertSettings/VP1PLUGINPATH")==""){
803 vp1pluginpath<<QCoreApplication::applicationDirPath()+"/../lib";
804 } else{
805 vp1pluginpath<<VP1QtUtils::expertSettingValue("expert","ExpertSettings/VP1PLUGINPATH");
806 }
807 #endif
808
809 //Currentdir:
810 if (currentdir) {
811 vp1pluginpath<<QDir::currentPath();
812 if (QDir::currentPath()!=VP1Settings::defaultFileSelectDirectory())
814 }
815
816 //Add directories from pathvar (looking in subdir instareasubdir):
817 QProcessEnvironment env = QProcessEnvironment::systemEnvironment();
818 VP1Msg::messageDebug("This is the 'pathvar' variable: " + pathvar);
819 QString path = env.value(pathvar);
820 VP1Msg::messageDebug("Add directories from 'pathvar' variable: " + path);
821
822 if (!path.isEmpty()) {
823#if QTCORE_VERSION >= 0x050E00
824 VP1Msg::messageDebug("We're using Qt5...");
825 QStringList tmp = path.split(":",Qt::SkipEmptyParts);//This 'tmp' is for SLC3 compilation.
826#else
827 VP1Msg::messageDebug("We're using Qt older than 5...");
828 QStringList tmp = path.split(":",QString::SkipEmptyParts);//This 'tmp' is for SLC3 compilation.
829#endif
830 for (const QString& dir : tmp) {
831 vp1pluginpath << ( instareasubdir.isEmpty() ? dir : dir+QDir::separator()+instareasubdir );
832 }
833 }
834
835 // Remove duplicates
836 int nDuplicatesRemoved = vp1pluginpath.removeDuplicates();
837 VP1Msg::messageDebug("Removed '" + QString::number(nDuplicatesRemoved) + "' duplicate paths.");
838
839 // Remove all nonexisting directories:
840 QStringList validPluginPaths;
841 validPluginPaths.reserve(vp1pluginpath.size());
842 for (const QString& plugindir : vp1pluginpath) {
843 VP1Msg::messageDebug("plugindir: '" + plugindir + "'");
844 QFileInfo fi(plugindir);
845
846 if (fi.exists() && fi.isDir()) {
847 validPluginPaths << plugindir;
848 } else {
849 VP1Msg::messageDebug("Removed non-valid path: '" + plugindir + "'");
850 }
851 }
852 vp1pluginpath = validPluginPaths;
853
854
855 //Find all files with required extension in the directories (in case of duplicates - the ones appearing first are used):
856 QMap<QString,QString> plugins2fullpath;
857 for (const QString& plugindir : vp1pluginpath) {
858 QStringList plugins = QDir(plugindir).entryList((QStringList()<<("*"+extension)),QDir::CaseSensitive | QDir::Files | QDir::Readable,QDir::Name);
859 for (QString plugin : plugins) {
860 plugin = QFileInfo(plugin).fileName();
861 if (!plugins2fullpath.contains(plugin)) {
862 QString fullpath = plugindir+QDir::separator()+plugin;
863 plugins2fullpath[plugin]=fullpath;
864 }
865 }
866 }
867 return plugins2fullpath;
868}
869
870//_________________________________________________________________________________
871QMap<QString,QString> VP1MainWindow::availablePluginFiles() const
872{
873VP1Msg::messageDebug("VP1MainWindow::availablePluginFiles()");
874
875#ifdef __APPLE__
876 QString sharedlibsuffix = "dylib";
877#else
878 QString sharedlibsuffix = "so";
879#endif
880
881 return availableFiles( "."+sharedlibsuffix, "LD_LIBRARY_PATH", "vp1plugins", "VP1PLUGINPATH" );
882
883}
884
885//_________________________________________________________________________________
887 if (!m_plugindialog)
888 return;
889
890 int res = m_plugindialog->result();
891 QString filename = m_plugindialog->unloadfile();
892 disconnect(m_plugindialog,SIGNAL(finished(int)),this,SLOT(pluginDialogClosed()));
893 m_plugindialog->deleteLater();
894 m_plugindialog = 0;
895
896 if (res!=QDialog::Accepted||filename.isEmpty())
897 return;
898
899 QStringList bns = m_channelmanager->channelsInPluginFile(filename);
900
901 for (const QString& bn : bns) {
902 while(m_channelmanager->basename2UniqueNames(bn).count()>0)
903 m_tabmanager->removeChannel(m_channelmanager->basename2UniqueNames(bn).value(0));
904 }
905
906 m_currentunloadpluginfiles << filename;
907 QTimer::singleShot(0, this, SLOT(unloadPlugin_continue()));
908
909}
910
911//_________________________________________________________________________________
913{
914 for (const QString& filename : m_currentunloadpluginfiles) {
915 bool success = m_channelmanager->unloadPluginFile(filename);
916 if (!success)
917 QMessageBox::critical(0, "Error - problems unloading plugin file: "+filename,
918 "Problems encountered while attempting to unload plugin file: "+filename,QMessageBox::Ok,QMessageBox::Ok);
919 }
921}
922
923//_________________________________________________________________________________
925{
926 return ! (m_betweenevents || (m_availEvents&&m_availEvents->freshEvents().isEmpty()));
927}
928
929
930//_________________________________________________________________________________
932 m_betweenevents=true;
933 if (m_availEvents) {
934 QList<VP1EventFile> evts = m_availEvents->freshEvents();
935 if (evts.empty()) {
936 addToMessageBox("ERROR: Going to next event, but one is not available!");
937 m_scheduler->setNextRequestedEventFile("");
938 } else {
939 m_scheduler->setNextRequestedEventFile(evts.front().fileName());
940 }
941 }
943}
944
945//_________________________________________________________________________________
947 #if defined BUILDVP1LIGHT
948 std::cout << "goToNextEvent: \n"
949 << "m_scheduler->getEvtNr()+2: " << m_scheduler->getEvtNr()+2
950 << "\nm_scheduler->getTotEvtNr(): " << m_scheduler->getTotEvtNr() << std::endl;
951 if ( m_scheduler->getEvtNr()+2 < m_scheduler->getTotEvtNr() ) {
952 std::cout << "First case" << std::endl;
953 m_scheduler->setEvtNr(m_scheduler->getEvtNr()+1);
954 nextEvent();
955 qApp->quit();
956 }
957 else if( m_scheduler->getEvtNr()+2 == m_scheduler->getTotEvtNr() ) {
958 std::cout << "Second case" << std::endl;
959 m_scheduler->setEvtNr(m_scheduler->getEvtNr()+1);
960 nextEvent();
961 qApp->quit();
962 }
963 #else
964 nextEvent();
965 qApp->quit();
966 #endif
967}
968
969#if defined BUILDVP1LIGHT
970//_________________________________________________________________________________
971void VP1MainWindow::goToPreviousEvent() {
972 if ( m_scheduler->getEvtNr()-1 > 0 ) {
973 m_scheduler->setEvtNr(m_scheduler->getEvtNr()-1);
974 nextEvent();
975 qApp->quit();
976 }
977 else if( m_scheduler->getEvtNr()-1 == 0 ) {
978 m_scheduler->setEvtNr(m_scheduler->getEvtNr()-1);
979 nextEvent();
980 qApp->quit();
981 }
982}
983#endif
984
985//_________________________________________________________________________________
986void VP1MainWindow::closeEvent(QCloseEvent * event)
987{
988 VP1Msg::messageDebug("VP1MainWindow::closeEvent()");
989
990 bool checkEnableAskOnClose;
991 #if defined BUILDVP1LIGHT
992 checkEnableAskOnClose = VP1QtUtils::expertSettingIsSet("general","ExpertSettings/VP1_ENABLE_ASK_ON_CLOSE");
993 #else
994 checkEnableAskOnClose = VP1QtUtils::environmentVariableIsOn("VP1_ENABLE_ASK_ON_CLOSE");
995 #endif
996
997 if (checkEnableAskOnClose) {
998 int ret = QMessageBox::warning(this,
999 "Close VP1?",
1000 "You are about to close VP1 and end the job.\nProceed?",
1001 QMessageBox::Ok| QMessageBox::Cancel,
1002 QMessageBox::Cancel );
1003 if (ret!=QMessageBox::Ok) {
1004 event->ignore();
1005 return;
1006 }
1007 m_userRequestedExit = true;
1008 }
1009
1010 hide();
1011
1012 VP1Msg::messageDebug("calling tabmanager->setSelectedDockWidget(0)...");
1013 m_tabmanager->setSelectedDockWidget(0);
1014 VP1Msg::messageDebug("tabmanager->setSelectedDockWidget(0) called.");
1015
1016 m_mustquit=true; // this will inform VP1Alg that we want to quit VP1 (then we'll quit the Athena algorithm)
1017 VP1Msg::messageDebug("calling qApp->quit()...");
1018 qApp->quit();
1019}
1020
1021//_________________________________________________________________________________
1022void VP1MainWindow::setRunEvtNumber(const int& r, const unsigned long long& e, const unsigned& triggerType, const unsigned& time, const bool& printmessage ) {
1023
1024 m_scheduler->setNextRequestedEventFile("");
1025 const bool sameasold(m_runnumber==r&&m_eventnumber==e);
1026
1027 m_runnumber=r;
1028 m_eventnumber=e;
1029 m_timestamp=time;
1030
1031 m_betweenevents = false;
1032 if (m_availEvents)
1033 m_availEvents->setCurrentEvent(r,e);
1034
1035 for(IVP1ChannelWidget* channel : m_tabmanager->allChannels()) {
1036 channel->setRunEvtNumber(r,e);
1037 channel->setEvtTimestamp(time);
1038 }
1039
1040 if(printmessage) {
1041 qulonglong evNumber = m_eventnumber;
1042 QString evtstr = "run# "+QString::number(m_runnumber)+", event# "+QString::number(evNumber)+(sameasold?" (reused)":"");
1043 QString trighex = triggerType > 0 ? "0x"+QString::number(triggerType, 16).toUpper().rightJustified(sizeof(triggerType),'0') : "";
1044 QString expandedevtstr = evtstr
1045 + QString(trighex.isEmpty()?QString(""):", triggerType: "+trighex)
1046 + QString(time>0 ? ", time: "+eventTimeUTC(time) : "")
1047 + QString(m_currentStream.isEmpty()?"":", "+m_currentStream);
1048
1049 #ifdef BUILDVP1LIGHT
1050 setWindowTitle("VP1Light ["+expandedevtstr+"]");
1051 #else
1052 setWindowTitle("VP1 (Virtual Point 1) ["+expandedevtstr+"]");
1053 #endif // BUILDVP1LIGHT
1054
1055 groupBox_event->setTitle("Event [loaded]");
1056 QString eventDetails =
1057 "Run: " + QString::number(m_runnumber) +
1058 "\nEvent: " + QString::number(evNumber);
1059 if (time > 0) {
1060 eventDetails +=
1061 "\nTime UTC: " + eventTimeUTC(time) +
1062 "\nTime Europe/Zurich (CERN): " + eventTimeCERN(time);
1063 }
1064 label_run_event->setText(eventDetails);
1065
1066 addToMessageBox("New event: "+expandedevtstr,"color:#ff0000");
1067
1068 }
1070}
1071
1072//_________________________________________________________________________________
1073void VP1MainWindow::addToMessageBox( const QString& m, const QString& extrastyleopts,
1074 const QString& title, const QString& titleextrastyleopts )
1075{
1076
1077 if (title.isEmpty())
1078 std::cout<<VP1Msg::prefix_msg()<<": "<<m.toStdString()<<std::endl;
1079 else
1080 std::cout<<VP1Msg::prefix_msg()<<": "<<title.toStdString() << ": " <<m.toStdString()<<std::endl;
1081
1082
1083 QString titlepart = ( title.isEmpty() ? "" : ( titleextrastyleopts.isEmpty() ? title
1084 : "<span style=\"font-style:italic;"+titleextrastyleopts+";\">["+title+"]</span> "));
1085
1086 textBrowser_channelmessages->append(titlepart
1087 + ( extrastyleopts.isEmpty() ? m
1088 : "<span style=\"font-style:italic;"+extrastyleopts+";\">"+m+"</span>"));
1089 textBrowser_channelmessages->verticalScrollBar()->setSliderPosition(textBrowser_channelmessages->verticalScrollBar()->maximum());
1090}
1091
1092//_________________________________________________________________________________
1094{
1095 IVP1System*sys = static_cast<IVP1System*>(sender());
1096 if (!sys) {
1097 addToMessageBox("VP1MainWindow::systemAddToMessageBox Error: Only prints system messages!");
1098 return;
1099 }
1100 if (!sys->channel()) {
1101 addToMessageBox("VP1MainWindow::systemAddToMessageBox Error: System does not know its channel!");
1102 return;
1103 }
1104 addToMessageBox( m, "color:#000000",sys->channel()->unique_name()+"/"+sys->name(),"color:#0000ff" );
1105}
1106
1107//_________________________________________________________________________________
1109{
1110 IVP1ChannelWidget*cw = static_cast<IVP1ChannelWidget*>(sender());
1111 if (!cw) {
1112 addToMessageBox("VP1MainWindow::channelAddToMessageBox Error: Only prints channelwidget messages!");
1113 return;
1114 }
1115 addToMessageBox(m,"color:#000000", cw->unique_name(),"color:#0000ff");
1116}
1117
1118//_________________________________________________________________________________
1120{
1121 addToMessageBox(m);
1122}
1123
1124//_________________________________________________________________________________
1126 if(!m_tabmanager->selectedChannelWidget())
1127 return;
1128
1129 QString out = "Information about channel: "+m_tabmanager->selectedChannelWidget()->name() + "\n\n";
1130 out += "Contact: "+m_tabmanager->selectedChannelWidget()->contact_info()+"\n";
1131 out += "Information: "+m_tabmanager->selectedChannelWidget()->information()+"\n";
1132 out += "Systems:\n\n";
1133 std::set<IVP1System *>::iterator itsys, itsysE = m_tabmanager->selectedChannelWidget()->systems().end();
1134 for (itsys = m_tabmanager->selectedChannelWidget()->systems().begin();itsys!=itsysE;++itsys) {
1135 out += " ==> System "+(*itsys)->name()+"\n";
1136 out += " Contact: "+(*itsys)->contact_info()+"\n";
1137 out += " Information: "+(*itsys)->information()+"\n";
1138 out += "\n";
1139 }
1140
1141 QMessageBox::information(0, "Information about channel: "+m_tabmanager->selectedChannelWidget()->name(),Qt::convertFromPlainText(out),QMessageBox::Ok,QMessageBox::Ok);
1142}
1143
1144//_________________________________________________________________________________
1146{
1147 VP1Msg::messageVerbose("VP1MainWindow::makeAllChannelsEventDisplay()");
1148
1149 QList<QPixmap> list;
1150 QStringList listNames;
1151 QList<unsigned long long> listRunEventNumberTimestamp;
1152
1153 getAllChannelsIntoSnapshots(list, listNames);
1154
1155 listRunEventNumberTimestamp << m_runnumber;
1156 listRunEventNumberTimestamp << m_eventnumber;
1157 listRunEventNumberTimestamp << m_timestamp;
1158
1159 // create a new editor window
1160 m_edEditor = new VP1EventDisplayEditor(this, listRunEventNumberTimestamp);
1161
1162 m_edEditor->addPixmapList(list, listNames);
1163
1164 // pass the lists of all tabs and their names to the editor
1165 m_edEditor->setTabsList( listNames);
1166
1167 m_edEditor->show();
1168
1169}
1170
1171
1172
1173
1174//_________________________________________________________________________________
1175void VP1MainWindow::getAllChannelsIntoSnapshots(QList<QPixmap>& list, QStringList& listNames)
1176{
1177 VP1Msg::messageDebug("VP1MainWindow::getAllChannelsIntoSnapshots()");
1178
1179// int nTabs = m_tabmanager->nTabs();
1180 QList<IVP1ChannelWidget*> allTabs = m_tabmanager->allChannels();
1181
1182 if (allTabs.isEmpty()) {
1183 VP1Msg::message("WARNING - No tabs to save.");
1184 return;
1185 }
1186
1187 int nT = 0;
1188
1189 // loop over all tabs/channels
1190 for(IVP1ChannelWidget* widg : allTabs) {
1191
1192 // increase tab number
1193 ++nT;
1194
1195 // get channel name (e.g. Geometry, 3DCocktail)
1196 QString channelname = m_tabmanager->channelToTab(widg);
1197 channelname.replace(' ','_');
1198 VP1Msg::messageDebug("tab: " + channelname);
1199
1200 // DEBUG MSGS
1201 // get channel info, only for debug
1202 //QString info = widg->information();
1203 //VP1Msg::messageDebug("channel info: " + info);
1204
1205
1206 QPixmap snap = getSingleChannelCustomSnapshot(widg);
1207
1208 list << snap;
1209 listNames << channelname;
1210
1211 }
1212
1213 VP1Msg::messageVerbose(QString::number(nT)+" tabs/channels saved in the QList.");
1214
1215}
1216
1217//_________________________________________________________________________________
1219{
1220 VP1Msg::messageDebug("VP1MainWindow::getSingleChannelCustomSnapshot()");
1221
1222 std::cout << "tab: " << tab << std::endl;
1223
1224 // save the anti-aliasing status, set by the user
1225 bool antialias_original = tab->isAntiAliasing();
1226
1227 // for the final event display images we want the anti-aliasing turned ON,
1228 tab->setAntiAliasing(true);
1229
1230 // get the snapshot
1231 QPixmap snap;
1232 if (width)
1233 snap = tab->getSnapshot(true, width); // 'true' means 'transparent background'
1234 else
1235 snap = tab->getSnapshot(true); // 'true' means 'transparent background'
1236
1237 if (snap.isNull()) {
1238 VP1Msg::message("ERROR! - No snapshot produced!");
1239 return QPixmap();
1240 }
1241
1242 // go back to the original anti-aliasing status, set by the user for the tab
1243 tab->setAntiAliasing(antialias_original);
1244
1245 return snap;
1246}
1247//_________________________________________________________________________________
1248QPixmap VP1MainWindow::getSingleChannelCustomSnapshot(const QString& tabName, int width)
1249{
1250 QList<IVP1ChannelWidget*> allTabs = m_tabmanager->allChannels();
1251
1252 if (allTabs.isEmpty()) {
1253 VP1Msg::message("WARNING - No tabs to get snapshots from.");
1254 }
1255
1256 // loop over all tabs/channels
1257 for(IVP1ChannelWidget* widg : allTabs) {
1258
1259 // get channel name (e.g. Geometry, 3DCocktail)
1260 QString channelname = m_tabmanager->channelToTab(widg);
1261 channelname.replace(' ','_');
1262
1263 if (channelname == tabName) {
1264 VP1Msg::messageDebug("found tab: " + channelname);
1265
1266 if (width)
1268 else
1269 return getSingleChannelCustomSnapshot(widg);
1270
1271 }
1272 }
1273 return QPixmap();
1274}
1275
1276//_________________________________________________________________________________
1278{
1279 VP1Msg::messageDebug("VP1MainWindow::saveAllCurrentChannels()");
1280
1281 int nTabs = m_tabmanager->nTabs();
1282
1283 VP1Msg::messageDebug("# of tabs: " + QString::number(nTabs));
1284
1285 QList<IVP1ChannelWidget*> allTabs = m_tabmanager->allChannels();
1286
1287 if (allTabs.isEmpty()) {
1288 VP1Msg::message("WARNING - No tabs to save.");
1289 return;
1290 }
1291
1292
1293// QString guess;
1294// QString chnlname = m_tabmanager->selectedChannelWidget()->name().toLower();
1295// chnlname.replace(' ','_');
1296
1297 QString base=m_currentsaveimagepath+QDir::separator()+"vp1"
1298 + "_run"+QString::number(m_runnumber)+"_evt"+QString::number(m_eventnumber)
1299 + QString(m_timestamp>0 ? "_"+QDateTime::fromTime_t(m_timestamp).toString(Qt::ISODate).replace(':','-') : "");
1300
1301
1302 // check for existing files
1303 int i(2);
1304 while (QFile::exists(base+".png")) {
1305 base = base+"_"+QString::number(i++);
1306 }
1307
1308 // let the user choose the base filename
1309 QString filename = QFileDialog::getSaveFileName(0, "Select target image file", base,
1310 "Image (*.png *.bmp)",
1311 0,QFileDialog::DontResolveSymlinks);
1312 if(filename.isEmpty()) {
1313 VP1Msg::message("WARNING - No filename selected.");
1314 return;
1315 }
1316
1317 m_currentsaveimagepath = QFileInfo(filename).dir().absolutePath ();
1318
1319
1320 QStringList tab_save_files;
1321
1322 int nT = 0;
1323 for(IVP1ChannelWidget* widg : allTabs) {
1324
1325 // increase tab number
1326 ++nT;
1327
1328 // get channel name (e.g. Geometry, 3DCocktail)
1329 QString channelname = widg->name().toLower();
1330 channelname.replace(' ','_');
1331 VP1Msg::messageDebug("tab: " + channelname);
1332
1333// // get channel info, only for debug
1334// QString info = widg->information();
1335// VP1Msg::messageDebug("channel info: " + info);
1336
1337 QPixmap snap = widg->getSnapshot();
1338 QString tabfilename = filename + "_" + QString::number(nT) + "_" + channelname + ".png";
1339
1340 if (!(tabfilename.endsWith(".png",Qt::CaseInsensitive)||tabfilename.endsWith(".bmp",Qt::CaseInsensitive)))
1341 tabfilename += ".png";
1342
1343
1344 if (!saveSnapshot(this, snap, tabfilename))
1345 return;
1346
1347 tab_save_files << tabfilename;
1348 }
1349
1350 VP1Msg::message("Tabs saved as: " + tab_save_files.join(" - "));
1351
1352
1353 QMessageBox::information(this, tr("Snapshots saved."),
1354 "All tabs have been saved as snapshots in the following files:\n\n"+tab_save_files.join("\n"),
1355 QMessageBox::Ok,
1356 QMessageBox::Ok);
1357
1358
1359// // TODO: test to create a multilayered PSD or TIFF file
1360// // but doesn't work with the ImageMagick version shipped with SLC5...
1361// // So I give it up now...
1362// QProcess *proc = new QProcess();
1363// QString program = "convert";
1364// QStringList arguments;
1365// arguments = tab_save_files;
1366// arguments << " " + m_currentsaveimagepath + QDir::separator() + "out.psd";
1367// VP1Msg::messageDebug("running: " + program + " " + arguments.join(" "));
1368//
1369// // start the process
1370// proc->start(program, arguments );
1371//
1372// if (!proc->waitForStarted())
1373// return;
1374//
1375// if (!proc->waitForFinished())
1376// return;
1377
1378}
1379
1380//_________________________________________________________________________________
1381/*
1382 * save a snaphot of the currently selected tab.
1383 *
1384 * nsnap is an optional parameter: it's an extra label being added
1385 * to the output filename.
1386 */
1388{
1389
1390 VP1Msg::messageDebug("VP1MainWindow::request_saveChannelSnapshot()");
1391
1392 if(!m_tabmanager->selectedChannelWidget()) {
1393 return QString();
1394 }
1395
1396 QString guess;
1397 QString chnlname = m_tabmanager->selectedChannelWidget()->name().toLower();
1398 chnlname.replace(' ','_');
1399
1400 QString base=m_currentsaveimagepath+QDir::separator()+"vp1_"+chnlname
1401 +"_run"+QString::number(m_runnumber)+"_evt"+QString::number(m_eventnumber)
1402 + QString(m_timestamp>0 ? "_"+QDateTime::fromTime_t(m_timestamp).toString(Qt::ISODate).replace(':','-') : "");
1403
1404
1405 // check for existing files
1406 guess=base;
1407 int i(2);
1408 while (QFile::exists(guess+".png")) {
1409 guess=base+"_"+QString::number(i++);
1410 }
1411 guess+=".png";
1412
1413
1414 // adding the extra label xLabel, if provided
1415 if (!xLabel.isEmpty()) {
1416 guess += "_" + xLabel;
1417 }
1418
1419
1420 QString filename = QFileDialog::getSaveFileName(0, "Select target image file", guess,
1421 "Image (*.png *.bmp)",
1422 0,QFileDialog::DontResolveSymlinks);
1423 if(filename.isEmpty())
1424 return QString();
1425
1426 m_currentsaveimagepath = QFileInfo(filename).dir().absolutePath ();
1427
1428 if (!(filename.endsWith(".png",Qt::CaseInsensitive)||filename.endsWith(".bmp",Qt::CaseInsensitive)))
1429 filename += ".png";
1430
1431 VP1Msg::messageVerbose("calling snapshot");
1432 QPixmap pm = m_tabmanager->selectedChannelWidget()->getSnapshot();
1433
1434 if (!saveSnapshot(this, pm, filename))
1435 return QString();
1436
1437 return filename;
1438}
1439
1440//_________________________________________________________________________________
1442 if(!m_tabmanager->selectedChannelWidget())
1443 return;
1444
1445 //The following will paint the widget onto a paper and bring up the print dialog:
1446 QPrinter printer;
1447 QPrintDialog dialog(&printer, this);
1448 if (dialog.exec() == QDialog::Accepted) {
1449 QPixmap pm = m_tabmanager->selectedChannelWidget()->getSnapshot();
1450 if (pm.isNull())
1451 return;
1452 QPainter painter;
1453 painter.begin(&printer);
1454 painter.drawPixmap(0,0,pm);
1455 painter.end();
1456 }
1457}
1458
1459
1460//_________________________________________________________________________________
1462 m_tabmanager->loadConfigurationFromFile(file,availablePluginFiles());
1463}
1464
1465//_________________________________________________________________________________
1467{
1468 VP1Msg::messageDebug("VP1MainWindow::replaceConfigurationFile() : " + file);
1469 m_tabmanager->removeAllTabs();
1470 m_tabmanager->loadConfigurationFromFile(file,availablePluginFiles());
1471}
1472
1473//_________________________________________________________________________________
1475{
1476 QString err;
1477 if (!m_tcpserver.listen(err)) {
1478 qDebug("%s", err.toStdString().c_str());
1479 }
1480}
1481
1482
1483//_________________________________________________________________________________
1485{
1487 if (!m_requestqueue.empty())
1488 QTimer::singleShot(0, this, SLOT(processEnqueuedRequests()));
1489}
1490
1491
1492//_________________________________________________________________________________
1498
1499//_________________________________________________________________________________
1501{
1503 return;
1504 if (m_messages_blockedsenders.contains(request.sender()))
1505 return;
1506 if (m_messages_blockedexactmessages.contains(request))
1507 return;
1509 //Fixme: store TIME of incoming request (to show the user).
1510 if (m_requestqueue.count()<999) {
1511 m_requestqueue.enqueue(request);
1512 m_currentincomingdialog->updatependinginfo();
1513 }
1514 return;
1515 }
1520 connect(md,SIGNAL(finished(int)),this,SLOT(finishedIncomingDialog()));
1521 m_tabmanager->dropOutOfFullScreen();
1522 md->show();
1523}
1524
1525//_________________________________________________________________________________
1527{
1528 if (pushButton_cruise->isChecked()) {
1529 if (radioButton_cruise_event->isChecked()) {
1531 groupBox_cruise->setTitle("Cruise Mode [event]");
1532 } else if (radioButton_cruise_tab->isChecked()) {
1534 groupBox_cruise->setTitle("Cruise Mode [tab]");
1535 } else if (radioButton_cruise_both->isChecked()) {
1537 groupBox_cruise->setTitle("Cruise Mode [event && tab]");
1538 } else { assert(0); }
1539 } else {
1541 groupBox_cruise->setTitle("Cruise Mode [off]");
1542 }
1543}
1544
1545//_________________________________________________________________________________
1547{
1548 m_menu_loadPlugin->clear();
1549
1550 QMap<QString,QString> plugins2fullpath = availablePluginFiles();
1551
1552 if (plugins2fullpath.empty()) {
1553 m_menu_loadPlugin->addAction("No plugins found")->setEnabled(false);
1554 return;
1555 }
1556
1557 QStringList pluglist(plugins2fullpath.keys());
1558 pluglist.sort();
1559
1560 QStringList currentpluginfiles = m_channelmanager->currentPluginFiles();
1561 for(const QString& plug : pluglist) {
1562 QAction * act = m_menu_loadPlugin->addAction(plug);
1563 assert(plugins2fullpath.contains(plug));
1564 QString fullpath = plugins2fullpath[plug];
1565 if (currentpluginfiles.contains(fullpath)) {
1566 act->setEnabled(false);
1567 } else {
1568 act->setData(fullpath);
1569 act->setStatusTip(fullpath);
1570 connect(act,SIGNAL(triggered(bool)),this,SLOT(showMenu_loadPluginItemSelected()));
1571 }
1572 }
1573
1574 m_menu_loadPlugin->addSeparator();
1575 QAction * act_browse = m_menu_loadPlugin->addAction("&Browse...");
1576 act_browse->setStatusTip("Browse filesystem for VP1 plugin files");
1577 connect(act_browse,SIGNAL(triggered(bool)),this,SLOT(request_loadPlugin()));
1578
1579}
1580
1581//_________________________________________________________________________________
1583{
1584 QAction * act = static_cast<QAction*>(sender());
1585 assert(act);
1586 if (!act)
1587 return;
1588 loadPluginFile(act->data().toString());
1589}
1590
1591
1592//_________________________________________________________________________________
1594{
1595 m_menu_loadConfFile->clear();
1596
1597 QMap<QString,QString> conffile2fullpath = availableFiles( ".vp1", "DATAPATH", "", "VP1CONFIGFILEPATH", true );
1598
1599 #ifndef BUILDVP1LIGHT
1600 if (conffile2fullpath.empty()) {
1601 m_menu_loadConfFile->addAction("No .vp1 config files found")->setEnabled(false);
1602 return;
1603 }
1604
1605 QStringList filelist(conffile2fullpath.keys());
1606 filelist.sort();
1607
1608 for(const QString& file : filelist) {
1609 QAction * act = m_menu_loadConfFile->addAction(file);
1610 assert(conffile2fullpath.contains(file));
1611 QString fullpath = conffile2fullpath[file];
1612 act->setData(fullpath);
1613 act->setStatusTip(fullpath);
1614 connect(act,SIGNAL(triggered(bool)),this,SLOT(showMenu_loadConfFileItemSelected()));
1615 }
1616 #endif
1617
1618 m_menu_loadConfFile->addSeparator();
1619 QAction * act_browse = m_menu_loadConfFile->addAction("&Browse...");
1620 act_browse->setStatusTip("Browse filesystem for .vp1 config file");
1621 connect(act_browse,SIGNAL(triggered(bool)),this,SLOT(request_loadConfig()));
1622
1623}
1624
1625
1626//_________________________________________________________________________________
1628{
1629 QAction * act = static_cast<QAction*>(sender());
1630 assert(act);
1631 if (!act)
1632 return;
1633 loadConfigurationFromFile(act->data().toString());
1634}
1635
1636//_________________________________________________________________________________
1638{
1639 QAction * act = static_cast<QAction*>(sender());
1640 assert(act);
1641 if (!act)
1642 return;
1643 assert(QStyleFactory::keys().contains(act->text()));
1644 if (!QStyleFactory::keys().contains(act->text()))
1645 return;
1646 QApplication::setStyle(QStyleFactory::create(act->text()));
1647 QSettings s(m_settingsfile,QSettings::IniFormat);
1648 s.setValue("style/defaultstyle",act->text());
1649
1650}
1651
1652//_________________________________________________________________________________
1654{
1655 QAction * act = static_cast<QAction*>(sender());
1656 assert(act);
1657 if (!act)
1658 return;
1659 bool ok;
1660 int goal = act->data().toInt(&ok);
1661 assert(ok);
1662 if (!ok)
1663 return;
1664 changeFontSize(goal);
1665}
1666
1667//_________________________________________________________________________________
1669{
1670 QFont newfont = m_defaultfont;
1671 QSettings s(m_settingsfile,QSettings::IniFormat);
1672 if (m_defaultfont_pointsize<0.0) {
1673 //pixels
1674 assert(m_defaultfont_pixelsize+goal>0);
1675 if (m_defaultfont_pixelsize+goal<=0)
1676 return;
1677 if (m_defaultfont_pixelsize+goal>200)
1678 return;
1679 newfont.setPixelSize(m_defaultfont_pixelsize+goal);
1680 s.setValue("font/pixelsize_diff",goal);
1681 } else {
1682 //pointsize
1683 double fact = (goal+100.0)/100.0;
1684 if (fact<0.01||fact>50)
1685 return;
1686 double newpointsize=m_defaultfont_pointsize*fact;
1687 if (newpointsize<0)
1688 return;
1689 newfont.setPointSizeF(newpointsize);
1690 s.setValue("font/pointsize_relativepercent",goal);
1691 }
1692 QApplication::setFont(newfont);
1693}
1694
1695
1696//_________________________________________________________________________________
1698{
1699 QWidget * targetpage = tabWidget_central->count() ? page_tabwidget : page_instructions;
1700 if (stackedWidget_central->currentWidget() != targetpage)
1701 stackedWidget_central->setCurrentWidget(targetpage);
1702}
1703
1704//_________________________________________________________________________________
1706{
1707 VP1Msg::messageVerbose("VP1MainWindow::quickSetupTriggered()");
1708
1709 QSettings settings("ATLAS", "VP1Light");
1710
1711 QString plugfile, channelname, tabname;
1712
1713 if (sender()==pushButton_quicksetup_geometrystudies||sender()==action_quicklaunch_Geometry_studies) {
1714
1715 //Open geometry database selection dialog for VP1Light
1716#ifdef BUILDVP1LIGHT
1717 if(settings.value("db/dbByEnv").toString().isEmpty()){
1718 VP1GeoDBSelection dbSelection;
1719 dbSelection.exec();
1720 if(!dbSelection.result())
1721 return;
1722 }
1723#endif // BUILDVP1LIGHT
1724
1725 plugfile="libVP1GeometryPlugin.so";
1726 channelname="Geometry";
1727 tabname = "Geometry";
1728 } else if (sender()==pushButton_quicksetup_trackingstudies||sender()==action_quicklaunch_Tracking_studies) {
1729 plugfile="libVP1TrackPlugin.so";
1730 channelname="Tracking";
1731 tabname = "Tracking";
1732 } else if (sender()==pushButton_quicksetup_calostudies||sender()==action_quicklaunch_Calo_studies) {
1733 plugfile="libVP1CaloPlugin.so";
1734 channelname="Calo Cells";
1735 tabname = "Calorimeter";
1736 } else if (sender()==action_quicklaunch_Storegate_browser) {
1737 plugfile="libVP1BanksPlugin.so";
1738 channelname="Banks";
1739 tabname = "StoreGate";
1740 } else if (sender()==pushButton_quicksetup_3dcocktail||sender()==action_quicklaunch_3dcocktail) {
1741#ifndef BUILDVP1LIGHT
1742 plugfile="libVP13DCocktailPlugin.so";
1743 channelname="3DCocktail";
1744 tabname = "3D Cocktail";
1745#else
1746 //Open Geometry DB and AOD file selection dialog for VP1Light
1747 if(settings.value("aod/aodByEnv").toString().isEmpty()){
1748 VP1AODSelection aodSelection;
1749 aodSelection.exec();
1750 if(!aodSelection.result())
1751 return;
1752 }
1753 if(settings.value("db/dbByEnv").toString().isEmpty()){
1754 VP1GeoDBSelection dbSelection;
1755 dbSelection.exec();
1756 if(!dbSelection.result())
1757 return;
1758 }
1759 m_scheduler->loadEvent();
1760
1761 pushButton_eventselect->setEnabled(true);
1762 plugfile="libVP1LightPlugin.so";
1763 channelname="VP1Light";
1764 tabname = "Geometry/AOD";
1765#endif // BUILDVP1LIGHT
1766 } else if (sender()==action_quicklaunch_trackcalo_commis) {
1767 plugfile="libVP13DCocktailPlugin.so";
1768 channelname="TrackCalo";
1769 tabname = "Track/Calo";
1770 } else if (sender()==pushButton_quicksetup_analysisstudies||sender()==action_quicklaunch_analysisstudies) {
1771
1772 //Open AOD file selection dialog for VP1Light
1773#ifdef BUILDVP1LIGHT
1774 if(settings.value("aod/aodByEnv").toString().isEmpty()){
1775 VP1AODSelection aodSelection;
1776 aodSelection.exec();
1777 if(!aodSelection.result())
1778 return;
1779 }
1780 m_scheduler->loadEvent();
1781 pushButton_eventselect->setEnabled(true);
1782#endif // BUILDVP1LIGHT
1783
1784 plugfile="libVP1AODPlugin.so";
1785 channelname="AOD";
1786 tabname = "Analysis";
1787 } else {
1788 addToMessageBox("quickSetupTriggered() Error: Unknown sender");
1789 return;
1790 }
1791
1792#ifdef __APPLE__
1793 if (plugfile.endsWith(".so"))
1794 plugfile = plugfile.left(plugfile.count()-3)+".dylib";
1795#endif
1796
1797
1798 //Check that the plugin is available:
1799 QMap<QString,QString> plugins2fullpath = availablePluginFiles();
1800 if(VP1Msg::debug()){
1801 qDebug() << "plugins2fullpath: " << plugins2fullpath;
1802 }
1803
1804 if (!plugins2fullpath.contains(plugfile)) {
1805 QMessageBox::critical(0, "Error - could not locate plugin file: "+plugfile,
1806 "could not locate plugin file: "
1807 +plugfile,QMessageBox::Ok,QMessageBox::Ok);
1808 return;
1809 }
1810 QString plugfile_fullpath = plugins2fullpath[plugfile];
1811
1812
1813 //Load plugin
1814 if (!m_channelmanager->currentPluginFiles().contains(plugfile_fullpath)) {
1815 QString err = m_channelmanager->loadPluginFile(plugfile_fullpath);
1816 if (!err.isEmpty()||!m_channelmanager->currentPluginFiles().contains(plugfile_fullpath)) {
1817 QMessageBox::critical(0, "Error - could not load plugin file: "+plugfile_fullpath,//Fixme: Error message here is hardcoded to be the same as in loadPluginFile method!!
1818 "Could not load plugin file: "
1819 +plugfile_fullpath+"\n\nReason: "+err,QMessageBox::Ok,QMessageBox::Ok);
1820 return;
1821 }
1822 }
1823
1824
1825 //Check that plugin contains necessary channel:
1826 if (!m_channelmanager->channelsInPluginFile(plugfile_fullpath).contains(channelname)) {
1827 QMessageBox::critical(0, "Error - did not find necessary channel: "+channelname,
1828 "Could not find channel: "+channelname+" in loaded plugin "+plugfile_fullpath,
1829 QMessageBox::Ok,QMessageBox::Ok);
1830 return;
1831 }
1832
1833 bool save = updatesEnabled();
1834 setUpdatesEnabled(false);
1835
1836
1837 //Add tab:
1838 QString newtabname = m_tabmanager->suggestNewTabName(tabname);
1839 m_tabmanager->addNewTab(newtabname);
1840 if (!m_tabmanager->hasTab(newtabname)) {
1841 QMessageBox::critical(0, "Error - could not create tab: "+newtabname,
1842 "Could not create tab: "+newtabname,
1843 QMessageBox::Ok,QMessageBox::Ok);
1844 setUpdatesEnabled(save);
1845 return;
1846 }
1847
1848
1849 //Finally, add channel:
1850
1851 if (!m_tabmanager->addChannelToTab( channelname, newtabname )) {
1852 QMessageBox::critical(0, "Error - problems launching channel: "+channelname,
1853 "Problems launching channel: "+channelname,
1854 QMessageBox::Ok,QMessageBox::Ok);
1855 setUpdatesEnabled(save);
1856 return;
1857 }
1858
1859
1860 m_tabmanager->showTab(newtabname);
1861
1862
1863 setUpdatesEnabled(save);
1864}
1865
1866//_________________________________________________________________________________
1868{
1869 pushButton_nextevent->setEnabled(okToProceedToNextEvent());
1870 #if defined BUILDVP1LIGHT
1871 pushButton_previousevent->setEnabled(okToProceedToNextEvent());
1872 #endif
1873}
1874
1875//_________________________________________________________________________________
1877{
1878 if(!m_mutex->tryLock()) return;
1879
1880 QFont f;
1881 QFont fb;
1882 fb.setBold(true);
1883
1884 for (QAction * act : m_inputdiractions) {
1885 VP1DirStatusData& dirstatus = m_inputdirstatuses[act];
1886 QString inputdir(act->data().toString());
1887 QString dirname = QDir(inputdir).dirName();
1888 act->setEnabled(dirstatus.enabled);
1889 act->setFont(dirstatus.bold?fb:f);
1890 act->setText(dirname+" ["+dirstatus.dirStatus+"]");
1891 }
1892
1893 m_mutex->unlock();
1894}
1895
1896//_________________________________________________________________________________
1898{
1899 QAction * act = dynamic_cast<QAction*>(sender());
1900 if (!act)
1901 return;
1902 VP1AvailEvtsLocalDir* availLocal = dynamic_cast<VP1AvailEvtsLocalDir*>(m_availEvents);
1903 if (!availLocal)
1904 return;
1905 QString inputdir(act->data().toString());
1906 QFileInfo fi(inputdir);
1907 if (fi.exists()&&fi.isDir()) {
1908 availLocal->setSourceDir(inputdir);
1909 std::cout<<VP1Msg::prefix_msg()<<": "
1910 <<"VP1Message: inputdirectory changed to "
1911 <<availLocal->currentSourceDir().toStdString()<<std::endl;
1912 m_currentStream = QDir(availLocal->currentSourceDir()).dirName();
1913 }
1914
1915
1916}
1917
1918//________________________________________________________________________________
1920{
1921 QStringList returnval(m_userRequestedFiles);
1922 m_userRequestedFiles.clear();
1923 return returnval;
1924}
1925
1926//_________________________________________________________________________________
1928{
1929 QString newEventFile = QFileDialog::getOpenFileName(NULL
1930 ,tr("Open Event File")
1932 ,tr("All files (*.*)"));
1933 if(newEventFile.isEmpty()) return;
1934 if(VP1FileUtilities::fileExistsAndReadable(newEventFile.toStdString())) {
1935 m_userRequestedFiles.append(newEventFile);
1936 addToMessageBox(newEventFile + " will be appended to the list of input files");
1937 }
1938 else
1939 QMessageBox::critical(0, newEventFile + " either does not exist or is not readable",
1940 newEventFile + " either does not exist or is not readable",
1941 QMessageBox::Ok,QMessageBox::Ok);
1942}
1943
1944//_________________________________________________________________________________
1945#ifdef BUILDVP1LIGHT
1946void VP1MainWindow::request_expertSettings(){
1948 es.exec();
1949}
1950
1951void VP1MainWindow::chooseEvent(){
1952 //Open event selection dialog for VP1Light
1953 VP1SelectEvent selectEvent(m_scheduler->getTotEvtNr(), m_scheduler->getEvtNr());
1954 selectEvent.exec();
1955 int newEvtNr = selectEvent.result()-1;
1956
1957 if( (newEvtNr >= 0) && (newEvtNr <= m_scheduler->getTotEvtNr()-1) ){
1958 m_scheduler->setEvtNr(newEvtNr);
1959 nextEvent();
1960 qApp->quit();
1961 }
1962}
1963#endif // BUILDVP1LIGHT
std::shared_ptr< HepMC3::Writer > writer
std::pair< std::vector< unsigned int >, bool > res
std::string toString(const float number)
Pipe a number to a string.
const char * pathvar
const double width
virtual QPixmap getSnapshot(bool transp=false, int width=0, bool batch=false)
virtual bool setAntiAliasing(bool aa)
const QString unique_name() const
virtual bool isAntiAliasing()
const QString & currentSourceDir() const
void setSourceDir(const QString &)
const QStringList & availableSourceDirectories() const
static QString highlightStyle()
const QString & sender() const
static bool fileExistsAndReadable(const std::string &)
void finishedIncomingDialog()
void request_loadPlugin()
void helperAddToMessageBox(const QString &)
void setRunEvtNumber(const int &runnumber, const unsigned long long &eventnumber, const unsigned &triggerType=0, const unsigned &time=0, const bool &printmessage=true)
void changeFontSize(int)
QQueue< VP1ExternalRequest > m_requestqueue
void updateCentralStackWidget()
void help_openUserSupport()
int m_defaultfont_pixelsize
QMenu * m_menu_changeFontSize
VP1EventDisplayEditor * m_edEditor
VP1AvailEvents * m_availEvents
void systemAddToMessageBox(const QString &)
void receivedExternalRequest(VP1ExternalRequest)
QLabel * m_statusbarlabel
void saveAllCurrentChannels()
QString m_currentconfigfile
double m_defaultfont_pointsize
void showMenu_loadConfFileItemSelected()
VP1ChannelManager * m_channelmanager
VP1TabManager * m_tabmanager
QString m_currentsaveimagepath
QString m_currentloadpluginpath
QMap< QString, QString > availablePluginFiles() const
VP1MainWindow(VP1ExecutionScheduler *, VP1AvailEvents *availEvents, QWidget *parent=0)
VP1IncomingMessageDialog * m_currentincomingdialog
QStringList userRequestedFiles()
void request_saveasConfig()
void addChannelIconsToComboBox(QComboBox *cb, const bool &isbasenames)
QAction * m_action_openUsersSupport
QMenu * m_menu_loadPlugin
void request_cruisemodechange()
QWidget * m_dummyemptycontroller
const QString m_settingsfile
QAction * m_actionSave_current_tabs
QList< VP1ExternalRequest > m_messages_blockedexactmessages
void addToMessageBox(const QString &, const QString &extrastyleopts="", const QString &title="", const QString &titleextrastyleopts="")
void replaceConfigurationFile(const QString &file)
QProgressBar * progressbar
QAction * m_action_openUsersGuide
void processEnqueuedRequests()
bool mustQuit() const
QStringList m_userRequestedFiles
void changeStyleActionTriggered()
QMenu * m_menu_loadConfFile
void unloadPlugin_continue()
QString m_currentStream
unsigned long long m_eventnumber
void help_openUserGuide()
QMap< QString, QString > availableFiles(const QString &extension, const QString &pathvar, const QString &instareasubdir, const QString &extradirenvvar, bool currentdir=false) const
bool okToProceedToNextEvent() const
unsigned m_timestamp
QAction * m_action_openVP1Site
void request_loadConfig()
QAction * m_actionAdd_empty_tab
void getAllChannelsIntoSnapshots(QList< QPixmap > &list, QStringList &listNames)
QString request_saveChannelSnapshot(const QString &xLabel="")
void inputDirectoryActionTriggered()
void loadConfigurationFromFile(const QString &file)
VP1PluginDialog * m_plugindialog
void closeEvent(QCloseEvent *event)
void channelAddToMessageBox(const QString &)
VP1DirStatuses m_inputdirstatuses
void request_printChannel()
VP1TcpServer m_tcpserver
QList< QAction * > m_inputdiractions
QAction * m_actionEnableExpertSettings
QStringList m_currentunloadpluginfiles
void loadPluginFile(const QString &filename)
VP1StreamMenuUpdater * m_streamMenuUpdater
void request_channelInformation()
VP1ExecutionScheduler * m_scheduler
void pluginDialogClosed()
void makeAllChannelsEventDisplay()
QAction * m_action_addEventFile
void changeFontSizeActionTriggered()
void selectedChannelChanged(IVP1ChannelWidget *)
void request_addEmptyTab()
void tabListChanged(const QStringList &)
QAction * m_action_openAbout
void launch3DstereoEditor()
void updateInputDirectoriesStatus()
void request_saveConfig()
void showMenu_loadConfFile()
void help_openVP1WebSite()
QList< QString > m_messages_blockedsenders
void showMenu_loadPluginItemSelected()
QMenu * m_menu_changeStyle
QPixmap getSingleChannelCustomSnapshot(IVP1ChannelWidget *tab, int width=0)
static bool debug()
Definition VP1Msg.h:32
static void messageVerbose(const QString &)
Definition VP1Msg.cxx:84
static void messageDebug(const QString &)
Definition VP1Msg.cxx:39
static void message(const QString &, IVP1System *sys=0)
Definition VP1Msg.cxx:30
static const char * prefix_msg()
Definition VP1Msg.h:56
static bool environmentVariableIsOn(const QString &name)
static bool expertSettingIsSet(const QString &type, const QString &name)
static QString expertSettingValue(const QString &type, const QString &name)
static QString defaultFileSelectDirectory()
int r
Definition globals.cxx:22
std::string replace(std::string s, const std::string &s2, const std::string &s3)
Definition hcg.cxx:312
bool contains(const std::string &s, const std::string &regx)
does a string contain the substring
Definition hcg.cxx:116
std::string base
Definition hcg.cxx:83
std::vector< std::string > split(const std::string &s, const std::string &t=":")
Definition hcg.cxx:179
output
Definition merge.py:16
TFile * file
std::string dirname(std::string name)
Definition utils.cxx:200