LIBS += -mwindows -L../win32/release64 -lbacula
}
!cross-win32 {
- LIBS += -L../lib -lbac -L../findlib -lbacfind -L/opt/local/lib -lssl -lcrypto
+ LIBS += -L../lib -lbac -L../findlib -lbacfind -lssl -lcrypto
}
qwt {
--- /dev/null
+/*
+ Bacula(R) - The Network Backup Solution
+
+ Copyright (C) 2000-2017 Kern Sibbald
+
+ The original author of Bacula is Kern Sibbald, with contributions
+ from many others, a complete list can be found in the file AUTHORS.
+
+ You may use this file and others of this release according to the
+ license defined in the LICENSE file, which includes the Affero General
+ Public License, v3.0 ("AGPLv3") and some additional permissions and
+ terms pursuant to its AGPLv3 Section 7.
+
+ This notice must be preserved when any source code is
+ conveyed and/or propagated.
+
+ Bacula(R) is a registered trademark of Kern Sibbald.
+*/
+#include "clientselectwizardpage.h"
+#include "ui_clientselectwizardpage.h"
+#include "common.h"
+ClientSelectWizardPage::ClientSelectWizardPage(QWidget *parent) :
+ QWizardPage(parent),
+ ui(new Ui::ClientSelectWizardPage)
+{
+ ui->setupUi(this);
+
+ registerField("currentClient*", ui->backupClientComboBox);
+}
+
+ClientSelectWizardPage::~ClientSelectWizardPage()
+{
+ delete ui;
+}
+
+void ClientSelectWizardPage::setClients(alist *lst)
+{
+ if (lst && lst->size() > 0) {
+ ui->backupClientComboBox->clear();
+ QStringList list;
+ char *str;
+ foreach_alist(str, lst) {
+ list << QString(str);
+ }
+ ui->backupClientComboBox->addItems(list);
+ ui->backupClientComboBox->setEnabled(true);
+ } else {
+ ui->backupClientComboBox->setEnabled(false);
+ }
+}
--- /dev/null
+/*
+ Bacula(R) - The Network Backup Solution
+
+ Copyright (C) 2000-2017 Kern Sibbald
+
+ The original author of Bacula is Kern Sibbald, with contributions
+ from many others, a complete list can be found in the file AUTHORS.
+
+ You may use this file and others of this release according to the
+ license defined in the LICENSE file, which includes the Affero General
+ Public License, v3.0 ("AGPLv3") and some additional permissions and
+ terms pursuant to its AGPLv3 Section 7.
+
+ This notice must be preserved when any source code is
+ conveyed and/or propagated.
+
+ Bacula(R) is a registered trademark of Kern Sibbald.
+*/
+#ifndef CLIENTSELECTWIZARDPAGE_H
+#define CLIENTSELECTWIZARDPAGE_H
+
+#include <QWizardPage>
+
+class alist;
+
+namespace Ui {
+class ClientSelectWizardPage;
+}
+
+class ClientSelectWizardPage : public QWizardPage
+{
+ Q_OBJECT
+
+public:
+ explicit ClientSelectWizardPage(QWidget *parent = 0);
+ ~ClientSelectWizardPage();
+
+ void setClients(alist *lst);
+
+private:
+ Ui::ClientSelectWizardPage *ui;
+};
+
+#endif // CLIENTSELECTWIZARDPAGE_H
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>ClientSelectWizardPage</class>
+ <widget class="QWizardPage" name="ClientSelectWizardPage">
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>714</width>
+ <height>330</height>
+ </rect>
+ </property>
+ <property name="windowTitle">
+ <string>WizardPage</string>
+ </property>
+ <layout class="QHBoxLayout" name="horizontalLayout">
+ <item>
+ <widget class="QLabel" name="backupClientLabel">
+ <property name="enabled">
+ <bool>true</bool>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Expanding" vsizetype="Expanding">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="minimumSize">
+ <size>
+ <width>0</width>
+ <height>0</height>
+ </size>
+ </property>
+ <property name="contextMenuPolicy">
+ <enum>Qt::DefaultContextMenu</enum>
+ </property>
+ <property name="text">
+ <string>Backup Client:</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QComboBox" name="backupClientComboBox">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="MinimumExpanding" vsizetype="Fixed">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="minimumSize">
+ <size>
+ <width>595</width>
+ <height>0</height>
+ </size>
+ </property>
+ <property name="accessibleName">
+ <string/>
+ </property>
+ <property name="currentIndex">
+ <number>-1</number>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ <resources/>
+ <connections/>
+</ui>
--- /dev/null
+/*
+ Bacula(R) - The Network Backup Solution
+
+ Copyright (C) 2000-2017 Kern Sibbald
+
+ The original author of Bacula is Kern Sibbald, with contributions
+ from many others, a complete list can be found in the file AUTHORS.
+
+ You may use this file and others of this release according to the
+ license defined in the LICENSE file, which includes the Affero General
+ Public License, v3.0 ("AGPLv3") and some additional permissions and
+ terms pursuant to its AGPLv3 Section 7.
+
+ This notice must be preserved when any source code is
+ conveyed and/or propagated.
+
+ Bacula(R) is a registered trademark of Kern Sibbald.
+*/
+#include "fileselectwizardpage.h"
+#include "ui_fileselectwizardpage.h"
+#include "task.h"
+#include "filesmodel.h"
+#include <QStandardItemModel>
+
+FileSelectWizardPage::FileSelectWizardPage(QWidget *parent) :
+ QWizardPage(parent),
+ ui(new Ui::FileSelectWizardPage),
+ currentPathId(0)
+{
+ ui->setupUi(this);
+ registerField("currentFile", this, "currentFile", "currentFileChanged");
+
+ connect(ui->sourceListView, SIGNAL(activated(const QModelIndex&)), this, SLOT(changeCurrentFolder(const QModelIndex&)));
+ ui->sourceListView->setLayoutMode(QListView::Batched);
+ ui->sourceListView->setBatchSize(BATCH_SIZE);
+
+ /* FIXME : need context menu + shortcuts for del */
+ FileDestModel *destModel = new FileDestModel();
+ connect(destModel, SIGNAL(rowsInserted(const QModelIndex &, int, int)), this, SIGNAL(completeChanged()));
+ connect(destModel, SIGNAL(rowsRemoved(const QModelIndex &, int, int)), this, SIGNAL(completeChanged()));
+ ui->destListView->setModel(destModel);
+
+
+}
+
+FileSelectWizardPage::~FileSelectWizardPage()
+{
+ delete ui;
+}
+
+void FileSelectWizardPage::setModels(QStandardItemModel *src_model, QStandardItemModel *dest_model)
+{
+ ui->sourceListView->setModel(src_model);
+ src_model->clear();
+ currentPathId = 0;
+
+ ui->destListView->setModel(dest_model);
+ connect(dest_model, SIGNAL(rowsInserted(const QModelIndex &, int, int)), this, SIGNAL(completeChanged()));
+ connect(dest_model, SIGNAL(rowsRemoved(const QModelIndex &, int, int)), this, SIGNAL(completeChanged()));
+
+}
+
+qulonglong FileSelectWizardPage::currentFile() const
+{
+ return currentPathId;
+}
+
+void FileSelectWizardPage::changeCurrentFolder(const QModelIndex& current)
+{
+ if (current.isValid() && ui->sourceListView->model()) {
+ QStandardItem *item = ((QStandardItemModel *)ui->sourceListView->model())->itemFromIndex(current);
+ if (item && item->data(TypeRole) == TYPEROLE_DIRECTORY) {
+ currentPathId = item->data(PathIdRole).toULongLong();
+ emit currentFileChanged();
+ }
+ }
+}
+
+bool FileSelectWizardPage::isComplete() const
+{
+ return ui->destListView->model() && ui->destListView->model()->rowCount() != 0;
+}
--- /dev/null
+/*
+ Bacula(R) - The Network Backup Solution
+
+ Copyright (C) 2000-2017 Kern Sibbald
+
+ The original author of Bacula is Kern Sibbald, with contributions
+ from many others, a complete list can be found in the file AUTHORS.
+
+ You may use this file and others of this release according to the
+ license defined in the LICENSE file, which includes the Affero General
+ Public License, v3.0 ("AGPLv3") and some additional permissions and
+ terms pursuant to its AGPLv3 Section 7.
+
+ This notice must be preserved when any source code is
+ conveyed and/or propagated.
+
+ Bacula(R) is a registered trademark of Kern Sibbald.
+*/
+#ifndef FILESELECTWIZARDPAGE_H
+#define FILESELECTWIZARDPAGE_H
+
+#include <QWizardPage>
+
+class QStandardItemModel;
+class QModelIndex;
+
+namespace Ui {
+class FileSelectWizardPage;
+}
+
+class FileSelectWizardPage : public QWizardPage
+{
+ Q_OBJECT
+ Q_PROPERTY(qulonglong currentFile READ currentFile NOTIFY currentFileChanged)
+
+public:
+ explicit FileSelectWizardPage(QWidget *parent = 0);
+ ~FileSelectWizardPage();
+
+ void setModels(QStandardItemModel *src_model, QStandardItemModel *dest_model);
+
+ qulonglong currentFile() const;
+
+ bool isComplete() const;
+
+signals:
+ void currentFileChanged();
+
+protected slots:
+ void changeCurrentFolder(const QModelIndex& current);
+
+private:
+ Ui::FileSelectWizardPage *ui;
+ qulonglong currentPathId;
+};
+
+#endif // FILESELECTWIZARDPAGE_H
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>FileSelectWizardPage</class>
+ <widget class="QWizardPage" name="FileSelectWizardPage">
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>739</width>
+ <height>437</height>
+ </rect>
+ </property>
+ <property name="windowTitle">
+ <string>WizardPage</string>
+ </property>
+ <layout class="QGridLayout" name="gridLayout">
+ <item row="0" column="0">
+ <widget class="QGroupBox" name="groupBox">
+ <property name="title">
+ <string>Drag from left to right</string>
+ </property>
+ <layout class="QHBoxLayout" name="horizontalLayout">
+ <item>
+ <widget class="QListView" name="sourceListView">
+ <property name="editTriggers">
+ <set>QAbstractItemView::NoEditTriggers</set>
+ </property>
+ <property name="showDropIndicator" stdset="0">
+ <bool>false</bool>
+ </property>
+ <property name="dragEnabled">
+ <bool>true</bool>
+ </property>
+ <property name="dragDropMode">
+ <enum>QAbstractItemView::DragOnly</enum>
+ </property>
+ <property name="alternatingRowColors">
+ <bool>true</bool>
+ </property>
+ <property name="selectionMode">
+ <enum>QAbstractItemView::ExtendedSelection</enum>
+ </property>
+ <property name="selectionBehavior">
+ <enum>QAbstractItemView::SelectRows</enum>
+ </property>
+ <property name="layoutMode">
+ <enum>QListView::Batched</enum>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QListView" name="destListView">
+ <property name="acceptDrops">
+ <bool>false</bool>
+ </property>
+ <property name="editTriggers">
+ <set>QAbstractItemView::NoEditTriggers</set>
+ </property>
+ <property name="dragEnabled">
+ <bool>true</bool>
+ </property>
+ <property name="dragDropOverwriteMode">
+ <bool>false</bool>
+ </property>
+ <property name="dragDropMode">
+ <enum>QAbstractItemView::DropOnly</enum>
+ </property>
+ <property name="defaultDropAction">
+ <enum>Qt::CopyAction</enum>
+ </property>
+ <property name="selectionMode">
+ <enum>QAbstractItemView::ExtendedSelection</enum>
+ </property>
+ <property name="selectionBehavior">
+ <enum>QAbstractItemView::SelectRows</enum>
+ </property>
+ <property name="layoutMode">
+ <enum>QListView::Batched</enum>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ <resources/>
+ <connections/>
+</ui>
--- /dev/null
+/*
+ Bacula(R) - The Network Backup Solution
+
+ Copyright (C) 2000-2017 Kern Sibbald
+
+ The original author of Bacula is Kern Sibbald, with contributions
+ from many others, a complete list can be found in the file AUTHORS.
+
+ You may use this file and others of this release according to the
+ license defined in the LICENSE file, which includes the Affero General
+ Public License, v3.0 ("AGPLv3") and some additional permissions and
+ terms pursuant to its AGPLv3 Section 7.
+
+ This notice must be preserved when any source code is
+ conveyed and/or propagated.
+
+ Bacula(R) is a registered trademark of Kern Sibbald.
+*/
+#ifndef FILESMODEL_H
+#define FILESMODEL_H
+#include <QStandardItemModel>
+#include <QFileIconProvider>
+#include <QMimeData>
+#include "task.h"
+enum {
+ PathIdRole = Qt::UserRole+1,
+ FilenameIdRole = Qt::UserRole+2,
+ FileIdRole = Qt::UserRole+3,
+ JobIdRole = Qt::UserRole+4,
+ LStatRole = Qt::UserRole+5,
+ PathRole = Qt::UserRole+6,
+ TypeRole = Qt::UserRole+7
+};
+
+enum {
+ TYPEROLE_DIRECTORY = 0,
+ TYPEROLE_FILE
+};
+
+class DirectoryItem : public QStandardItem
+{
+public:
+ DirectoryItem() : QStandardItem()
+ {
+ /* explicit set the data, so it can be serialized in Mime Data for D&D */
+ setData(QVariant(TYPEROLE_DIRECTORY), TypeRole);
+ }
+ QVariant data(int role = Qt::UserRole + 1) const
+ {
+ if (role == Qt::DecorationRole) {
+ QFileIconProvider provider;
+ return provider.icon(QFileIconProvider::Folder);
+ }
+
+ return QStandardItem::data(role);
+ }
+};
+
+class FileItem : public QStandardItem
+{
+public:
+ FileItem() : QStandardItem()
+ {
+ /* explicit set the data, so it can be serialized in Mime Data for D&D */
+ setData(QVariant(TYPEROLE_FILE), TypeRole);
+ }
+ enum {
+ FILE_TYPE = UserType +2
+ };
+
+ QVariant data(int role = Qt::UserRole + 1) const
+ {
+ if (role == Qt::DecorationRole) {
+ QFileIconProvider provider;
+ return provider.icon(QFileIconProvider::File);
+ }
+
+ return QStandardItem::data(role);
+ }
+};
+
+#define BATCH_SIZE 100
+class FileSourceModel : public QStandardItemModel
+{
+public:
+ FileSourceModel() : QStandardItemModel(),
+ m_cursor(0),
+ m_batchSize(BATCH_SIZE),
+ m_canFetchMore(true)
+ {}
+
+ bool canFetchMore(const QModelIndex &parent) const
+ {
+ Q_UNUSED(parent)
+ return false/*m_canFetchMore*/;
+ }
+ void fetchMore(const QModelIndex &parent)
+ {
+ Q_UNUSED(parent)
+ }
+
+public slots:
+ void taskComplete(task *t)
+ {
+ // increase cursor
+ // update canfetch
+ // deletelater
+ t->deleteLater();
+ }
+
+private:
+ u_int64_t m_cursor;
+ u_int64_t m_batchSize;
+ bool m_canFetchMore;
+};
+
+class FileDestModel : public QStandardItemModel
+{
+ bool canDropMimeData(const QMimeData *data, Qt::DropAction action, int row, int column, const QModelIndex &parent) const
+ {
+ Q_UNUSED(action)
+ Q_UNUSED(row)
+ Q_UNUSED(column)
+ Q_UNUSED(parent)
+
+ if (data->hasFormat("application/x-qstandarditemmodeldatalist")) {
+ QByteArray encoded = data->data("application/x-qabstractitemmodeldatalist");
+ QDataStream stream(&encoded, QIODevice::ReadOnly);
+
+ while (!stream.atEnd())
+ {
+ int row, col;
+ QMap<int, QVariant> roleDataMap;
+ stream >> row >> col >> roleDataMap;
+
+ /* do something with the data */
+ int type = roleDataMap[TypeRole].toInt();
+
+ switch(type) {
+ case TYPEROLE_DIRECTORY:
+ case TYPEROLE_FILE:
+ break;
+ default:
+ return false;
+ }
+ }
+ return true;
+ }
+ return false;
+ }
+
+ bool dropMimeData(const QMimeData * data, Qt::DropAction action, int row, int column, const QModelIndex & parent)
+ {
+ Q_UNUSED(action)
+ Q_UNUSED(row)
+ Q_UNUSED(column)
+ Q_UNUSED(parent)
+
+ QByteArray encoded = data->data("application/x-qabstractitemmodeldatalist");
+ QDataStream stream(&encoded, QIODevice::ReadOnly);
+
+ while (!stream.atEnd())
+ {
+ int row, col;
+ QMap<int, QVariant> roleDataMap;
+ stream >> row >> col >> roleDataMap;
+
+ QStandardItem *item;
+ /* do something with the data */
+ int type = roleDataMap[TypeRole].toInt();
+
+ switch(type) {
+ case TYPEROLE_DIRECTORY:
+ item = new DirectoryItem();
+ break;
+ case TYPEROLE_FILE:
+ item = new FileItem();
+ break;
+ default:
+ return false;
+ }
+
+ item->setData(roleDataMap[PathIdRole], PathIdRole);
+ item->setData(roleDataMap[FilenameIdRole], FilenameIdRole);
+ item->setData(roleDataMap[FileIdRole], FileIdRole);
+ item->setData(roleDataMap[JobIdRole], JobIdRole);
+ item->setData(roleDataMap[LStatRole], LStatRole);
+ item->setData(roleDataMap[PathRole], PathRole);
+ item->setData(roleDataMap[PathRole], Qt::DisplayRole);
+
+ appendRow(item);
+ }
+ return true;
+ }
+};
+
+#endif // FILESMODEL_H
--- /dev/null
+/*
+ Bacula(R) - The Network Backup Solution
+
+ Copyright (C) 2000-2017 Kern Sibbald
+
+ The original author of Bacula is Kern Sibbald, with contributions
+ from many others, a complete list can be found in the file AUTHORS.
+
+ You may use this file and others of this release according to the
+ license defined in the LICENSE file, which includes the Affero General
+ Public License, v3.0 ("AGPLv3") and some additional permissions and
+ terms pursuant to its AGPLv3 Section 7.
+
+ This notice must be preserved when any source code is
+ conveyed and/or propagated.
+
+ Bacula(R) is a registered trademark of Kern Sibbald.
+*/
+#include "jobselectwizardpage.h"
+#include "ui_jobselectwizardpage.h"
+#include <QStandardItemModel>
+
+JobSelectWizardPage::JobSelectWizardPage(QWidget *parent) :
+ QWizardPage(parent),
+ ui(new Ui::JobSelectWizardPage)
+{
+ ui->setupUi(this);
+ registerField("currentJob*", this, "currentJob", SIGNAL(currentJobChanged()));
+}
+
+JobSelectWizardPage::~JobSelectWizardPage()
+{
+ delete ui;
+}
+
+void JobSelectWizardPage::setModel(QStandardItemModel *model)
+{
+ ui->BackupTableView->setModel(model);
+
+ connect(ui->BackupTableView->selectionModel(), SIGNAL(selectionChanged(const QItemSelection&, const QItemSelection&)), this, SIGNAL(completeChanged()));
+ connect(ui->BackupTableView->selectionModel(), SIGNAL(selectionChanged(const QItemSelection&, const QItemSelection&)), this, SIGNAL(currentJobChanged()));
+}
+
+bool JobSelectWizardPage::isComplete() const
+{
+ int s = ui->BackupTableView->selectionModel() ?
+ ui->BackupTableView->selectionModel()->selectedRows().size() : 0;
+
+ return (ui->BackupTableView->selectionModel() && s>0);
+}
+
+void JobSelectWizardPage::optimizeSize()
+{
+ ui->BackupTableView->resizeColumnsToContents();
+ ui->BackupTableView->horizontalHeader()->setStretchLastSection(true);
+ ui->BackupTableView->horizontalHeader()->setSortIndicator(0, Qt::AscendingOrder);
+}
+
+u_int64_t JobSelectWizardPage::currentJob() const
+{
+ if (ui->BackupTableView->selectionModel())
+ {
+ QModelIndex idx = ui->BackupTableView->selectionModel()->currentIndex();
+ /* return the JobId (column 0) */
+ QModelIndex idIdx = idx.sibling(idx.row(), 0);
+ return idIdx.data().toULongLong();
+ }
+ return -1;
+}
--- /dev/null
+/*
+ Bacula(R) - The Network Backup Solution
+
+ Copyright (C) 2000-2017 Kern Sibbald
+
+ The original author of Bacula is Kern Sibbald, with contributions
+ from many others, a complete list can be found in the file AUTHORS.
+
+ You may use this file and others of this release according to the
+ license defined in the LICENSE file, which includes the Affero General
+ Public License, v3.0 ("AGPLv3") and some additional permissions and
+ terms pursuant to its AGPLv3 Section 7.
+
+ This notice must be preserved when any source code is
+ conveyed and/or propagated.
+
+ Bacula(R) is a registered trademark of Kern Sibbald.
+*/
+#ifndef JOBSELECTWIZARDPAGE_H
+#define JOBSELECTWIZARDPAGE_H
+
+#include <QWizardPage>
+
+class QStandardItemModel;
+class QItemSelection;
+
+namespace Ui {
+class JobSelectWizardPage;
+}
+
+class JobSelectWizardPage : public QWizardPage
+{
+ Q_OBJECT
+ Q_PROPERTY(qlonglong currentJob READ currentJob NOTIFY currentJobChanged)
+
+public:
+ explicit JobSelectWizardPage(QWidget *parent = 0);
+ ~JobSelectWizardPage();
+
+ void setModel(QStandardItemModel *model);
+
+ u_int64_t currentJob() const;
+
+ bool isComplete() const;
+
+signals:
+ void currentJobChanged();
+
+public slots:
+ void optimizeSize();
+
+private:
+ Ui::JobSelectWizardPage *ui;
+ qlonglong m_jobId;
+};
+
+#endif // JOBSELECTWIZARDPAGE_H
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>JobSelectWizardPage</class>
+ <widget class="QWizardPage" name="JobSelectWizardPage">
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>706</width>
+ <height>360</height>
+ </rect>
+ </property>
+ <property name="windowTitle">
+ <string>WizardPage</string>
+ </property>
+ <layout class="QGridLayout" name="gridLayout">
+ <item row="0" column="0">
+ <widget class="QTableView" name="BackupTableView">
+ <property name="editTriggers">
+ <set>QAbstractItemView::NoEditTriggers</set>
+ </property>
+ <property name="selectionMode">
+ <enum>QAbstractItemView::SingleSelection</enum>
+ </property>
+ <property name="selectionBehavior">
+ <enum>QAbstractItemView::SelectRows</enum>
+ </property>
+ <property name="sortingEnabled">
+ <bool>true</bool>
+ </property>
+ <property name="wordWrap">
+ <bool>false</bool>
+ </property>
+ <property name="cornerButtonEnabled">
+ <bool>false</bool>
+ </property>
+ <attribute name="horizontalHeaderHighlightSections">
+ <bool>false</bool>
+ </attribute>
+ <attribute name="horizontalHeaderStretchLastSection">
+ <bool>true</bool>
+ </attribute>
+ <attribute name="verticalHeaderVisible">
+ <bool>false</bool>
+ </attribute>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ <resources/>
+ <connections/>
+</ui>
--- /dev/null
+/*
+ Bacula(R) - The Network Backup Solution
+
+ Copyright (C) 2000-2017 Kern Sibbald
+
+ The original author of Bacula is Kern Sibbald, with contributions
+ from many others, a complete list can be found in the file AUTHORS.
+
+ You may use this file and others of this release according to the
+ license defined in the LICENSE file, which includes the Affero General
+ Public License, v3.0 ("AGPLv3") and some additional permissions and
+ terms pursuant to its AGPLv3 Section 7.
+
+ This notice must be preserved when any source code is
+ conveyed and/or propagated.
+
+ Bacula(R) is a registered trademark of Kern Sibbald.
+*/
+#include "jobsmodel.h"
+
+JobsModel::JobsModel(const QList<row_struct>& t, QObject *parent)
+ : QAbstractTableModel(parent)
+ , table(t)
+{
+}
+
+QVariant JobsModel::headerData(int section, Qt::Orientation orientation, int role) const
+{
+ if (role != Qt::DisplayRole)
+ return QVariant();
+
+ if (orientation == Qt::Horizontal) {
+ switch (section) {
+ case ID_COLUMN:
+ return tr("Id");
+ case TDATE_COLUMN:
+ return tr("Date");
+ case HASCACHE_COLUMN:
+ return tr("Cache");
+ case NAME_COLUMN:
+ return tr("Name");
+ default:
+ return QVariant();
+ }
+ }
+ return QVariant();
+
+
+ return QVariant();
+}
+
+int JobsModel::rowCount(const QModelIndex &parent) const
+{
+ if (parent.isValid())
+ return 0;
+
+ return table.size();
+}
+
+int JobsModel::columnCount(const QModelIndex &parent) const
+{
+ if (parent.isValid())
+ return 0;
+
+ return NUM_COLUMN;
+}
+
+QVariant JobsModel::data(const QModelIndex &index, int role) const
+{
+ if (!index.isValid())
+ return QVariant();
+
+ if (index.row() >= table.size() || index.row() < 0)
+ return QVariant();
+
+ if (index.column() >= NUM_COLUMN || index.column() < 0)
+ return QVariant();
+
+ if (role == Qt::DisplayRole) {
+ row_struct row = table.at(index.row());
+ switch(index.column())
+ {
+ case 0:
+ return quint64(row.id);
+ break;
+ case 1:
+ return row.tdate;
+ break;
+ case 2:
+ return row.hasCache;
+ break;
+ case 3:
+ return row.name;
+ break;
+ }
+ }
+ return QVariant();
+}
--- /dev/null
+/*
+ Bacula(R) - The Network Backup Solution
+
+ Copyright (C) 2000-2017 Kern Sibbald
+
+ The original author of Bacula is Kern Sibbald, with contributions
+ from many others, a complete list can be found in the file AUTHORS.
+
+ You may use this file and others of this release according to the
+ license defined in the LICENSE file, which includes the Affero General
+ Public License, v3.0 ("AGPLv3") and some additional permissions and
+ terms pursuant to its AGPLv3 Section 7.
+
+ This notice must be preserved when any source code is
+ conveyed and/or propagated.
+
+ Bacula(R) is a registered trademark of Kern Sibbald.
+*/
+#ifndef JOBSMODEL_H
+#define JOBSMODEL_H
+
+#include <QAbstractTableModel>
+#include "common.h"
+
+class JobsModel : public QAbstractTableModel
+{
+ Q_OBJECT
+
+public:
+ enum {
+ ID_COLUMN =0,
+ TDATE_COLUMN,
+ HASCACHE_COLUMN,
+ NAME_COLUMN,
+ NUM_COLUMN
+ };
+
+ struct row_struct {
+ uint64_t id;
+ QDateTime tdate;
+ QString hasCache;
+ QString name;
+ };
+
+ explicit JobsModel(const QList<row_struct>& t, QObject *parent = NULL);
+ // Header:
+ QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const;
+
+ // Basic functionality:
+ int rowCount(const QModelIndex &parent = QModelIndex()) const;
+ int columnCount(const QModelIndex &parent = QModelIndex()) const;
+
+ QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const;
+
+private:
+ QList<row_struct> table;
+};
+
+#endif // JOBSMODEL_H
--- /dev/null
+/*
+ Bacula(R) - The Network Backup Solution
+
+ Copyright (C) 2000-2017 Kern Sibbald
+
+ The original author of Bacula is Kern Sibbald, with contributions
+ from many others, a complete list can be found in the file AUTHORS.
+
+ You may use this file and others of this release according to the
+ license defined in the LICENSE file, which includes the Affero General
+ Public License, v3.0 ("AGPLv3") and some additional permissions and
+ terms pursuant to its AGPLv3 Section 7.
+
+ This notice must be preserved when any source code is
+ conveyed and/or propagated.
+
+ Bacula(R) is a registered trademark of Kern Sibbald.
+*/
+#include "restoreoptionswizardpage.h"
+#include "ui_restoreoptionswizardpage.h"
+#include "common.h"
+#include "filesmodel.h"
+#include "task.h"
+
+RestoreOptionsWizardPage::RestoreOptionsWizardPage(QWidget *parent) :
+ QWizardPage(parent),
+ ui(new Ui::RestoreOptionsWizardPage),
+ dest_model(0),
+ m_res(0)
+
+{
+ ui->setupUi(this);
+
+ registerField("restoreClient*", ui->restoreClientComboxBox);
+ registerField("restoreWhere", ui->whereLineEdit);
+ registerField("restoreReplace*", ui->replaceComboBox);
+ registerField("restoreComment", ui->commentLineEdit);
+}
+
+RestoreOptionsWizardPage::~RestoreOptionsWizardPage()
+{
+ delete ui;
+}
+
+
+void RestoreOptionsWizardPage::fill_defaults(task *t)
+{
+ if (ui->restoreClientComboxBox->isEnabled()) {
+ ui->restoreClientComboxBox->setCurrentIndex(ui->restoreClientComboxBox->findData(t->res->defaults.client));
+ }
+ if (ui->whereLineEdit->isEnabled()) {
+ ui->whereLineEdit->setText(t->res->defaults.where);
+ }
+}
+
+void RestoreOptionsWizardPage::setClients(alist *lst)
+{
+ if (lst && lst->size() > 0) {
+ ui->restoreClientComboxBox->clear();
+ QStringList list;
+ char *str;
+ foreach_alist(str, lst) {
+ list << QString(str);
+ }
+ ui->restoreClientComboxBox->addItems(list);
+ ui->restoreClientComboxBox->setEnabled(true);
+ } else {
+ ui->restoreClientComboxBox->setEnabled(false);
+ }
+
+ /* by default, select the same client as in clientselectwizardPage */
+ /* this is assuming lists are identical and in the same order. It should be the case */
+ ui->restoreClientComboxBox->setCurrentIndex(field("currentClient").toInt());
+}
+
+void RestoreOptionsWizardPage::setModel(QStandardItemModel *model)
+{
+ dest_model = model;
+}
+
+void RestoreOptionsWizardPage::setResmon(RESMON *res)
+{
+ m_res = res;
+}
+extern int decode_stat(char *buf, struct stat *statp, int stat_size, int32_t *LinkFI);
+
+bool RestoreOptionsWizardPage::validatePage()
+{
+ task *t = new task();
+ connect(t, SIGNAL(done(task*)), t, SLOT(deleteLater()));
+
+ t->init(m_res, TASK_RESTORE);
+
+ t->arg = (char*) m_res->clients->get(field("restoreClient").toInt());
+
+ if (!field("restoreWhere").isNull()) {
+ t->arg2 = field("restoreWhere").toString().toUtf8();
+ } else {
+ t->arg2 = NULL;
+ }
+
+ if (!field("restoreComment").isNull()) {
+ t->arg3 = field("restoreComment").toString().toUtf8();
+ } else {
+ t->arg3 = NULL;
+ }
+
+ t->model = dest_model;
+
+ m_res->wrk->queue(t);
+ return true;
+}
--- /dev/null
+/*
+ Bacula(R) - The Network Backup Solution
+
+ Copyright (C) 2000-2017 Kern Sibbald
+
+ The original author of Bacula is Kern Sibbald, with contributions
+ from many others, a complete list can be found in the file AUTHORS.
+
+ You may use this file and others of this release according to the
+ license defined in the LICENSE file, which includes the Affero General
+ Public License, v3.0 ("AGPLv3") and some additional permissions and
+ terms pursuant to its AGPLv3 Section 7.
+
+ This notice must be preserved when any source code is
+ conveyed and/or propagated.
+
+ Bacula(R) is a registered trademark of Kern Sibbald.
+*/
+#ifndef RESTOREOPTIONSWIZARDPAGE_H
+#define RESTOREOPTIONSWIZARDPAGE_H
+
+#include <QWizardPage>
+
+class alist;
+class QStandardItemModel;
+class RESMON;
+class task;
+
+namespace Ui {
+class RestoreOptionsWizardPage;
+}
+
+class RestoreOptionsWizardPage : public QWizardPage
+{
+ Q_OBJECT
+
+public:
+ explicit RestoreOptionsWizardPage(QWidget *parent = 0);
+ ~RestoreOptionsWizardPage();
+
+ void setClients(alist *lst);
+ void setModel(QStandardItemModel *model);
+ void setResmon(RESMON *res);
+
+ bool validatePage();
+
+public slots:
+ void fill_defaults(task *t);
+
+private:
+ Ui::RestoreOptionsWizardPage *ui;
+ QStandardItemModel *dest_model;
+ RESMON *m_res;
+};
+
+#endif // RESTOREOPTIONSWIZARDPAGE_H
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>RestoreOptionsWizardPage</class>
+ <widget class="QWizardPage" name="RestoreOptionsWizardPage">
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>419</width>
+ <height>304</height>
+ </rect>
+ </property>
+ <property name="windowTitle">
+ <string>WizardPage</string>
+ </property>
+ <layout class="QFormLayout" name="formLayout">
+ <item row="0" column="0">
+ <widget class="QLabel" name="restoreClientLabel">
+ <property name="text">
+ <string>Restore Client:</string>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="1">
+ <widget class="QComboBox" name="restoreClientComboxBox"/>
+ </item>
+ <item row="1" column="0">
+ <widget class="QLabel" name="whereLabel">
+ <property name="text">
+ <string>Where :</string>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="1">
+ <widget class="QLineEdit" name="whereLineEdit"/>
+ </item>
+ <item row="2" column="0">
+ <widget class="QLabel" name="replaceLabel">
+ <property name="text">
+ <string>Replace :</string>
+ </property>
+ </widget>
+ </item>
+ <item row="2" column="1">
+ <widget class="QComboBox" name="replaceComboBox">
+ <item>
+ <property name="text">
+ <string>never</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>always</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>if newer</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>if older</string>
+ </property>
+ </item>
+ </widget>
+ </item>
+ <item row="3" column="0">
+ <widget class="QLabel" name="commentLabel">
+ <property name="text">
+ <string>Comment :</string>
+ </property>
+ </widget>
+ </item>
+ <item row="3" column="1">
+ <widget class="QLineEdit" name="commentLineEdit"/>
+ </item>
+ </layout>
+ </widget>
+ <resources/>
+ <connections/>
+</ui>
--- /dev/null
+/*
+ Bacula(R) - The Network Backup Solution
+
+ Copyright (C) 2000-2017 Kern Sibbald
+
+ The original author of Bacula is Kern Sibbald, with contributions
+ from many others, a complete list can be found in the file AUTHORS.
+
+ You may use this file and others of this release according to the
+ license defined in the LICENSE file, which includes the Affero General
+ Public License, v3.0 ("AGPLv3") and some additional permissions and
+ terms pursuant to its AGPLv3 Section 7.
+
+ This notice must be preserved when any source code is
+ conveyed and/or propagated.
+
+ Bacula(R) is a registered trademark of Kern Sibbald.
+*/
+#include "restorewizard.h"
+#include "ui_restorewizard.h"
+#include "filesmodel.h"
+#include "task.h"
+#include <QStandardItemModel>
+
+RestoreWizard::RestoreWizard(RESMON *r, QWidget *parent) :
+ QWizard(parent),
+ res(r),
+ ui(new Ui::RestoreWizard),
+ jobs_model(new QStandardItemModel),
+ src_files_model(new FileSourceModel),
+ dest_files_model(new FileDestModel)
+{
+ ui->setupUi(this);
+
+ connect(this, SIGNAL(currentIdChanged(int)), this, SLOT(pageChanged(int)));
+
+ ui->RestWizBackupSelectPage->setModel(jobs_model);
+ ui->RestWiFileSelectionPage->setModels(src_files_model, dest_files_model);
+ connect(ui->RestWiFileSelectionPage, SIGNAL(currentFileChanged()), this, SLOT(fillFilePage()));
+ ui->RestWizAdvancedOptionsPage->setModel(dest_files_model);
+ ui->RestWizAdvancedOptionsPage->setResmon(res);
+
+}
+
+void RestoreWizard::pageChanged(int index)
+{
+ switch(index) {
+ case RW_CLIENT_PAGE:
+ ui->RestWizClientPage->setClients(res->clients);
+ break;
+ case RW_JOB_PAGE:
+ fillJobPage();
+ break;
+ case RW_FILE_PAGE:
+ fillFilePage();
+ break;
+ case RW_ADVANCEDOPTIONS_PAGE:
+ fillOptionsPage();
+ break;
+ default:
+ qDebug( "pageChanged default: %d", index );
+ break;
+ }
+}
+RestoreWizard::~RestoreWizard()
+{
+ delete ui;
+}
+
+void RestoreWizard::fillJobPage()
+{
+ task *t = new task();
+ connect(t, SIGNAL(done(task*)), ui->RestWizBackupSelectPage, SLOT(optimizeSize()), Qt::QueuedConnection);
+ connect(t, SIGNAL(done(task*)), t, SLOT(deleteLater()));
+
+ t->init(res, TASK_LIST_CLIENT_JOBS);
+
+ int idx = field("currentClient").toInt();
+ char *p = (char*) res->clients->get(idx);
+ POOL_MEM info;
+ pm_strcpy(info, p);
+ t->arg = info.c_str();
+ t->model = jobs_model;
+ res->wrk->queue(t);
+}
+
+void RestoreWizard::fillFilePage()
+{
+ task *t = new task();
+ connect(t, SIGNAL(done(task*)), t, SLOT(deleteLater()));
+
+ t->init(res, TASK_LIST_JOB_FILES);
+
+ const char *p = field("currentJob").toString().toUtf8();
+ POOL_MEM info;
+ pm_strcpy(info, p);
+ t->arg = info.c_str();
+
+ t->pathId = field("currentFile").toULongLong();
+ t->model = src_files_model;
+
+ res->wrk->queue(t);
+}
+
+void RestoreWizard::fillOptionsPage()
+{
+ ui->RestWizAdvancedOptionsPage->setClients(res->clients);
+
+ task *t = new task();
+ connect(t, SIGNAL(done(task *)), ui->RestWizAdvancedOptionsPage, SLOT(fill_defaults(task *)), Qt::QueuedConnection);
+ connect(t, SIGNAL(done(task*)), t, SLOT(deleteLater()));
+
+ const char *p = "RestoreFile";/*field("currentJob").toString().toStdString().c_str();*/
+ POOL_MEM info;
+ pm_strcpy(info, p);
+ res->mutex->lock();
+ bfree_and_null(res->defaults.job);
+ res->defaults.job = bstrdup(info.c_str());
+ res->mutex->unlock();
+
+ t->init(res, TASK_DEFAULTS);
+ res->wrk->queue(t);
+}
--- /dev/null
+/*
+ Bacula(R) - The Network Backup Solution
+
+ Copyright (C) 2000-2017 Kern Sibbald
+
+ The original author of Bacula is Kern Sibbald, with contributions
+ from many others, a complete list can be found in the file AUTHORS.
+
+ You may use this file and others of this release according to the
+ license defined in the LICENSE file, which includes the Affero General
+ Public License, v3.0 ("AGPLv3") and some additional permissions and
+ terms pursuant to its AGPLv3 Section 7.
+
+ This notice must be preserved when any source code is
+ conveyed and/or propagated.
+
+ Bacula(R) is a registered trademark of Kern Sibbald.
+*/
+#ifndef RESTOREWIZARD_H
+#define RESTOREWIZARD_H
+
+#include <QWizard>
+#include <QModelIndex>
+namespace Ui {
+class RestoreWizard;
+}
+
+class task;
+class RESMON;
+class QStandardItemModel;
+
+class RestoreWizard : public QWizard
+{
+ Q_OBJECT
+
+public:
+ enum {
+ RW_CLIENT_PAGE = 0,
+ RW_JOB_PAGE = 1,
+ RW_FILE_PAGE = 2,
+ RW_ADVANCEDOPTIONS_PAGE = 3
+ };
+
+ explicit RestoreWizard(RESMON *r, QWidget *parent = 0);
+ ~RestoreWizard();
+
+public slots:
+ void pageChanged(int index);
+
+protected slots:
+ void fillJobPage();
+ void fillFilePage();
+ void fillOptionsPage();
+
+private:
+ RESMON *res;
+ Ui::RestoreWizard *ui;
+
+ QStandardItemModel *jobs_model;
+ QStandardItemModel *src_files_model;
+ QStandardItemModel *dest_files_model;
+};
+
+#endif // RESTOREWIZARD_H
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>RestoreWizard</class>
+ <widget class="QWizard" name="RestoreWizard">
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>853</width>
+ <height>444</height>
+ </rect>
+ </property>
+ <property name="windowTitle">
+ <string>Wizard</string>
+ </property>
+ <property name="autoFillBackground">
+ <bool>false</bool>
+ </property>
+ <property name="sizeGripEnabled">
+ <bool>false</bool>
+ </property>
+ <widget class="ClientSelectWizardPage" name="RestWizClientPage">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Preferred" vsizetype="Preferred">
+ <horstretch>2</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="autoFillBackground">
+ <bool>false</bool>
+ </property>
+ <property name="title">
+ <string>Restore</string>
+ </property>
+ <property name="subTitle">
+ <string>Select a Client.</string>
+ </property>
+ </widget>
+ <widget class="JobSelectWizardPage" name="RestWizBackupSelectPage">
+ <property name="title">
+ <string>Restore</string>
+ </property>
+ <property name="subTitle">
+ <string>Select Backup to restore.</string>
+ </property>
+ </widget>
+ <widget class="FileSelectWizardPage" name="RestWiFileSelectionPage">
+ <property name="title">
+ <string>Restore</string>
+ </property>
+ <property name="subTitle">
+ <string>Files Selection</string>
+ </property>
+ </widget>
+ <widget class="RestoreOptionsWizardPage" name="RestWizAdvancedOptionsPage">
+ <property name="title">
+ <string>Restore Options</string>
+ </property>
+ <property name="subTitle">
+ <string>Select advanced options for restore and plugins </string>
+ </property>
+ </widget>
+ </widget>
+ <customwidgets>
+ <customwidget>
+ <class>ClientSelectWizardPage</class>
+ <extends>QWizardPage</extends>
+ <header>clientselectwizardpage.h</header>
+ <container>1</container>
+ </customwidget>
+ <customwidget>
+ <class>JobSelectWizardPage</class>
+ <extends>QWizardPage</extends>
+ <header>jobselectwizardpage.h</header>
+ <container>1</container>
+ </customwidget>
+ <customwidget>
+ <class>FileSelectWizardPage</class>
+ <extends>QWizardPage</extends>
+ <header>fileselectwizardpage.h</header>
+ <container>1</container>
+ </customwidget>
+ <customwidget>
+ <class>RestoreOptionsWizardPage</class>
+ <extends>QWizardPage</extends>
+ <header location="global">restoreoptionswizardpage.h</header>
+ <container>1</container>
+ </customwidget>
+ </customwidgets>
+ <resources/>
+ <connections>
+ <connection>
+ <sender>RestWizClientPage</sender>
+ <signal>completeChanged()</signal>
+ <receiver>RestoreWizard</receiver>
+ <slot>setFocus()</slot>
+ <hints>
+ <hint type="sourcelabel">
+ <x>424</x>
+ <y>288</y>
+ </hint>
+ <hint type="destinationlabel">
+ <x>424</x>
+ <y>274</y>
+ </hint>
+ </hints>
+ </connection>
+ </connections>
+</ui>
#include "task.h"
#include "jcr.h"
+#include "filesmodel.h"
+
#define dbglvl 10
int authenticate_daemon(JCR *jcr, MONITOR *monitor, RESMON *res);
static void *handle_task(void *data)
{
- task *t;
- worker *wrk = (worker *)data;
- lmgr_init_thread();
-
- wrk->set_running();
- Dmsg0(dbglvl, "Worker started\n");
-
- while (!wrk->is_quit_state()) {
- if (wrk->is_wait_state()) {
- wrk->wait();
- continue;
- }
- t = (task *)wrk->dequeue();
- if (!t) {
- continue;
- }
- /* Do the work */
- switch(t->type) {
- case TASK_STATUS:
- t->do_status();
- break;
- case TASK_RESOURCES:
- t->get_resources();
- break;
- case TASK_DEFAULTS:
- t->get_job_defaults();
- break;
- case TASK_RUN:
- t->run_job();
- break;
- case TASK_BWLIMIT:
- t->set_bandwidth();
- break;
- case TASK_INFO:
- t->get_job_info(t->arg2);
- break;
- case TASK_DISCONNECT:
- t->disconnect_bacula();
- t->mark_as_done();
- break;
- default:
- Mmsg(t->errmsg, "Unknown task");
- t->mark_as_failed();
- break;
- }
- }
- Dmsg0(dbglvl, "Worker stoped\n");
- lmgr_cleanup_thread();
- return NULL;
+ task *t;
+ worker *wrk = (worker *)data;
+ lmgr_init_thread();
+
+ wrk->set_running();
+ Dmsg0(dbglvl, "Worker started\n");
+
+ while (!wrk->is_quit_state()) {
+ if (wrk->is_wait_state()) {
+ wrk->wait();
+ continue;
+ }
+ t = (task *)wrk->dequeue();
+ if (!t) {
+ continue;
+ }
+ /* Do the work */
+ switch(t->type) {
+ case TASK_STATUS:
+ t->do_status();
+ break;
+ case TASK_RESOURCES:
+ t->get_resources();
+ break;
+ case TASK_DEFAULTS:
+ t->get_job_defaults();
+ break;
+ case TASK_RUN:
+ t->run_job();
+ break;
+ case TASK_BWLIMIT:
+ t->set_bandwidth();
+ break;
+ case TASK_INFO:
+ t->get_job_info(t->arg2);
+ break;
+ case TASK_DISCONNECT:
+ t->disconnect_bacula();
+ t->mark_as_done();
+ break;
+ case TASK_LIST_CLIENT_JOBS:
+ t->get_client_jobs(t->arg);
+ break;
+ case TASK_LIST_JOB_FILES:
+ t->get_job_files(t->arg, t->pathId);
+ break;
+ case TASK_RESTORE:
+ t->restore(QString("b21234"));
+ break;
+ default:
+ Mmsg(t->errmsg, "Unknown task");
+ t->mark_as_failed();
+ break;
+ }
+ }
+ Dmsg0(dbglvl, "Worker stoped\n");
+ lmgr_cleanup_thread();
+ return NULL;
}
bool task::set_bandwidth()
}
if (!res->bs || !res->bs->is_open() || res->bs->is_error()) {
- if (!connect_bacula()) {
+ if (!connect_bacula()) {
mark_as_failed();
return false;
}
char *start, *end;
struct s_running_job *item = NULL;
alist *running_jobs = New(alist(10, owned_by_alist));
-
+
while (r->bs->recv() >= -1) {
if (r->bs->msglen < 0 &&
r->bs->msglen != BNET_CMD_BEGIN &&
if (r->bs->is_error()) {
Mmsg(errmsg, "Got error on the socket communication line");
goto bail_out;
- }
+ }
}
if (item) {
Dmsg1(dbglvl, "Append item %ld\n", item->JobId);
Mmsg(errmsg, "Got error on the socket communication line");
goto bail_out;
- }
+ }
r->last_update = time(NULL);
r->mutex->unlock();
}
char *p;
if (!res->bs || !res->bs->is_open() || res->bs->is_error()) {
- if (!connect_bacula()) {
+ if (!connect_bacula()) {
goto bail_out;
}
}
bfree_and_null(res->defaults.type);
bfree_and_null(res->defaults.fileset);
bfree_and_null(res->defaults.catalog);
+ bfree_and_null(res->defaults.where);
tid = start_thread_timer(NULL, pthread_self(), (uint32_t)120);
if (res->type == R_CLIENT && !res->proxy_sent) {
}
*p++ = 0;
if (strcasecmp(curline, "client") == 0) {
- res->defaults.client = bstrdup(p);
+ res->defaults.client = bstrdup(p);
} else if (strcasecmp(curline, "pool") == 0) {
- res->defaults.pool = bstrdup(p);
+ res->defaults.pool = bstrdup(p);
} else if (strcasecmp(curline, "storage") == 0) {
- res->defaults.storage = bstrdup(p);
+ res->defaults.storage = bstrdup(p);
} else if (strcasecmp(curline, "level") == 0) {
- res->defaults.level = bstrdup(p);
+ res->defaults.level = bstrdup(p);
} else if (strcasecmp(curline, "type") == 0) {
- res->defaults.type = bstrdup(p);
+ res->defaults.type = bstrdup(p);
} else if (strcasecmp(curline, "fileset") == 0) {
- res->defaults.fileset = bstrdup(p);
+ res->defaults.fileset = bstrdup(p);
} else if (strcasecmp(curline, "catalog") == 0) {
- res->defaults.catalog = bstrdup(p);
+ res->defaults.catalog = bstrdup(p);
} else if (strcasecmp(curline, "priority") == 0) {
- res->defaults.priority = str_to_uint64(p);
+ res->defaults.priority = str_to_uint64(p);
+
+ } else if (strcasecmp(curline, "where") == 0) {
+ res->defaults.where = bstrdup(p);
}
+
}
ret = true;
bail_out:
} else {
mark_as_failed();
}
- res->mutex->unlock();
+ res->mutex->unlock();
return ret;
}
char *p;
if (!res->bs || !res->bs->is_open() || res->bs->is_error()) {
- if (!connect_bacula()) {
+ if (!connect_bacula()) {
goto bail_out;
}
}
btimer_t *tid = NULL;
if (!res->bs || !res->bs->is_open() || res->bs->is_error()) {
- if (!connect_bacula()) {
+ if (!connect_bacula()) {
goto bail_out;
}
}
}
// Close the socket, it's over or we don't want to reuse it
disconnect_bacula();
-
+
+bail_out:
+
+ if (tid) {
+ stop_thread_timer(tid);
+ }
+ if (ret) {
+ mark_as_done();
+ } else {
+ mark_as_failed();
+ }
+ return ret;
+}
+
+bool task::get_client_jobs(const char* client)
+{
+ bool ret = false;
+ btimer_t *tid = NULL;
+ int row=0;
+ QStringList headers;
+ headers << tr("JobId") << tr("Job") << tr("Level") << tr("Date") << tr("Files") << tr("Bytes");
+
+ if (!model) {
+ goto bail_out;
+ }
+
+ model->clear();
+ model->setHorizontalHeaderLabels(headers);
+
+ if (!res->bs || !res->bs->is_open() || res->bs->is_error()) {
+ if (!connect_bacula()) {
+ goto bail_out;
+ }
+ }
+
+ tid = start_thread_timer(NULL, pthread_self(), (uint32_t)120);
+
+ if (res->type == R_CLIENT && !res->proxy_sent) {
+ res->proxy_sent = true;
+ res->bs->fsend("proxy\n");
+ while (get_next_line(res)) {
+ if (strncmp(curline, "2000", 4) != 0) {
+ pm_strcpy(errmsg, curline);
+ goto bail_out;
+ }
+ Dmsg2(dbglvl, "<- %d %s\n", res->bs->msglen, curline);
+ }
+ }
+
+ res->bs->fsend(".api 2\n");
+ while (get_next_line(res)) {
+ Dmsg2(dbglvl, "<- %d %s\n", res->bs->msglen, curline);
+ }
+
+ if (res->type == R_DIRECTOR && res->use_setip) {
+ res->bs->fsend("setip\n");
+ while (get_next_line(res)) {
+ Dmsg2(dbglvl, "<- %d %s\n", res->bs->msglen, curline);
+ }
+ }
+
+ res->bs->fsend(".bvfs_get_jobs client=%s\n", client);
+ while (get_next_line(res)) {
+ QString line(curline);
+ QStringList line_lst = line.split(" ", QString::SkipEmptyParts);
+
+ model->setItem(row, 0, new QStandardItem(line_lst[0]));
+
+ model->setItem(row, 1, new QStandardItem(line_lst[3]));
+
+ QDateTime date;
+ date.setTime_t(line_lst[1].toUInt());
+ QStandardItem *dateItem = new QStandardItem();
+ dateItem->setData(date, Qt::DisplayRole);
+ model->setItem(row, 3, dateItem);
+
+ ret = true;
+ ++row;
+ }
+
+ // Close the socket, it's over or we don't want to reuse it
+ disconnect_bacula();
+
+// // fill extra job info
+// for (int r=0; r<model->rowCount(); ++r) {
+// arg = model->item(r, 0)->text().toUtf8();
+// get_job_info(NULL);
+// model->setItem(r, 2, new QStandardItem(res->infos.JobLevel));
+// model->setItem(r, 4, new QStandardItem(res->infos.JobFiles));
+// model->setItem(r, 5, new QStandardItem(res->infos.JobBytes));
+// }
+
bail_out:
if (tid) {
return ret;
}
+
+bool task::get_job_files(const char* job, uint64_t pathid)
+{
+ bool ret = false;
+ btimer_t *tid = NULL;
+ QString jobs;
+
+ if (model) {
+ model->clear();
+ }
+
+ if (!res->bs || !res->bs->is_open() || res->bs->is_error()) {
+ if (!connect_bacula()) {
+ goto bail_out;
+ }
+ }
+
+ tid = start_thread_timer(NULL, pthread_self(), (uint32_t)120);
+
+ if (res->type == R_CLIENT && !res->proxy_sent) {
+ res->proxy_sent = true;
+ res->bs->fsend("proxy\n");
+ while (get_next_line(res)) {
+ if (strncmp(curline, "2000", 4) != 0) {
+ pm_strcpy(errmsg, curline);
+ goto bail_out;
+ }
+ Dmsg2(dbglvl, "<- %d %s\n", res->bs->msglen, curline);
+ }
+ }
+
+ if (res->type == R_DIRECTOR && res->use_setip) {
+ res->bs->fsend("setip\n");
+ while (get_next_line(res)) {
+ Dmsg2(dbglvl, "<- %d %s\n", res->bs->msglen, curline);
+ }
+ }
+
+ res->bs->fsend(".api 2\n");
+ while (get_next_line(res)) {
+ Dmsg2(dbglvl, "<- %d %s\n", res->bs->msglen, curline);
+ }
+
+ /* retrieve all job ids*/
+ res->bs->fsend(".bvfs_get_jobids jobid=%s\n", job);
+ while (get_next_line(res)) {
+ jobs = QString(curline);
+ Dmsg2(dbglvl, "<- %d %s\n", res->bs->msglen, curline);
+ }
+
+ /* cache the file set */
+ res->bs->fsend(".bvfs_update jobid=%s\n", jobs.toUtf8());
+ while (get_next_line(res)) {
+ Dmsg2(dbglvl, "<- %d %s\n", res->bs->msglen, curline);
+ }
+
+ if (pathid == 0) {
+ res->bs->fsend(".bvfs_lsdirs jobid=%s path=\"\"\n", jobs.toUtf8());
+ } else {
+ res->bs->fsend(".bvfs_lsdirs jobid=%s pathid=%lld\n", jobs.toUtf8(), pathid);
+ }
+
+ while (get_next_line(res)) {
+ QString line(curline);
+ QStringList line_lst = line.split("\t", QString::KeepEmptyParts);
+ if ((line_lst.size() == 6) && line_lst[5] != ".")
+ {
+ DirectoryItem *d = new DirectoryItem();
+ d->setData(QVariant(line_lst[0]), PathIdRole);
+ d->setData(QVariant(line_lst[1]), FilenameIdRole);
+ d->setData(QVariant(line_lst[2]), FileIdRole);
+ d->setData(QVariant(line_lst[3]), JobIdRole);
+ d->setData(QVariant(line_lst[4]), LStatRole);
+ d->setData(QVariant(line_lst[5]), PathRole);
+ d->setData(QVariant(line_lst[5]), Qt::DisplayRole);
+
+ model->appendRow(d);
+ ret = true;
+ }
+ }
+
+ /* then, request files */
+ if (pathid == 0) {
+ res->bs->fsend(".bvfs_lsfiles jobid=%s path=\"\"\n", jobs.toUtf8());
+ } else {
+ res->bs->fsend(".bvfs_lsfiles jobid=%s pathid=%lld\n", jobs.toUtf8(), pathid);
+ }
+
+ while (get_next_line(res)) {
+ QString line(curline);
+ QStringList line_lst = line.split("\t", QString::SkipEmptyParts);
+ if ((line_lst.size() == 6) && line_lst[5] != ".")
+ {
+ FileItem *f = new FileItem();
+ f->setData(QVariant(line_lst[0]), PathIdRole);
+ f->setData(QVariant(line_lst[1]), FilenameIdRole);
+ f->setData(QVariant(line_lst[2]), FileIdRole);
+ f->setData(QVariant(line_lst[3]), JobIdRole);
+ f->setData(QVariant(line_lst[4]), LStatRole);
+ f->setData(QVariant(line_lst[5]), PathRole);
+ f->setData(QVariant(line_lst[5]), Qt::DisplayRole);
+ model->appendRow(f);
+ ret = true;
+ }
+ }
+
+ // Close the socket, it's over or we don't want to reuse it
+ disconnect_bacula();
+
+bail_out:
+
+ if (tid) {
+ stop_thread_timer(tid);
+ }
+ if (ret) {
+ mark_as_done();
+ } else {
+ mark_as_failed();
+ }
+ return ret;
+}
+
+extern int decode_stat(char *buf, struct stat *statp, int stat_size, int32_t *LinkFI);
+
+bool task::prepare_restore(const QString& tableName)
+{
+ bool ret = false;
+ btimer_t *tid = NULL;
+ QString q;
+ QStringList fileids, jobids, dirids, findexes;
+ struct stat statp;
+ int32_t LinkFI;
+
+ for (int row=0; row < model->rowCount(); ++row) {
+ QModelIndex idx = model->index(row, 0);
+ if (idx.data(TypeRole) == TYPEROLE_FILE) {
+ fileids << idx.data(FileIdRole).toString();
+ jobids << idx.data(JobIdRole).toString();
+ decode_stat(idx.data(LStatRole).toString().toLocal8Bit().data(),
+ &statp, sizeof(statp), &LinkFI);
+ if (LinkFI) {
+ findexes << idx.data(JobIdRole).toString() + "," + QString().setNum(LinkFI);
+ }
+ } else // TYPEROLE_DIRECTORY
+ {
+ dirids << idx.data(PathIdRole).toString();
+ jobids << idx.data(JobIdRole).toString().split(","); // Can have multiple jobids
+ }
+ }
+
+ fileids.removeDuplicates();
+ jobids.removeDuplicates();
+ dirids.removeDuplicates();
+ findexes.removeDuplicates();
+
+ if (!res->bs || !res->bs->is_open() || res->bs->is_error()) {
+ if (!connect_bacula()) {
+ goto bail_out;
+ }
+ }
+
+ tid = start_thread_timer(NULL, pthread_self(), (uint32_t)120);
+
+ if (res->type == R_CLIENT && !res->proxy_sent) {
+ res->proxy_sent = true;
+ res->bs->fsend("proxy\n");
+ while (get_next_line(res)) {
+ if (strncmp(curline, "2000", 4) != 0) {
+ pm_strcpy(errmsg, curline);
+ goto bail_out;
+ }
+ Dmsg2(dbglvl, "<- %d %s\n", res->bs->msglen, curline);
+ }
+ }
+
+ if (res->type == R_DIRECTOR && res->use_setip) {
+ res->bs->fsend("setip\n");
+ while (get_next_line(res)) {
+ Dmsg2(dbglvl, "<- %d %s\n", res->bs->msglen, curline);
+ }
+ }
+
+ res->bs->fsend(".api 2\n");
+ while (get_next_line(res)) {
+ Dmsg2(dbglvl, "<- %d %s\n", res->bs->msglen, curline);
+ }
+
+ /* retrieve all job ids*/
+ q = QString(".bvfs_restore path=%1 jobid=%2").arg(tableName, jobids.join(","));
+ if (fileids.size() > 0) {
+ q += " fileid=" + fileids.join(",");
+ }
+ if (dirids.size() > 0) {
+ q += " dirid=" + dirids.join(",");
+ }
+ if (findexes.size() > 0) {
+ q += " hardlink=" + findexes.join(",");
+ }
+
+ q += "\n";
+ res->bs->fsend(q.toUtf8());
+ while (get_next_line(res)) {
+ ret = true;
+ Dmsg2(dbglvl, "<- %d %s\n", res->bs->msglen, curline);
+ }
+
+ // Close the socket, it's over or we don't want to reuse it
+ disconnect_bacula();
+
+ bail_out:
+
+ if (tid) {
+ stop_thread_timer(tid);
+ }
+ if (ret) {
+ mark_as_done();
+ } else {
+ mark_as_failed();
+ }
+ return ret;
+}
+
+bool task::run_restore(const QString& tableName)
+{
+ bool ret = false;
+ btimer_t *tid = NULL;
+ QString q;
+
+ if (!res->bs || !res->bs->is_open() || res->bs->is_error()) {
+ if (!connect_bacula()) {
+ goto bail_out;
+ }
+ }
+
+ tid = start_thread_timer(NULL, pthread_self(), (uint32_t)120);
+
+ if (res->type == R_CLIENT && !res->proxy_sent) {
+ res->proxy_sent = true;
+ res->bs->fsend("proxy\n");
+ while (get_next_line(res)) {
+ if (strncmp(curline, "2000", 4) != 0) {
+ pm_strcpy(errmsg, curline);
+ goto bail_out;
+ }
+ Dmsg2(dbglvl, "<- %d %s\n", res->bs->msglen, curline);
+ }
+ }
+
+ if (res->type == R_DIRECTOR && res->use_setip) {
+ res->bs->fsend("setip\n");
+ while (get_next_line(res)) {
+ Dmsg2(dbglvl, "<- %d %s\n", res->bs->msglen, curline);
+ }
+ }
+
+ res->bs->fsend(".api 2\n");
+ while (get_next_line(res)) {
+ Dmsg2(dbglvl, "<- %d %s\n", res->bs->msglen, curline);
+ }
+
+ q = QString("restore client=%1").arg(arg);
+
+ if (arg2) {
+ QString where(arg2);
+ where.replace("\"", "");
+ q += " where=\"" + where + "\"";
+ }
+
+ if (arg3) {
+ QString comment(arg3);
+ comment.replace("\"", " ");
+ q += " comment=\"" + comment+ "\"";
+ }
+
+ q += " file=\"?" + tableName + "\"";
+ q += " done yes\n";
+
+ res->bs->fsend(q.toUtf8());
+ while (get_next_line(res)) {
+ ret = true;
+ // FIXME : report a signal to have a progress feedback
+ Dmsg2(dbglvl, "<- %d %s\n", res->bs->msglen, curline);
+ }
+
+ // Close the socket, it's over or we don't want to reuse it
+ disconnect_bacula();
+
+ bail_out:
+
+ if (tid) {
+ stop_thread_timer(tid);
+ }
+ if (ret) {
+ mark_as_done();
+ } else {
+ mark_as_failed();
+ }
+ return ret;
+}
+
+bool task::clean_restore(const QString& tableName)
+{
+ bool ret = false;
+ btimer_t *tid = NULL;
+ QString q;
+
+ if (!res->bs || !res->bs->is_open() || res->bs->is_error()) {
+ if (!connect_bacula()) {
+ goto bail_out;
+ }
+ }
+
+ tid = start_thread_timer(NULL, pthread_self(), (uint32_t)120);
+
+ if (res->type == R_CLIENT && !res->proxy_sent) {
+ res->proxy_sent = true;
+ res->bs->fsend("proxy\n");
+ while (get_next_line(res)) {
+ if (strncmp(curline, "2000", 4) != 0) {
+ pm_strcpy(errmsg, curline);
+ goto bail_out;
+ }
+ Dmsg2(dbglvl, "<- %d %s\n", res->bs->msglen, curline);
+ }
+ }
+
+ if (res->type == R_DIRECTOR && res->use_setip) {
+ res->bs->fsend("setip\n");
+ while (get_next_line(res)) {
+ Dmsg2(dbglvl, "<- %d %s\n", res->bs->msglen, curline);
+ }
+ }
+
+ res->bs->fsend(".api 2\n");
+ while (get_next_line(res)) {
+ Dmsg2(dbglvl, "<- %d %s\n", res->bs->msglen, curline);
+ }
+
+ q = QString(".bvfs_cleanup path=%1\n").arg(tableName);
+
+ res->bs->fsend(q.toUtf8());
+ while (get_next_line(res)) {
+ ret = true;
+ // FIXME : report a signal to have a progress feedback
+ Dmsg2(dbglvl, "<- %d %s\n", res->bs->msglen, curline);
+ }
+
+ // Close the socket, it's over or we don't want to reuse it
+ disconnect_bacula();
+
+ bail_out:
+
+ if (tid) {
+ stop_thread_timer(tid);
+ }
+ if (ret) {
+ mark_as_done();
+ } else {
+ mark_as_failed();
+ }
+ return ret;
+}
+
+bool task::restore(const QString& tableName)
+{
+ bool ret=prepare_restore(tableName);
+ if (ret) {
+ ret = run_restore(tableName);
+ if (ret) {
+ return clean_restore(tableName);
+ }
+ }
+ return false;
+}
+
/* Get resources to run a job */
bool task::get_resources()
{
btimer_t *tid = NULL;
if (!res->bs || !res->bs->is_open() || res->bs->is_error()) {
- if (!connect_bacula()) {
+ if (!connect_bacula()) {
goto bail_out;
}
}
#include "common.h"
#include <QtCore/QObject>
+#include <QStandardItemModel>
#include "tray_conf.h"
enum {
TASK_RESOURCES,
TASK_QUERY,
TASK_RUN,
+ TASK_LIST_CLIENT_JOBS,
+ TASK_LIST_JOB_FILES,
TASK_RESTORE,
TASK_DEFAULTS,
TASK_CLOSE,
Q_OBJECT
public:
- RESMON *res;
- POOLMEM *errmsg;
- int type;
- bool status;
- char *curline;
- char *curend;
- char *arg; /* Argument that can be used by some tasks */
- char *arg2;
+ RESMON *res;
+ POOLMEM *errmsg;
+ int type;
+ bool status;
+ char *curline;
+ char *curend;
+ const char *arg; /* Argument that can be used by some tasks */
+ const char *arg2;
+ const char *arg3;
+ QStandardItemModel *model; /* model to fill, depending on context */
+ uint64_t pathId;
union {
bool b;
void mark_as_done() {
status = true;
emit done(this);
- };
+ }
void mark_as_failed() {
status = false;
emit done(this);
- };
+ }
bool get_resources();
bool get_next_line(RESMON *res);
bool get_job_defaults(); /* Look r->defaults.job */
bool run_job();
bool get_job_info(const char *level); /* look r->info */
+ bool get_client_jobs(const char* client);
+ bool get_job_files(const char* job, uint64_t pathId);
+
+ bool prepare_restore(const QString& tableName);
+ bool run_restore(const QString& tableName);
+ bool clean_restore(const QString& tableName);
+ bool restore(const QString& tableName);
signals:
void done(task *t);
#
# CONFIG options for Windows are pulled from win32/qmake.conf
CONFIG += qt
-#CONFIG += qt debug
+#CONFIG += qt debug
cross-win32 {
LIBS += -mwindows -L../../win32/release32 -lbacula
UI_DIR = ui
# Main directory
-HEADERS += tray-monitor.h tray_conf.h tray-ui.h fdstatus.h task.h ../util/fmtwidgetitem.h dirstatus.h conf.h sdstatus.h runjob.h status.h
-SOURCES += tray-monitor.cpp tray_conf.cpp fdstatus.cpp task.cpp authenticate.cpp ../util/fmtwidgetitem.cpp dirstatus.cpp sdstatus.cpp conf.cpp runjob.cpp status.cpp common.h
-
-FORMS += fd-monitor.ui dir-monitor.ui sd-monitor.ui main-conf.ui res-conf.ui run.ui
+HEADERS += tray-monitor.h tray_conf.h tray-ui.h fdstatus.h task.h ../util/fmtwidgetitem.h dirstatus.h conf.h sdstatus.h runjob.h status.h restorewizard.h filesmodel.h clientselectwizardpage.h jobselectwizardpage.h fileselectwizardpage.h restoreoptionswizardpage.h
+SOURCES += tray-monitor.cpp tray_conf.cpp fdstatus.cpp task.cpp authenticate.cpp ../util/fmtwidgetitem.cpp dirstatus.cpp sdstatus.cpp conf.cpp runjob.cpp status.cpp restorewizard.cpp clientselectwizardpage.cpp jobselectwizardpage.cpp fileselectwizardpage.cpp restoreoptionswizardpage.cpp
+FORMS += fd-monitor.ui dir-monitor.ui sd-monitor.ui main-conf.ui res-conf.ui run.ui restorewizard.ui clientselectwizardpage.ui jobselectwizardpage.ui fileselectwizardpage.ui restoreoptionswizardpage.ui
TRANSLATIONS += ts/tm_fr.ts ts/tm_de.ts ts/tm_ja.ts
QMAKE_RC = i686-w64-mingw32-windres
# Main directory
-HEADERS += tray-monitor.h tray_conf.h tray-ui.h fdstatus.h task.h ../util/fmtwidgetitem.h dirstatus.h conf.h sdstatus.h runjob.h status.h
-SOURCES += tray-monitor.cpp tray_conf.cpp fdstatus.cpp task.cpp authenticate.cpp ../util/fmtwidgetitem.cpp dirstatus.cpp sdstatus.cpp conf.cpp runjob.cpp status.cpp common.h
-
-FORMS += fd-monitor.ui dir-monitor.ui sd-monitor.ui main-conf.ui res-conf.ui run.ui
+HEADERS += tray-monitor.h tray_conf.h tray-ui.h fdstatus.h task.h ../util/fmtwidgetitem.h dirstatus.h conf.h sdstatus.h runjob.h status.h restorewizard.h filesmodel.h clientselectwizardpage.h jobselectwizardpage.h fileselectwizardpage.h restoreoptionswizardpage.h
+SOURCES += tray-monitor.cpp tray_conf.cpp fdstatus.cpp task.cpp authenticate.cpp ../util/fmtwidgetitem.cpp dirstatus.cpp sdstatus.cpp conf.cpp runjob.cpp status.cpp restorewizard.cpp clientselectwizardpage.cpp jobselectwizardpage.cpp fileselectwizardpage.cpp restoreoptionswizardpage.cpp
+FORMS += fd-monitor.ui dir-monitor.ui sd-monitor.ui main-conf.ui res-conf.ui run.ui restorewizard.ui clientselectwizardpage.ui jobselectwizardpage.ui fileselectwizardpage.ui restoreoptionswizardpage.ui
TRANSLATIONS += ts/tm_fr.ts ts/tm_de.ts ts/tm_ja.ts
QMAKE_RC = x86_64-w64-mingw32-windres
# Main directory
-HEADERS += tray-monitor.h tray_conf.h tray-ui.h fdstatus.h task.h ../util/fmtwidgetitem.h dirstatus.h conf.h sdstatus.h runjob.h status.h
-SOURCES += tray-monitor.cpp tray_conf.cpp fdstatus.cpp task.cpp authenticate.cpp ../util/fmtwidgetitem.cpp dirstatus.cpp sdstatus.cpp conf.cpp runjob.cpp status.cpp common.h
-
-FORMS += fd-monitor.ui dir-monitor.ui sd-monitor.ui main-conf.ui res-conf.ui run.ui
+HEADERS += tray-monitor.h tray_conf.h tray-ui.h fdstatus.h task.h ../util/fmtwidgetitem.h dirstatus.h conf.h sdstatus.h runjob.h status.h restorewizard.h filesmodel.h clientselectwizardpage.h jobselectwizardpage.h fileselectwizardpage.h restoreoptionswizardpage.h
+SOURCES += tray-monitor.cpp tray_conf.cpp fdstatus.cpp task.cpp authenticate.cpp ../util/fmtwidgetitem.cpp dirstatus.cpp sdstatus.cpp conf.cpp runjob.cpp status.cpp restorewizard.cpp clientselectwizardpage.cpp jobselectwizardpage.cpp fileselectwizardpage.cpp restoreoptionswizardpage.cpp
+FORMS += fd-monitor.ui dir-monitor.ui sd-monitor.ui main-conf.ui res-conf.ui run.ui restorewizard.ui clientselectwizardpage.ui jobselectwizardpage.ui fileselectwizardpage.ui restoreoptionswizardpage.ui
TRANSLATIONS += ts/tm_fr.ts ts/tm_de.ts ts/tm_ja.ts
#include "dirstatus.h"
#include "conf.h"
#include "runjob.h"
+#include "restorewizard.h"
void display_error(const char *fmt, ...);
QSpinBox *spinRefresh;
QTimer *timer;
bool have_systray;
-
+ RestoreWizard *restorewiz;
+
TrayUI():
QMainWindow(),
tabWidget(NULL),
tray(NULL),
spinRefresh(NULL),
timer(NULL),
- have_systray(QSystemTrayIcon::isSystemTrayAvailable())
+ have_systray(QSystemTrayIcon::isSystemTrayAvailable()),
+ restorewiz(NULL)
{
- };
+ }
~TrayUI() {
- };
+ }
void addTab(RESMON *r)
{
QWidget *tab;
}
tabWidget->setUpdatesEnabled(false);
tabWidget->addTab(tab, t);
- tabWidget->setUpdatesEnabled(true);
+ tabWidget->setUpdatesEnabled(true);
}
void clearTabs()
{
verticalLayout->addLayout(hLayout);
//QSystemTrayIcon::isSystemTrayAvailable
+
tray = new QSystemTrayIcon(TrayMonitor);
QMenu* stmenu = new QMenu(TrayMonitor);
QAction* actRun = new QAction(QApplication::translate("TrayMonitor",
"Run...",
0, QApplication::UnicodeUTF8),TrayMonitor);
-/* Not yet ready
- * QAction* actRes = new QAction(QApplication::translate("TrayMonitor",
- * "Restore...",
- * 0, QApplication::UnicodeUTF8),TrayMonitor);
- */
+ QAction* actRes = new QAction(QApplication::translate("TrayMonitor",
+ "Restore...",
+ 0, QApplication::UnicodeUTF8),TrayMonitor);
+
QAction* actConf = new QAction(QApplication::translate("TrayMonitor",
"Configure...",
0, QApplication::UnicodeUTF8),TrayMonitor);
stmenu->addAction(actShow);
stmenu->addAction(actRun);
- //stmenu->addAction(actRes);
+ stmenu->addAction(actRes);
stmenu->addSeparator();
stmenu->addAction(actConf);
stmenu->addSeparator();
connect(actRun, SIGNAL(triggered()), this, SLOT(cb_run()));
connect(actShow, SIGNAL(triggered()), this, SLOT(cb_show()));
connect(actConf, SIGNAL(triggered()), this, SLOT(cb_conf()));
- //connect(actRes, SIGNAL(triggered()), this, SLOT(cb_restore()));
+ connect(actRes, SIGNAL(triggered()), this, SLOT(cb_restore()));
connect(actQuit, SIGNAL(triggered()), this, SLOT(cb_quit()));
connect(actAbout, SIGNAL(triggered()), this, SLOT(cb_about()));
connect(spinRefresh, SIGNAL(valueChanged(int)), this, SLOT(cb_refresh(int)));
if (!dir) {
return;
}
+ task *t = new task();
+ connect(t, SIGNAL(done(task *)), this, SLOT(start_restore_wizard(task *)), Qt::QueuedConnection);
+ t->init(dir, TASK_RESOURCES);
+ dir->wrk->queue(t);
}
+
void cb_trayIconActivated(QSystemTrayIcon::ActivationReason r) {
if (r == QSystemTrayIcon::Trigger) {
cb_show();
void task_done(task *t) {
Dmsg0(0, "Task done!\n");
t->deleteLater();
- };
+ }
void run_job(task *t) {
Dmsg0(0, "Task done!\n");
RESMON *dir = t->res;
t->deleteLater();
new RunJob(dir);
- };
+ }
+
+ void start_restore_wizard(task *t) {
+ RESMON *dir = t->res;
+ restorewiz = new RestoreWizard(dir);
+ restorewiz->show();
+ t->deleteLater();
+ }
+
};
#include "common.h"
-/* NOTE: #includes at the end of this file */
-
/*
* Resource codes -- they must be sequential for indexing
*/
char *fileset;
char *catalog;
int priority;
+ char *where;
} defaults;
/* Information about the job */
} infos;
};
+Q_DECLARE_METATYPE(RESMON*)
+
/*
* Tray Monitor Resource
*