/*
- Bacula® - The Network Backup Solution
+ Bacula(R) - The Network Backup Solution
+ Copyright (C) 2000-2015 Kern Sibbald
Copyright (C) 2007-2009 Free Software Foundation Europe e.V.
- The main author of Bacula is Kern Sibbald, with contributions from
- many others, a complete list can be found in the file AUTHORS.
- This program is Free Software; you can redistribute it and/or
- modify it under the terms of version two of the GNU General Public
- License as published by the Free Software Foundation and included
- in the file LICENSE.
-
- 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. See the GNU
- General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
- 02110-1301, USA.
-
- Bacula® is a registered trademark of Kern Sibbald.
- The licensor of Bacula is the Free Software Foundation Europe
- (FSFE), Fiduciary Program, Sumatrastrasse 25, 8006 Zürich,
- Switzerland, email:ftf@fsfeurope.org.
+ 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.
*/
/*
- * Version $Id$
- *
* Dirk Bartley, March 2007
*/
#include <QTableWidgetItem>
#include "joblist.h"
#include "restore.h"
+#include "job/job.h"
#include "joblog/joblog.h"
#ifdef HAVE_QWT
#include "jobgraphs/jobplot.h"
*/
JobList::JobList(const QString &mediaName, const QString &clientName,
const QString &jobName, const QString &filesetName, QTreeWidgetItem *parentTreeWidgetItem)
+ : Pages()
{
setupUi(this);
- m_name = ""; /* treeWidgetName has a virtual override in this class */
+ m_name = "Jobs Run"; /* treeWidgetName has a virtual override in this class */
m_mediaName = mediaName;
m_clientName = clientName;
m_jobName = jobName;
m_filesetName = filesetName;
- m_filesetName = filesetName;
pgInitialize("", parentTreeWidgetItem);
QTreeWidgetItem* thisitem = mainWin->getFromHash(this);
thisitem->setIcon(0,QIcon(QString::fromUtf8(":images/emblem-system.png")));
m_resultCount = 0;
m_populated = false;
m_closeable = false;
- if ((m_mediaName != "") || (m_clientName != "") || (m_jobName != "") || (m_filesetName != ""))
+ if ((m_mediaName != "") || (m_clientName != "") || (m_jobName != "") || (m_filesetName != "")) {
m_closeable=true;
+ }
m_checkCurrentWidget = true;
- createConnections();
/* Set Defaults for check and spin for limits */
limitCheckBox->setCheckState(mainWin->m_recordLimitCheck ? Qt::Checked : Qt::Unchecked);
limitSpinBox->setValue(mainWin->m_recordLimitVal);
daysCheckBox->setCheckState(mainWin->m_daysLimitCheck ? Qt::Checked : Qt::Unchecked);
daysSpinBox->setValue(mainWin->m_daysLimitVal);
- dockPage();
QGridLayout *gridLayout = new QGridLayout(this);
gridLayout->setSpacing(6);
area->setObjectName(QString::fromUtf8("area"));
area->setWidget(frame);
area->setWidgetResizable(true);
- m_splitter->addWidget(mp_tableWidget);
m_splitter->addWidget(area);
+ m_splitter->addWidget(mp_tableWidget);
gridLayout->addWidget(m_splitter, 0, 0, 1, 1);
+ createConnections();
readSettings();
+ if (m_closeable) { dockPage(); }
}
/*
m_startIndex = headerlist.indexOf(tr("Job Starttime"));
m_filesIndex = headerlist.indexOf(tr("Job Files"));
m_bytesIndex = headerlist.indexOf(tr("Job Bytes"));
+ m_levelIndex = headerlist.indexOf(tr("Job Level"));
+ m_nameIndex = headerlist.indexOf(tr("Job Name"));
+ m_filesetIndex = headerlist.indexOf(tr("File Set"));
+ m_clientIndex = headerlist.indexOf(tr("Client"));
/* Initialize the QTableWidget */
m_checkCurrentWidget = false;
}
/* make read only */
- int rcnt = mp_tableWidget->rowCount();
- int ccnt = mp_tableWidget->columnCount();
- for(int r=0; r < rcnt; r++) {
- for(int c=0; c < ccnt; c++) {
- QTableWidgetItem* item = mp_tableWidget->item(r, c);
- if (item) {
- item->setFlags(Qt::ItemFlags(item->flags() & (~Qt::ItemIsEditable)));
- }
- }
- }
+ mp_tableWidget->setEditTriggers(QAbstractItemView::NoEditTriggers);
}
void JobList::prepareFilterWidgets()
{
if (!m_populated) {
populateTable();
+ /* Lets make sure the splitter is not all the way to size index 0 == 0 */
+ QList<int> sizes = m_splitter->sizes();
+ if (sizes[0] == 0) {
+ int frameMax = frame->maximumHeight();
+ int sizeSum = 0;
+ foreach(int size, sizes) { sizeSum += size; }
+ int tabHeight = mainWin->tabWidget->geometry().height();
+ sizes[0] = frameMax;
+ sizes[1] = tabHeight - frameMax;
+ m_splitter->setSizes(sizes);
+ }
+ }
+ if (!isOnceDocked()) {
+ dockPage();
}
}
void JobList::treeWidgetName(QString &desc)
{
if (m_mediaName != "" ) {
- desc = tr("JobList of Volume %1").arg(m_mediaName);
+ desc = tr("Jobs Run on Volume %1").arg(m_mediaName);
} else if (m_clientName != "" ) {
- desc = tr("JobList of Client %1").arg(m_clientName);
+ desc = tr("Jobs Run from Client %1").arg(m_clientName);
} else if (m_jobName != "" ) {
- desc = tr("JobList of Job %1").arg(m_jobName);
+ desc = tr("Jobs Run of Job %1").arg(m_jobName);
} else if (m_filesetName != "" ) {
- desc = tr("JobList of fileset %1").arg(m_filesetName);
+ desc = tr("Jobs Run with fileset %1").arg(m_filesetName);
} else {
- desc = tr("JobList");
+ desc = tr("Jobs Run");
}
}
{
/* connect to the action specific to this pages class that shows up in the
* page selector tree */
- connect(actionRefreshJobList, SIGNAL(triggered()), this,
- SLOT(populateTable()));
+ connect(actionRefreshJobList, SIGNAL(triggered()), this, SLOT(populateTable()));
connect(refreshButton, SIGNAL(pressed()), this, SLOT(populateTable()));
#ifdef HAVE_QWT
connect(graphButton, SIGNAL(pressed()), this, SLOT(graphTable()));
#endif
/* for the selectionChanged to maintain m_currentJob and a delete selection */
connect(mp_tableWidget, SIGNAL(itemSelectionChanged()), this, SLOT(selectionChanged()));
+ connect(mp_tableWidget, SIGNAL(itemDoubleClicked(QTableWidgetItem*)), this, SLOT(showInfoForJob()));
/* Do what is required for the local context sensitive menu */
/* setContextMenuPolicy is required */
mp_tableWidget->setContextMenuPolicy(Qt::ActionsContextMenu);
- connect(actionListJobid, SIGNAL(triggered()), this,
- SLOT(consoleListJobid()));
- connect(actionListFilesOnJob, SIGNAL(triggered()), this,
- SLOT(consoleListFilesOnJob()));
- connect(actionListJobMedia, SIGNAL(triggered()), this,
- SLOT(consoleListJobMedia()));
- connect(actionListVolumes, SIGNAL(triggered()), this,
- SLOT(consoleListVolumes()));
- connect(actionDeleteJob, SIGNAL(triggered()), this,
- SLOT(consoleDeleteJob()));
- connect(actionPurgeFiles, SIGNAL(triggered()), this,
- SLOT(consolePurgeFiles()));
- connect(actionRestoreFromJob, SIGNAL(triggered()), this,
- SLOT(preRestoreFromJob()));
- connect(actionRestoreFromTime, SIGNAL(triggered()), this,
- SLOT(preRestoreFromTime()));
- connect(actionShowLogForJob, SIGNAL(triggered()), this,
- SLOT(showLogForJob()));
- connect(actionCancelJob, SIGNAL(triggered()), this,
- SLOT(consoleCancelJob()));
- connect(actionListJobTotals, SIGNAL(triggered()), this,
- SLOT(consoleListJobTotals()));
+ connect(actionListFilesOnJob, SIGNAL(triggered()), this, SLOT(consoleListFilesOnJob()));
+ connect(actionListJobMedia, SIGNAL(triggered()), this, SLOT(consoleListJobMedia()));
+ connect(actionDeleteJob, SIGNAL(triggered()), this, SLOT(consoleDeleteJob()));
+ connect(actionRestartJob, SIGNAL(triggered()), this, SLOT(consoleRestartJob()));
+ connect(actionPurgeFiles, SIGNAL(triggered()), this, SLOT(consolePurgeFiles()));
+ connect(actionRestoreFromJob, SIGNAL(triggered()), this, SLOT(preRestoreFromJob()));
+ connect(actionRestoreFromTime, SIGNAL(triggered()), this, SLOT(preRestoreFromTime()));
+ connect(actionShowLogForJob, SIGNAL(triggered()), this, SLOT(showLogForJob()));
+ connect(actionShowInfoForJob, SIGNAL(triggered()), this, SLOT(showInfoForJob()));
+ connect(actionCancelJob, SIGNAL(triggered()), this, SLOT(consoleCancelJob()));
+ connect(actionListJobTotals, SIGNAL(triggered()), this, SLOT(consoleListJobTotals()));
+ connect(m_splitter, SIGNAL(splitterMoved(int, int)), this, SLOT(splitterMoved(int, int)));
m_contextActions.append(actionRefreshJobList);
m_contextActions.append(actionListJobTotals);
* Functions to respond to local context sensitive menu sending console commands
* If I could figure out how to make these one function passing a string, Yaaaaaa
*/
-void JobList::consoleListJobid()
-{
- QString cmd("list jobid=");
- cmd += m_currentJob;
- if (mainWin->m_longList) { cmd.prepend("l"); }
- consoleCommand(cmd);
-}
void JobList::consoleListFilesOnJob()
{
QString cmd("list files jobid=");
if (mainWin->m_longList) { cmd.prepend("l"); }
consoleCommand(cmd);
}
-void JobList::consoleListVolumes()
-{
- QString cmd("list volumes jobid=");
- cmd += m_currentJob;
- if (mainWin->m_longList) { cmd.prepend("l"); }
- consoleCommand(cmd);
-}
+
void JobList::consoleListJobTotals()
{
QString cmd("list jobtotals");
if (mainWin->m_longList) { cmd.prepend("l"); }
consoleCommand(cmd);
}
+
void JobList::consoleDeleteJob()
{
if (QMessageBox::warning(this, "Bat",
consoleCommand(cmd, false);
populateTable();
}
+
+void JobList::consoleRestartJob()
+{
+ QString cmd;
+
+ cmd = tr("run job=\"%1\" client=\"%2\" level=%3").arg(m_jobName).arg(m_clientName).arg(m_levelName);
+ if (m_filesetName != "" && m_filesetName != "*None*") {
+ cmd += tr(" fileset=\"%1\"").arg(m_filesetName);
+ }
+
+ if (mainWin->m_commandDebug) Pmsg1(000, "Run cmd : %s\n",cmd.toUtf8().data());
+ consoleCommand(cmd, false);
+ populateTable();
+}
+
+
+
void JobList::consolePurgeFiles()
{
if (QMessageBox::warning(this, "Bat",
QMessageBox::Ok | QMessageBox::Cancel)
== QMessageBox::Cancel) { return; }
+ m_console->m_warningPrevent = true;
foreach(QString job, m_selectedJobsList) {
QString cmd("purge files jobid=");
cmd += job;
consoleCommand(cmd, false);
}
+ m_console->m_warningPrevent = false;
populateTable();
}
new JobLog(m_currentJob, pageSelectorTreeWidgetItem);
}
+/*
+ * Subroutine to call class to show the log in the database from that job
+ */
+void JobList::showInfoForJob(QTableWidgetItem * /*item*/)
+{
+ QTreeWidgetItem* pageSelectorTreeWidgetItem = mainWin->getFromHash(this);
+ new Job(m_currentJob, pageSelectorTreeWidgetItem);
+}
+
/*
* Cancel a running job
*/
void JobList::readSettings()
{
m_groupText = "JobListPage";
- m_splitText = "splitterSizes_1";
+ m_splitText = "splitterSizes_2";
QSettings settings(m_console->m_dir->name(), "bat");
settings.beginGroup(m_groupText);
- m_splitter->restoreState(settings.value(m_splitText).toByteArray());
+ if (settings.contains(m_splitText)) {
+ m_splitter->restoreState(settings.value(m_splitText).toByteArray());
+ }
filterCopyCheckBox->setCheckState((Qt::CheckState)settings.value("FilterCopyCheckState").toInt());
filterMigrationCheckBox->setCheckState((Qt::CheckState)settings.value("FilterMigrationCheckState").toInt());
settings.endGroup();
/* Add Actions */
mp_tableWidget->addAction(actionRefreshJobList);
if (m_selectedJobsCount == 1) {
- mp_tableWidget->addAction(actionListJobid);
mp_tableWidget->addAction(actionListFilesOnJob);
mp_tableWidget->addAction(actionListJobMedia);
- mp_tableWidget->addAction(actionListVolumes);
+ mp_tableWidget->addAction(actionRestartJob);
mp_tableWidget->addAction(actionRestoreFromJob);
mp_tableWidget->addAction(actionRestoreFromTime);
mp_tableWidget->addAction(actionShowLogForJob);
+ mp_tableWidget->addAction(actionShowInfoForJob);
}
if (m_selectedJobsCount >= 1) {
mp_tableWidget->addAction(actionDeleteJob);
if (m_checkCurrentWidget) {
int row = mp_tableWidget->currentRow();
QTableWidgetItem* jobitem = mp_tableWidget->item(row, 0);
- m_currentJob = jobitem->text();
+ m_currentJob = jobitem->text(); /* get JobId */
+ jobitem = mp_tableWidget->item(row, m_clientIndex);
+ m_clientName = jobitem->text(); /* get Client Name */
+ jobitem = mp_tableWidget->item(row, m_nameIndex);
+ m_jobName = jobitem->text(); /* get Job Name */
+ jobitem = mp_tableWidget->item(row, m_levelIndex);
+ m_levelName = jobitem->text(); /* get level */
+ jobitem = mp_tableWidget->item(row, m_filesetIndex);
+ if (jobitem) {
+ m_filesetName = jobitem->text(); /* get FileSet Name */
+ } else {
+ m_filesetName = "";
+ }
/* include purged action or not */
jobitem = mp_tableWidget->item(row, m_purgedIndex);
if (purged == tr("No") ) {
mp_tableWidget->addAction(actionPurgeFiles);
}*/
+
/* include restore from time and job action or not */
jobitem = mp_tableWidget->item(row, m_typeIndex);
QString type = jobitem->text();
mp_tableWidget->addAction(actionRestoreFromTime);
}
}
+
/* include cancel action or not */
jobitem = mp_tableWidget->item(row, m_statusIndex);
QString status = jobitem->text();
}
}
}
+
+/*
+ * Function to prevent the splitter from making index 0 of the size larger than it
+ * needs to be
+ */
+void JobList::splitterMoved(int /*pos*/, int /*index*/)
+{
+ int frameMax = frame->maximumHeight();
+ QList<int> sizes = m_splitter->sizes();
+ int sizeSum = 0;
+ foreach(int size, sizes) { sizeSum += size; }
+ if (sizes[0] > frameMax) {
+ sizes[0] = frameMax;
+ sizes[1] = sizeSum - frameMax;
+ m_splitter->setSizes(sizes);
+ }
+}