]> git.ipfire.org Git - thirdparty/bacula.git/commitdiff
Fix build of Windows tray-monitor
authorKern Sibbald <kern@sibbald.com>
Sun, 22 Apr 2018 12:48:46 +0000 (14:48 +0200)
committerKern Sibbald <kern@sibbald.com>
Sun, 22 Apr 2018 12:48:46 +0000 (14:48 +0200)
36 files changed:
bacula/src/qt-console/main.cpp
bacula/src/qt-console/make-win32
bacula/src/qt-console/tray-monitor/clientselectwizardpage.cpp
bacula/src/qt-console/tray-monitor/clientselectwizardpage.h
bacula/src/qt-console/tray-monitor/fileselectwizardpage.cpp
bacula/src/qt-console/tray-monitor/fileselectwizardpage.h
bacula/src/qt-console/tray-monitor/fileselectwizardpage.ui
bacula/src/qt-console/tray-monitor/filesmodel.h
bacula/src/qt-console/tray-monitor/jobselectwizardpage.cpp
bacula/src/qt-console/tray-monitor/jobselectwizardpage.h
bacula/src/qt-console/tray-monitor/pluginmodel.h [new file with mode: 0644]
bacula/src/qt-console/tray-monitor/pluginwizardpage.cpp [new file with mode: 0644]
bacula/src/qt-console/tray-monitor/pluginwizardpage.h [new file with mode: 0644]
bacula/src/qt-console/tray-monitor/pluginwizardpage.ui [new file with mode: 0644]
bacula/src/qt-console/tray-monitor/restoreoptionswizardpage.cpp
bacula/src/qt-console/tray-monitor/restoreoptionswizardpage.h
bacula/src/qt-console/tray-monitor/restoreoptionswizardpage.ui
bacula/src/qt-console/tray-monitor/restorewizard.cpp
bacula/src/qt-console/tray-monitor/restorewizard.h
bacula/src/qt-console/tray-monitor/restorewizard.ui
bacula/src/qt-console/tray-monitor/runjob.cpp
bacula/src/qt-console/tray-monitor/task.cpp
bacula/src/qt-console/tray-monitor/task.h
bacula/src/qt-console/tray-monitor/tray-monitor.cpp
bacula/src/qt-console/tray-monitor/tray-monitor.pro.in
bacula/src/qt-console/tray-monitor/tray-monitor.pro.mingw64.in
bacula/src/qt-console/tray-monitor/tray-ui.h
bacula/src/qt-console/tray-monitor/tray_conf.cpp
bacula/src/qt-console/tray-monitor/tray_conf.h
bacula/src/qt-console/tray-monitor/ts/tm_de.ts [new file with mode: 0644]
bacula/src/qt-console/tray-monitor/ts/tm_fr.ts [new file with mode: 0644]
bacula/src/qt-console/tray-monitor/ts/tm_ja.ts [new file with mode: 0644]
bacula/src/qt-console/tray-monitor/win32/qmake.conf [new file with mode: 0644]
bacula/src/qt-console/tray-monitor/win32/qplatformdefs.h [new file with mode: 0644]
bacula/src/win32/compat/compat.cpp
bacula/src/win32/compat/winsock.h [deleted file]

index cb6dc1c6124a798d08c0b268b40614ec296f84c2..3c1924c98897fbf688ea7986f27a098895d34a2f 100644 (file)
@@ -1,7 +1,7 @@
 /*
    Bacula(R) - The Network Backup Solution
 
-   Copyright (C) 2000-2016 Kern Sibbald
+   Copyright (C) 2000-2018 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.
@@ -11,7 +11,7 @@
    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 
+   This notice must be preserved when any source code is
    conveyed and/or propagated.
 
    Bacula(R) is a registered trademark of Kern Sibbald.
@@ -185,14 +185,14 @@ static void usage()
 {
    fprintf(stderr, _(
 PROG_COPYRIGHT
-"\nVersion: %s (%s) %s %s %s\n\n"
+"\n%sVersion: %s (%s) %s %s %s\n\n"
 "Usage: bat [-s] [-c config_file] [-d debug_level] [config_file]\n"
 "       -c <file>   set configuration file to file\n"
 "       -dnn        set debug level to nn\n"
 "       -s          no signals\n"
 "       -t          test - read configuration and exit\n"
 "       -?          print this message.\n"
-"\n"), 2007, VERSION, BDATE, HOST_OS, DISTNAME, DISTVER);
+"\n"), 2007, BDEMO, VERSION, BDATE, HOST_OS, DISTNAME, DISTVER);
 
    exit(1);
 }
index d064ba9400b6ec392570f8726713cad00ebfdd2a..76a7059907b492f24a35d5cbaafcfe88bf68bf7e 100755 (executable)
@@ -74,4 +74,4 @@ if test -e ../config.h.orig ; then
    mv -f ../config.h.orig ../config.h
 fi
 
-#prepare_tray_monitor_build ${BUILD_ARCH:-64}
+prepare_tray_monitor_build ${BUILD_ARCH:-64}
index 4b06c297dbc8e9453654f5bd87571d92818e046c..8bef54d1a7edf734a4d5df4ff43caef4180ca657 100644 (file)
@@ -1,7 +1,7 @@
 /*
    Bacula(R) - The Network Backup Solution
 
-   Copyright (C) 2000-2017 Kern Sibbald
+   Copyright (C) 2000-2018 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.
 
    Bacula(R) is a registered trademark of Kern Sibbald.
 */
+/*
+ * Restore Wizard: Client selection page
+ *
+ * Written by Norbert Bizet, May MMXVII
+ *
+ */
+#include "common.h"
 #include "clientselectwizardpage.h"
 #include "ui_clientselectwizardpage.h"
-#include "common.h"
+#include "conf.h"
 ClientSelectWizardPage::ClientSelectWizardPage(QWidget *parent) :
     QWizardPage(parent),
     ui(new Ui::ClientSelectWizardPage)
 {
     ui->setupUi(this);
-
+    /* currentClient field is mandatory */
     registerField("currentClient*", ui->backupClientComboBox);
 }
 
@@ -33,13 +40,13 @@ ClientSelectWizardPage::~ClientSelectWizardPage()
     delete ui;
 }
 
