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
+ modify it under the terms of version three of the GNU Affero General Public
License as published by the Free Software Foundation and included
in the file LICENSE.
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
+ You should have received a copy of the GNU Affero 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.
#include <QTableWidgetItem>
#include "joblist.h"
#include "restore.h"
+#include "job/job.h"
#include "joblog/joblog.h"
#ifdef HAVE_QWT
#include "jobgraphs/jobplot.h"
const QString &jobName, const QString &filesetName, QTreeWidgetItem *parentTreeWidgetItem)
{
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()
" Job.JobBytes AS Bytes, Job.JobStatus AS Status,"
" Job.PurgedFiles AS Purged, FileSet.FileSet,"
" Pool.Name AS Pool,"
- " (SELECT Media.VolumeName FROM JobMedia JOIN Media ON JobMedia.MediaId=Media.MediaId WHERE JobMedia.JobId=Job.JobId ORDER BY JobMediaId LIMIT 1) AS FirdtVolume,"
+ " (SELECT Media.VolumeName FROM JobMedia JOIN Media ON JobMedia.MediaId=Media.MediaId WHERE JobMedia.JobId=Job.JobId ORDER BY JobMediaId LIMIT 1) AS FirstVolume,"
" (SELECT count(DISTINCT MediaId) FROM JobMedia WHERE JobMedia.JobId=Job.JobId) AS Volumes"
" FROM Job"
" JOIN Client ON (Client.ClientId=Job.ClientId)"
{
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",
QString cmd("delete job jobid=");
cmd += m_selectedJobs;
- consoleCommand(cmd);
+ 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);
+ 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);
+ }
+}