37
37
#include " RemediationRoleSaver.h"
38
38
39
39
#include < QFileDialog>
40
+ #include < QPushButton>
40
41
#include < QAbstractEventDispatcher>
41
42
#include < QCloseEvent>
43
+ #include < QFileSystemWatcher>
42
44
#include < QDesktopWidget>
43
45
#include < QMenu>
44
46
@@ -85,6 +87,9 @@ MainWindow::MainWindow(QWidget* parent):
85
87
86
88
mIgnoreProfileComboBox(false ),
87
89
90
+ mFSWatch(new QFileSystemWatcher()),
91
+ mFSLastSeen(" " ),
92
+
88
93
mRuleResultsExpanded(false )
89
94
{
90
95
mUI .setupUi (this );
@@ -125,6 +130,10 @@ MainWindow::MainWindow(QWidget* parent):
125
130
mUI .actionOpenCustomizationFile , SIGNAL (triggered ()),
126
131
this , SLOT (openCustomizationFile ())
127
132
);
133
+ QObject::connect (
134
+ mUI .actionReloadContent , SIGNAL (triggered ()),
135
+ this , SLOT (reloadContent ())
136
+ );
128
137
QObject::connect (
129
138
mUI .checklistComboBox , SIGNAL (currentIndexChanged (int )),
130
139
this , SLOT (checklistComboboxChanged (int ))
@@ -272,6 +281,11 @@ MainWindow::MainWindow(QWidget* parent):
272
281
remediationButtonMenu->addAction (genAnsibleRemediation);
273
282
remediationButtonMenu->addAction (genPuppetRemediation);
274
283
mUI .genRemediationButton ->setMenu (remediationButtonMenu);
284
+
285
+ QObject::connect (
286
+ mFSWatch , SIGNAL (fileChanged (const QString&)),
287
+ this , SLOT (fileChanged (const QString&))
288
+ );
275
289
}
276
290
277
291
MainWindow::~MainWindow ()
@@ -288,6 +302,9 @@ MainWindow::~MainWindow()
288
302
289
303
delete mQSettings ;
290
304
mQSettings = 0 ;
305
+
306
+ delete mFSWatch ;
307
+ mFSWatch = NULL ;
291
308
}
292
309
293
310
void MainWindow::setSkipValid (bool skipValid)
@@ -333,7 +350,7 @@ void MainWindow::clearResults()
333
350
mUI .actionOpen ->setEnabled (true );
334
351
}
335
352
336
- void MainWindow::openFile (const QString& path)
353
+ void MainWindow::openFile (const QString& path, bool reload )
337
354
{
338
355
try
339
356
{
@@ -348,7 +365,7 @@ void MainWindow::openFile(const QString& path)
348
365
}
349
366
350
367
mScanningSession ->setSkipValid (mSkipValid );
351
- mScanningSession ->openFile (inputPath);
368
+ mScanningSession ->openFile (inputPath, reload );
352
369
353
370
// In case openscap autonegotiated opening a tailoring file directly
354
371
if (tailoringPath.isEmpty () && mScanningSession ->hasTailoring ())
@@ -375,6 +392,14 @@ void MainWindow::openFile(const QString& path)
375
392
376
393
centralWidget ()->setEnabled (true );
377
394
395
+ // Refill mFSWatch after opening file
396
+ mFSWatch ->removePaths (mFSWatch ->files ());
397
+ for (const QString path : mScanningSession ->getOriginalClosure ())
398
+ {
399
+ mFSWatch ->addPath (path);
400
+ }
401
+ mFSLastSeen = " " ;
402
+
378
403
mDiagnosticsDialog ->infoMessage (QObject::tr (" Opened file '%1'." ).arg (path));
379
404
}
380
405
catch (const std::exception& e)
@@ -423,7 +448,7 @@ void MainWindow::openFileDialog()
423
448
424
449
if (fileOpened ())
425
450
{
426
- if (openNewFileQuestionDialog (mScanningSession ->getOpenedFilePath ()) == QMessageBox::Yes)
451
+ if (openNewFileQuestionDialog (mScanningSession ->getOriginalFilePath ()) == QMessageBox::Yes)
427
452
closeFile ();
428
453
else
429
454
// user cancelled closing current file, we have to abort
@@ -489,7 +514,7 @@ void MainWindow::openSSGDialog(const QString& customDismissLabel)
489
514
490
515
if (fileOpened ())
491
516
{
492
- if (openNewFileQuestionDialog (mScanningSession ->getOpenedFilePath ()) == QMessageBox::Yes)
517
+ if (openNewFileQuestionDialog (mScanningSession ->getOriginalFilePath ()) == QMessageBox::Yes)
493
518
{
494
519
closeFile ();
495
520
}
@@ -524,6 +549,24 @@ void MainWindow::openTailoringFile(const QString& path)
524
549
refreshTailoringProfiles ();
525
550
}
526
551
552
+ void MainWindow::reloadContent ()
553
+ {
554
+ const QString currentFile = mScanningSession ->getOriginalFilePath ();
555
+ openFile (currentFile, true );
556
+
557
+ if (!fileOpened ())
558
+ {
559
+ // Error occurred, keep pumping events and don't move on until user
560
+ // dismisses diagnostics dialog.
561
+ mDiagnosticsDialog ->waitUntilHidden ();
562
+
563
+ if (!close ())
564
+ {
565
+ throw MainWindowException (" Failed to close main window!" );
566
+ }
567
+ }
568
+ }
569
+
527
570
void MainWindow::closeMainWindowAsync ()
528
571
{
529
572
emit closeMainWindow ();
@@ -581,6 +624,7 @@ void MainWindow::scanAsync(ScannerMode scannerMode)
581
624
582
625
mUI .menuSave ->setEnabled (false );
583
626
mUI .actionOpen ->setEnabled (false );
627
+ mUI .actionReloadContent ->setEnabled (false );
584
628
585
629
mUI .ruleResultsTree ->prepareForScanning ();
586
630
@@ -599,6 +643,7 @@ void MainWindow::scanAsync(ScannerMode scannerMode)
599
643
600
644
mUI .menuSave ->setEnabled (true );
601
645
mUI .actionOpen ->setEnabled (true );
646
+ mUI .actionReloadContent ->setEnabled (true );
602
647
603
648
return ;
604
649
}
@@ -1275,6 +1320,7 @@ void MainWindow::scanEnded(bool canceled)
1275
1320
1276
1321
mUI .menuSave ->setEnabled (true );
1277
1322
mUI .actionOpen ->setEnabled (true );
1323
+ mUI .actionReloadContent ->setEnabled (true );
1278
1324
1279
1325
cleanupScanThread ();
1280
1326
}
@@ -1507,6 +1553,29 @@ bool MainWindow::unsavedTailoringChanges() const
1507
1553
return mUI .tailoringFileComboBox ->currentIndex () == idx;
1508
1554
}
1509
1555
1556
+ void MainWindow::fileChanged (const QString& path)
1557
+ {
1558
+ if (path == mFSLastSeen )
1559
+ return ;
1560
+ mFSLastSeen = path;
1561
+
1562
+ QMessageBox question;
1563
+ question.setText (QObject::tr (" The following file was modified after opening: %1" ).arg (path));
1564
+ question.setInformativeText (QObject::tr (" Do you wish to reload it, losing any unsaved tailoring changes?" ));
1565
+
1566
+ QPushButton *reload = question.addButton (QObject::tr (" Reload" ), QMessageBox::AcceptRole);
1567
+ QPushButton *ignore = question.addButton (QObject::tr (" Ignore" ), QMessageBox::RejectRole);
1568
+ question.setDefaultButton (ignore);
1569
+ question.setIcon (QMessageBox::Question);
1570
+
1571
+ question.exec ();
1572
+
1573
+ if (question.clickedButton () == reload)
1574
+ {
1575
+ reloadContent ();
1576
+ }
1577
+ }
1578
+
1510
1579
QString MainWindow::getDefaultSaveDirectory ()
1511
1580
{
1512
1581
return mQSettings ->value (" last_save_directory" , " " ).toString ();
0 commit comments