-void ClientSelectWizardPage::setClients(alist *lst)
+void ClientSelectWizardPage::initializePage()
 {
-    if (lst && lst->size() > 0) {
+    if (res && res->clients && res->clients->size() > 0) {
        ui->backupClientComboBox->clear();
        QStringList list;
        char *str;
-       foreach_alist(str, lst) {
+       foreach_alist(str, res->clients) {
           list << QString(str);
        }
        ui->backupClientComboBox->addItems(list);
index c0a2fd963b1f7dad1f4dc40bc1011cd27ebd64f1..673d8755dd323f2e8359b480ddb13a66b6a4c6e8 100644 (file)
@@ -1,7 +1,7 @@
 /*
    Bacula(R) - The Network Backup Solution
 
-   Copyright (C) 2000-2017 Kern Sibbald
+   Copyright (C) 2000-2018 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.
 
    Bacula(R) is a registered trademark of Kern Sibbald.
 */
+/*
+ * Restore Wizard: Client selection page
+ *
+ * Written by Norbert Bizet, May MMXVII
+ *
+ */
 #ifndef CLIENTSELECTWIZARDPAGE_H
 #define CLIENTSELECTWIZARDPAGE_H
 
 #include <QWizardPage>
 
-class alist;
+class RESMON;
 
 namespace Ui {
 class ClientSelectWizardPage;
@@ -34,11 +40,14 @@ class ClientSelectWizardPage : public QWizardPage
 public:
     explicit ClientSelectWizardPage(QWidget *parent = 0);
     ~ClientSelectWizardPage();
-
-    void setClients(alist *lst);
+    /* QWizardPage interface */
+    void initializePage();    
+    /* local interface */
+    inline void setRes(RESMON *r) {res=r;}
 
 private:
     Ui::ClientSelectWizardPage *ui;
+    RESMON *res;
 };
 
 #endif // CLIENTSELECTWIZARDPAGE_H
index 746b070c28c5d2bc0e8f253ed0c8fa79271cdd48..52579ca869e0288ae6c2b7c4200bc52293a5fd60 100644 (file)
@@ -1,7 +1,7 @@
 /*
    Bacula(R) - The Network Backup Solution
 
-   Copyright (C) 2000-2017 Kern Sibbald
+   Copyright (C) 2000-2018 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.
 
    Bacula(R) is a registered trademark of Kern Sibbald.
 */
+/*
+ * Restore Wizard: File selection page
+ *
+ * Written by Norbert Bizet, May MMXVII
+ *
+ */
+#include "common.h"
 #include "fileselectwizardpage.h"
+#include "filesmodel.h"
 #include "ui_fileselectwizardpage.h"
+#include "restorewizard.h"
 #include "task.h"
-#include "filesmodel.h"
 #include <QStandardItemModel>
+#include <QShortcut>
 
 FileSelectWizardPage::FileSelectWizardPage(QWidget *parent) :
     QWizardPage(parent),
+    m_currentSourceId(0),
+    m_currentPathStr(""),
     ui(new Ui::FileSelectWizardPage),
-    currentPathId(0)
+    src_files_model(new FileSourceModel),
+    dest_files_model(new FileDestModel),
+    m_filterTimer(new QTimer),
+    res(NULL),
+    need_optimize(true)
 {
     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);
+    /* keep track of the current source view selection */
+    registerField("currentSourceId", this, "currentSourceId", "currentSourceIdChanged");
+    registerField("currentPathStr", this, "currentPathStr", "currentPathStrChanged");
+    registerField("fileFilter", ui->FilterEdit);
+    /* usefull to the following pages */
+    registerField("jobIds", this, "jobIds", "jobIdsChanged");
+    registerField("fileIds", this, "fileIds", "fileIdsChanged");
+    registerField("dirIds", this, "dirIds", "dirIdsChanged");
+    registerField("hardlinks", this, "hardlinks", "hardlinksChanged");
+    registerField("pluginIds", this, "pluginIds", "pluginIdsChanged");
+    registerField("pluginNames", this, "pluginNames", "pluginNamesChanged");
+
+    QStringList headers;
+    headers << tr("Name") << tr("Size") << tr("Date");
 
-    /* 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);
+    ui->sourceTableView->setModel(src_files_model);
+    //ui->sourceTableView->setLayoutMode(QListView::Batched);
+    //ui->sourceTableView->setBatchSize(BATCH_SIZE);
+    src_files_model->setHorizontalHeaderLabels(headers);
+    connect(ui->sourceTableView, SIGNAL(activated(const QModelIndex &)), this, SLOT(changeCurrentFolder(const QModelIndex&)));
+    connect(ui->sourceTableView, SIGNAL(activated(const QModelIndex &)), this, SLOT(updateSourceModel()));
 
+    ui->destTableView->setModel(dest_files_model);
+    dest_files_model->setHorizontalHeaderLabels(headers);
+    connect(dest_files_model, SIGNAL(rowsInserted(const QModelIndex &, int, int)), this, SIGNAL(completeChanged()));
+    connect(dest_files_model, SIGNAL(rowsRemoved(const QModelIndex &, int, int)), this, SIGNAL(completeChanged()));
 
+    connect(ui->filePathComboPath, SIGNAL(activated(const QString &)), this, SLOT(changeCurrentText(const QString &)));
+    connect(ui->filePathComboPath, SIGNAL(activated(const QString &)), this, SLOT(updateSourceModel()));
+
+    connect(ui->FilterEdit, SIGNAL(textChanged(const QString &)), this, SLOT(delayedFilter()));
+
+    m_filterTimer->setSingleShot(true);
+    connect(m_filterTimer, SIGNAL(timeout()), this, SLOT(unFreezeSrcView()));
+    connect(m_filterTimer, SIGNAL(timeout()), this, SLOT(updateSourceModel()));
+
+    QShortcut *shortcut = new QShortcut(QKeySequence(Qt::Key_Delete), this);
+    QObject::connect(shortcut, SIGNAL(activated()), this, SLOT(deleteDestSelection()));
 }
 
 FileSelectWizardPage::~FileSelectWizardPage()
@@ -48,35 +89,214 @@ FileSelectWizardPage::~FileSelectWizardPage()
     delete ui;
 }
 
-void FileSelectWizardPage::setModels(QStandardItemModel *src_model, QStandardItemModel *dest_model)
+void FileSelectWizardPage::initializePage()
+{
+    /* first request synchronous */
+    if (res) {
+        task t;
+        t.init(res, -1);
+
+        const char *p = field("fileFilter").toString().toLatin1().data();
+        POOL_MEM info2;
+        pm_strcpy(info2, p);
+        t.arg2 = info2.c_str();
+
+        p = currentPathStr().toLatin1().data();
+        POOL_MEM info3;
+        pm_strcpy(info3, p);
+        t.arg3 = info3.c_str();
+
+        t.model = src_files_model;
+
+        t.get_job_files(field("currentJob").toString().toLatin1().data(), currentSourceId());
+    }
+
+    need_optimize = true;
+}
+
+bool FileSelectWizardPage::isComplete() const
+{
+    return dest_files_model->rowCount() != 0;
+}
+
+int FileSelectWizardPage::nextId() const
+{
+    /* if some plugins are used in current selection, move to plugin page, otherwise options */
+    if (field("pluginIds").toString().isEmpty()) {
+        return RestoreWizard::RW_ADVANCEDOPTIONS_PAGE;
+    }
+    return RestoreWizard::RW_PLUGIN_PAGE;
+}
+
+bool FileSelectWizardPage::validatePage()
+{
+    /* compute result fields based on destination model content */
+    QStringList fileids, jobids, dirids, findexes;
+    struct stat statp;
+    int32_t LinkFI;
+
+    for (int row=0; row < dest_files_model->rowCount(); ++row) {
+        QModelIndex idx = dest_files_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();
+
+    m_jobIds = jobids.join(",");
+    m_fileIds = fileids.join(",");
+    m_dirIds = dirids.join(",");
+    m_hardlinks = findexes.join(",");
+
+    /* plugin Ids and Names are retrieved now, so NextId() can decide to schedule the PluginPage before RestoreOptionsPage */
+    /* Stored as properties so thru the next Wizard Page can use them */
+    task t;
+    t.init(res, -1); /* pass res, ID is set to -1 because task method is called synchronously */
+    m_pluginIds = t.plugins_ids(m_jobIds);
+    m_pluginNames = t.plugins_names(m_jobIds);
+
+    return true;
+}
+
+void FileSelectWizardPage::updateSourceModel()
 {
-    ui->sourceListView->setModel(src_model);
-    src_model->clear();
-    currentPathId = 0;
+    /* subsequent request async */
+    if (res) {
+        task *t = new task();
+
+        /* optimize size only once */
+        if (need_optimize) {
+            connect(t, SIGNAL(done(task*)), this, SLOT(optimizeSize()));
+            need_optimize = false;
+        }
+        connect(t, SIGNAL(done(task*)), t, SLOT(deleteLater()));
+
+        t->init(res, TASK_LIST_JOB_FILES);
+
+        const char *p = field("currentJob").toString().toLatin1().data();
+        POOL_MEM info;
+        pm_strcpy(info, p);
+        t->arg = info.c_str();
 
-    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()));
+        p = field("fileFilter").toString().toLatin1().data();
+        POOL_MEM info2;
+        pm_strcpy(info2, p);
+        t->arg2 = info2.c_str();
 
+        p = currentPathStr().toLatin1().data();
+        POOL_MEM info3;
+        pm_strcpy(info3, p);
+        t->arg3 = info3.c_str();
+
+        t->pathId = currentSourceId();
+        t->model = src_files_model;
+
+        res->wrk->queue(t);
+    }
 }
 
-qulonglong FileSelectWizardPage::currentFile() const
+void FileSelectWizardPage::optimizeSize()
 {
-    return currentPathId;
+    int w = ui->destTableView->width()/4;
+    ui->destTableView->horizontalHeader()->resizeSection( 0, w*2);
+    ui->destTableView->horizontalHeader()->resizeSection( 1, w);
+    ui->destTableView->horizontalHeader()->resizeSection( 2, w );
+    ui->destTableView->horizontalHeader()->setStretchLastSection(true);
+
+    w = ui->sourceTableView->width()/4;
+    ui->sourceTableView->horizontalHeader()->resizeSection( 0, w*2);
+    ui->sourceTableView->horizontalHeader()->resizeSection( 1, w);
+    ui->sourceTableView->horizontalHeader()->resizeSection( 2, w );
+    ui->sourceTableView->horizontalHeader()->setStretchLastSection(true);
 }
 
 void FileSelectWizardPage::changeCurrentFolder(const QModelIndex& current)
 {
-    if (current.isValid() && ui->sourceListView->model()) {
-        QStandardItem *item = ((QStandardItemModel *)ui->sourceListView->model())->itemFromIndex(current);
+    if (current.isValid()) {
+        QStandardItem *item = src_files_model->itemFromIndex(current);
         if (item && item->data(TypeRole) == TYPEROLE_DIRECTORY) {
-            currentPathId = item->data(PathIdRole).toULongLong();
-            emit currentFileChanged();
+            QString path = item->text();
+            m_currentSourceId = item->data(PathIdRole).toULongLong();
+            if (m_currentSourceId  > 0) {
+                // Choose .. update current path to parent dir
+                if (path == "..") {
+                    if (m_currentPathStr == "/") {
+                        m_currentPathStr = "";
+                    } else {
+                        m_currentPathStr.remove(QRegExp("[^/]+/$"));
+                    }
+
+                } else if (path == "/" && m_currentPathStr == "") {
+                    m_currentPathStr += path;
+
+                } else if (path != "/") {
+                    m_currentPathStr += path;
+                }
+            }
+
+            emit currentSourceIdChanged();
+            emit currentPathStrChanged();
+
+            int idx = ui->filePathComboPath->findText(m_currentPathStr);
+            if (idx >= 0) {
+                ui->filePathComboPath->setCurrentIndex(idx);
+            } else {
+                ui->filePathComboPath->insertItem(-1, m_currentPathStr, QVariant(m_currentSourceId));
+                ui->filePathComboPath->model()->sort(0);
+                ui->filePathComboPath->setCurrentIndex(ui->filePathComboPath->findText(m_currentPathStr));
+            }
         }
     }
 }
 
-bool FileSelectWizardPage::isComplete() const
+void FileSelectWizardPage::changeCurrentText(const QString& current)
+{
+    int idx = ui->filePathComboPath->findText(current);
+    m_currentSourceId = ui->filePathComboPath->itemData(idx).toULongLong();
+    m_currentPathStr = ui->filePathComboPath->itemText(idx);
+    emit currentSourceIdChanged();
+}
+
+void FileSelectWizardPage::deleteDestSelection()
+{
+    QMap<int, int> rows;
+    foreach (QModelIndex index, ui->destTableView->selectionModel()->selectedIndexes())
+        rows.insert(index.row(), 0);
+    QMapIterator<int, int> r(rows);
+    r.toBack();
+    while (r.hasPrevious()) {
+        r.previous();
+        ui->destTableView->model()->removeRow(r.key());
+    }
+}
+
+void FileSelectWizardPage::delayedFilter()
+{
+    freezeSrcView();
+    m_filterTimer->start( 100 );
+}
+
+void FileSelectWizardPage::freezeSrcView()
+{
+    ui->sourceTableView->setUpdatesEnabled(false);
+}
+
+void FileSelectWizardPage::unFreezeSrcView()
 {
-    return ui->destListView->model() && ui->destListView->model()->rowCount() != 0;
+    ui->sourceTableView->setUpdatesEnabled(true);
+    ui->sourceTableView->update();
 }
index c054b658409235730063359fcdec2733883fa8b3..bb59c4df3f7e657e5a72f3666bf3476cb85faaf9 100644 (file)
@@ -1,7 +1,7 @@
 /*
    Bacula(R) - The Network Backup Solution
 
-   Copyright (C) 2000-2017 Kern Sibbald
+   Copyright (C) 2000-2018 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.
 
    Bacula(R) is a registered trademark of Kern Sibbald.
 */
+/*
+ * Restore Wizard: File selection page
+ *
+ * Written by Norbert Bizet, May MMXVII
+ *
+ */
 #ifndef FILESELECTWIZARDPAGE_H
 #define FILESELECTWIZARDPAGE_H
 
@@ -23,6 +29,8 @@
 
 class QStandardItemModel;
 class QModelIndex;
+class RESMON;
+class task;
 
 namespace Ui {
 class FileSelectWizardPage;
@@ -31,27 +39,74 @@ class FileSelectWizardPage;
 class FileSelectWizardPage : public QWizardPage
 {
     Q_OBJECT
-    Q_PROPERTY(qulonglong currentFile READ currentFile NOTIFY currentFileChanged)
+
+    Q_PROPERTY(qulonglong currentSourceId READ currentSourceId NOTIFY currentSourceIdChanged)
+    Q_PROPERTY(QString currentPathStr READ currentPathStr NOTIFY currentPathStrChanged)
+    Q_PROPERTY(QString jobIds READ jobIds NOTIFY jobIdsChanged)
+    Q_PROPERTY(QString fileIds READ fileIds NOTIFY fileIdsChanged)
+    Q_PROPERTY(QString dirIds READ dirIds NOTIFY dirIdsChanged)
+    Q_PROPERTY(QString hardlinks READ hardlinks NOTIFY hardlinksChanged)
+    Q_PROPERTY(QString pluginIds READ pluginIds NOTIFY pluginIdsChanged)
+    Q_PROPERTY(QString pluginNames READ pluginNames NOTIFY pluginNamesChanged)
+
+private:    qulonglong          m_currentSourceId;
+public:     qulonglong          currentSourceId() const { return m_currentSourceId; }
+signals:    void                currentSourceIdChanged();
+private:    QString             m_currentPathStr;
+public:     QString             currentPathStr() const { return m_currentPathStr; }
+signals:    void                currentPathStrChanged();
+private:    QString             m_jobIds;
+public:     QString             jobIds() const { return m_jobIds; }
+signals:    void                jobIdsChanged();
+private:    QString             m_fileIds;
+public:     QString             fileIds() const { return m_fileIds; }
+signals:    void                fileIdsChanged();
+private:    QString             m_dirIds;
+public:     QString             dirIds() const { return m_dirIds; }
+signals:    void                dirIdsChanged();
+private:    QString             m_hardlinks;
+public:     QString             hardlinks() const { return m_hardlinks; }
+signals:    void                hardlinksChanged();
+private:    QString             m_pluginIds;
+public:     QString             pluginIds() const { return m_pluginIds; }
+signals:    void                pluginIdsChanged();
+private:    QString             m_pluginNames;
+public:     QString             pluginNames() const { return m_pluginNames; }
+signals:    void                pluginNamesChanged();
 
 public:
     explicit FileSelectWizardPage(QWidget *parent = 0);
     ~FileSelectWizardPage();
+    /* QWizardPage interface */
+    void initializePage();
+    bool isComplete() const;
+    int nextId() const;
+    bool validatePage();
+    /* local interface */
+    void setRes(RESMON *r) {res=r;}
 
-    void setModels(QStandardItemModel *src_model, QStandardItemModel *dest_model);
+protected slots:
+    void updateSourceModel();
 
-    qulonglong currentFile() const;
+    void optimizeSize();
 
-    bool isComplete() const;
+    void changeCurrentFolder(const QModelIndex& current);
+    void changeCurrentText(const QString &current);
 
-signals:
-    void currentFileChanged();
+    void deleteDestSelection();
 
-protected slots:
-    void changeCurrentFolder(const QModelIndex& current);
+    void delayedFilter();
+
+    void freezeSrcView();
+    void unFreezeSrcView();
 
 private:
-    Ui::FileSelectWizardPage *ui;
-    qulonglong                currentPathId;
+    Ui::FileSelectWizardPage    *ui;
+    QStandardItemModel          *src_files_model;
+    QStandardItemModel          *dest_files_model;
+    QTimer                      *m_filterTimer;
+    RESMON                      *res;
+    bool                        need_optimize;
 };
 
 #endif // FILESELECTWIZARDPAGE_H
index 4413c9ff8537f9aed38900ad3e076c013f4aa587..41d7d85afea405c921a963de224d2b1a5565cc73 100644 (file)
    <rect>
     <x>0</x>
     <y>0</y>
-    <width>739</width>
-    <height>437</height>
+    <width>698</width>
+    <height>484</height>
    </rect>
   </property>
   <property name="windowTitle">
    <string>WizardPage</string>
   </property>
   <layout class="QGridLayout" name="gridLayout">
-   <item row="0" column="0">
+   <item row="0" column="1">
     <widget class="QGroupBox" name="groupBox">
      <property name="title">
       <string>Drag from left to right</string>
      </property>
-     <layout class="QHBoxLayout" name="horizontalLayout">
+     <layout class="QVBoxLayout" name="verticalLayout">
       <item>
-       <widget class="QListView" name="sourceListView">
-        <property name="editTriggers">
-         <set>QAbstractItemView::NoEditTriggers</set>
-        </property>
-        <property name="showDropIndicator" stdset="0">
+       <widget class="QComboBox" name="filePathComboPath">
+        <property name="editable">
          <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>
+       <layout class="QHBoxLayout" name="horizontalLayout">
+        <item>
+         <layout class="QVBoxLayout" name="verticalLayout_2">
+          <item>
+           <widget class="QTableView" name="sourceTableView">
+            <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>false</bool>
+            </property>
+            <property name="selectionMode">
+             <enum>QAbstractItemView::ExtendedSelection</enum>
+            </property>
+            <property name="selectionBehavior">
+             <enum>QAbstractItemView::SelectRows</enum>
+            </property>
+            <property name="showGrid">
+             <bool>false</bool>
+            </property>
+            <property name="cornerButtonEnabled">
+             <bool>false</bool>
+            </property>
+            <attribute name="verticalHeaderVisible">
+             <bool>false</bool>
+            </attribute>
+            <attribute name="verticalHeaderHighlightSections">
+             <bool>false</bool>
+            </attribute>
+           </widget>
+          </item>
+          <item>
+           <layout class="QHBoxLayout" name="horizontalLayout_2">
+            <item>
+             <widget class="QLabel" name="FilterLabel">
+              <property name="text">
+               <string>Filter</string>
+              </property>
+             </widget>
+            </item>
+            <item>
+             <widget class="QLineEdit" name="FilterEdit"/>
+            </item>
+           </layout>
+          </item>
+         </layout>
+        </item>
+        <item>
+         <widget class="QTableView" name="destTableView">
+          <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="showGrid">
+           <bool>false</bool>
+          </property>
+          <property name="cornerButtonEnabled">
+           <bool>false</bool>
+          </property>
+          <attribute name="horizontalHeaderHighlightSections">
+           <bool>false</bool>
+          </attribute>
+          <attribute name="verticalHeaderVisible">
+           <bool>false</bool>
+          </attribute>
+          <attribute name="verticalHeaderHighlightSections">
+           <bool>false</bool>
+          </attribute>
+         </widget>
+        </item>
+       </layout>
       </item>
      </layout>
     </widget>
index 1940fcfda9e9ea3e8641c977c45044ce9d82f2f3..db8ebba897daa6b9998a1e0eaf1c93694f7a1130 100644 (file)
@@ -1,7 +1,7 @@
 /*
    Bacula(R) - The Network Backup Solution
 
-   Copyright (C) 2000-2017 Kern Sibbald
+   Copyright (C) 2000-2018 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.
 
    Bacula(R) is a registered trademark of Kern Sibbald.
 */
+/*
+ * definition of models related to file selection wizard page.
+ *
+ * Written by Norbert Bizet, May MMXVII
+ *
+ */
 #ifndef FILESMODEL_H
 #define FILESMODEL_H
 #include <QStandardItemModel>
 #include <QFileIconProvider>
 #include <QMimeData>
 #include "task.h"
+#include <QTableWidgetItem>
+#include "../util/fmtwidgetitem.h"
+
 enum {
     PathIdRole = Qt::UserRole+1,
     FilenameIdRole = Qt::UserRole+2,
@@ -29,7 +38,8 @@ enum {
     JobIdRole = Qt::UserRole+4,
     LStatRole = Qt::UserRole+5,
     PathRole = Qt::UserRole+6,
-    TypeRole = Qt::UserRole+7
+    TypeRole = Qt::UserRole+7,
+    FullPathRole = Qt::UserRole+8
 };
 
 enum {
@@ -102,9 +112,6 @@ public:
 public slots:
     void taskComplete(task *t)
     {
-        // increase cursor
-        // update canfetch
-        // deletelater
         t->deleteLater();
     }
 
@@ -114,6 +121,8 @@ private:
     bool            m_canFetchMore;
 };
 
+extern int decode_stat(char *buf, struct stat *statp, int stat_size, int32_t *LinkFI);
+
 class FileDestModel : public QStandardItemModel
 {
     bool canDropMimeData(const QMimeData *data, Qt::DropAction action, int row, int column, const QModelIndex &parent) const
@@ -165,30 +174,44 @@ class FileDestModel : public QStandardItemModel
             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;
-            }
+            if (col == 0) {
+                QStandardItem *item;
+                /* do something with the data */
+                int type = roleDataMap[TypeRole].toInt();
 
-            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);
+                switch(type) {
+                case TYPEROLE_DIRECTORY:
+                    item = new DirectoryItem();
+                    break;
+                case TYPEROLE_FILE:
+                    item = new FileItem();
+                    break;
+                default:
+                    return false;
+                }
 
-            appendRow(item);
+                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[Qt::DisplayRole], Qt::DisplayRole);
+                item->setData(roleDataMap[Qt::ToolTipRole], Qt::ToolTipRole);
+                if (type == TYPEROLE_FILE) {
+                    QList<QStandardItem*> colums;
+                    struct stat statp;
+                    int32_t LinkFI;
+                    decode_stat(roleDataMap[LStatRole].toString().toLocal8Bit().data(),
+                                &statp, sizeof(statp), &LinkFI);
+                    char buf[200];
+                    bstrutime(buf, sizeof(buf), statp.st_mtime);
+                    colums << item << new QStandardItem(convertBytesSI(statp.st_size)) << new QStandardItem(buf);
+                    appendRow(colums);
+                } else {
+                    appendRow(item);
+                }
+            }
         }
         return true;
     }
index 66302c7580e0ee4dde14281f05d9e14803d7e1c7..f54a3ea4d842eea30a95389b923064b32f1f5d3c 100644 (file)
@@ -1,7 +1,7 @@
 /*
    Bacula(R) - The Network Backup Solution
 
-   Copyright (C) 2000-2017 Kern Sibbald
+   Copyright (C) 2000-2018 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.
 
    Bacula(R) is a registered trademark of Kern Sibbald.
 */
+/*
+ * Restore Wizard: Job selection page
+ *
+ * Written by Norbert Bizet, May MMXVII
+ *
+ */
+#include "common.h"
 #include "jobselectwizardpage.h"
+#include "conf.h"
+#include "task.h"
 #include "ui_jobselectwizardpage.h"
 #include <QStandardItemModel>
 
 JobSelectWizardPage::JobSelectWizardPage(QWidget *parent) :
     QWizardPage(parent),
-    ui(new Ui::JobSelectWizardPage)
+    ui(new Ui::JobSelectWizardPage),
+    res(NULL),
+    model(new QStandardItemModel),
+    m_jobId(-1)
 {
     ui->setupUi(this);
+    /* currentJob in mandatory */
     registerField("currentJob*", this, "currentJob", SIGNAL(currentJobChanged()));
+    /* assign model to widget */
+    ui->BackupTableView->setModel(model);
+    /* when selection change, change the field value and the next button state */
+    connect(ui->BackupTableView->selectionModel(), SIGNAL(selectionChanged(const QItemSelection&, const QItemSelection&)), this, SIGNAL(currentJobChanged()));
+    connect(ui->BackupTableView->selectionModel(), SIGNAL(selectionChanged(const QItemSelection&, const QItemSelection&)), this, SIGNAL(completeChanged()));
 }
 
 JobSelectWizardPage::~JobSelectWizardPage()
 {
+    delete model;
     delete ui;
 }
 
-void JobSelectWizardPage::setModel(QStandardItemModel *model)
+void JobSelectWizardPage::initializePage()
 {
-    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()));
+    /* populate model */
+    if (res && (!res->terminated_jobs || res->terminated_jobs->empty())) {
+        /* get terminated_jobs info if not present. Queue populateModel() at end of task */
+        task *t = new task();
+        connect(t, SIGNAL(done(task*)), this , SLOT(populateModel()), Qt::QueuedConnection);
+        connect(t, SIGNAL(done(task*)), t, SLOT(deleteLater()));
+        t->init(res, TASK_STATUS);
+        res->wrk->queue(t);
+    } else {
+        /* populate Model directly */
+        populateModel();
+    }
 }
 
 bool JobSelectWizardPage::isComplete() const
 {
-    int s = ui->BackupTableView->selectionModel() ?
-                ui->BackupTableView->selectionModel()->selectedRows().size() : 0;
-
-    return (ui->BackupTableView->selectionModel() && s>0);
+    /* any selection will do since it's single selection */
+    return (ui->BackupTableView->selectionModel()
+            && !ui->BackupTableView->selectionModel()->selectedRows().isEmpty()
+            );
 }
 
-void JobSelectWizardPage::optimizeSize()
+qlonglong JobSelectWizardPage::currentJob() const
 {
-    ui->BackupTableView->resizeColumnsToContents();
-    ui->BackupTableView->horizontalHeader()->setStretchLastSection(true);
-    ui->BackupTableView->horizontalHeader()->setSortIndicator(0, Qt::AscendingOrder);
+    /* single selection */
+    QModelIndex idx = ui->BackupTableView->selectionModel()->currentIndex();
+    /* return the JobId in column 0 */
+    QModelIndex idIdx = idx.sibling(idx.row(), 0);
+    return idIdx.data().toLongLong();
 }
 
-u_int64_t JobSelectWizardPage::currentJob() const
+void JobSelectWizardPage::populateModel()
 {
-    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();
+    if (res) {
+        /* populate model with jobs listed in currentClient */
+        task *t = new task();
+        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 = model;
+        res->wrk->queue(t);
     }
-    return -1;
 }
index d299fa676bc6f51fff4653175c7af2db5e733d50..034cea788b9658eca60e12001c9f56376de6d50f 100644 (file)
@@ -1,7 +1,7 @@
 /*
    Bacula(R) - The Network Backup Solution
 
-   Copyright (C) 2000-2017 Kern Sibbald
+   Copyright (C) 2000-2018 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.
 
    Bacula(R) is a registered trademark of Kern Sibbald.
 */
