void JobListWidget::backupAllJobs()
{
    for(int i = 0; i < count(); ++i)
    {
        JobPtr job = static_cast<JobListWidgetItem *>(item(i))->job();
        emit   backupJob(job);
    }
}
void JobListWidget::backupItem()
{
    if(sender())
    {
        JobPtr job = qobject_cast<JobListWidgetItem *>(sender())->job();
        if(job)
            emit backupJob(job);
    }
}
void JobListWidget::backupSelectedItems()
{
    if(selectedItems().isEmpty())
        return;

    QMessageBox::StandardButton confirm =
        QMessageBox::question(this, tr("Confirm action"),
                              tr("Initiate backup for the %1 selected job(s)?")
                                  .arg(selectedItems().count()));
    if(confirm != QMessageBox::Yes)
        return;

    for(QListWidgetItem *item : selectedItems())
    {
        if(item->isSelected())
        {
            JobPtr job = static_cast<JobListWidgetItem *>(item)->job();
            emit   backupJob(job);
        }
    }
}
Exemple #4
0
MainWindow::MainWindow(QWidget *parent) :
    QWidget(parent),
    _ui(new Ui::MainWindow),
    _tarsnapLogo(this),
    _menuBar(NULL),
    _appMenu(NULL),
    _actionAbout(this),
    _useSIPrefixes(false),
    _purgeTimerCount(0),
    _purgeCountdownWindow(this)
{
    _ui->setupUi(this);

    _ui->backupListWidget->setAttribute(Qt::WA_MacShowFocusRect, false);
    _ui->archiveListWidget->setAttribute(Qt::WA_MacShowFocusRect, false);
    _ui->jobListWidget->setAttribute(Qt::WA_MacShowFocusRect, false);

    QPixmap logo(":/resources/icons/tarsnap.png");
    _tarsnapLogo.setPixmap(logo.scaled(200, 100, Qt::KeepAspectRatio, Qt::SmoothTransformation));
    _tarsnapLogo.adjustSize();
    _tarsnapLogo.lower();
    _tarsnapLogo.show();

    Ui::aboutWidget aboutUi;
    aboutUi.setupUi(&_aboutWindow);
    aboutUi.versionLabel->setText(tr("version ") + QCoreApplication::applicationVersion());
    _aboutWindow.setWindowFlags(Qt::CustomizeWindowHint|Qt::WindowCloseButtonHint);
    connect(aboutUi.checkUpdateButton, &QPushButton::clicked,
            [=](){
                QDesktopServices::openUrl(QUrl("https://github.com/Tarsnap/tarsnap-gui/releases"));
            });

    if(_menuBar.isNativeMenuBar())
    {
        _actionAbout.setMenuRole(QAction::AboutRole);
        connect(&_actionAbout, SIGNAL(triggered()), &_aboutWindow, SLOT(show()));
        _appMenu.addAction(&_actionAbout);
        _menuBar.addMenu(&_appMenu);
    }
    connect(_ui->aboutButton, SIGNAL(clicked()), &_aboutWindow, SLOT(show()));

    _ui->mainContentSplitter->setCollapsible(0, false);
    _ui->journalLog->hide();
    _ui->archiveDetailsWidget->hide();
    _ui->jobDetailsWidget->hide();

    connect(&Debug::instance(), SIGNAL(message(QString)), this , SLOT(appendToConsoleLog(QString))
            , Qt::QueuedConnection);

    loadSettings();

    // Ui actions
    _ui->mainTabWidget->setCurrentWidget(_ui->backupTab);
    _ui->settingsToolbox->setCurrentWidget(_ui->settingsAccountPage);

    _ui->archiveListWidget->addAction(_ui->actionRefresh);
    connect(_ui->actionRefresh, SIGNAL(triggered()), _ui->archiveListWidget
            , SIGNAL(getArchiveList()), Qt::QueuedConnection);
    _ui->backupListWidget->addAction(_ui->actionClearList);
    connect(_ui->actionClearList, SIGNAL(triggered()), _ui->backupListWidget
            , SLOT(clear()), Qt::QueuedConnection);
    _ui->backupListWidget->addAction(_ui->actionBrowseItems);
    connect(_ui->actionBrowseItems, SIGNAL(triggered()), this, SLOT(browseForBackupItems()));
    _ui->jobListWidget->addAction(_ui->actionAddJob);
    connect(_ui->actionAddJob, SIGNAL(triggered()), this, SLOT(addJobClicked()));
    _ui->jobListWidget->addAction(_ui->actionJobBackup);
    connect(_ui->actionJobBackup, SIGNAL(triggered()), _ui->jobListWidget, SLOT(backupSelectedItems()));
    _ui->settingsTab->addAction(_ui->actionRefreshStats);
    connect(_ui->actionRefreshStats, SIGNAL(triggered()), this, SIGNAL(getOverallStats()));
    this->addAction(_ui->actionGoBackup);
    this->addAction(_ui->actionGoBrowse);
    this->addAction(_ui->actionGoJobs);
    this->addAction(_ui->actionGoSettings);
    this->addAction(_ui->actionGoHelp);
    connect(_ui->actionGoBackup, &QAction::triggered,
            [=](){
                _ui->mainTabWidget->setCurrentWidget(_ui->backupTab);
            });
    connect(_ui->actionGoBrowse, &QAction::triggered,
            [=](){
                _ui->mainTabWidget->setCurrentWidget(_ui->archivesTab);
            });
    connect(_ui->actionGoJobs, &QAction::triggered,
            [=](){
                _ui->mainTabWidget->setCurrentWidget(_ui->jobsTab);
            });
    connect(_ui->actionGoSettings, &QAction::triggered,
            [=](){
                _ui->mainTabWidget->setCurrentWidget(_ui->settingsTab);
            });
    connect(_ui->actionGoHelp, &QAction::triggered,
            [=](){
                _ui->mainTabWidget->setCurrentWidget(_ui->helpTab);
            });

    connect(_ui->backupListInfoLabel, SIGNAL(linkActivated(QString)), this,
            SLOT(browseForBackupItems()));
    connect(_ui->backupButton, SIGNAL(clicked()), this, SLOT(backupButtonClicked()));
    connect(_ui->appendTimestampCheckBox, SIGNAL(toggled(bool)), this, SLOT(appendTimestampCheckBoxToggled(bool)));
    connect(_ui->accountMachineUseHostnameButton, SIGNAL(clicked()), this, SLOT(accountMachineUseHostnameButtonClicked()));
    connect(_ui->accountMachineKeyBrowseButton, SIGNAL(clicked()), this, SLOT(accountMachineKeyBrowseButtonClicked()));
    connect(_ui->tarsnapPathBrowseButton, SIGNAL(clicked()), this, SLOT(tarsnapPathBrowseButtonClicked()));
    connect(_ui->tarsnapCacheBrowseButton, SIGNAL(clicked()), this, SLOT(tarsnapCacheBrowseButton()));
    connect(_ui->repairCacheButton, SIGNAL(clicked()), this, SLOT(repairCacheButtonClicked()));
    connect(_ui->purgeArchivesButton, SIGNAL(clicked()), this, SLOT(purgeArchivesButtonClicked()));
    connect(_ui->runSetupWizard, SIGNAL(clicked()), this, SLOT(runSetupWizardClicked()));
    connect(_ui->expandJournalButton, SIGNAL(toggled(bool)), this, SLOT(expandJournalButtonToggled(bool)));
    connect(_ui->downloadsDirBrowseButton, SIGNAL(clicked()), this, SLOT(downloadsDirBrowseButtonClicked()));
    connect(_ui->busyWidget, SIGNAL(clicked()), this, SLOT(cancelRunningTasks()));

    connect(&_purgeTimer, SIGNAL(timeout()), this, SLOT(purgeTimerFired()));

    // Settings page
    connect(_ui->accountUserLineEdit, SIGNAL(editingFinished()), this, SLOT(commitSettings()));
    connect(_ui->accountMachineLineEdit, SIGNAL(editingFinished()), this, SLOT(commitSettings()));
    connect(_ui->accountMachineKeyLineEdit, SIGNAL(editingFinished()), this, SLOT(commitSettings()));
    connect(_ui->tarsnapPathLineEdit, SIGNAL(editingFinished()), this, SLOT(commitSettings()));
    connect(_ui->tarsnapCacheLineEdit, SIGNAL(editingFinished()), this, SLOT(commitSettings()));
    connect(_ui->aggressiveNetworkingCheckBox, SIGNAL(toggled(bool)), this, SLOT(commitSettings()));
    connect(_ui->accountMachineKeyLineEdit, SIGNAL(textChanged(QString)), this, SLOT(validateMachineKeyPath()));
    connect(_ui->tarsnapPathLineEdit, SIGNAL(textChanged(QString)), this, SLOT(validateTarsnapPath()));
    connect(_ui->tarsnapCacheLineEdit, SIGNAL(textChanged(QString)), this, SLOT(validateTarsnapCache()));
    connect(_ui->siPrefixesCheckBox, SIGNAL(toggled(bool)), this, SLOT(commitSettings()));
    connect(_ui->preservePathsCheckBox, SIGNAL(toggled(bool)), this, SLOT(commitSettings()));
    connect(_ui->downloadsDirLineEdit, SIGNAL(editingFinished()), this, SLOT(commitSettings()));
    connect(_ui->traverseMountCheckBox, SIGNAL(toggled(bool)), this, SLOT(commitSettings()));
    connect(_ui->followSymLinksCheckBox, SIGNAL(toggled(bool)), this, SLOT(commitSettings()));
    connect(_ui->skipFilesSpinBox, SIGNAL(editingFinished()), this, SLOT(commitSettings()));

    // Backup and Browse
    connect(_ui->backupListWidget, SIGNAL(itemTotals(qint64,qint64)), this
            , SLOT(updateBackupItemTotals(qint64, qint64)));
    connect(_ui->archiveListWidget, SIGNAL(getArchiveList()), this, SIGNAL(getArchiveList()));
    connect(this, SIGNAL(archiveList(QList<ArchivePtr >))
            , _ui->archiveListWidget, SLOT(addArchives(QList<ArchivePtr >)));
    connect(_ui->archiveListWidget, SIGNAL(inspectArchive(ArchivePtr)), this
            , SLOT(displayInspectArchive(ArchivePtr)));
    connect(_ui->archiveListWidget, SIGNAL(deleteArchives(QList<ArchivePtr>)), this
            , SIGNAL(deleteArchives(QList<ArchivePtr>)));
    connect(_ui->archiveListWidget, SIGNAL(restoreArchive(ArchivePtr,ArchiveRestoreOptions)),
            this, SIGNAL(restoreArchive(ArchivePtr,ArchiveRestoreOptions)));
    connect(_ui->mainTabWidget, SIGNAL(currentChanged(int)), this, SLOT(currentPaneChanged(int)));

    // Jobs
    connect(_ui->addJobButton, SIGNAL(clicked()), this, SLOT(addJobClicked()), Qt::QueuedConnection);
    connect(_ui->jobDetailsWidget, SIGNAL(cancel()), this, SLOT(hideJobDetails()), Qt::QueuedConnection);
    connect(_ui->jobDetailsWidget, SIGNAL(jobAdded(JobPtr)), _ui->jobListWidget, SLOT(addJob(JobPtr)), Qt::QueuedConnection);
    connect(_ui->jobDetailsWidget, SIGNAL(jobAdded(JobPtr)), this, SLOT(displayJobDetails(JobPtr)), Qt::QueuedConnection);
    connect(_ui->jobDetailsWidget, SIGNAL(inspectJobArchive(ArchivePtr)), this, SLOT(displayInspectArchive(ArchivePtr)), Qt::QueuedConnection);
    connect(_ui->jobDetailsWidget, SIGNAL(restoreJobArchive(ArchivePtr,ArchiveRestoreOptions)), this, SIGNAL(restoreArchive(ArchivePtr,ArchiveRestoreOptions)), Qt::QueuedConnection);
    connect(_ui->jobDetailsWidget, SIGNAL(deleteJobArchives(QList<ArchivePtr>)), this, SIGNAL(deleteArchives(QList<ArchivePtr>)), Qt::QueuedConnection);
    connect(_ui->jobDetailsWidget, SIGNAL(enableSave(bool)), _ui->addJobButton, SLOT(setEnabled(bool)), Qt::QueuedConnection);
    connect(_ui->jobListWidget, SIGNAL(displayJobDetails(JobPtr)), this, SLOT(displayJobDetails(JobPtr)), Qt::QueuedConnection);
    connect(_ui->jobListWidget, SIGNAL(backupJob(BackupTaskPtr)), this, SIGNAL(backupNow(BackupTaskPtr)), Qt::QueuedConnection);
    connect(_ui->jobListWidget, SIGNAL(restoreArchive(ArchivePtr,ArchiveRestoreOptions)), this, SIGNAL(restoreArchive(ArchivePtr,ArchiveRestoreOptions)), Qt::QueuedConnection);
    connect(_ui->jobListWidget, SIGNAL(deleteJobArchives(QList<ArchivePtr>)), this, SIGNAL(deleteArchives(QList<ArchivePtr>)), Qt::QueuedConnection);

    //lambda slots to quickly update various UI components
    connect(_ui->archiveListWidget, &ArchiveListWidget::getArchiveList,
            [=](){updateStatusMessage(tr("Refreshing archives list..."));});
    connect(this, &MainWindow::archiveList,
            [=](){updateStatusMessage(tr("Refreshing archives list...done"));});
    connect(this, &MainWindow::loadArchiveStats,
            [=](const ArchivePtr archive){updateStatusMessage(tr("Fetching details for archive <i>%1</i>.").arg(archive->name()));});
    connect(this, &MainWindow::loadArchiveContents,
            [=](const ArchivePtr archive){updateStatusMessage(tr("Fetching contents for archive <i>%1</i>.").arg(archive->name()));});
    connect(_ui->archiveListWidget, &ArchiveListWidget::deleteArchives,
            [=](const QList<ArchivePtr> archives){archivesDeleted(archives,false);});
    connect(_ui->backupNameLineEdit, &QLineEdit::textChanged,
            [=](const QString text){
                if(text.isEmpty())
                {
                    _ui->backupButton->setEnabled(false);
                    _ui->appendTimestampCheckBox->setChecked(false);
                }
                else if(_ui->backupListWidget->count())
                {
                    _ui->backupButton->setEnabled(true);
                }
            });
    connect(this, &MainWindow::restoreArchive,
            [=](const ArchivePtr archive){updateStatusMessage(tr("Restoring archive <i>%1</i>...").arg(archive->name()));});
    connect(_ui->downloadsDirLineEdit, &QLineEdit::textChanged,
            [=](){
                QFileInfo file(_ui->downloadsDirLineEdit->text());
                if(file.exists() && file.isDir() && file.isWritable())
                    _ui->downloadsDirLineEdit->setStyleSheet("QLineEdit{color:black;}");
                else
                    _ui->downloadsDirLineEdit->setStyleSheet("QLineEdit{color:red;}");
            });
    connect(_ui->jobListWidget, &JobListWidget::backupJob,
            [=](BackupTaskPtr backup){
                connect(backup, SIGNAL(statusUpdate(const TaskStatus&)), this, SLOT(backupTaskUpdate(const TaskStatus&)), Qt::QueuedConnection);
            });