]> git.sur5r.net Git - bacula/bacula/blob - bacula/src/qt-console/joblist/joblist.cpp
On vacation I am having a little fun !!
[bacula/bacula] / bacula / src / qt-console / joblist / joblist.cpp
1 /*
2    Bacula® - The Network Backup Solution
3
4    Copyright (C) 2007-2009 Free Software Foundation Europe e.V.
5
6    The main author of Bacula is Kern Sibbald, with contributions from
7    many others, a complete list can be found in the file AUTHORS.
8    This program is Free Software; you can redistribute it and/or
9    modify it under the terms of version two of the GNU General Public
10    License as published by the Free Software Foundation and included
11    in the file LICENSE.
12
13    This program is distributed in the hope that it will be useful, but
14    WITHOUT ANY WARRANTY; without even the implied warranty of
15    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16    General Public License for more details.
17
18    You should have received a copy of the GNU General Public License
19    along with this program; if not, write to the Free Software
20    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
21    02110-1301, USA.
22
23    Bacula® is a registered trademark of Kern Sibbald.
24    The licensor of Bacula is the Free Software Foundation Europe
25    (FSFE), Fiduciary Program, Sumatrastrasse 25, 8006 Zürich,
26    Switzerland, email:ftf@fsfeurope.org.
27 */
28 /*
29  *   Version $Id$
30  *
31  *   Dirk Bartley, March 2007
32  */
33  
34 #include "bat.h"
35 #include <QAbstractEventDispatcher>
36 #include <QTableWidgetItem>
37 #include "joblist.h"
38 #include "restore.h"
39 #include "joblog/joblog.h"
40 #ifdef HAVE_QWT
41 #include "jobgraphs/jobplot.h"
42 #endif
43 #include "util/fmtwidgetitem.h"
44 #include "util/comboutil.h"
45
46 /*
47  * Constructor for the class
48  */
49 JobList::JobList(const QString &mediaName, const QString &clientName,
50           const QString &jobName, const QString &filesetName, QTreeWidgetItem *parentTreeWidgetItem)
51 {
52    setupUi(this);
53    m_name = ""; /* treeWidgetName has a virtual override in this class */
54    m_mediaName = mediaName;
55    m_clientName = clientName;
56    m_jobName = jobName;
57    m_filesetName = filesetName;
58    m_filesetName = filesetName;
59    pgInitialize("", parentTreeWidgetItem);
60    QTreeWidgetItem* thisitem = mainWin->getFromHash(this);
61    thisitem->setIcon(0,QIcon(QString::fromUtf8(":images/emblem-system.png")));
62
63    m_resultCount = 0;
64    m_populated = false;
65    m_closeable = false;
66    if ((m_mediaName != "") || (m_clientName != "") || (m_jobName != "") || (m_filesetName != ""))
67       m_closeable=true;
68    m_checkCurrentWidget = true;
69    createConnections();
70
71    /* Set Defaults for check and spin for limits */
72    limitCheckBox->setCheckState(mainWin->m_recordLimitCheck ? Qt::Checked : Qt::Unchecked);
73    limitSpinBox->setValue(mainWin->m_recordLimitVal);
74    daysCheckBox->setCheckState(mainWin->m_daysLimitCheck ? Qt::Checked : Qt::Unchecked);
75    daysSpinBox->setValue(mainWin->m_daysLimitVal);
76    dockPage();
77
78    QGridLayout *gridLayout = new QGridLayout(this);
79    gridLayout->setSpacing(6);
80    gridLayout->setMargin(9);
81    gridLayout->setObjectName(QString::fromUtf8("gridLayout"));
82
83    m_splitter = new QSplitter(Qt::Vertical, this);
84    QScrollArea *area = new QScrollArea();
85    area->setObjectName(QString::fromUtf8("area"));
86    area->setWidget(frame);
87    area->setWidgetResizable(true);
88    m_splitter->addWidget(mp_tableWidget);
89    m_splitter->addWidget(area);
90
91    gridLayout->addWidget(m_splitter, 0, 0, 1, 1);
92    readSettings();
93 }
94
95 /*
96  * Write the m_splitter settings in the destructor
97  */
98 JobList::~JobList()
99 {
100    writeSettings();
101 }
102
103 /*
104  * The Meat of the class.
105  * This function will populate the QTableWidget, mp_tablewidget, with
106  * QTableWidgetItems representing the results of a query for what jobs exist on
107  * the media name passed from the constructor stored in m_mediaName.
108  */
109 void JobList::populateTable()
110 {
111    /* Can't do this in constructor because not neccesarily conected in constructor */
112    prepareFilterWidgets();
113    m_populated = true;
114
115    Freeze frz(*mp_tableWidget); /* disable updating*/
116
117    /* Set up query */
118    QString query;
119    fillQueryString(query);
120
121    /* Set up the Header for the table */
122    QStringList headerlist = (QStringList()
123       << tr("Job Id") << tr("Job Name") << tr("Client") << tr("Job Starttime") 
124       << tr("Job Type") << tr("Job Level") << tr("Job Files") 
125       << tr("Job Bytes") << tr("Job Status")  << tr("Purged") << tr("File Set")
126       << tr("Pool Name"));
127
128    m_jobIdIndex = headerlist.indexOf(tr("Job Id"));
129    m_purgedIndex = headerlist.indexOf(tr("Purged"));
130    m_typeIndex = headerlist.indexOf(tr("Job Type"));
131    m_statusIndex = headerlist.indexOf(tr("Job Status"));
132    m_startIndex = headerlist.indexOf(tr("Job Starttime"));
133    m_filesIndex = headerlist.indexOf(tr("Job Files"));
134    m_bytesIndex = headerlist.indexOf(tr("Job Bytes"));
135
136    /* Initialize the QTableWidget */
137    m_checkCurrentWidget = false;
138    mp_tableWidget->clear();
139    m_checkCurrentWidget = true;
140    mp_tableWidget->setColumnCount(headerlist.size());
141    mp_tableWidget->setHorizontalHeaderLabels(headerlist);
142    mp_tableWidget->horizontalHeader()->setHighlightSections(false);
143    mp_tableWidget->setSelectionBehavior(QAbstractItemView::SelectRows);
144    mp_tableWidget->setSortingEnabled(false); /* rows move on insert if sorting enabled */
145
146    if (mainWin->m_sqlDebug) {
147       Pmsg1(000, "Query cmd : %s\n",query.toUtf8().data());
148    }
149
150    QStringList results;
151    if (m_console->sql_cmd(query, results)) {
152       m_resultCount = results.count();
153
154       QStringList fieldlist;
155       mp_tableWidget->setRowCount(results.size());
156
157       int row = 0;
158       /* Iterate through the record returned from the query */
159       QString resultline;
160       foreach (resultline, results) {
161          fieldlist = resultline.split("\t");
162          if (fieldlist.size() < 13)
163             continue; /* some fields missing, ignore row */
164
165          TableItemFormatter jobitem(*mp_tableWidget, row);
166   
167          /* Iterate through fields in the record */
168          QStringListIterator fld(fieldlist);
169          int col = 0;
170
171          /* job id */
172          jobitem.setNumericFld(col++, fld.next());
173
174          /* job name */
175          jobitem.setTextFld(col++, fld.next());
176
177          /* client */
178          jobitem.setTextFld(col++, fld.next());
179
180          /* job starttime */
181          jobitem.setTextFld(col++, fld.next(), true);
182
183          /* job type */
184          jobitem.setJobTypeFld(col++, fld.next());
185
186          /* job level */
187          jobitem.setJobLevelFld(col++, fld.next());
188
189          /* job files */
190          jobitem.setNumericFld(col++, fld.next());
191
192          /* job bytes */
193          jobitem.setBytesFld(col++, fld.next());
194
195          /* job status */
196          jobitem.setJobStatusFld(col++, fld.next());
197
198          /* purged */
199          jobitem.setBoolFld(col++, fld.next());
200
201          /* fileset */
202          jobitem.setTextFld(col++, fld.next());
203
204          /* pool name */
205          jobitem.setTextFld(col++, fld.next());
206          row++;
207       }
208    } 
209    /* set default sorting */
210    mp_tableWidget->sortByColumn(m_jobIdIndex, Qt::DescendingOrder);
211    mp_tableWidget->setSortingEnabled(true);
212    
213    /* Resize the columns */
214    mp_tableWidget->resizeColumnsToContents();
215    mp_tableWidget->resizeRowsToContents();
216    mp_tableWidget->verticalHeader()->hide();
217    if ((m_mediaName != tr("Any")) && (m_resultCount == 0)){
218       /* for context sensitive searches, let the user know if there were no
219        * results */
220       QMessageBox::warning(this, "Bat",
221           tr("The Jobs query returned no results.\n"
222          "Press OK to continue?"), QMessageBox::Ok );
223    }
224
225    /* make read only */
226    int rcnt = mp_tableWidget->rowCount();
227    int ccnt = mp_tableWidget->columnCount();
228    for(int r=0; r < rcnt; r++) {
229       for(int c=0; c < ccnt; c++) {
230          QTableWidgetItem* item = mp_tableWidget->item(r, c);
231          if (item) {
232             item->setFlags(Qt::ItemFlags(item->flags() & (~Qt::ItemIsEditable)));
233          }
234       }
235    }
236 }
237
238 void JobList::prepareFilterWidgets()
239 {
240    if (!m_populated) {
241       clientComboBox->addItem(tr("Any"));
242       clientComboBox->addItems(m_console->client_list);
243       comboSel(clientComboBox, m_clientName);
244
245       QStringList volumeList;
246       getVolumeList(volumeList);
247       volumeComboBox->addItem(tr("Any"));
248       volumeComboBox->addItems(volumeList);
249       comboSel(volumeComboBox, m_mediaName);
250
251       jobComboBox->addItem(tr("Any"));
252       jobComboBox->addItems(m_console->job_list);
253       comboSel(jobComboBox, m_jobName);
254
255       levelComboFill(levelComboBox);
256
257       boolComboFill(purgedComboBox);
258
259       fileSetComboBox->addItem(tr("Any"));
260       fileSetComboBox->addItems(m_console->fileset_list);
261       comboSel(fileSetComboBox, m_filesetName);
262
263       poolComboBox->addItem(tr("Any"));
264       poolComboBox->addItems(m_console->pool_list);
265
266       jobStatusComboFill(statusComboBox);
267    }
268 }
269
270 void JobList::fillQueryString(QString &query)
271 {
272    query = "";
273    int volumeIndex = volumeComboBox->currentIndex();
274    if (volumeIndex != -1)
275       m_mediaName = volumeComboBox->itemText(volumeIndex);
276    QString distinct = "";
277    if (m_mediaName != tr("Any")) { distinct = "DISTINCT "; }
278    query += "SELECT " + distinct + "Job.Jobid AS Id, Job.Name AS JobName, " 
279             " Client.Name AS Client,"
280             " Job.Starttime AS JobStart, Job.Type AS JobType,"
281             " Job.Level AS BackupLevel, Job.Jobfiles AS FileCount,"
282             " Job.JobBytes AS Bytes, Job.JobStatus AS Status,"
283             " Job.PurgedFiles AS Purged, FileSet.FileSet,"
284             " Pool.Name AS Pool"
285             " FROM Job"
286             " JOIN Client ON (Client.ClientId=Job.ClientId)"
287             " LEFT OUTER JOIN FileSet ON (FileSet.FileSetId=Job.FileSetId) "
288             " LEFT OUTER JOIN pool ON Job.PoolId = Pool.PoolId ";
289    QStringList conditions;
290    if (m_mediaName != tr("Any")) {
291       query += " LEFT OUTER JOIN JobMedia ON (JobMedia.JobId=Job.JobId) "
292                " LEFT OUTER JOIN Media ON (JobMedia.MediaId=Media.MediaId) ";
293       conditions.append("Media.VolumeName='" + m_mediaName + "'");
294    }
295
296    comboCond(conditions, clientComboBox, "Client.Name");
297    comboCond(conditions, jobComboBox, "Job.Name");
298    levelComboCond(conditions, levelComboBox, "Job.Level");
299    jobStatusComboCond(conditions, statusComboBox, "Job.JobStatus");
300    boolComboCond(conditions, purgedComboBox, "Job.PurgedFiles");
301    comboCond(conditions, fileSetComboBox, "FileSet.FileSet");
302    comboCond(conditions, poolComboBox, "Pool.Name");
303
304    /* If Limit check box For limit by days is checked  */
305    if (daysCheckBox->checkState() == Qt::Checked) {
306       QDateTime stamp = QDateTime::currentDateTime().addDays(-daysSpinBox->value());
307       QString since = stamp.toString(Qt::ISODate);
308       conditions.append("Job.Starttime>'" + since + "'");
309    }
310    bool first = true;
311    foreach (QString condition, conditions) {
312       if (first) {
313          query += " WHERE " + condition;
314          first = false;
315       } else {
316          query += " AND " + condition;
317       }
318    }
319    /* Descending */
320    query += " ORDER BY Job.JobId DESC";
321    /* If Limit check box for limit records returned is checked  */
322    if (limitCheckBox->checkState() == Qt::Checked) {
323       QString limit;
324       limit.setNum(limitSpinBox->value());
325       query += " LIMIT " + limit;
326    }
327 }
328
329 /*
330  * When the treeWidgetItem in the page selector tree is singleclicked, Make sure
331  * The tree has been populated.
332  */
333 void JobList::PgSeltreeWidgetClicked()
334 {
335    if (!m_populated) {
336       populateTable();
337    }
338 }
339
340 /*
341  *  Virtual function override of pages function which is called when this page
342  *  is visible on the stack
343  */
344 void JobList::currentStackItem()
345 {
346 /*   if (!m_populated) populate every time user comes back to this object */
347       populateTable();
348 }
349
350 /*
351  * Virtual Function to return the name for the medialist tree widget
352  */
353 void JobList::treeWidgetName(QString &desc)
354 {
355    if (m_mediaName != "" ) {
356      desc = tr("JobList of Volume %1").arg(m_mediaName);
357    } else if (m_clientName != "" ) {
358      desc = tr("JobList of Client %1").arg(m_clientName);
359    } else if (m_jobName != "" ) {
360      desc = tr("JobList of Job %1").arg(m_jobName);
361    } else if (m_filesetName != "" ) {
362      desc = tr("JobList of fileset %1").arg(m_filesetName);
363    } else {
364      desc = tr("JobList");
365    }
366 }
367
368 /*
369  * This functions much line tableItemChanged for trees like the page selector,
370  * but I will do much less here
371  */
372 void JobList::tableItemChanged(QTableWidgetItem *currentItem, QTableWidgetItem * /*previousItem*/)
373 {
374    if (m_checkCurrentWidget) {
375       int row = currentItem->row();
376       QTableWidgetItem* jobitem = mp_tableWidget->item(row, 0);
377       m_currentJob = jobitem->text();
378
379       /* include purged action or not */
380       jobitem = mp_tableWidget->item(row, m_purgedIndex);
381       QString purged = jobitem->text();
382       mp_tableWidget->removeAction(actionPurgeFiles);
383       if (purged == tr("No") ) {
384          mp_tableWidget->addAction(actionPurgeFiles);
385       }
386       /* include restore from time and job action or not */
387       jobitem = mp_tableWidget->item(row, m_typeIndex);
388       QString type = jobitem->text();
389       mp_tableWidget->removeAction(actionRestoreFromJob);
390       mp_tableWidget->removeAction(actionRestoreFromTime);
391       if (type == tr("Backup")) {
392          mp_tableWidget->addAction(actionRestoreFromJob);
393          mp_tableWidget->addAction(actionRestoreFromTime);
394       }
395       /* include cancel action or not */
396       jobitem = mp_tableWidget->item(row, m_statusIndex);
397       QString status = jobitem->text();
398       mp_tableWidget->removeAction(actionCancelJob);
399       if (status == tr("Running") || status == tr("Created, not yet running")) {
400          mp_tableWidget->addAction(actionCancelJob);
401       }
402    }
403 }
404
405 /*
406  * Function to create connections for context sensitive menu for this and
407  * the page selector
408  */
409 void JobList::createConnections()
410 {
411    /* connect to the action specific to this pages class that shows up in the 
412     * page selector tree */
413    connect(actionRefreshJobList, SIGNAL(triggered()), this,
414                 SLOT(populateTable()));
415    connect(refreshButton, SIGNAL(pressed()), this, SLOT(populateTable()));
416 #ifdef HAVE_QWT
417    connect(graphButton, SIGNAL(pressed()), this, SLOT(graphTable()));
418 #else
419    graphButton->setEnabled(false);
420    graphButton->setVisible(false);
421 #endif
422    /* for the tableItemChanged to maintain m_currentJob */
423    connect(mp_tableWidget, SIGNAL(
424            currentItemChanged(QTableWidgetItem *, QTableWidgetItem *)),
425            this, SLOT(tableItemChanged(QTableWidgetItem *, QTableWidgetItem *)));
426
427    /* for the tableItemChanged to maintain a delete selection */
428    connect(mp_tableWidget, SIGNAL( itemSelectionChanged()),
429            this, SLOT(selectedJobsGet()) );
430
431    /* Do what is required for the local context sensitive menu */
432
433
434    /* setContextMenuPolicy is required */
435    mp_tableWidget->setContextMenuPolicy(Qt::ActionsContextMenu);
436
437    /* Add Actions */
438    mp_tableWidget->addAction(actionRefreshJobList);
439    mp_tableWidget->addAction(actionListJobid);
440    mp_tableWidget->addAction(actionListFilesOnJob);
441    mp_tableWidget->addAction(actionListJobMedia);
442    mp_tableWidget->addAction(actionListVolumes);
443    mp_tableWidget->addAction(actionDeleteJob);
444    mp_tableWidget->addAction(actionPurgeFiles);
445    mp_tableWidget->addAction(actionRestoreFromJob);
446    mp_tableWidget->addAction(actionRestoreFromTime);
447    mp_tableWidget->addAction(actionShowLogForJob);
448
449    /* Make Connections */
450    connect(actionListJobid, SIGNAL(triggered()), this,
451                 SLOT(consoleListJobid()));
452    connect(actionListFilesOnJob, SIGNAL(triggered()), this,
453                 SLOT(consoleListFilesOnJob()));
454    connect(actionListJobMedia, SIGNAL(triggered()), this,
455                 SLOT(consoleListJobMedia()));
456    connect(actionListVolumes, SIGNAL(triggered()), this,
457                 SLOT(consoleListVolumes()));
458    connect(actionDeleteJob, SIGNAL(triggered()), this,
459                 SLOT(consoleDeleteJob()));
460    connect(actionPurgeFiles, SIGNAL(triggered()), this,
461                 SLOT(consolePurgeFiles()));
462    connect(actionRestoreFromJob, SIGNAL(triggered()), this,
463                 SLOT(preRestoreFromJob()));
464    connect(actionRestoreFromTime, SIGNAL(triggered()), this,
465                 SLOT(preRestoreFromTime()));
466    connect(actionShowLogForJob, SIGNAL(triggered()), this,
467                 SLOT(showLogForJob()));
468    connect(actionCancelJob, SIGNAL(triggered()), this,
469                 SLOT(consoleCancelJob()));
470    connect(actionListJobTotals, SIGNAL(triggered()), this,
471                 SLOT(consoleListJobTotals()));
472
473    m_contextActions.append(actionRefreshJobList);
474    m_contextActions.append(actionListJobTotals);
475 }
476
477 /*
478  * Functions to respond to local context sensitive menu sending console commands
479  * If I could figure out how to make these one function passing a string, Yaaaaaa
480  */
481 void JobList::consoleListJobid()
482 {
483    QString cmd("list jobid=");
484    cmd += m_currentJob;
485    if (mainWin->m_longList) { cmd.prepend("l"); }
486    consoleCommand(cmd);
487 }
488 void JobList::consoleListFilesOnJob()
489 {
490    QString cmd("list files jobid=");
491    cmd += m_currentJob;
492    if (mainWin->m_longList) { cmd.prepend("l"); }
493    consoleCommand(cmd);
494 }
495 void JobList::consoleListJobMedia()
496 {
497    QString cmd("list jobmedia jobid=");
498    cmd += m_currentJob;
499    if (mainWin->m_longList) { cmd.prepend("l"); }
500    consoleCommand(cmd);
501 }
502 void JobList::consoleListVolumes()
503 {
504    QString cmd("list volumes jobid=");
505    cmd += m_currentJob;
506    if (mainWin->m_longList) { cmd.prepend("l"); }
507    consoleCommand(cmd);
508 }
509 void JobList::consoleListJobTotals()
510 {
511    QString cmd("list jobtotals");
512    if (mainWin->m_longList) { cmd.prepend("l"); }
513    consoleCommand(cmd);
514 }
515 void JobList::consoleDeleteJob()
516 {
517    if (QMessageBox::warning(this, "Bat",
518       tr("Are you sure you want to delete??  !!!.\n"
519 "This delete command is used to delete a Job record and all associated catalog"
520 " records that were created. This command operates only on the Catalog"
521 " database and has no effect on the actual data written to a Volume. This"
522 " command can be dangerous and we strongly recommend that you do not use"
523 " it unless you know what you are doing.  The Job and all its associated"
524 " records (File and JobMedia) will be deleted from the catalog."
525       "Press OK to proceed with delete operation.?"),
526       QMessageBox::Ok | QMessageBox::Cancel)
527       == QMessageBox::Cancel) { return; }
528
529    QString cmd("delete job jobid=");
530    cmd += m_selectedJobs;
531    consoleCommand(cmd);
532 }
533 void JobList::consolePurgeFiles()
534 {
535    if (QMessageBox::warning(this, "Bat",
536       tr("Are you sure you want to purge ??  !!!.\n"
537 "The Purge command will delete associated Catalog database records from Jobs and"
538 " Volumes without considering the retention period. Purge  works only on the"
539 " Catalog database and does not affect data written to Volumes. This command can"
540 " be dangerous because you can delete catalog records associated with current"
541 " backups of files, and we recommend that you do not use it unless you know what"
542 " you are doing.\n"
543       "Press OK to proceed with the purge operation?"),
544       QMessageBox::Ok | QMessageBox::Cancel)
545       == QMessageBox::Cancel) { return; }
546
547    QString cmd("purge files jobid=");
548    cmd += m_currentJob;
549    consoleCommand(cmd);
550 }
551
552 /*
553  * Subroutine to call preRestore to restore from a select job
554  */
555 void JobList::preRestoreFromJob()
556 {
557    new prerestorePage(m_currentJob, R_JOBIDLIST);
558 }
559
560 /*
561  * Subroutine to call preRestore to restore from a select job
562  */
563 void JobList::preRestoreFromTime()
564 {
565    new prerestorePage(m_currentJob, R_JOBDATETIME);
566 }
567
568 /*
569  * Subroutine to call class to show the log in the database from that job
570  */
571 void JobList::showLogForJob()
572 {
573    QTreeWidgetItem* pageSelectorTreeWidgetItem = mainWin->getFromHash(this);
574    new JobLog(m_currentJob, pageSelectorTreeWidgetItem);
575 }
576
577 /*
578  * Cancel a running job
579  */
580 void JobList::consoleCancelJob()
581 {
582    QString cmd("cancel jobid=");
583    cmd += m_currentJob;
584    consoleCommand(cmd);
585 }
586
587 /*
588  * Graph this table
589  */
590 void JobList::graphTable()
591 {
592 #ifdef HAVE_QWT
593    JobPlotPass pass;
594    pass.recordLimitCheck = limitCheckBox->checkState();
595    pass.daysLimitCheck = daysCheckBox->checkState();
596    pass.recordLimitSpin = limitSpinBox->value();
597    pass.daysLimitSpin = daysSpinBox->value();
598    pass.jobCombo = jobComboBox->currentText();
599    pass.clientCombo = clientComboBox->currentText();
600    pass.volumeCombo = volumeComboBox->currentText();
601    pass.fileSetCombo = fileSetComboBox->currentText();
602    pass.purgedCombo = purgedComboBox->currentText();
603    pass.levelCombo = levelComboBox->currentText();
604    pass.statusCombo = statusComboBox->currentText();
605    pass.use = true;
606    QTreeWidgetItem* pageSelectorTreeWidgetItem = mainWin->getFromHash(this);
607    new JobPlot(pageSelectorTreeWidgetItem, pass);
608 #endif
609 }
610
611 /*
612  * Save user settings associated with this page
613  */
614 void JobList::writeSettings()
615 {
616    QSettings settings(m_console->m_dir->name(), "bat");
617    settings.beginGroup(m_groupText);
618    settings.setValue(m_splitText, m_splitter->saveState());
619    settings.endGroup();
620 }
621
622 /*
623  * Read and restore user settings associated with this page
624  */
625 void JobList::readSettings()
626 {
627    m_groupText = "JobListPage";
628    m_splitText = "splitterSizes_1";
629    QSettings settings(m_console->m_dir->name(), "bat");
630    settings.beginGroup(m_groupText);
631    m_splitter->restoreState(settings.value(m_splitText).toByteArray());
632    settings.endGroup();
633 }
634
635 /*
636  * Function to fill m_selectedJobsCount and m_selectedJobs with selected values
637  */
638 void JobList::selectedJobsGet()
639 {
640    QList<int> rowList;
641    QList<QTableWidgetItem *> sitems = mp_tableWidget->selectedItems();
642    foreach (QTableWidgetItem *sitem, sitems) {
643       int row = sitem->row();
644       if (!rowList.contains(row)) {
645          rowList.append(row);
646       }
647    }
648
649    m_selectedJobs = "";
650    bool first = true;
651    foreach(int row, rowList) {
652       QTableWidgetItem * sitem = mp_tableWidget->item(row, m_jobIdIndex);
653       if (!first) m_selectedJobs.append(",");
654       else first = false;
655       m_selectedJobs.append(sitem->text());
656    }
657    m_selectedJobsCount = rowList.count();
658    if (m_selectedJobsCount > 1) {
659      QString text = QString( tr("Delete list of %1 Jobs")).arg(m_selectedJobsCount);
660        actionDeleteJob->setText(text);
661    } else {
662      actionDeleteJob->setText(tr("Delete Single Job"));
663    }
664 }