+/*
+ * Restore Wizard: Job selection page
+ *
+ * Written by Norbert Bizet, May MMXVII
+ *
+ */
 #ifndef JOBSELECTWIZARDPAGE_H
 #define JOBSELECTWIZARDPAGE_H
 
+#include "common.h"
 #include <QWizardPage>
 
 class QStandardItemModel;
 class QItemSelection;
+class RESMON;
 
 namespace Ui {
 class JobSelectWizardPage;
@@ -36,22 +44,26 @@ class JobSelectWizardPage : public QWizardPage
 public:
     explicit JobSelectWizardPage(QWidget *parent = 0);
     ~JobSelectWizardPage();
-
-    void setModel(QStandardItemModel *model);
-
-    u_int64_t currentJob() const;
-
+    /* QWizardPage interface */
+    void initializePage();
     bool isComplete() const;
+    /* local interface */
+    inline void setRes(RESMON *r) {res=r;}
+    /* currentJob READ */
+    qlonglong currentJob() const;
 
 signals:
+    /* currentJob NOTIFY */
     void currentJobChanged();
 
-public slots:
-    void optimizeSize();
+protected slots:
+    void populateModel();
 
 private:
-    Ui::JobSelectWizardPage *ui;
-    qlonglong               m_jobId;
+    Ui::JobSelectWizardPage     *ui;
+    RESMON                      *res;
+    QStandardItemModel          *model;
+    qlonglong                   m_jobId;
 };
 
 #endif // JOBSELECTWIZARDPAGE_H
diff --git a/bacula/src/qt-console/tray-monitor/pluginmodel.h b/bacula/src/qt-console/tray-monitor/pluginmodel.h
new file mode 100644 (file)
index 0000000..f7bdca6
--- /dev/null
@@ -0,0 +1,28 @@
+/*
+   Bacula(R) - The Network Backup Solution
+
+   Copyright (C) 2000-2018 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 PLUGINMODEL_H
+#define PLUGINMODEL_H
+enum {
+    PluginNameRole = Qt::UserRole+1,
+    PluginTypeRole = Qt::UserRole+2,
+    PluginCommentRole = Qt::UserRole+3,
+    PluginRequiredRole = Qt::UserRole+4,
+    PluginDefaultRole = Qt::UserRole+5
+};
+#endif // PLUGINMODEL_H
diff --git a/bacula/src/qt-console/tray-monitor/pluginwizardpage.cpp b/bacula/src/qt-console/tray-monitor/pluginwizardpage.cpp
new file mode 100644 (file)
index 0000000..164a5b5
--- /dev/null
@@ -0,0 +1,177 @@
+/*
+   Bacula(R) - The Network Backup Solution
+
+   Copyright (C) 2000-2018 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.
+*/
+/*
+ * Restore Wizard: Plugin selection page
+ *
+ * Written by Norbert Bizet, May MMXVII
+ *
+ */
+#include "common.h"
+#include "pluginwizardpage.h"
+#include "ui_pluginwizardpage.h"
+#include "pluginmodel.h"
+#include "task.h"
+#include <QStandardItemModel>
+#include <QFormLayout>
+#include <QLineEdit>
+#include <QCheckBox>
+#include <QDateTimeEdit>
+#include "lib/ini.h"
+
+PluginWizardPage::PluginWizardPage(QWidget *parent) :
+    QWizardPage(parent),
+    ui(new Ui::PluginWizardPage),
+    res(NULL)
+{
+    ui->setupUi(this);
+    ui->tabWidget->clear();
+    registerField("pluginKeysStr", this, "pluginKeysStr", "pluginKeysStrChanged");
+}
+
+PluginWizardPage::~PluginWizardPage()
+{
+    delete ui;
+}
+
+void PluginWizardPage::initializePage()
+{
+    /* build plugin form UI dynamically*/
+    task t;
+    t.init(res, -1);
+    QStringList idsList = field("pluginIds").toString().split(",");
+    QStringList nameList = field("pluginNames").toString().split(",");
+    /* process ids and name lists with the assumption that indexes match */
+    ASSERT(idsList.count() == nameList.count());
+    for( int c=0; c<idsList.count(); ++c ) {
+        QString pluginId = idsList[c];
+        QString pluginName = nameList[c];
+
+        /* don't tab the same plugin twice */
+        bool exists(false);
+        for (int j=0; j<ui->tabWidget->count(); ++j) {
+            if (ui->tabWidget->tabText(j) == pluginName) {
+                exists=true;
+                break;
+            }
+        }
+        if (exists) continue;
+        /* create a tab widget */
+        QWidget *pluginWidget = new QWidget();
+        /* insert a tab widget with an empty form layout */
+        QFormLayout *layout = new QFormLayout();
+        pluginWidget->setLayout(layout);
+        ui->tabWidget->addTab(pluginWidget, pluginName);
+
+        /* parse each plugin fields*/
+        t.plugin(nameList[c], field("jobIds").toString(), pluginId.toInt());
+        ConfigFile cf;
+        cf.unserialize(pluginName.toLatin1().data());
+
+        /* for each field */
+        for (int i=0; i < MAX_INI_ITEMS && cf.items[i].name; i++) {
+            ini_items f = cf.items[i];
+            /* create the w Widget dynamically, based on the field value type */
+            QWidget *w(NULL);
+            if (f.handler == ini_store_str ||
+                    f.handler == ini_store_name ||
+                    f.handler == ini_store_alist_str) /*FIXME: treat alist separatly*/
+            {
+                QLineEdit *l = new QLineEdit();
+                w=l;
+                if (f.default_value)
+                    l->setText(f.default_value);
+            }
+            else if (f.handler == ini_store_pint64 ||
+                     f.handler == ini_store_int64 ||
+                     f.handler == ini_store_pint32 ||
+                     f.handler == ini_store_int32)
+            {
+                QLineEdit *l = new QLineEdit();
+                w=l;
+                l->setValidator(new QIntValidator());
+                if (f.default_value)
+                    l->setText(f.default_value);
+            }
+            else if (f.handler == ini_store_bool)
+            {
+                QCheckBox *c = new QCheckBox();
+                w=c;
+                if (f.default_value)
+                    c->setChecked(f.default_value);
+            }
+            else if (f.handler == ini_store_date)
+            {
+                QDateTimeEdit *d = new QDateTimeEdit();
+                w=d;
+                if (f.default_value)
+                    d->setDateTime(QDateTime::fromString(f.default_value, "yyyy-MM-dd hh:mm:ss"));
+            }
+
+            if (w) {
+                w->setToolTip(f.comment);
+                QString field_name = QString("%1_%2").arg(nameList[c]).arg(f.name);
+                /* This doesn't work FIXME
+                 * if (f.required) {
+                    field_name.append("*");
+                }*/
+
+                registerField(field_name, w);
+                /* there's no way to iterate thru page-register field */
+                /* As a workaround we keep track of registered fields in a separate list */
+                registeredFields.append(field_name);
+
+                layout->addRow(f.name, w);
+                emit completeChanged();
+            }
+        }
+    }
+}
+
+bool PluginWizardPage::validatePage()
+{
+    QStringList pluginKeys;
+    QStringList idsList = field("pluginIds").toString().split(",");
+    QStringList nameList = field("pluginNames").toString().split(",");
+    for (int idx=0; idx<ui->tabWidget->count(); ++idx) {
+        QString name = ui->tabWidget->tabText(idx);
+        ASSERT(name.compare(nameList[idx]) == 0);
+
+        QFile file(name);
+        if (file.open(QIODevice::WriteOnly)) {
+            QTextStream outputStream(&file);
+            foreach(QString fld, registeredFields) {
+                QStringList sl = fld.split("_");
+                if ( (name.compare(sl[0]) == 0) && field(fld).isValid()) {
+                    QString s = QString("%1=%2\n").arg(sl[1]).arg(field(fld).toString());
+                    outputStream << s;
+                }
+            }
+        }
+
+        /* create the key */
+        QString key = QString("j%1i%2").arg(field("jobIds").toString().remove(',').simplified()).arg(idsList[idx].simplified());
+        QString restoreKey = QString("%1:%2").arg(idsList[idx].simplified()).arg(key);
+        pluginKeys.append(restoreKey);
+    }
+
+    m_pluginKeysStr = pluginKeys.join(",");
+    emit pluginKeysStrChanged();
+
+    return true;
+}
diff --git a/bacula/src/qt-console/tray-monitor/pluginwizardpage.h b/bacula/src/qt-console/tray-monitor/pluginwizardpage.h
new file mode 100644 (file)
index 0000000..ebb2573
--- /dev/null
@@ -0,0 +1,60 @@
+/*
+   Bacula(R) - The Network Backup Solution
+
+   Copyright (C) 2000-2018 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.
+*/
+/*
+ * Restore Wizard: Plugin selection page
+ *
+ * Written by Norbert Bizet, May MMXVII
+ *
+ */
+#ifndef PLUGINWIZARDPAGE_H
+#define PLUGINWIZARDPAGE_H
+
+#include <QWizardPage>
+
+namespace Ui {
+class PluginWizardPage;
+}
+
+class RESMON;
+
+class PluginWizardPage : public QWizardPage
+{
+    Q_OBJECT
+    Q_PROPERTY(QString pluginKeysStr READ pluginKeysStr NOTIFY pluginKeysStrChanged)
+
+private: QString    m_pluginKeysStr;
+public:  QString    pluginKeysStr() const { return m_pluginKeysStr; }
+signals: void       pluginKeysStrChanged();
+
+public:
+    explicit PluginWizardPage(QWidget *parent = 0);
+    ~PluginWizardPage();
+    /* QWizardPage interface */
+    void initializePage();
+    bool validatePage();
+    /* local interface */
+    inline void setRes(RESMON *r) {res=r;}
+private:
+    Ui::PluginWizardPage *ui;
+    RESMON *res;
+    QStringList         registeredFields;
+
+};
+
+#endif // PLUGINWIZARDPAGE_H
diff --git a/bacula/src/qt-console/tray-monitor/pluginwizardpage.ui b/bacula/src/qt-console/tray-monitor/pluginwizardpage.ui
new file mode 100644 (file)
index 0000000..e55a6d2
--- /dev/null
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>PluginWizardPage</class>
+ <widget class="QWizardPage" name="PluginWizardPage">
+  <property name="geometry">
+   <rect>
+    <x>0</x>
+    <y>0</y>
+    <width>637</width>
+    <height>503</height>
+   </rect>
+  </property>
+  <property name="windowTitle">
+   <string>WizardPage</string>
+  </property>
+  <layout class="QGridLayout" name="gridLayout">
+   <item row="0" column="0">
+    <widget class="QTabWidget" name="tabWidget">
+     <widget class="QWidget" name="tab">
+      <attribute name="title">
+       <string>Tab 1</string>
+      </attribute>
+     </widget>
+     <widget class="QWidget" name="tab_2">
+      <attribute name="title">
+       <string>Tab 2</string>
+      </attribute>
+     </widget>
+    </widget>
+   </item>
+  </layout>
+ </widget>
+ <resources/>
+ <connections/>
+</ui>
index ffd01f8bf09bfce93bd42f4e6fb2e8101ae5e2f4..9ca86a695ae10dc22819e41d4d44c901362a3fcc 100644 (file)
@@ -1,7 +1,7 @@
 /*
    Bacula(R) - The Network Backup Solution
 
-   Copyright (C) 2000-2017 Kern Sibbald
+   Copyright (C) 2000-2018 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.
 
    Bacula(R) is a registered trademark of Kern Sibbald.
 */
+/*
+ * Restore Wizard : Options page
+ *
+ * Written by Norbert Bizet, May MMXVII
+ *
+ */
+#include "common.h"
 #include "restoreoptionswizardpage.h"
 #include "ui_restoreoptionswizardpage.h"
 #include "common.h"
 #include "filesmodel.h"
 #include "task.h"
 
+#define TABLENAME "b21234"
 RestoreOptionsWizardPage::RestoreOptionsWizardPage(QWidget *parent) :
     QWizardPage(parent),
     ui(new Ui::RestoreOptionsWizardPage),
-    dest_model(0),
-    m_res(0)
+    res(0)
 
 {
     ui->setupUi(this);
 
-    registerField("restoreClient*", ui->restoreClientComboxBox);
+    registerField("restoreClient", ui->restoreClientComboxBox);
     registerField("restoreWhere", ui->whereLineEdit);
-    registerField("restoreReplace*", ui->replaceComboBox);
+    registerField("restoreReplace", ui->replaceComboBox);
     registerField("restoreComment", ui->commentLineEdit);
 }
 
@@ -42,71 +49,63 @@ 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)
+void RestoreOptionsWizardPage::initializePage()
 {
-    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);
+    /* first request synchronous */
+    if (res) {
+        QStringList list;
+        char *str;
+        foreach_alist(str, res->clients) {
+           list << QString(str);
+        }
+
+        ui->restoreClientComboxBox->clear();
+        if (!list.isEmpty()) {
+            ui->restoreClientComboxBox->addItems(list);
+            ui->restoreClientComboxBox->setEnabled(true);
+            ui->restoreClientComboxBox->setCurrentIndex(0);
+        } else {
+            ui->restoreClientComboxBox->setEnabled(false);
+        }
+
+        /* find RestoreFiles default */
+        const char *p = "RestoreFiles";
+        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();
+
+        task t;
+        t.init(res, -1);
+        t.get_job_defaults();
+
+        ui->whereLineEdit->setText(res->defaults.where);
+        ui->replaceComboBox->setCurrentIndex(res->defaults.replace);
     }
-
-    /* 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*)), wizard(), SLOT(deleteLater()));
     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);
+    t->init(res, TASK_RESTORE);
+
+    t->restore_field.tableName = QString(TABLENAME);
+    t->restore_field.jobIds = field("jobIds").toString();
+    t->restore_field.fileIds = field("fileIds").toString();
+    t->restore_field.dirIds = field("dirIds").toString();
+    t->restore_field.hardlinks = field("hardlinks").toString();
+    int idx = field("currentClient").toInt();
+    t->restore_field.client = QString((char*)res->clients->get(idx));
+    t->restore_field.where = field("restoreWhere").toString();
+    t->restore_field.replace = ui->replaceComboBox->currentText();
+    t->restore_field.comment = field("restoreComment").toString();
+    t->restore_field.pluginnames = field("pluginNames").toString();
+    t->restore_field.pluginkeys = field("pluginKeysStr").toString();
+
+    res->wrk->queue(t);
     return true;
 }
index e503f866dc9edde549cc5e19a20b21239264ab3f..8ea3fe0901eb7c6b83f143893d8f7c98ecfd79b3 100644 (file)
@@ -1,7 +1,7 @@
 /*
    Bacula(R) - The Network Backup Solution
 
-   Copyright (C) 2000-2017 Kern Sibbald
+   Copyright (C) 2000-2018 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.
 
    Bacula(R) is a registered trademark of Kern Sibbald.
 */
+/*
+ * Restore Wizard: Options page
+ *
+ * Written by Norbert Bizet, May MMXVII
+ *
+ */
 #ifndef RESTOREOPTIONSWIZARDPAGE_H
 #define RESTOREOPTIONSWIZARDPAGE_H
 
@@ -37,20 +43,15 @@ class RestoreOptionsWizardPage : public QWizardPage
 public:
     explicit RestoreOptionsWizardPage(QWidget *parent = 0);
     ~RestoreOptionsWizardPage();
-
-    void setClients(alist *lst);
-    void setModel(QStandardItemModel *model);
-    void setResmon(RESMON *res);
-
+    /* QWizardPage interface */
+    void initializePage();
     bool validatePage();
-
-public slots:
-    void fill_defaults(task *t);
+    /* local interface */
+    inline void setRes(RESMON *r) {res=r;}
 
 private:
     Ui::RestoreOptionsWizardPage *ui;
-    QStandardItemModel *dest_model;
-    RESMON *m_res;
+    RESMON *res;
 };
 
 #endif // RESTOREOPTIONSWIZARDPAGE_H
index 54379c18f5365c4211694b79bfa1b4d1a21f4f01..cbc16ff8d72cfb4675e788b3cc5e30edf8ce40ce 100644 (file)
     <widget class="QComboBox" name="replaceComboBox">
      <item>
       <property name="text">
-       <string>never</string>
+       <string>Never</string>
       </property>
      </item>
      <item>
       <property name="text">
-       <string>always</string>
+       <string>Always</string>
       </property>
      </item>
      <item>
       <property name="text">
-       <string>if newer</string>
+       <string>IfNewer</string>
       </property>
      </item>
      <item>
       <property name="text">
-       <string>if older</string>
+       <string>IfOlder</string>
       </property>
      </item>
     </widget>
index e25bfdddc017aca4cbf7c05002580a9baa9b3e1e..0f55ef2029740db6fa3d16a10aeb153398efbb9d 100644 (file)
@@ -1,7 +1,7 @@
 /*
    Bacula(R) - The Network Backup Solution
 
-   Copyright (C) 2000-2017 Kern Sibbald
+   Copyright (C) 2000-2018 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.
 
    Bacula(R) is a registered trademark of Kern Sibbald.
 */
