Пример #1
0
JobWidget::JobWidget(QWidget *parent) :
    QWidget(parent),
    _ui(new Ui::JobWidget)
{
    _ui->setupUi(this);
    _ui->restoreListWidget->setAttribute(Qt::WA_MacShowFocusRect, false);

    connect(_ui->listArchivesButton, &QPushButton::clicked,
            [=](){
                _ui->stackedWidget->setCurrentWidget(_ui->jobRestorePage);
            });
    connect(_ui->restoreBackButton, &QPushButton::clicked,
            [=](){
                _ui->stackedWidget->setCurrentWidget(_ui->jobDetailPage);
            });
    connect(_ui->optionsBackButton, &QPushButton::clicked,
            [=](){
            if(_job->objectKey().isEmpty())
                _ui->stackedWidget->setCurrentWidget(_ui->jobNewPage);
            else
                _ui->stackedWidget->setCurrentWidget(_ui->jobDetailPage);
            });
    connect(_ui->optionsButton, &QPushButton::clicked,
            [=](){
                _ui->stackedWidget->setCurrentWidget(_ui->jobOptionsPage);
            });
    connect(_ui->jobNameLineEdit, &QLineEdit::textChanged,
            [=](){
                    emit enableSave(canSaveNew());
            });
    connect(_ui->newJobTreeWidget, &FilePicker::selectionChanged,
            [=](){
                    emit enableSave(canSaveNew());
            });
    connect(_ui->newJobOptionsButton, &QPushButton::clicked,
            [=](){
                _ui->stackedWidget->setCurrentWidget(_ui->jobOptionsPage);
            });

    connect(_ui->detailTreeWidget, SIGNAL(focusLost()), this, SLOT(save()));
    connect(_ui->preservePathsCheckBox, SIGNAL(toggled(bool)), this, SLOT(save()));
    connect(_ui->traverseMountCheckBox, SIGNAL(toggled(bool)), this, SLOT(save()));
    connect(_ui->followSymLinksCheckBox, SIGNAL(toggled(bool)), this, SLOT(save()));
    connect(_ui->skipFilesSpinBox, SIGNAL(valueChanged(int)), this, SLOT(save()));
    connect(_ui->cancelButton, SIGNAL(clicked()), this, SIGNAL(cancel()));
    connect(_ui->restoreLatestArchiveButton, SIGNAL(clicked()), this, SLOT(restoreLatestArchive()));
    connect(_ui->restoreListWidget, SIGNAL(inspectArchive(ArchivePtr)), this, SIGNAL(inspectJobArchive(ArchivePtr)));
    connect(_ui->restoreListWidget, SIGNAL(restoreArchive(ArchivePtr,ArchiveRestoreOptions)), this, SIGNAL(restoreJobArchive(ArchivePtr,ArchiveRestoreOptions)));
    connect(_ui->restoreListWidget, SIGNAL(deleteArchives(QList<ArchivePtr>)), this, SIGNAL(deleteJobArchives(QList<ArchivePtr>)));
}
Пример #2
0
void ArchiveListWidget::restoreItem()
{
    ArchiveListWidgetItem *archiveItem =
        qobject_cast<ArchiveListWidgetItem *>(sender());
    if(archiveItem)
    {
        RestoreDialog *restoreDialog =
            new RestoreDialog(this, archiveItem->archive());
        restoreDialog->show();
        connect(restoreDialog, &RestoreDialog::accepted, [=] {
            emit restoreArchive(restoreDialog->archive(),
                                restoreDialog->getOptions());
        });
    }
}
Пример #3
0
void JobListWidget::restoreItem()
{
    if(sender())
    {
        JobPtr job = qobject_cast<JobListWidgetItem *>(sender())->job();
        if(!job->archives().isEmpty())
        {
            ArchivePtr     archive       = job->archives().first();
            RestoreDialog *restoreDialog = new RestoreDialog(this, archive);
            restoreDialog->show();
            connect(restoreDialog, &RestoreDialog::accepted, [=] {
                emit restoreArchive(restoreDialog->archive(),
                                    restoreDialog->getOptions());
            });
        }
    }
}
Пример #4
0
void ArchiveListWidget::restoreSelectedItem()
{
    if(!selectedItems().isEmpty())
    {
        ArchiveListWidgetItem *archiveItem =
            static_cast<ArchiveListWidgetItem *>(selectedItems().first());
        if(archiveItem && !archiveItem->archive()->deleteScheduled())
        {
            RestoreDialog *restoreDialog =
                new RestoreDialog(this, archiveItem->archive());
            restoreDialog->show();
            connect(restoreDialog, &RestoreDialog::accepted, [=] {
                emit restoreArchive(restoreDialog->archive(),
                                    restoreDialog->getOptions());
            });
        }
    }
}
Пример #5
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);
            });