+/*
+ * Restore Wizard
+ *
+ * Written by Norbert Bizet, May MMXVII
+ *
+ */
+#include "common.h"
 #include "restorewizard.h"
 #include "ui_restorewizard.h"
 #include "filesmodel.h"
 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(new Ui::RestoreWizard)
 {
     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);
-
+    ui->RestWizClientPage->setRes(res);
+    ui->RestWizJobSelectPage->setRes(res);
+    ui->RestWiFileSelectionPage->setRes(res);
+    ui->RestWizPluginPage->setRes(res);
+    ui->RestWizAdvancedOptionsPage->setRes(res);
+
+    /* avoid connect warnings */
+    qRegisterMetaType<Qt::Orientation>("Qt::Orientation");
+    qRegisterMetaType< QList < QPersistentModelIndex > >("QList<QPersistentModelIndex>");
+    qRegisterMetaType< QVector < int > >("QVector<int>");
+#if QT_VERSION >= 0x050000
+    qRegisterMetaType< QAbstractItemModel::LayoutChangeHint >("QAbstractItemModel::LayoutChangeHint");
+#endif
 }
 
-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);
-}
index 17880ab6cfda3e0fceac58016b5fba02657053be..76b9a83a8ef6edf01a79aaaf0751a82852930046 100644 (file)
@@ -1,7 +1,7 @@
 /*
    Bacula(R) - The Network Backup Solution
 
-   Copyright (C) 2000-2017 Kern Sibbald
+   Copyright (C) 2000-2018 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.
 
    Bacula(R) is a registered trademark of Kern Sibbald.
 */
+/*
+ * Restore Wizard
+ *
+ * Written by Norbert Bizet, May MMXVII
+ *
+ */
 #ifndef RESTOREWIZARD_H
 #define RESTOREWIZARD_H
 
@@ -38,27 +44,16 @@ public:
         RW_CLIENT_PAGE = 0,
         RW_JOB_PAGE = 1,
         RW_FILE_PAGE = 2,
-        RW_ADVANCEDOPTIONS_PAGE = 3
+        RW_PLUGIN_PAGE = 3,
+        RW_ADVANCEDOPTIONS_PAGE = 4
     };
 
     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
index 5c24c032f543c9a260581f380591802ed3526364..7671cdf890ac9072cf5ab2df47e3edcac73361f7 100644 (file)
@@ -36,7 +36,7 @@
     <string>Select a Client.</string>
    </property>
   </widget>
-  <widget class="JobSelectWizardPage" name="RestWizBackupSelectPage">
+  <widget class="JobSelectWizardPage" name="RestWizJobSelectPage">
    <property name="title">
     <string>Restore</string>
    </property>
     <string>Files Selection</string>
    </property>
   </widget>
+  <widget class="PluginWizardPage" name="RestWizPluginPage">
+   <property name="title">
+    <string>Plugins</string>
+   </property>
+   <property name="subTitle">
+    <string>Restore pluging values</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>
+    <string>Select advanced options for restore</string>
    </property>
   </widget>
  </widget>
   <customwidget>
    <class>RestoreOptionsWizardPage</class>
    <extends>QWizardPage</extends>
-   <header location="global">restoreoptionswizardpage.h</header>
+   <header>restoreoptionswizardpage.h</header>
+   <container>1</container>
+  </customwidget>
+  <customwidget>
+   <class>PluginWizardPage</class>
+   <extends>QWizardPage</extends>
+   <header location="global">pluginwizardpage.h</header>
    <container>1</container>
   </customwidget>
  </customwidgets>
index 5305e148f650946668e81ea23fa7ee2eed7f35de..e588ba30a9a4c0dc44a82cb38413c711dd3b5fc2 100644 (file)
@@ -1,7 +1,7 @@
 /*
    Bacula(R) - The Network Backup Solution
 
-   Copyright (C) 2000-2017 Kern Sibbald
+   Copyright (C) 2000-2018 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.
@@ -83,7 +83,7 @@ RunJob::RunJob(RESMON *r): QDialog(), res(r), tabAdvanced(NULL)
    }
 
    show();
-};
+}
 
 void RunJob::tabChange(int idx)
 {
@@ -181,9 +181,9 @@ void RunJob::runjob()
    
    // Build the command and run it!
    task *t = new task();
+   t->init(res, TASK_RUN);
    connect(t, SIGNAL(done(task *)), this, SLOT(jobStarted(task *)), Qt::QueuedConnection);
    t->arg = command.c_str();
-   t->init(res, TASK_RUN);
    res->wrk->queue(t);
 }
 
@@ -223,11 +223,11 @@ void RunJob::jobChanged(int)
    p = ui.jobCombo->currentText().toUtf8().data();
    if (p && *p) {
       task *t = new task();
+      t->init(res, TASK_INFO);
       pm_strcpy(info, p);
       connect(t, SIGNAL(done(task *)), this, SLOT(jobInfo(task *)), Qt::QueuedConnection);
       t->arg = info.c_str();    // Jobname
       t->arg2 = NULL;           // Level
-      t->init(res, TASK_INFO);
       res->wrk->queue(t);
    }
 }
@@ -243,9 +243,9 @@ void RunJob::levelChanged(int)
          task *t = new task();
          pm_strcpy(level, p);
          connect(t, SIGNAL(done(task *)), this, SLOT(jobInfo(task *)), Qt::QueuedConnection);
+         t->init(res, TASK_INFO);
          t->arg = info.c_str();    // Jobname
          t->arg2 = level.c_str();  // Level
-         t->init(res, TASK_INFO);
          res->wrk->queue(t);
       }
    }
@@ -426,9 +426,9 @@ void TSched::timerEvent(QTimerEvent *event)
    
                   // Build the command and run it!
                   t = new task();
+                  t->init(res, TASK_RUN);
                   connect(t, SIGNAL(done(task *)), this, SLOT(jobStarted(task *)), Qt::QueuedConnection);
                   t->arg = command.c_str();
-                  t->init(res, TASK_RUN);
                   res->wrk->queue(t);
 
                   break;
index 1a53ec3b455fe6df95e41388d08fa65016254e16..0781f9a1ba4108b43e95d1eee54b1a8d817d4990 100644 (file)
@@ -1,7 +1,7 @@
 /*
    Bacula(R) - The Network Backup Solution
 
-   Copyright (C) 2000-2017 Kern Sibbald
+   Copyright (C) 2000-2018 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.
 
    Bacula(R) is a registered trademark of Kern Sibbald.
 */
-
 #include "task.h"
 #include "jcr.h"
 #include "filesmodel.h"
+#include "pluginmodel.h"
+#include <QTableWidgetItem>
+#include "../util/fmtwidgetitem.h"
 
 #define dbglvl 10
 int authenticate_daemon(JCR *jcr, MONITOR *monitor, RESMON *res);
@@ -73,7 +75,7 @@ static void *handle_task(void *data)
             t->get_job_files(t->arg, t->pathId);
             break;
         case TASK_RESTORE:
-            t->restore(QString("b21234"));
+            t->restore();
             break;
         default:
             Mmsg(t->errmsg, "Unknown task");
@@ -668,7 +670,7 @@ bool task::get_job_defaults()
    while (get_next_line(res)) {
       Dmsg2(dbglvl, "<- %d %s\n", res->bs->msglen, curline);
    }
-   res->bs->fsend(".defaults job=\"%s\"\n", res->defaults.job);
+   res->bs->fsend(".defaults job=%s\n", res->defaults.job);
    while (get_next_line(res)) {
       Dmsg1(dbglvl, "line = [%s]\n", curline);
       if ((p = strchr(curline, '=')) == NULL) {
@@ -701,6 +703,9 @@ bool task::get_job_defaults()
 
       } else if (strcasecmp(curline, "where") == 0) {
           res->defaults.where = bstrdup(p);
+
+      } else if (strcasecmp(curline, "replace") == 0) {
+          res->defaults.replace = str_to_uint64(p);
       }
 
    }
@@ -852,106 +857,115 @@ bail_out:
 
 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);
+    bool ret = false;
+    btimer_t *tid = NULL;
+    int row=0;
+    QStringList headers;
+    struct s_last_job *ljob=NULL;
 
-   if (!res->bs || !res->bs->is_open() || res->bs->is_error()) {
-      if (!connect_bacula()) {
-         goto bail_out;
-      }
-   }
+    if (!model) {
+        goto bail_out;
+    }
 
-   tid = start_thread_timer(NULL, pthread_self(), (uint32_t)120);
+    model->clear();
+    headers << tr("JobId") << tr("Job") << tr("Level") << tr("Date") << tr("Files") << tr("Bytes");
+    model->setHorizontalHeaderLabels(headers);
 
-   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);
+    if (!res->bs || !res->bs->is_open() || res->bs->is_error()) {
+        if (!connect_bacula()) {
             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);
+    tid = start_thread_timer(NULL, pthread_self(), (uint32_t)120);
 
-       model->setItem(row, 0, new QStandardItem(line_lst[0]));
+    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);
+        }
+    }
 
-       model->setItem(row, 1, new QStandardItem(line_lst[3]));
+    res->bs->fsend(".api 2\n");
+    while (get_next_line(res)) {
+        Dmsg2(dbglvl, "<- %d %s\n", res->bs->msglen, curline);
+    }
 
-       QDateTime date;
-       date.setTime_t(line_lst[1].toUInt());
-       QStandardItem *dateItem = new QStandardItem();
-       dateItem->setData(date, Qt::DisplayRole);
-       model->setItem(row, 3, dateItem);
+    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);
+        }
+    }
 
-       ret = true;
-       ++row;
-   }
+    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);
+
+        /* find the job in res terminated list */
+        if (res->terminated_jobs) {
+            foreach_dlist(ljob, res->terminated_jobs) {
+                if (ljob->JobId == line_lst[0].toUInt()) {
+                    model->setItem(row, 2, new QStandardItem(QString(job_level_to_str(ljob->JobLevel))));
+                    model->setItem(row, 4, new QStandardItem(QString::number(ljob->JobFiles)));
+                    model->setItem(row, 5, new QStandardItem(QString::number(ljob->JobBytes)));
+                    break;
+                }
+            }
+        }
 
-   // Close the socket, it's over or we don't want to reuse it
-   disconnect_bacula();
+        ret = true;
+        ++row;
+    }
 
-//   // 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));
-//   }
+    // 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;
+    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::get_job_files(const char* job, uint64_t pathid)
 {
     bool ret = false;
     btimer_t *tid = NULL;
     QString jobs;
+    struct stat statp;
+    int32_t LinkFI;
 
-    if (model) {
-        model->clear();
+    if (!model) {
+        goto bail_out;
     }
 
+    model->removeRows(0, model->rowCount());
+
     if (!res->bs || !res->bs->is_open() || res->bs->is_error()) {
         if (!connect_bacula()) {
             goto bail_out;
@@ -992,17 +1006,18 @@ bool task::get_job_files(const char* job, uint64_t pathid)
     }
 
     /* cache the file set */
-    res->bs->fsend(".bvfs_update jobid=%s\n", jobs.toUtf8());
+    res->bs->fsend(".bvfs_update jobid=%s\n", jobs.toLatin1().data());
     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());
+        res->bs->fsend(".bvfs_lsdirs jobid=%s path=\"\"\n", jobs.toLatin1().data());
     } else {
-        res->bs->fsend(".bvfs_lsdirs jobid=%s pathid=%lld\n", jobs.toUtf8(), pathid);
+        res->bs->fsend(".bvfs_lsdirs jobid=%s pathid=%lld\n", jobs.toLatin1().data(), pathid);
     }
 
+    //+ " limit=" + limit + " offset=" + offset ;
     while (get_next_line(res)) {
         QString line(curline);
         QStringList line_lst = line.split("\t", QString::KeepEmptyParts);
@@ -1012,22 +1027,32 @@ bool task::get_job_files(const char* job, uint64_t pathid)
             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(jobs), JobIdRole);
             d->setData(QVariant(line_lst[4]), LStatRole);
             d->setData(QVariant(line_lst[5]), PathRole);
+            QFileInfo fi(QDir(QString(arg3)), line_lst[5]);
+            d->setData(QVariant(fi.absoluteFilePath()), Qt::ToolTipRole);
             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());
+    if (strcmp(arg2,"") == 0) {
+        if (pathid == 0) {
+            res->bs->fsend(".bvfs_lsfiles jobid=%s path=\"\"\n", jobs.toLatin1().data());
+        } else {
+            res->bs->fsend(".bvfs_lsfiles jobid=%s pathid=%lld\n", jobs.toLatin1().data(), pathid);
+        }
     } else {
-        res->bs->fsend(".bvfs_lsfiles jobid=%s pathid=%lld\n", jobs.toUtf8(), pathid);
+        if (pathid == 0) {
+            res->bs->fsend(".bvfs_lsfiles jobid=%s path=\"\" pattern=\"%s\"\n", jobs.toLatin1().data(), arg2);
+        } else {
+            res->bs->fsend(".bvfs_lsfiles jobid=%s pathid=%lld pattern=\"%s\"\n", jobs.toLatin1().data(), pathid, arg2);
+        }
     }
+    //+ " limit=" + limit + " offset=" + offset ;
 
     while (get_next_line(res)) {
         QString line(curline);
@@ -1038,11 +1063,19 @@ bool task::get_job_files(const char* job, uint64_t pathid)
             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(jobs), JobIdRole);
             f->setData(QVariant(line_lst[4]), LStatRole);
             f->setData(QVariant(line_lst[5]), PathRole);
+            QFileInfo fi(QDir(QString(arg3)), line_lst[5]);
+            f->setData(QVariant(fi.absoluteFilePath()), Qt::ToolTipRole);
             f->setData(QVariant(line_lst[5]), Qt::DisplayRole);
-            model->appendRow(f);
+            QList<QStandardItem*> colums;
+            decode_stat(line_lst[4].toLocal8Bit().data(),
+                        &statp, sizeof(statp), &LinkFI);
+            char buf[200];
+            bstrutime(buf, sizeof(buf), statp.st_mtime);
+            colums << f << new QStandardItem(convertBytesSI(statp.st_size)) << new QStandardItem(buf);
+            model->appendRow(colums);
             ret = true;
         }
     }
@@ -1063,38 +1096,27 @@ bail_out:
     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 task::prepare_restore()
 {
     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
-        }
+    /* in the restore prepare phase, we apply plugins settings. 
+    * Upload and restoration must be done in one shot within the same connection since
+    *  the director uses UA adress to create a local file unique name */
+    FILE *fp;
+    int idx = 0;
+    QStringList pluginKeys;
+    QStringList pluginNames;
+
+    if (!restore_field.pluginkeys.isEmpty()) {
+        pluginKeys = restore_field.pluginkeys.split(',');
+    }
+    if (!restore_field.pluginnames.isEmpty()) {
+        pluginNames = restore_field.pluginnames.split(',');
     }
 
-    fileids.removeDuplicates();
-    jobids.removeDuplicates();
-    dirids.removeDuplicates();
-    findexes.removeDuplicates();
+    ASSERT(pluginKeys.count() == pluginNames.count());
 
     if (!res->bs || !res->bs->is_open() || res->bs->is_error()) {
         if (!connect_bacula()) {
@@ -1129,24 +1151,60 @@ bool task::prepare_restore(const QString& tableName)
     }
 
     /* retrieve all job ids*/
-    q = QString(".bvfs_restore path=%1 jobid=%2").arg(tableName, jobids.join(","));
-    if (fileids.size() > 0) {
-        q += " fileid=" + fileids.join(",");
+    q = QString(".bvfs_restore path=%1 jobid=%2").arg(restore_field.tableName, restore_field.jobIds);
+    if (!restore_field.fileIds.isEmpty()) {
+        q += QString(" fileid=%1").arg(restore_field.fileIds);
     }
-    if (dirids.size() > 0) {
-        q += " dirid=" + dirids.join(",");
+    if (!restore_field.dirIds.isEmpty()) {
+        q += QString(" dirid=%1").arg(restore_field.dirIds);
     }
-    if (findexes.size() > 0) {
-        q += " hardlink=" + findexes.join(",");
+    if (!restore_field.hardlinks.isEmpty()) {
+        q += QString(" hardlink=%1").arg(restore_field.hardlinks);
     }
-
     q += "\n";
-    res->bs->fsend(q.toUtf8());
+    res->bs->fsend(q.toLatin1().data());
     while (get_next_line(res)) {
         ret = true;
         Dmsg2(dbglvl, "<- %d %s\n", res->bs->msglen, curline);
     }
 
+    /* parse plugins files, upload them and call restore pluginrestoreconf*/
+    foreach(QString k, pluginKeys) {
+        QStringList keysplit=k.split(':');
+        if (keysplit.count() > 1) {
+            QString key = keysplit[1];
+            QString name = pluginNames[idx];
+
+            fp = fopen(name.toLatin1().data(), "r");
+            if (!fp) {
+                berrno be;
+                Dmsg2(dbglvl, "Unable to open %s. ERR=%s\n", name.toLatin1().data(), be.bstrerror(errno));
+                goto bail_out;
+            }
+
+            res->bs->fsend(".putfile key=\"%s\"\n", key.toLatin1().data());
+
+            /* Just read the file and send it to the director */
+            while (!feof(fp)) {
+                int i = fread(res->bs->msg, 1, sizeof_pool_memory(res->bs->msg) - 1, fp);
+                if (i > 0) {
+                    res->bs->msg[i] = 0;
+                    res->bs->msglen = i;
+                    res->bs->send();
+                }
+            }
+
+            res->bs->signal(BNET_EOD);
+            fclose(fp);
+
+            res->bs->fsend("restore pluginrestoreconf=\"%s\"\n", k.toLatin1().data());
+            while (get_next_line(res)) {
+                Dmsg2(dbglvl, "<- %d %s\n", res->bs->msglen, curline);
+            }
+        }
+        ++idx;
+    }
+
     // Close the socket, it's over or we don't want to reuse it
     disconnect_bacula();
 
@@ -1155,17 +1213,14 @@ bool task::prepare_restore(const QString& tableName)
     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 task::run_restore()
 {
     bool ret = false;
+    uint timeout = 1000;
     btimer_t *tid = NULL;
     QString q;
 
@@ -1201,24 +1256,24 @@ bool task::run_restore(const QString& tableName)
         Dmsg2(dbglvl, "<- %d %s\n", res->bs->msglen, curline);
     }
 
-    q = QString("restore client=%1").arg(arg);
+    q = QString("restore client=%1").arg(restore_field.client);
 
-    if (arg2) {
-        QString where(arg2);
-        where.replace("\"", "");
-        q += " where=\"" + where + "\"";
+    if (!restore_field.where.isEmpty()) {
+        restore_field.where.replace("\"", "");
+        q += QString(" where=\"%1\"").arg(restore_field.where);
     }
 
-    if (arg3) {
-        QString comment(arg3);
-        comment.replace("\"", " ");
-        q += " comment=\"" + comment+ "\"";
+    if (!restore_field.comment.isEmpty()) {
+        restore_field.comment.replace("\"", "");
+        q += QString(" comment=\"%1\"").arg(restore_field.comment);
     }
 
-    q += " file=\"?" + tableName + "\"";
+    q += QString(" file=\"?%1\"").arg(restore_field.tableName);
     q += " done yes\n";
 
-    res->bs->fsend(q.toUtf8());
+    res->bs->fsend(q.toLatin1().data());
+
+    /* drain the messages */
     while (get_next_line(res)) {
         ret = true;
         // FIXME : report a signal to have a progress feedback
@@ -1233,15 +1288,11 @@ bool task::run_restore(const QString& tableName)
     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 task::clean_restore()
 {
     bool ret = false;
     btimer_t *tid = NULL;
@@ -1279,9 +1330,9 @@ bool task::clean_restore(const QString& tableName)
         Dmsg2(dbglvl, "<- %d %s\n", res->bs->msglen, curline);
     }
 
-    q = QString(".bvfs_cleanup path=%1\n").arg(tableName);
+    q = QString(".bvfs_cleanup path=%1\n").arg(restore_field.tableName);
 
-    res->bs->fsend(q.toUtf8());
+    res->bs->fsend(q.toLatin1().data());
     while (get_next_line(res)) {
         ret = true;
         // FIXME : report a signal to have a progress feedback
@@ -1296,6 +1347,20 @@ bool task::clean_restore(const QString& tableName)
     if (tid) {
        stop_thread_timer(tid);
     }
+
+    return ret;
+}
+
+bool task::restore()
+{
+    bool ret=prepare_restore();
+    if (ret) {
+        ret = run_restore();
+        if (ret) {
+            ret = clean_restore();
+        }
+    }
+
     if (ret) {
        mark_as_done();
     } else {
@@ -1304,16 +1369,137 @@ bool task::clean_restore(const QString& tableName)
     return ret;
 }
 
-bool task::restore(const QString& tableName)
+QString task::plugins_ids(const QString& jobIds)
 {
-    bool ret=prepare_restore(tableName);
-    if (ret) {
-        ret = run_restore(tableName);
-        if (ret) {
-            return clean_restore(tableName);
+    return parse_plugins(jobIds, "restoreobjectid");
+}
+
+QString task::plugins_names(const QString& jobIds)
+{
+    return parse_plugins(jobIds, "pluginname");
+}
+
+QString task::parse_plugins(const QString& jobIds, const QString& fieldName)
+{
+    btimer_t *tid = NULL;
+    QString ret;
+    QString q;
+
+    if (!res->bs || !res->bs->is_open() || res->bs->is_error()) {
+        if (!connect_bacula()) {
+            return ret;
         }
     }
-    return false;
+
+    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);
+                return ret;
+            }
+            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);
+        }
+    }
+
+    q = QString("llist pluginrestoreconf jobid=%1\n").arg(jobIds);
+    res->bs->fsend(q.toLatin1().data());
+
+    QStringList sl;
+    while (get_next_line(res)) {
+        QString line(curline);
+        line = line.simplified();
+        QStringList line_lst = line.split(":", QString::SkipEmptyParts);
+
+        if (!line_lst.empty() && fieldName.compare(line_lst[0]) == 0) {
+            sl << line_lst[1];
+        }
+    }
+
+    ret = sl.join(",");
+    // Close the socket, it's over or we don't want to reuse it
+    disconnect_bacula();
+
+
+    if (tid) {
+        stop_thread_timer(tid);
+    }
+
+    return ret;
+}
+
+QFile* task::plugin(const QString& name, const QString& jobIds, int id)
+{
+    QFile *ret(NULL);
+    btimer_t *tid = NULL;
+    QString q;
+
+    if (id < 0)
+        return NULL;
+
+    if (!res->bs || !res->bs->is_open() || res->bs->is_error()) {
+        if (!connect_bacula()) {
+            return NULL;
+        }
+    }
+
+    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);
+                return NULL;
+            }
+            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 1\n");
+    while (get_next_line(res)) {
+        Dmsg2(dbglvl, "<- %d %s\n", res->bs->msglen, curline);
+    }
+
+    ret = new QFile(name);
+    ret->open(QIODevice::WriteOnly);
+
+    q = QString("llist pluginrestoreconf jobid=%1 id=%2\n").arg(jobIds).arg(id);
+    res->bs->fsend(q.toLatin1().data());
+    while (get_next_line(res)) {
+        if (QString(curline).contains(":"))
+            continue;
+        ret->write(curline);
+        ret->write("\n");
+    }
+    ret->close();
+
+    // Close the socket, it's over or we don't want to reuse it
+    disconnect_bacula();
+
+    if (tid) {
+        stop_thread_timer(tid);
+    }
+
+    return ret;
 }
 
 /* Get resources to run a job */
@@ -1398,7 +1584,7 @@ bool task::get_resources()
       res->storages->append(bstrdup(curline));
    }
 
-   res->bs->fsend(".catalog\n");
+   res->bs->fsend(".catalogs\n");
    while (get_next_line(res)) {
       res->catalogs->append(bstrdup(curline));
    }
index 2b9bf6e79bc6fa8b3c977c287d0a70fd085f80b1..ad62194b2b455cc13907e9e00b3c783fcf4447dc 100644 (file)
@@ -1,7 +1,7 @@
 /*
    Bacula(R) - The Network Backup Solution
 
-   Copyright (C) 2000-2017 Kern Sibbald
+   Copyright (C) 2000-2018 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.
@@ -34,6 +34,7 @@ enum {
    TASK_LIST_CLIENT_JOBS,
    TASK_LIST_JOB_FILES,
    TASK_RESTORE,
+   TASK_PLUGIN,
    TASK_DEFAULTS,
    TASK_CLOSE,
    TASK_INFO,
@@ -65,27 +66,50 @@ public:
       char  c[256];
    } result;                    /* The task might return something */
    
+   struct r_field
+   {
+       QString tableName;
+       QString jobIds;
+       QString fileIds;
+       QString dirIds;
+       QString hardlinks;
+       QString client;
+       QString where;
+       QString replace;
+       QString comment;
+       QString pluginnames;
+       QString pluginkeys;
+   } restore_field;
+
    task(): QObject(), res(NULL), type(TASK_NONE), status(false), curline(NULL),
-      curend(NULL), arg(NULL), arg2(NULL)
+      curend(NULL), arg(NULL), arg2(NULL), arg3(NULL), model(NULL), pathId(0)
    {
       errmsg = get_pool_memory(PM_FNAME);
       *errmsg = 0;
       memset(result.c, 0, sizeof(result.c));
-   };
+   }
+
    ~task() {
       Enter();
       disconnect();             /* disconnect all signals */
       free_pool_memory(errmsg);
-   };
+   }
+
    void init(int t) {
       res = NULL;
       type = t;
       status = false;
-   };
+      arg = NULL;
+      arg2 = NULL;
+      arg3 = NULL;
+      model = NULL;
+      pathId = 0;
+   }
+
    void init(RESMON *s, int t) {
       init(t);
       res = s;
-   };
+   }
 
    RESMON *get_res();
    void lock_res();
@@ -113,12 +137,18 @@ public:
    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);
+   bool prepare_restore();
+   bool run_restore();
+   bool clean_restore();
+   bool restore();
+
+   QString plugins_ids(const QString &jobIds);
+   QString plugins_names(const QString& jobIds);
+   QString parse_plugins(const QString& jobIds, const QString& fieldName);
+   QFile* plugin(const QString &name, const QString& jobIds, int id);
 
 signals:
+
    void done(task *t);
 };
 
index c6c15c6b392f88947e98583cfbc1be6829a21f22..5f29a9f88a38feb30d9c5de1cd980178fa0add73 100644 (file)
@@ -1,7 +1,7 @@
 /*
    Bacula(R) - The Network Backup Solution
 
-   Copyright (C) 2000-2017 Kern Sibbald
+   Copyright (C) 2000-2018 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.
@@ -50,7 +50,7 @@ PROG_COPYRIGHT
 "       -t            test - read configuration and exit\n"
 "       -W 0/1        force the detection of the systray\n"
 "       -?            print this message.\n"
-"\n"), 2004, "", VERSION, BDATE, HOST_OS, DISTNAME, DISTVER);
+"\n"), 2004, BDEMO, VERSION, BDATE, HOST_OS, DISTNAME, DISTVER);
 }
 
 void refresh_tray(TrayUI *t)
index 71da7a09d8abc133b151aa7c7a994d58720fcef2..b82ab1e009fdcf89bc0192933e2a044bdf68bbae 100644 (file)
@@ -1,3 +1,7 @@
+#
+# Copyright (C) 2000-2018 Kern Sibbald
+# License: BSD 2-Clause; see file LICENSE-FOSS
+#
 ######################################################################
 #
 #  !!!!!!! IMPORTANT !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
@@ -6,9 +10,6 @@
 #
 #  !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
 #    
-# Copyright (C) 2000-2017 Kern Sibbald
-# License: BSD 2-Clause; see file LICENSE-FOSS
-#
 # CONFIG options for Windows are pulled from win32/qmake.conf
 CONFIG += qt
 #CONFIG += qt debug
@@ -50,8 +51,8 @@ OBJECTS_DIR  = obj
 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 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
+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 pluginwizardpage.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 pluginwizardpage.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 pluginwizardpage.ui
 
 TRANSLATIONS += ts/tm_fr.ts ts/tm_de.ts ts/tm_ja.ts
index 38c8811a331ba86987564a12f1e5299a43a82f1f..92cb9e114b17bd3f879f5586cf759cb6861ab70d 100644 (file)
@@ -1,3 +1,21 @@
+/*
+   Bacula(R) - The Network Backup Solution
+
+   Copyright (C) 2000-2018 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.
+*/
 ######################################################################
 #
 #  !!!!!!! IMPORTANT !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
@@ -18,7 +36,7 @@ CONFIG += qt cross-win32
 greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
 
 cross-win32 {
-  LIBS       +=  -mwindows -L../../win32/release64 -lbacula -lpthread
+  LIBS       +=  ../../win32/lib/obj64/ini.o -mwindows -L../../win32/release64 -lbacula -lpthread
   INCLUDEPATH += ../../win32/compat
 }
 !cross-win32 {
@@ -60,8 +78,8 @@ QMAKE_LIB               = x86_64-w64-mingw32-ar -ru
 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 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
+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 pluginwizardpage.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 pluginwizardpage.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 pluginwizardpage.ui
 
 TRANSLATIONS += ts/tm_fr.ts ts/tm_de.ts ts/tm_ja.ts
index 57346bdc177f4a5f741f03ef175345f9fd677cb6..355c651b4f8d0291ea700352b203afb0e99d088e 100644 (file)
@@ -1,7 +1,7 @@
 /*
    Bacula(R) - The Network Backup Solution
 
-   Copyright (C) 2000-2017 Kern Sibbald
+   Copyright (C) 2000-2018 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.
@@ -294,8 +294,8 @@ private slots:
     void cb_about() {
        QMessageBox::about(this, "Bacula Tray Monitor", "Bacula Tray Monitor\n"
                           "For more information, see: www.bacula.org\n"
-                          "Copyright (C) 1999-2017, Kern Sibbald.\n"
-                          "All rights reserved.");
+                          "Copyright (C) 2000-2018, Kern Sibbald\n"
+                          "License: AGPLv3");
     }
     RESMON *get_director() {
        QStringList dirs;
@@ -392,7 +392,9 @@ private slots:
           return;
        }
        task *t = new task();
-       connect(t, SIGNAL(done(task *)), this, SLOT(start_restore_wizard(task *)), Qt::QueuedConnection);
+       connect(t, SIGNAL(done(task *)), this, SLOT(start_restore_wizard(task *)), Qt::QueuedConnection);       
+       connect(t, SIGNAL(done(task*)), t, SLOT(deleteLater()));
+
        t->init(dir, TASK_RESOURCES);
        dir->wrk->queue(t);
     }
@@ -428,12 +430,10 @@ public slots:
     }
 
     void start_restore_wizard(task *t) {
-        RESMON *dir = t->res;
-        restorewiz = new RestoreWizard(dir);
+        restorewiz = new RestoreWizard(t->res);
         restorewiz->show();
-        t->deleteLater();
     }
-
+    
 };
 
 
index 76809ff895757ff9db7cd6fd12753033549f6490..2f0d57e7a52b01b9585b3d4587e9663c7bcc8114 100644 (file)
@@ -1,7 +1,7 @@
 /*
    Bacula(R) - The Network Backup Solution
 
-   Copyright (C) 2000-2017 Kern Sibbald
+   Copyright (C) 2000-2018 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.
index cfd52f056ccf4412bdb009b028208302b0017598..575d008a859f6a1e8618238d7a54094f20d333ad 100644 (file)
@@ -140,6 +140,7 @@ struct RESMON {
       char *catalog;
       int   priority;
       char *where;
+      int   replace;
    } defaults;
 
    /* Information about the job */
diff --git a/bacula/src/qt-console/tray-monitor/ts/tm_de.ts b/bacula/src/qt-console/tray-monitor/ts/tm_de.ts
new file mode 100644 (file)
index 0000000..3f5449c
--- /dev/null
@@ -0,0 +1,720 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!DOCTYPE TS>
+<TS version="2.1" language="de_DE">
+<context>
+    <name>Conf</name>
+    <message>
+        <location filename="../main-conf.ui" line="14"/>
+        <source>Configuration</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../main-conf.ui" line="24"/>
+        <source>Monitor Configuration</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../main-conf.ui" line="35"/>
+        <location filename="../main-conf.ui" line="45"/>
+        <source>The Monitor name will be used during the authentication phase.</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../main-conf.ui" line="38"/>
+        <source>Name:</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../main-conf.ui" line="55"/>
+        <source>Refresh Interval:</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../main-conf.ui" line="75"/>
+        <location filename="../main-conf.ui" line="87"/>
+        <source>Specify the &quot;Command Directory&quot; where the tray-monitor program will check regularly for jobs to run</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../main-conf.ui" line="78"/>
+        <source>Command Directory:</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../main-conf.ui" line="94"/>
+        <source>...</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../main-conf.ui" line="103"/>
+        <location filename="../main-conf.ui" line="113"/>
+        <source>Display or Hide advanced options in the &quot;Run Job&quot; window</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../main-conf.ui" line="106"/>
+        <source>Display Advanced Options:</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../main-conf.ui" line="131"/>
+        <source>Save and Apply the changes</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../main-conf.ui" line="134"/>
+        <source>Save</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../main-conf.ui" line="145"/>
+        <source>Cancel</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../main-conf.ui" line="169"/>
+        <source>Show/Hide Passwords</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../main-conf.ui" line="172"/>
+        <source>Password</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../main-conf.ui" line="183"/>
+        <source>Add Client resource to monitor</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../main-conf.ui" line="186"/>
+        <source>Client   </source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../main-conf.ui" line="197"/>
+        <source>Add Storage resource to monitor</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../main-conf.ui" line="200"/>
+        <source>Storage</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../main-conf.ui" line="211"/>
+        <source>Add Director resource to monitor</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../main-conf.ui" line="214"/>
+        <source> Director</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../conf.cpp" line="375"/>
+        <source>Select Command Directory</source>
+        <translation type="unfinished"></translation>
+    </message>
+</context>
+<context>
+    <name>ConfTab</name>
+    <message>
+        <location filename="../conf.cpp" line="383"/>
+        <source>Select CA Certificate File PEM file</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../conf.cpp" line="391"/>
+        <source>Select CA Certificate Directory</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../conf.cpp" line="399"/>
+        <location filename="../conf.cpp" line="407"/>
+        <source>Select TLS Certificate File</source>
+        <translation type="unfinished"></translation>
+    </message>
+</context>
+<context>
+    <name>DIRStatus</name>
+    <message>
+        <location filename="../dirstatus.cpp" line="57"/>
+        <location filename="../dirstatus.cpp" line="89"/>
+        <source>JobId</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../dirstatus.cpp" line="58"/>
+        <location filename="../dirstatus.cpp" line="90"/>
+        <source>Job</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../dirstatus.cpp" line="58"/>
+        <location filename="../dirstatus.cpp" line="90"/>
+        <source>Level</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../dirstatus.cpp" line="58"/>
+        <source>Client</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../dirstatus.cpp" line="59"/>
+        <location filename="../dirstatus.cpp" line="91"/>
+        <source>Status</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../dirstatus.cpp" line="59"/>
+        <source>Storage</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../dirstatus.cpp" line="60"/>
+        <location filename="../dirstatus.cpp" line="91"/>
+        <source>Files</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../dirstatus.cpp" line="60"/>
+        <location filename="../dirstatus.cpp" line="91"/>
+        <source>Bytes</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../dirstatus.cpp" line="60"/>
+        <location filename="../dirstatus.cpp" line="92"/>
+        <source>Errors</source>
+        <translation type="unfinished"></translation>
+    </message>
+</context>
+<context>
+    <name>FDStatus</name>
+    <message>
+        <location filename="../fdstatus.cpp" line="58"/>
+        <location filename="../fdstatus.cpp" line="88"/>
+        <source>JobId</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../fdstatus.cpp" line="59"/>
+        <location filename="../fdstatus.cpp" line="89"/>
+        <source>Job</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../fdstatus.cpp" line="59"/>
+        <location filename="../fdstatus.cpp" line="89"/>
+        <source>Level</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../fdstatus.cpp" line="60"/>
+        <location filename="../fdstatus.cpp" line="90"/>
+        <source>Files</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../fdstatus.cpp" line="60"/>
+        <location filename="../fdstatus.cpp" line="90"/>
+        <source>Bytes</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../fdstatus.cpp" line="60"/>
+        <location filename="../fdstatus.cpp" line="90"/>
+        <source>Errors</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../fdstatus.cpp" line="60"/>
+        <source>Current File</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../fdstatus.cpp" line="90"/>
+        <source>Status</source>
+        <translation type="unfinished"></translation>
+    </message>
+</context>
+<context>
+    <name>QObject</name>
+    <message>
+        <location filename="../../util/fmtwidgetitem.cpp" line="46"/>
+        <source>Invalid job status %1</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../../util/fmtwidgetitem.cpp" line="259"/>
+        <location filename="../../util/fmtwidgetitem.cpp" line="267"/>
+        <source>Yes</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../../util/fmtwidgetitem.cpp" line="261"/>
+        <location filename="../../util/fmtwidgetitem.cpp" line="269"/>
+        <source>No</source>
+        <translation type="unfinished"></translation>
+    </message>
+</context>
+<context>
+    <name>ResConf</name>
+    <message>
+        <location filename="../res-conf.ui" line="14"/>
+        <source>Form</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../res-conf.ui" line="20"/>
+        <source>General</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../res-conf.ui" line="29"/>
+        <location filename="../res-conf.ui" line="39"/>
+        <source>The Name will be used only in the Tray Monitor interface</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../res-conf.ui" line="32"/>
+        <source>Name:</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../res-conf.ui" line="49"/>
+        <source>Description:</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../res-conf.ui" line="63"/>
+        <source>Password:</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../res-conf.ui" line="83"/>
+        <source>Address:</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../res-conf.ui" line="97"/>
+        <source>Port:</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../res-conf.ui" line="123"/>
+        <source>Timeout:</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../res-conf.ui" line="149"/>
+        <location filename="../res-conf.ui" line="159"/>
+        <source>Use Client Initiated backup/restore feature</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../res-conf.ui" line="152"/>
+        <source>Remote</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../res-conf.ui" line="169"/>
+        <location filename="../res-conf.ui" line="179"/>
+        <source>Update the tray monitor icon with the status of this component</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../res-conf.ui" line="172"/>
+        <source>Monitor:</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../res-conf.ui" line="196"/>
+        <source>Use SetIp:</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../res-conf.ui" line="206"/>
+        <source>TLS</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../res-conf.ui" line="212"/>
+        <location filename="../res-conf.ui" line="236"/>
+        <location filename="../res-conf.ui" line="253"/>
+        <location filename="../res-conf.ui" line="283"/>
+        <source>...</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../res-conf.ui" line="219"/>
+        <source>CA Certificate File:</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../res-conf.ui" line="226"/>
+        <source>Enabled</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../res-conf.ui" line="243"/>
+        <source>Key File:</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../res-conf.ui" line="260"/>
+        <source>Certificate File:</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../res-conf.ui" line="276"/>
+        <source>CA Certificate Directory:</source>
+        <translation type="unfinished"></translation>
+    </message>
+</context>
+<context>
+    <name>RunJob</name>
+    <message>
+        <location filename="../runjob.cpp" line="265"/>
+        <source>Computed over %1 job%2, the correlation is %3.</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../runjob.cpp" line="267"/>
+        <source>Computed over %1 job%2, The correlation is %3.</source>
+        <translation type="unfinished"></translation>
+    </message>
+</context>
+<context>
+    <name>SDStatus</name>
+    <message>
+        <location filename="../sdstatus.cpp" line="56"/>
+        <location filename="../sdstatus.cpp" line="87"/>
+        <source>JobId</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../sdstatus.cpp" line="57"/>
+        <location filename="../sdstatus.cpp" line="88"/>
+        <source>Job</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../sdstatus.cpp" line="57"/>
+        <location filename="../sdstatus.cpp" line="88"/>
+        <source>Level</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../sdstatus.cpp" line="57"/>
+        <source>Client</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../sdstatus.cpp" line="58"/>
+        <source>Storage</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../sdstatus.cpp" line="59"/>
+        <location filename="../sdstatus.cpp" line="89"/>
+        <source>Files</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../sdstatus.cpp" line="59"/>
+        <location filename="../sdstatus.cpp" line="89"/>
+        <source>Bytes</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../sdstatus.cpp" line="59"/>
+        <location filename="../sdstatus.cpp" line="90"/>
+        <source>Errors</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../sdstatus.cpp" line="89"/>
+        <source>Status</source>
+        <translation type="unfinished"></translation>
+    </message>
+</context>
+<context>
+    <name>TrayMonitor</name>
+    <message>
+        <location filename="../tray-ui.h" line="187"/>
+        <source>Display</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../tray-ui.h" line="190"/>
+        <source>Quit</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../tray-ui.h" line="193"/>
+        <source>About</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../tray-ui.h" line="196"/>
+        <source>Run...</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../tray-ui.h" line="204"/>
+        <source>Configure...</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../tray-ui.h" line="239"/>
+        <source>Bacula Tray Monitor</source>
+        <translation type="unfinished"></translation>
+    </message>
+</context>
+<context>
+    <name>dirStatus</name>
+    <message>
+        <location filename="../dir-monitor.ui" line="14"/>
+        <source>Form</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../dir-monitor.ui" line="22"/>
+        <source>Director Status</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../dir-monitor.ui" line="35"/>
+        <source>Name:</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../dir-monitor.ui" line="42"/>
+        <source>Started:</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../dir-monitor.ui" line="63"/>
+        <source>Version:</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../dir-monitor.ui" line="70"/>
+        <source>Plugins:</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../dir-monitor.ui" line="84"/>
+        <source>Reloaded:</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../dir-monitor.ui" line="101"/>
+        <source>Running Jobs</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../dir-monitor.ui" line="120"/>
+        <source>Terminated Jobs</source>
+        <translation type="unfinished"></translation>
+    </message>
+</context>
+<context>
+    <name>fdStatus</name>
+    <message>
+        <location filename="../fd-monitor.ui" line="14"/>
+        <source>Form</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../fd-monitor.ui" line="22"/>
+        <source>FileDaemon Status</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../fd-monitor.ui" line="42"/>
+        <source>Name:</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../fd-monitor.ui" line="49"/>
+        <source>Bandwidth Limit:</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../fd-monitor.ui" line="63"/>
+        <source>Started:</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../fd-monitor.ui" line="84"/>
+        <source>Version:</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../fd-monitor.ui" line="91"/>
+        <source>Plugins:</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../fd-monitor.ui" line="101"/>
+        <source>Running Jobs</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../fd-monitor.ui" line="120"/>
+        <source>Terminated Jobs</source>
+        <translation type="unfinished"></translation>
+    </message>
+</context>
+<context>
+    <name>runForm</name>
+    <message>
+        <location filename="../run.ui" line="20"/>
+        <source>Run job</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../run.ui" line="37"/>
+        <source>&lt;h3&gt;Run a Job&lt;/h3&gt;</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../run.ui" line="79"/>
+        <source>Properties</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../run.ui" line="94"/>
+        <source>Job:</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../run.ui" line="117"/>
+        <source>When:</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../run.ui" line="130"/>
+        <source>yyyy-MM-dd hh:mm:ss</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../run.ui" line="143"/>
+        <source>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Job statistics computed from the Catalog with previous jobs.&lt;/p&gt;&lt;p&gt;For accurate information, it is possible to use the bconsole &amp;quot;estimate&amp;quot; command.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../run.ui" line="146"/>
+        <source>Estimate:</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../run.ui" line="152"/>
+        <source>Job Bytes:</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../run.ui" line="166"/>
+        <source>Job Files:</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../run.ui" line="180"/>
+        <location filename="../run.ui" line="204"/>
+        <source>Level:</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../run.ui" line="198"/>
+        <source>Advanced</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../run.ui" line="217"/>
+        <source>Client:</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../run.ui" line="230"/>
+        <source>FileSet:</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../run.ui" line="243"/>
+        <source>Pool:</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../run.ui" line="256"/>
+        <source>Storage:</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../run.ui" line="269"/>
+        <source>Catalog:</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../run.ui" line="279"/>
+        <source>Priority:</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../run.ui" line="360"/>
+        <source>OK</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../run.ui" line="367"/>
+        <source>Cancel</source>
+        <translation type="unfinished"></translation>
+    </message>
+</context>
+<context>
+    <name>sdStatus</name>
+    <message>
+        <location filename="../sd-monitor.ui" line="14"/>
+        <source>Form</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../sd-monitor.ui" line="22"/>
+        <source>Storage Daemon Status</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../sd-monitor.ui" line="35"/>
+        <source>Name:</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../sd-monitor.ui" line="49"/>
+        <source>Started:</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../sd-monitor.ui" line="70"/>
+        <source>Version:</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../sd-monitor.ui" line="77"/>
+        <source>Plugins:</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../sd-monitor.ui" line="87"/>
+        <source>Running Jobs</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../sd-monitor.ui" line="106"/>
+        <source>Terminated Jobs</source>
+        <translation type="unfinished"></translation>
+    </message>
+</context>
+</TS>
diff --git a/bacula/src/qt-console/tray-monitor/ts/tm_fr.ts b/bacula/src/qt-console/tray-monitor/ts/tm_fr.ts
new file mode 100644 (file)
index 0000000..94938da
--- /dev/null
@@ -0,0 +1,720 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!DOCTYPE TS>
+<TS version="2.1" language="fr_FR">
+<context>
+    <name>Conf</name>
+    <message>
+        <location filename="../main-conf.ui" line="14"/>
+        <source>Configuration</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../main-conf.ui" line="24"/>
+        <source>Monitor Configuration</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../main-conf.ui" line="35"/>
+        <location filename="../main-conf.ui" line="45"/>
+        <source>The Monitor name will be used during the authentication phase.</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../main-conf.ui" line="38"/>
+        <source>Name:</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../main-conf.ui" line="55"/>
+        <source>Refresh Interval:</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../main-conf.ui" line="75"/>
+        <location filename="../main-conf.ui" line="87"/>
+        <source>Specify the &quot;Command Directory&quot; where the tray-monitor program will check regularly for jobs to run</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../main-conf.ui" line="78"/>
+        <source>Command Directory:</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../main-conf.ui" line="94"/>
+        <source>...</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../main-conf.ui" line="103"/>
+        <location filename="../main-conf.ui" line="113"/>
+        <source>Display or Hide advanced options in the &quot;Run Job&quot; window</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../main-conf.ui" line="106"/>
+        <source>Display Advanced Options:</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../main-conf.ui" line="131"/>
+        <source>Save and Apply the changes</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../main-conf.ui" line="134"/>
+        <source>Save</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../main-conf.ui" line="145"/>
+        <source>Cancel</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../main-conf.ui" line="169"/>
+        <source>Show/Hide Passwords</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../main-conf.ui" line="172"/>
+        <source>Password</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../main-conf.ui" line="183"/>
+        <source>Add Client resource to monitor</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../main-conf.ui" line="186"/>
+        <source>Client   </source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../main-conf.ui" line="197"/>
+        <source>Add Storage resource to monitor</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../main-conf.ui" line="200"/>
+        <source>Storage</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../main-conf.ui" line="211"/>
+        <source>Add Director resource to monitor</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../main-conf.ui" line="214"/>
+        <source> Director</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../conf.cpp" line="375"/>
+        <source>Select Command Directory</source>
+        <translation type="unfinished"></translation>
+    </message>
+</context>
+<context>
+    <name>ConfTab</name>
+    <message>
+        <location filename="../conf.cpp" line="383"/>
+        <source>Select CA Certificate File PEM file</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../conf.cpp" line="391"/>
+        <source>Select CA Certificate Directory</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../conf.cpp" line="399"/>
+        <location filename="../conf.cpp" line="407"/>
+        <source>Select TLS Certificate File</source>
+        <translation type="unfinished"></translation>
+    </message>
+</context>
+<context>
+    <name>DIRStatus</name>
+    <message>
+        <location filename="../dirstatus.cpp" line="57"/>
+        <location filename="../dirstatus.cpp" line="89"/>
+        <source>JobId</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../dirstatus.cpp" line="58"/>
+        <location filename="../dirstatus.cpp" line="90"/>
+        <source>Job</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../dirstatus.cpp" line="58"/>
+        <location filename="../dirstatus.cpp" line="90"/>
+        <source>Level</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../dirstatus.cpp" line="58"/>
+        <source>Client</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../dirstatus.cpp" line="59"/>
+        <location filename="../dirstatus.cpp" line="91"/>
+        <source>Status</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../dirstatus.cpp" line="59"/>
+        <source>Storage</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../dirstatus.cpp" line="60"/>
+        <location filename="../dirstatus.cpp" line="91"/>
+        <source>Files</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../dirstatus.cpp" line="60"/>
+        <location filename="../dirstatus.cpp" line="91"/>
+        <source>Bytes</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../dirstatus.cpp" line="60"/>
+        <location filename="../dirstatus.cpp" line="92"/>
+        <source>Errors</source>
+        <translation type="unfinished"></translation>
+    </message>
+</context>
+<context>
+    <name>FDStatus</name>
+    <message>
+        <location filename="../fdstatus.cpp" line="58"/>
+        <location filename="../fdstatus.cpp" line="88"/>
+        <source>JobId</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../fdstatus.cpp" line="59"/>
+        <location filename="../fdstatus.cpp" line="89"/>
+        <source>Job</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../fdstatus.cpp" line="59"/>
+        <location filename="../fdstatus.cpp" line="89"/>
+        <source>Level</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../fdstatus.cpp" line="60"/>
+        <location filename="../fdstatus.cpp" line="90"/>
+        <source>Files</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../fdstatus.cpp" line="60"/>
+        <location filename="../fdstatus.cpp" line="90"/>
+        <source>Bytes</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../fdstatus.cpp" line="60"/>
+        <location filename="../fdstatus.cpp" line="90"/>
+        <source>Errors</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../fdstatus.cpp" line="60"/>
+        <source>Current File</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../fdstatus.cpp" line="90"/>
+        <source>Status</source>
+        <translation type="unfinished"></translation>
+    </message>
+</context>
+<context>
+    <name>QObject</name>
+    <message>
+        <location filename="../../util/fmtwidgetitem.cpp" line="46"/>
+        <source>Invalid job status %1</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../../util/fmtwidgetitem.cpp" line="259"/>
+        <location filename="../../util/fmtwidgetitem.cpp" line="267"/>
+        <source>Yes</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../../util/fmtwidgetitem.cpp" line="261"/>
+        <location filename="../../util/fmtwidgetitem.cpp" line="269"/>
+        <source>No</source>
+        <translation type="unfinished"></translation>
+    </message>
+</context>
+<context>
+    <name>ResConf</name>
+    <message>
+        <location filename="../res-conf.ui" line="14"/>
+        <source>Form</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../res-conf.ui" line="20"/>
+        <source>General</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../res-conf.ui" line="29"/>
+        <location filename="../res-conf.ui" line="39"/>
+        <source>The Name will be used only in the Tray Monitor interface</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../res-conf.ui" line="32"/>
+        <source>Name:</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../res-conf.ui" line="49"/>
+        <source>Description:</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../res-conf.ui" line="63"/>
+        <source>Password:</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../res-conf.ui" line="83"/>
+        <source>Address:</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../res-conf.ui" line="97"/>
+        <source>Port:</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../res-conf.ui" line="123"/>
+        <source>Timeout:</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../res-conf.ui" line="149"/>
+        <location filename="../res-conf.ui" line="159"/>
+        <source>Use Client Initiated backup/restore feature</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../res-conf.ui" line="152"/>
+        <source>Remote</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../res-conf.ui" line="169"/>
+        <location filename="../res-conf.ui" line="179"/>
+        <source>Update the tray monitor icon with the status of this component</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../res-conf.ui" line="172"/>
+        <source>Monitor:</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../res-conf.ui" line="196"/>
+        <source>Use SetIp:</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../res-conf.ui" line="206"/>
+        <source>TLS</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../res-conf.ui" line="212"/>
+        <location filename="../res-conf.ui" line="236"/>
+        <location filename="../res-conf.ui" line="253"/>
+        <location filename="../res-conf.ui" line="283"/>
+        <source>...</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../res-conf.ui" line="219"/>
+        <source>CA Certificate File:</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../res-conf.ui" line="226"/>
+        <source>Enabled</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../res-conf.ui" line="243"/>
+        <source>Key File:</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../res-conf.ui" line="260"/>
+        <source>Certificate File:</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../res-conf.ui" line="276"/>
+        <source>CA Certificate Directory:</source>
+        <translation type="unfinished"></translation>
+    </message>
+</context>
+<context>
+    <name>RunJob</name>
+    <message>
+        <location filename="../runjob.cpp" line="265"/>
+        <source>Computed over %1 job%2, the correlation is %3.</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../runjob.cpp" line="267"/>
+        <source>Computed over %1 job%2, The correlation is %3.</source>
+        <translation type="unfinished"></translation>
+    </message>
+</context>
+<context>
+    <name>SDStatus</name>
+    <message>
+        <location filename="../sdstatus.cpp" line="56"/>
+        <location filename="../sdstatus.cpp" line="87"/>
+        <source>JobId</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../sdstatus.cpp" line="57"/>
+        <location filename="../sdstatus.cpp" line="88"/>
+        <source>Job</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../sdstatus.cpp" line="57"/>
+        <location filename="../sdstatus.cpp" line="88"/>
+        <source>Level</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../sdstatus.cpp" line="57"/>
+        <source>Client</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../sdstatus.cpp" line="58"/>
+        <source>Storage</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../sdstatus.cpp" line="59"/>
+        <location filename="../sdstatus.cpp" line="89"/>
+        <source>Files</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../sdstatus.cpp" line="59"/>
+        <location filename="../sdstatus.cpp" line="89"/>
+        <source>Bytes</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../sdstatus.cpp" line="59"/>
+        <location filename="../sdstatus.cpp" line="90"/>
+        <source>Errors</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../sdstatus.cpp" line="89"/>
+        <source>Status</source>
+        <translation type="unfinished"></translation>
+    </message>
+</context>
+<context>
+    <name>TrayMonitor</name>
+    <message>
+        <location filename="../tray-ui.h" line="187"/>
+        <source>Display</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../tray-ui.h" line="190"/>
+        <source>Quit</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../tray-ui.h" line="193"/>
+        <source>About</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../tray-ui.h" line="196"/>
+        <source>Run...</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../tray-ui.h" line="204"/>
+        <source>Configure...</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../tray-ui.h" line="239"/>
+        <source>Bacula Tray Monitor</source>
+        <translation type="unfinished"></translation>
+    </message>
+</context>
+<context>
+    <name>dirStatus</name>
+    <message>
+        <location filename="../dir-monitor.ui" line="14"/>
+        <source>Form</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../dir-monitor.ui" line="22"/>
+        <source>Director Status</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../dir-monitor.ui" line="35"/>
+        <source>Name:</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../dir-monitor.ui" line="42"/>
+        <source>Started:</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../dir-monitor.ui" line="63"/>
+        <source>Version:</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../dir-monitor.ui" line="70"/>
+        <source>Plugins:</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../dir-monitor.ui" line="84"/>
+        <source>Reloaded:</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../dir-monitor.ui" line="101"/>
+        <source>Running Jobs</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../dir-monitor.ui" line="120"/>
+        <source>Terminated Jobs</source>
+        <translation type="unfinished"></translation>
+    </message>
+</context>
+<context>
+    <name>fdStatus</name>
+    <message>
+        <location filename="../fd-monitor.ui" line="14"/>
+        <source>Form</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../fd-monitor.ui" line="22"/>
+        <source>FileDaemon Status</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../fd-monitor.ui" line="42"/>
+        <source>Name:</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../fd-monitor.ui" line="49"/>
+        <source>Bandwidth Limit:</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../fd-monitor.ui" line="63"/>
+        <source>Started:</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../fd-monitor.ui" line="84"/>
+        <source>Version:</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../fd-monitor.ui" line="91"/>
+        <source>Plugins:</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../fd-monitor.ui" line="101"/>
+        <source>Running Jobs</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../fd-monitor.ui" line="120"/>
+        <source>Terminated Jobs</source>
+        <translation type="unfinished"></translation>
+    </message>
+</context>
+<context>
+    <name>runForm</name>
+    <message>
+        <location filename="../run.ui" line="20"/>
+        <source>Run job</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../run.ui" line="37"/>
+        <source>&lt;h3&gt;Run a Job&lt;/h3&gt;</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../run.ui" line="79"/>
+        <source>Properties</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../run.ui" line="94"/>
+        <source>Job:</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../run.ui" line="117"/>
+        <source>When:</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../run.ui" line="130"/>
+        <source>yyyy-MM-dd hh:mm:ss</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../run.ui" line="143"/>
+        <source>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Job statistics computed from the Catalog with previous jobs.&lt;/p&gt;&lt;p&gt;For accurate information, it is possible to use the bconsole &amp;quot;estimate&amp;quot; command.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../run.ui" line="146"/>
+        <source>Estimate:</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../run.ui" line="152"/>
+        <source>Job Bytes:</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../run.ui" line="166"/>
+        <source>Job Files:</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../run.ui" line="180"/>
+        <location filename="../run.ui" line="204"/>
+        <source>Level:</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../run.ui" line="198"/>
+        <source>Advanced</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../run.ui" line="217"/>
+        <source>Client:</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../run.ui" line="230"/>
+        <source>FileSet:</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../run.ui" line="243"/>
+        <source>Pool:</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../run.ui" line="256"/>
+        <source>Storage:</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../run.ui" line="269"/>
+        <source>Catalog:</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../run.ui" line="279"/>
+        <source>Priority:</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../run.ui" line="360"/>
+        <source>OK</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../run.ui" line="367"/>
+        <source>Cancel</source>
+        <translation type="unfinished"></translation>
+    </message>
+</context>
+<context>
+    <name>sdStatus</name>
+    <message>
+        <location filename="../sd-monitor.ui" line="14"/>
+        <source>Form</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../sd-monitor.ui" line="22"/>
+        <source>Storage Daemon Status</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../sd-monitor.ui" line="35"/>
+        <source>Name:</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../sd-monitor.ui" line="49"/>
+        <source>Started:</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../sd-monitor.ui" line="70"/>
+        <source>Version:</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../sd-monitor.ui" line="77"/>
+        <source>Plugins:</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../sd-monitor.ui" line="87"/>
+        <source>Running Jobs</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../sd-monitor.ui" line="106"/>
+        <source>Terminated Jobs</source>
+        <translation type="unfinished"></translation>
+    </message>
+</context>
+</TS>
diff --git a/bacula/src/qt-console/tray-monitor/ts/tm_ja.ts b/bacula/src/qt-console/tray-monitor/ts/tm_ja.ts
new file mode 100644 (file)
index 0000000..0e419d9
--- /dev/null
@@ -0,0 +1,720 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!DOCTYPE TS>
+<TS version="2.1" language="ja_JP">
+<context>
+    <name>Conf</name>
+    <message>
+        <location filename="../main-conf.ui" line="14"/>
+        <source>Configuration</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../main-conf.ui" line="24"/>
+        <source>Monitor Configuration</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../main-conf.ui" line="35"/>
+        <location filename="../main-conf.ui" line="45"/>
+        <source>The Monitor name will be used during the authentication phase.</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../main-conf.ui" line="38"/>
+        <source>Name:</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../main-conf.ui" line="55"/>
+        <source>Refresh Interval:</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../main-conf.ui" line="75"/>
+        <location filename="../main-conf.ui" line="87"/>
+        <source>Specify the &quot;Command Directory&quot; where the tray-monitor program will check regularly for jobs to run</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../main-conf.ui" line="78"/>
+        <source>Command Directory:</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../main-conf.ui" line="94"/>
+        <source>...</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../main-conf.ui" line="103"/>
+        <location filename="../main-conf.ui" line="113"/>
+        <source>Display or Hide advanced options in the &quot;Run Job&quot; window</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../main-conf.ui" line="106"/>
+        <source>Display Advanced Options:</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../main-conf.ui" line="131"/>
+        <source>Save and Apply the changes</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../main-conf.ui" line="134"/>
+        <source>Save</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../main-conf.ui" line="145"/>
+        <source>Cancel</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../main-conf.ui" line="169"/>
+        <source>Show/Hide Passwords</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../main-conf.ui" line="172"/>
+        <source>Password</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../main-conf.ui" line="183"/>
+        <source>Add Client resource to monitor</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../main-conf.ui" line="186"/>
+        <source>Client   </source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../main-conf.ui" line="197"/>
+        <source>Add Storage resource to monitor</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../main-conf.ui" line="200"/>
+        <source>Storage</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../main-conf.ui" line="211"/>
+        <source>Add Director resource to monitor</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../main-conf.ui" line="214"/>
+        <source> Director</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../conf.cpp" line="375"/>
+        <source>Select Command Directory</source>
+        <translation type="unfinished"></translation>
+    </message>
+</context>
+<context>
+    <name>ConfTab</name>
+    <message>
+        <location filename="../conf.cpp" line="383"/>
+        <source>Select CA Certificate File PEM file</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../conf.cpp" line="391"/>
+        <source>Select CA Certificate Directory</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../conf.cpp" line="399"/>
+        <location filename="../conf.cpp" line="407"/>
+        <source>Select TLS Certificate File</source>
+        <translation type="unfinished"></translation>
+    </message>
+</context>
+<context>
+    <name>DIRStatus</name>
+    <message>
+        <location filename="../dirstatus.cpp" line="57"/>
+        <location filename="../dirstatus.cpp" line="89"/>
+        <source>JobId</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../dirstatus.cpp" line="58"/>
+        <location filename="../dirstatus.cpp" line="90"/>
+        <source>Job</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../dirstatus.cpp" line="58"/>
+        <location filename="../dirstatus.cpp" line="90"/>
+        <source>Level</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../dirstatus.cpp" line="58"/>
+        <source>Client</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../dirstatus.cpp" line="59"/>
+        <location filename="../dirstatus.cpp" line="91"/>
+        <source>Status</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../dirstatus.cpp" line="59"/>
+        <source>Storage</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../dirstatus.cpp" line="60"/>
+        <location filename="../dirstatus.cpp" line="91"/>
+        <source>Files</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../dirstatus.cpp" line="60"/>
+        <location filename="../dirstatus.cpp" line="91"/>
+        <source>Bytes</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../dirstatus.cpp" line="60"/>
+        <location filename="../dirstatus.cpp" line="92"/>
+        <source>Errors</source>
+        <translation type="unfinished"></translation>
+    </message>
+</context>
+<context>
+    <name>FDStatus</name>
+    <message>
+        <location filename="../fdstatus.cpp" line="58"/>
+        <location filename="../fdstatus.cpp" line="88"/>
+        <source>JobId</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../fdstatus.cpp" line="59"/>
+        <location filename="../fdstatus.cpp" line="89"/>
+        <source>Job</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../fdstatus.cpp" line="59"/>
+        <location filename="../fdstatus.cpp" line="89"/>
+        <source>Level</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../fdstatus.cpp" line="60"/>
+        <location filename="../fdstatus.cpp" line="90"/>
+        <source>Files</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../fdstatus.cpp" line="60"/>
+        <location filename="../fdstatus.cpp" line="90"/>
+        <source>Bytes</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../fdstatus.cpp" line="60"/>
+        <location filename="../fdstatus.cpp" line="90"/>
+        <source>Errors</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../fdstatus.cpp" line="60"/>
+        <source>Current File</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../fdstatus.cpp" line="90"/>
+        <source>Status</source>
+        <translation type="unfinished"></translation>
+    </message>
+</context>
+<context>
+    <name>QObject</name>
+    <message>
+        <location filename="../../util/fmtwidgetitem.cpp" line="46"/>
+        <source>Invalid job status %1</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../../util/fmtwidgetitem.cpp" line="259"/>
+        <location filename="../../util/fmtwidgetitem.cpp" line="267"/>
+        <source>Yes</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../../util/fmtwidgetitem.cpp" line="261"/>
+        <location filename="../../util/fmtwidgetitem.cpp" line="269"/>
+        <source>No</source>
+        <translation type="unfinished"></translation>
+    </message>
+</context>
+<context>
+    <name>ResConf</name>
+    <message>
+        <location filename="../res-conf.ui" line="14"/>
+        <source>Form</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../res-conf.ui" line="20"/>
+        <source>General</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../res-conf.ui" line="29"/>
+        <location filename="../res-conf.ui" line="39"/>
+        <source>The Name will be used only in the Tray Monitor interface</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../res-conf.ui" line="32"/>
+        <source>Name:</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../res-conf.ui" line="49"/>
+        <source>Description:</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../res-conf.ui" line="63"/>
+        <source>Password:</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../res-conf.ui" line="83"/>
+        <source>Address:</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../res-conf.ui" line="97"/>
+        <source>Port:</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../res-conf.ui" line="123"/>
+        <source>Timeout:</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../res-conf.ui" line="149"/>
+        <location filename="../res-conf.ui" line="159"/>
+        <source>Use Client Initiated backup/restore feature</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../res-conf.ui" line="152"/>
+        <source>Remote</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../res-conf.ui" line="169"/>
+        <location filename="../res-conf.ui" line="179"/>
+        <source>Update the tray monitor icon with the status of this component</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../res-conf.ui" line="172"/>
+        <source>Monitor:</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../res-conf.ui" line="196"/>
+        <source>Use SetIp:</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../res-conf.ui" line="206"/>
+        <source>TLS</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../res-conf.ui" line="212"/>
+        <location filename="../res-conf.ui" line="236"/>
+        <location filename="../res-conf.ui" line="253"/>
+        <location filename="../res-conf.ui" line="283"/>
+        <source>...</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../res-conf.ui" line="219"/>
+        <source>CA Certificate File:</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../res-conf.ui" line="226"/>
+        <source>Enabled</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../res-conf.ui" line="243"/>
+        <source>Key File:</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../res-conf.ui" line="260"/>
+        <source>Certificate File:</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../res-conf.ui" line="276"/>
+        <source>CA Certificate Directory:</source>
+        <translation type="unfinished"></translation>
+    </message>
+</context>
+<context>
+    <name>RunJob</name>
+    <message>
+        <location filename="../runjob.cpp" line="265"/>
+        <source>Computed over %1 job%2, the correlation is %3.</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../runjob.cpp" line="267"/>
+        <source>Computed over %1 job%2, The correlation is %3.</source>
+        <translation type="unfinished"></translation>
+    </message>
+</context>
+<context>
+    <name>SDStatus</name>
+    <message>
+        <location filename="../sdstatus.cpp" line="56"/>
+        <location filename="../sdstatus.cpp" line="87"/>
+        <source>JobId</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../sdstatus.cpp" line="57"/>
+        <location filename="../sdstatus.cpp" line="88"/>
+        <source>Job</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../sdstatus.cpp" line="57"/>
+        <location filename="../sdstatus.cpp" line="88"/>
+        <source>Level</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../sdstatus.cpp" line="57"/>
+        <source>Client</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../sdstatus.cpp" line="58"/>
+        <source>Storage</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../sdstatus.cpp" line="59"/>
+        <location filename="../sdstatus.cpp" line="89"/>
+        <source>Files</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../sdstatus.cpp" line="59"/>
+        <location filename="../sdstatus.cpp" line="89"/>
+        <source>Bytes</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../sdstatus.cpp" line="59"/>
+        <location filename="../sdstatus.cpp" line="90"/>
+        <source>Errors</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../sdstatus.cpp" line="89"/>
+        <source>Status</source>
+        <translation type="unfinished"></translation>
+    </message>
+</context>
+<context>
+    <name>TrayMonitor</name>
+    <message>
+        <location filename="../tray-ui.h" line="187"/>
+        <source>Display</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../tray-ui.h" line="190"/>
+        <source>Quit</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../tray-ui.h" line="193"/>
+        <source>About</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../tray-ui.h" line="196"/>
+        <source>Run...</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../tray-ui.h" line="204"/>
+        <source>Configure...</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../tray-ui.h" line="239"/>
+        <source>Bacula Tray Monitor</source>
+        <translation type="unfinished"></translation>
+    </message>
+</context>
+<context>
+    <name>dirStatus</name>
+    <message>
+        <location filename="../dir-monitor.ui" line="14"/>
+        <source>Form</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../dir-monitor.ui" line="22"/>
+        <source>Director Status</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../dir-monitor.ui" line="35"/>
+        <source>Name:</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../dir-monitor.ui" line="42"/>
+        <source>Started:</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../dir-monitor.ui" line="63"/>
+        <source>Version:</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../dir-monitor.ui" line="70"/>
+        <source>Plugins:</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../dir-monitor.ui" line="84"/>
+        <source>Reloaded:</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../dir-monitor.ui" line="101"/>
+        <source>Running Jobs</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../dir-monitor.ui" line="120"/>
+        <source>Terminated Jobs</source>
+        <translation type="unfinished"></translation>
+    </message>
+</context>
+<context>
+    <name>fdStatus</name>
+    <message>
+        <location filename="../fd-monitor.ui" line="14"/>
+        <source>Form</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../fd-monitor.ui" line="22"/>
+        <source>FileDaemon Status</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../fd-monitor.ui" line="42"/>
+        <source>Name:</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../fd-monitor.ui" line="49"/>
+        <source>Bandwidth Limit:</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../fd-monitor.ui" line="63"/>
+        <source>Started:</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../fd-monitor.ui" line="84"/>
+        <source>Version:</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../fd-monitor.ui" line="91"/>
+        <source>Plugins:</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../fd-monitor.ui" line="101"/>
+        <source>Running Jobs</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../fd-monitor.ui" line="120"/>
+        <source>Terminated Jobs</source>
+        <translation type="unfinished"></translation>
+    </message>
+</context>
+<context>
+    <name>runForm</name>
+    <message>
+        <location filename="../run.ui" line="20"/>
+        <source>Run job</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../run.ui" line="37"/>
+        <source>&lt;h3&gt;Run a Job&lt;/h3&gt;</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../run.ui" line="79"/>
+        <source>Properties</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../run.ui" line="94"/>
+        <source>Job:</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../run.ui" line="117"/>
+        <source>When:</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../run.ui" line="130"/>
+        <source>yyyy-MM-dd hh:mm:ss</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../run.ui" line="143"/>
+        <source>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Job statistics computed from the Catalog with previous jobs.&lt;/p&gt;&lt;p&gt;For accurate information, it is possible to use the bconsole &amp;quot;estimate&amp;quot; command.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../run.ui" line="146"/>
+        <source>Estimate:</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../run.ui" line="152"/>
+        <source>Job Bytes:</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../run.ui" line="166"/>
+        <source>Job Files:</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../run.ui" line="180"/>
+        <location filename="../run.ui" line="204"/>
+        <source>Level:</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../run.ui" line="198"/>
+        <source>Advanced</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../run.ui" line="217"/>
+        <source>Client:</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../run.ui" line="230"/>
+        <source>FileSet:</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../run.ui" line="243"/>
+        <source>Pool:</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../run.ui" line="256"/>
+        <source>Storage:</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../run.ui" line="269"/>
+        <source>Catalog:</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../run.ui" line="279"/>
+        <source>Priority:</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../run.ui" line="360"/>
+        <source>OK</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../run.ui" line="367"/>
+        <source>Cancel</source>
+        <translation type="unfinished"></translation>
+    </message>
+</context>
+<context>
+    <name>sdStatus</name>
+    <message>
+        <location filename="../sd-monitor.ui" line="14"/>
+        <source>Form</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../sd-monitor.ui" line="22"/>
+        <source>Storage Daemon Status</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../sd-monitor.ui" line="35"/>
+        <source>Name:</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../sd-monitor.ui" line="49"/>
+        <source>Started:</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../sd-monitor.ui" line="70"/>
+        <source>Version:</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../sd-monitor.ui" line="77"/>
+        <source>Plugins:</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../sd-monitor.ui" line="87"/>
+        <source>Running Jobs</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../sd-monitor.ui" line="106"/>
+        <source>Terminated Jobs</source>
+        <translation type="unfinished"></translation>
+    </message>
+</context>
+</TS>
diff --git a/bacula/src/qt-console/tray-monitor/win32/qmake.conf b/bacula/src/qt-console/tray-monitor/win32/qmake.conf
new file mode 100644 (file)
index 0000000..7a4c04b
--- /dev/null
@@ -0,0 +1,93 @@
+#
+# qmake configuration for win32-g++
+#
+# Written for MinGW
+#
+
+MAKEFILE_GENERATOR      = MINGW
+TEMPLATE                = app
+CONFIG                  += qt warn_on release link_prl copy_dir_files debug_and_release debug_and_release_target precompile_header cross-win32
+QT                      += core gui
+DEFINES                 += UNICODE QT_LARGEFILE_SUPPORT
+QMAKE_COMPILER_DEFINES  += __GNUC__ WIN32
+
+QMAKE_EXT_OBJ           = .o
+QMAKE_EXT_RES           = _res.o
+
+QMAKE_LEX               = flex
+QMAKE_LEXFLAGS          =
+QMAKE_YACC              = byacc
+QMAKE_YACCFLAGS         = -d
+QMAKE_CFLAGS            = -DHAVE_MINGW -DHAVE_WIN32 -DHAVE_MINGW_W64
+QMAKE_CFLAGS_DEPS       = -M
+QMAKE_CFLAGS_WARN_ON    = -Wall
+QMAKE_CFLAGS_WARN_OFF   = -w
+QMAKE_CFLAGS_RELEASE    = -O2
+QMAKE_CFLAGS_DEBUG      = -g -O2
+QMAKE_CFLAGS_YACC       = -Wno-unused -Wno-parentheses
+
+QMAKE_CXXFLAGS          = $$QMAKE_CFLAGS -DHAVE_MINGW -DHAVE_WIN32 -DHAVE_ZLIB_H -DHAVE_LIBZ -DHAVE_CRYPTO -DHAVE_OPENSSL -DHAVE_TLS -DHAVE_MINGW_W64
+QMAKE_CXXFLAGS_DEPS     = $$QMAKE_CFLAGS_DEPS
+QMAKE_CXXFLAGS_WARN_ON  = $$QMAKE_CFLAGS_WARN_ON
+QMAKE_CXXFLAGS_WARN_OFF = $$QMAKE_CFLAGS_WARN_OFF
+QMAKE_CXXFLAGS_RELEASE  = $$QMAKE_CFLAGS_RELEASE
+QMAKE_CXXFLAGS_DEBUG    = $$QMAKE_CFLAGS_DEBUG
+QMAKE_CXXFLAGS_YACC     = $$QMAKE_CFLAGS_YACC
+QMAKE_CXXFLAGS_THREAD   = $$QMAKE_CFLAGS_THREAD
+QMAKE_CXXFLAGS_RTTI_ON  = -frtti
+QMAKE_CXXFLAGS_RTTI_OFF = -fno-rtti
+QMAKE_CXXFLAGS_EXCEPTIONS_ON = -fexceptions -mthreads
+QMAKE_CXXFLAGS_EXCEPTIONS_OFF = -fno-exceptions
+
+QMAKE_INCDIR            = $(DEPKGS)/depkgs-mingw32/include/pthreads $(DEPKGS)/depkgs-mingw32/include/ ../win32/compat 
+QMAKE_INCDIR_QT         = $(DEPKGS)/depkgs-mingw32/include/qt
+QMAKE_LIBDIR_QT         = $(DEPKGS)/depkgs-mingw32/lib/qt
+
+QMAKE_RUN_CC            = $(CXX) -c $(CFLAGS) $(INCPATH) -o $obj $src
+QMAKE_RUN_CC_IMP        = $(CXX) -c $(CFLAGS) $(INCPATH) -o $@ $<
+QMAKE_RUN_CXX           = $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $obj $src
+QMAKE_RUN_CXX_IMP       = $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $<
+
+QMAKE_LINK              = i686-w64-mingw32-g++
+QMAKE_LFLAGS            = -mthreads -Wl,-enable-stdcall-fixup -Wl,-enable-auto-import -m32 -fno-strict-aliasing -Wl,-enable-runtime-pseudo-reloc
+
+QMAKE_LFLAGS_EXCEPTIONS_ON = -mthreads -Wl
+QMAKE_LFLAGS_EXCEPTIONS_OFF =
+QMAKE_LFLAGS_RELEASE    = -Wl,-s
+QMAKE_LFLAGS_DEBUG      =
+QMAKE_LFLAGS_CONSOLE    = -Wl,-subsystem,console
+QMAKE_LFLAGS_WINDOWS    = -Wl,-subsystem,windows
+QMAKE_LFLAGS_DLL        = -shared
+QMAKE_LINK_OBJECT_MAX   = 10
+QMAKE_LINK_OBJECT_SCRIPT= object_script
+
+
+QMAKE_LIBS              = -lwsock32 -lstdc++
+QMAKE_LIBS_CORE         = -lkernel32 -luser32 -lshell32 -luuid -lole32 -ladvapi32 -lws2_32
+QMAKE_LIBS_GUI          = -lgdi32 -lcomdlg32 -loleaut32 -limm32 -lwinmm -lwinspool -lws2_32 -lole32 -luuid -luser32 -ladvapi32
+QMAKE_LIBS_NETWORK      = -lws2_32
+QMAKE_LIBS_OPENGL       = -lopengl32 -lglu32 -lgdi32 -luser32
+QMAKE_LIBS_COMPAT       = -ladvapi32 -lshell32 -lcomdlg32 -luser32 -lgdi32 -lws2_32
+QMAKE_LIBS_QT_ENTRY     = -lmingw32 -lqtmain
+
+MINGW_IN_SHELL          = 1
+QMAKE_DIR_SEP           = /
+QMAKE_COPY              = cp
+QMAKE_COPY_DIR          = cp -r
+QMAKE_MOVE              = mv
+QMAKE_DEL_FILE          = rm -f
+QMAKE_MKDIR             = mkdir -p
+QMAKE_DEL_DIR           = rm -rf
+QMAKE_RCC               = rcc
+QMAKE_CHK_DIR_EXISTS    = test -d
+
+QMAKE_MOC               = $$[QT_INSTALL_BINS]$${DIR_SEPARATOR}moc
+QMAKE_UIC               = $$[QT_INSTALL_BINS]$${DIR_SEPARATOR}uic
+QMAKE_IDC               = $$[QT_INSTALL_BINS]$${DIR_SEPARATOR}idc
+
+QMAKE_IDL               = midl
+QMAKE_ZIP               = zip -r -9
+
+QMAKE_STRIP             = i686-w64-mingw32-strip
+QMAKE_STRIPFLAGS_LIB    += --strip-unneeded
+load(qt_config)
diff --git a/bacula/src/qt-console/tray-monitor/win32/qplatformdefs.h b/bacula/src/qt-console/tray-monitor/win32/qplatformdefs.h
new file mode 100644 (file)
index 0000000..4802c2b
--- /dev/null
@@ -0,0 +1,161 @@
+/****************************************************************************
+**
+** Copyright (C) 1992-2007 Trolltech ASA. All rights reserved.
+**
+** This file is part of the qmake spec of the Qt Toolkit.
+**
+** This file may be used under the terms of the GNU General Public
+** License version 2.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of
+** this file.  Please review the following information to ensure GNU
+** General Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/
+**
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** In addition, as a special exception, Trolltech gives you certain
+** additional rights. These rights are described in the Trolltech GPL
+** Exception version 1.0, which can be found at
+** http://www.trolltech.com/products/qt/gplexception/ and in the file
+** GPL_EXCEPTION.txt in this package.
+**
+** In addition, as a special exception, Trolltech, as the sole copyright
+** holder for Qt Designer, grants users of the Qt/Eclipse Integration
+** plug-in the right for the Qt/Eclipse Integration to link to
+** functionality provided by Qt Designer and its related libraries.
+**
+** Trolltech reserves all rights not expressly granted herein.
+** 
+** Trolltech ASA (c) 2007
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+****************************************************************************/
+
+#ifndef QPLATFORMDEFS_H
+#define QPLATFORMDEFS_H
+
+#ifdef UNICODE
+#ifndef _UNICODE
+#define _UNICODE
+#endif
+#endif
+
+// Get Qt defines/settings
+
+#include "qglobal.h"
+
+#include "winhdrs.h"
+#include <tchar.h>
+#include <io.h>
+#include <direct.h>
+#include <stdio.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <sys/stat.h>
+#include <stdlib.h>
+#include <limits.h>
+
+#if !defined(_WIN32_WINNT) || (_WIN32_WINNT-0 < 0x0500)
+typedef enum {
+    NameUnknown           = 0, 
+    NameFullyQualifiedDN  = 1, 
+    NameSamCompatible     = 2, 
+    NameDisplay           = 3, 
+    NameUniqueId          = 6, 
+    NameCanonical         = 7, 
+    NameUserPrincipal     = 8, 
+    NameCanonicalEx       = 9, 
+    NameServicePrincipal  = 10, 
+    NameDnsDomain         = 12
+} EXTENDED_NAME_FORMAT, *PEXTENDED_NAME_FORMAT;
+#endif
+
+#define Q_FS_FAT
+#ifdef QT_LARGEFILE_SUPPORT
+#define QT_STATBUF              struct _stati64         // non-ANSI defs
+#define QT_STATBUF4TSTAT        struct _stati64         // non-ANSI defs
+#define QT_STAT                 ::_stati64
+#define QT_FSTAT                ::_fstati64
+#else
+#define QT_STATBUF              struct _stat            // non-ANSI defs
+#define QT_STATBUF4TSTAT        struct _stat            // non-ANSI defs
+#define QT_STAT                 ::_stat
+#define QT_FSTAT                ::_fstat
+#endif
+#define QT_STAT_REG             _S_IFREG
+#define QT_STAT_DIR             _S_IFDIR
+#define QT_STAT_MASK            _S_IFMT
+#if defined(_S_IFLNK)
+#  define QT_STAT_LNK           _S_IFLNK
+#endif
+#define QT_FILENO               _fileno
+#define QT_OPEN                 ::_open
+#define QT_CLOSE                ::_close
+#ifdef QT_LARGEFILE_SUPPORT
+#define QT_LSEEK                ::_lseeki64
+#ifndef UNICODE
+#define QT_TSTAT                ::_stati64
+#else
+#define QT_TSTAT                ::_wstati64
+#endif
+#else
+#define QT_LSEEK                ::_lseek
+#ifndef UNICODE
+#define QT_TSTAT                ::_stat
+#else
+#define QT_TSTAT                ::_wstat
+#endif
+#endif
+#define QT_READ                 ::_read
+#define QT_WRITE                ::_write
+#define QT_ACCESS               ::_access
+#define QT_GETCWD               ::_getcwd
+#define QT_CHDIR                ::_chdir
+#define QT_MKDIR                ::_mkdir
+#define QT_RMDIR                ::_rmdir
+#define QT_OPEN_LARGEFILE       0
+#define QT_OPEN_RDONLY          _O_RDONLY
+#define QT_OPEN_WRONLY          _O_WRONLY
+#define QT_OPEN_RDWR            _O_RDWR
+#define QT_OPEN_CREAT           _O_CREAT
+#define QT_OPEN_TRUNC           _O_TRUNC
+#define QT_OPEN_APPEND          _O_APPEND
+#if defined(O_TEXT)
+# define QT_OPEN_TEXT           _O_TEXT
+# define QT_OPEN_BINARY         _O_BINARY
+#endif
+
+#define QT_FOPEN                ::fopen
+#ifdef QT_LARGEFILE_SUPPORT
+#define QT_FSEEK                ::fseeko64
+#define QT_FTELL                ::ftello64
+#else
+#define QT_FSEEK                ::fseek
+#define QT_FTELL                ::ftell
+#endif
+#define QT_FGETPOS              ::fgetpos
+#define QT_FSETPOS              ::fsetpos
+#define QT_FPOS_T               fpos_t
+#ifdef QT_LARGEFILE_SUPPORT
+#define QT_OFF_T                off64_t
+#else
+#define QT_OFF_T                long
+#endif
+
+#define QT_SIGNAL_ARGS          int
+
+#define QT_VSNPRINTF            ::_vsnprintf
+#define QT_SNPRINTF             ::_snprintf
+
+# define F_OK   0
+# define X_OK   1
+# define W_OK   2
+# define R_OK   4
+
+
+#endif // QPLATFORMDEFS_H
index e4a5eb84d3448c6467a82c5695573d2c5d2b63e6..bd9a24fa67e09f52292b2052f925fe62f520c5e5 100644 (file)
@@ -1,20 +1,20 @@
 /*
-   Bacula® - The Network Backup Solution
+   Bacula(R) - The Network Backup Solution
 
-   Copyright (C) 2004-2015 Bacula Systems S.A.
-   All Rights Reserved.
+   Copyright (C) 2000-2018 Kern Sibbald
 
-   The main author of Bacula is Kern Sibbald, with contributions from
-   many others, a complete list can be found in the file AUTHORS.
+   The original author of Bacula is Kern Sibbald, with contributions
+   from many others, a complete list can be found in the file AUTHORS.
 
-   For the details of the license, see the file LICENSE.
+   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 program is distributed in the hope that it will be useful, but
-   WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
-   General Public License for more details.
+   This notice must be preserved when any source code is
+   conveyed and/or propagated.
 
-   Bacula® is a registered trademark of Kern Sibbald.
+   Bacula(R) is a registered trademark of Kern Sibbald.
 */
 //                              -*- Mode: C++ -*-
 // compat.cpp -- compatibilty layer to make bacula-fd run
diff --git a/bacula/src/win32/compat/winsock.h b/bacula/src/win32/compat/winsock.h
deleted file mode 100644 (file)
index 0274d58..0000000
+++ /dev/null
@@ -1,6 +0,0 @@
-/*
-#include <winsock2.h>
-#ifdef HAVE_IPV6
-#include <ws2tcpip.h>
-#endif
-*/