]> git.sur5r.net Git - bacula/bacula/blob - bacula/src/qt-console/mainwin.cpp
Dont allow close of page with a child in the page selector.
[bacula/bacula] / bacula / src / qt-console / mainwin.cpp
1 /*
2    Bacula® - The Network Backup Solution
3
4    Copyright (C) 2007-2007 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 plus additions
11    that are listed 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 John Walker.
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 /*
30  *   Version $Id$
31  *
32  *  Main Window control for bat (qt-console)
33  *
34  *   Kern Sibbald, January MMVII
35  *
36  */ 
37
38 #include "bat.h"
39 #include "joblist/joblist.h"
40 #include "storage/storage.h"
41 #include "fileset/fileset.h"
42 #include "label/label.h"
43 #include "run/run.h"
44 #include "pages.h"
45 #include "restore/restore.h"
46 #include "medialist/medialist.h"
47 #include "joblist/joblist.h"
48 #include "clients/clients.h"
49 #include "help/help.h"
50 #include "jobs/jobs.h"
51
52 /* 
53  * Daemon message callback
54  */
55 void message_callback(int /* type */, char *msg)
56 {
57    QMessageBox::warning(mainWin, "Bat", msg, QMessageBox::Ok);
58 }
59
60 MainWin::MainWin(QWidget *parent) : QMainWindow(parent)
61 {
62    m_dtformat = "yyyy-MM-dd HH:mm:ss";
63    mainWin = this;
64    setupUi(this);                     /* Setup UI defined by main.ui (designer) */
65    register_message_callback(message_callback);
66    readPreferences();
67    treeWidget->clear();
68    treeWidget->setColumnCount(1);
69    treeWidget->setHeaderLabel("Select Page");
70    treeWidget->setContextMenuPolicy(Qt::ActionsContextMenu);
71
72    createPages();
73
74    resetFocus();
75
76    createConnections();
77
78    this->show();
79
80    readSettings();
81
82    foreach(Console *console, m_consoleHash) {
83       console->connect_dir();
84    }
85    m_currentConsole = (Console*)getFromHash(m_firstItem);
86    m_currentConsole->setCurrent();
87    if (m_miscDebug) {
88       QString directoryResourceName;
89       m_currentConsole->getDirResName(directoryResourceName);
90       Pmsg1(000, "Setting initial window to %s\n", directoryResourceName.toUtf8().data());
91    }
92 }
93
94 void MainWin::createPages()
95 {
96    DIRRES *dir;
97    QTreeWidgetItem *item, *topItem;
98    m_firstItem = NULL;
99
100    LockRes();
101    foreach_res(dir, R_DIRECTOR) {
102
103       /* Create console tree stacked widget item */
104       m_currentConsole = new Console(stackedWidget);
105       m_currentConsole->setDirRes(dir);
106       m_currentConsole->readSettings();
107
108       /* The top tree item representing the director */
109       topItem = new QTreeWidgetItem(treeWidget);
110       topItem->setText(0, dir->name());
111       topItem->setIcon(0, QIcon(":images/server.png"));
112       /* Set background to grey for ease of identification of inactive Director */
113       QBrush greyBrush(Qt::lightGray);
114       topItem->setBackground(0, greyBrush);
115       m_currentConsole->setDirectorTreeItem(topItem);
116       m_consoleHash.insert(topItem, m_currentConsole);
117
118       /* Create Tree Widget Item */
119       item = new QTreeWidgetItem(topItem);
120       item->setText(0, "Console");
121       if (!m_firstItem){ m_firstItem = item; }
122       item->setIcon(0,QIcon(QString::fromUtf8(":images/utilities-terminal.svg")));
123
124       /* insert the cosole and tree widget item into the hashes */
125       hashInsert(item, m_currentConsole);
126
127       /* Set Color of treeWidgetItem for the console
128       * It will be set to green in the console class if the connection is made.
129       */
130       QBrush redBrush(Qt::red);
131       item->setForeground(0, redBrush);
132       m_currentConsole->dockPage();
133
134       /*
135        * Create instances in alphabetic order of the rest 
136        *  of the classes that will by default exist under each Director.  
137        */
138 //      new bRestore();
139       new Clients();
140       new FileSet();
141       new Jobs();
142       createPageJobList("", "", "", "", NULL);
143       new MediaList();
144       new Storage();
145
146       treeWidget->expandItem(topItem);
147       stackedWidget->setCurrentWidget(m_currentConsole);
148    }
149    UnlockRes();
150 }
151
152 /*
153  * create an instance of the the joblist class on the stack
154  */
155 void MainWin::createPageJobList(const QString &media, const QString &client,
156               const QString &job, const QString &fileset, QTreeWidgetItem *parentTreeWidgetItem)
157 {
158    QTreeWidgetItem *holdItem;
159
160    /* save current tree widget item in case query produces no results */
161    holdItem = treeWidget->currentItem();
162    JobList* joblist = new JobList(media, client, job, fileset, parentTreeWidgetItem);
163    /* If this is a query of jobs on a specific media */
164    if ((media != "") || (client != "") || (job != "") || (fileset != "")) {
165       joblist->setCurrent();
166       /* did query produce results, if not close window and set back to hold */
167       if (joblist->m_resultCount == 0) {
168          joblist->closeStackPage();
169          treeWidget->setCurrentItem(holdItem);
170       }
171    }
172 }
173
174 /*
175  * Handle up and down arrow keys for the command line
176  *  history.
177  */
178 void MainWin::keyPressEvent(QKeyEvent *event)
179 {
180    if (m_cmd_history.size() == 0) {
181       event->ignore();
182       return;
183    }
184    switch (event->key()) {
185    case Qt::Key_Down:
186       if (m_cmd_last < 0 || m_cmd_last >= (m_cmd_history.size()-1)) {
187          event->ignore();
188          return;
189       }
190       m_cmd_last++;
191       break;
192    case Qt::Key_Up:
193       if (m_cmd_last == 0) {
194          event->ignore();
195          return;
196       }
197       if (m_cmd_last < 0 || m_cmd_last > (m_cmd_history.size()-1)) {
198          m_cmd_last = m_cmd_history.size() - 1;
199       } else {
200          m_cmd_last--;
201       }
202       break;
203    default:
204       event->ignore();
205       return;
206    }
207    lineEdit->setText(m_cmd_history[m_cmd_last]);
208 }
209
210 void MainWin::createConnections()
211 {
212    /* Connect signals to slots */
213    connect(lineEdit, SIGNAL(returnPressed()), this, SLOT(input_line()));
214    connect(actionAbout_bat, SIGNAL(triggered()), this, SLOT(about()));
215    connect(actionBat_Help, SIGNAL(triggered()), this, SLOT(help()));
216    connect(treeWidget, SIGNAL(itemClicked(QTreeWidgetItem *, int)), this, 
217            SLOT(treeItemClicked(QTreeWidgetItem *, int)));
218    connect(treeWidget, SIGNAL(
219            currentItemChanged(QTreeWidgetItem *, QTreeWidgetItem *)),
220            this, SLOT(treeItemChanged(QTreeWidgetItem *, QTreeWidgetItem *)));
221    connect(stackedWidget, SIGNAL(currentChanged(int)),
222            this, SLOT(stackItemChanged(int)));
223    connect(actionQuit, SIGNAL(triggered()), app, SLOT(closeAllWindows()));
224    connect(actionLabel, SIGNAL(triggered()), this,  SLOT(labelButtonClicked()));
225    connect(actionRun, SIGNAL(triggered()), this,  SLOT(runButtonClicked()));
226    connect(actionEstimate, SIGNAL(triggered()), this,  SLOT(estimateButtonClicked()));
227    connect(actionRestore, SIGNAL(triggered()), this,  SLOT(restoreButtonClicked()));
228    connect(actionUndock, SIGNAL(triggered()), this,  SLOT(undockWindowButton()));
229    connect(actionToggleDock, SIGNAL(triggered()), this,  SLOT(toggleDockContextWindow()));
230    connect(actionClosePage, SIGNAL(triggered()), this,  SLOT(closePage()));
231    connect(actionPreferences, SIGNAL(triggered()), this,  SLOT(setPreferences()));
232 }
233
234 /* 
235  * Reimplementation of QWidget closeEvent virtual function   
236  */
237 void MainWin::closeEvent(QCloseEvent *event)
238 {
239    writeSettings();
240    foreach(Console *console, m_consoleHash){
241       console->writeSettings();
242       console->terminate();
243    }
244    event->accept();
245    foreach(Pages *page, m_pagehash) {
246       if (!page->isDocked())
247          page->close();
248    }
249 }
250
251 void MainWin::writeSettings()
252 {
253    QSettings settings("bacula.org", "bat");
254
255    settings.beginGroup("MainWin");
256    settings.setValue("winSize", size());
257    settings.setValue("winPos", pos());
258    settings.setValue("state", saveState());
259    settings.endGroup();
260 }
261
262 void MainWin::readSettings()
263
264    QSettings settings("bacula.org", "bat");
265
266    settings.beginGroup("MainWin");
267    resize(settings.value("winSize", QSize(1041, 801)).toSize());
268    move(settings.value("winPos", QPoint(200, 150)).toPoint());
269    restoreState(settings.value("state").toByteArray());
270    settings.endGroup();
271 }
272
273 /*
274  * This subroutine is called with an item in the Page Selection window
275  *   is clicked 
276  */
277 void MainWin::treeItemClicked(QTreeWidgetItem *item, int /*column*/)
278 {
279    /* Is this a page that has been inserted into the hash  */
280    if (getFromHash(item)) {
281       Pages* page = getFromHash(item);
282       int stackindex=stackedWidget->indexOf(page);
283
284       if (stackindex >= 0) {
285          stackedWidget->setCurrentWidget(page);
286       }
287       /* run the virtual function in case this class overrides it */
288       page->PgSeltreeWidgetClicked();
289    }
290 }
291
292 /*
293  * Called with a change of the highlighed tree widget item in the page selector.
294  */
295 void MainWin::treeItemChanged(QTreeWidgetItem *currentitem, QTreeWidgetItem *previousitem)
296 {
297    Pages *previousPage, *nextPage;
298    Console *previousConsole, *nextConsole;
299
300    /* first determine the next item */
301
302    /* knowing the treeWidgetItem, get the page from the hash */
303    nextPage = getFromHash(currentitem);
304    nextConsole = m_consoleHash.value(currentitem);
305    /* Is this a page that has been inserted into the hash  */
306    if (nextPage) {
307       nextConsole = nextPage->console();
308       /* then is it a treeWidgetItem representing a director */
309    } else if (nextConsole) {
310       /* let the next page BE the console */
311       nextPage = nextConsole;
312    } else {
313       /* Should never get here */
314       nextPage = NULL;
315       nextConsole = NULL;
316    }
317           
318    /* The Previous item */
319
320    /* this condition prevents a segfault.  The first time there is no previousitem*/
321    if (previousitem) {
322       /* knowing the treeWidgetItem, get the page from the hash */
323       previousPage = getFromHash(previousitem);
324       previousConsole = m_consoleHash.value(previousitem);
325       if (previousPage) {
326          previousConsole = previousPage->console();
327       } else if (previousConsole) {
328          previousPage = previousConsole;
329       }
330       if ((previousPage) || (previousConsole)) {
331          if (nextConsole != previousConsole) {
332             /* remove connections to the current console */
333             disconnect(actionConnect, SIGNAL(triggered()), previousConsole, SLOT(connect_dir()));
334             disconnect(actionStatusDir, SIGNAL(triggered()), previousConsole, SLOT(status_dir()));
335             disconnect(actionMessages, SIGNAL(triggered()), previousConsole, SLOT(messages()));
336             disconnect(actionSelectFont, SIGNAL(triggered()), previousConsole, SLOT(set_font()));
337             QTreeWidgetItem *dirItem = previousConsole->directorTreeItem();
338             QBrush greyBrush(Qt::lightGray);
339             dirItem->setBackground(0, greyBrush);
340          }
341          /* make sure the close window and toggle dock options are removed */
342          treeWidget->removeAction(actionClosePage);
343          treeWidget->removeAction(actionToggleDock);
344          /* Is this a page that has been inserted into the hash  */
345          if (previousPage) {
346             foreach(QAction* pageaction, previousPage->m_contextActions) {
347                treeWidget->removeAction(pageaction);
348             }
349          } 
350       }
351    }
352
353    /* process the current (next) item */
354    
355    if ((nextPage) || (nextConsole)) {
356       if (nextConsole != previousConsole) {
357          /* make connections to the current console */
358          m_currentConsole = nextConsole;
359          connect(actionConnect, SIGNAL(triggered()), m_currentConsole, SLOT(connect_dir()));
360          connect(actionSelectFont, SIGNAL(triggered()), m_currentConsole, SLOT(set_font()));
361          connect(actionStatusDir, SIGNAL(triggered()), m_currentConsole, SLOT(status_dir()));
362          connect(actionMessages, SIGNAL(triggered()), m_currentConsole, SLOT(messages()));
363          /* Set director's tree widget background to magenta for ease of identification */
364          QTreeWidgetItem *dirItem = m_currentConsole->directorTreeItem();
365          QBrush magentaBrush(Qt::magenta);
366          dirItem->setBackground(0, magentaBrush);
367       }
368       /* set the value for the currently active console */
369       int stackindex = stackedWidget->indexOf(nextPage);
370    
371       /* Is this page currently on the stack or is it undocked */
372       if (stackindex >= 0) {
373          /* put this page on the top of the stack */
374          stackedWidget->setCurrentIndex(stackindex);
375       } else {
376          /* it is undocked, raise it to the front */
377          nextPage->raise();
378       }
379       /* for the page selectors menu action to dock or undock, set the text */
380       nextPage->setContextMenuDockText();
381
382       treeWidget->addAction(actionToggleDock);
383       /* if this page is closeable, and it has no childern, then add that action */
384       if ((nextPage->isCloseable()) && (currentitem->child(0) == NULL))
385          treeWidget->addAction(actionClosePage);
386
387       /* Add the actions to the Page Selectors tree widget that are part of the
388        * current items list of desired actions regardless of whether on top of stack*/
389       treeWidget->addActions(nextPage->m_contextActions);
390    }
391 }
392
393 void MainWin::labelButtonClicked() 
394 {
395    new labelPage();
396 }
397
398 void MainWin::runButtonClicked() 
399 {
400    new runPage();
401 }
402
403 void MainWin::estimateButtonClicked() 
404 {
405    new estimatePage();
406 }
407
408 void MainWin::restoreButtonClicked() 
409 {
410    new prerestorePage();
411 }
412
413 /*
414  * The user just finished typing a line in the command line edit box
415  */
416 void MainWin::input_line()
417 {
418    QString cmdStr = lineEdit->text();    /* Get the text */
419    lineEdit->clear();                    /* clear the lineEdit box */
420    if (m_currentConsole->is_connected()) {
421       m_currentConsole->consoleCommand(cmdStr);
422    } else {
423       set_status("Director not connected. Click on connect button.");
424    }
425    m_cmd_history.append(cmdStr);
426    m_cmd_last = -1;
427    if (treeWidget->currentItem() != getFromHash(m_currentConsole))
428       m_currentConsole->setCurrent();
429 }
430
431
432 void MainWin::about()
433 {
434    QMessageBox::about(this, tr("About bat"),
435       tr("<br><h2>bat 1.0, by Dirk H Bartley and Kern Sibbald</h2>"
436          "<p>Copyright &copy; " BYEAR " Free Software Foundation Europe e.V."
437          "<p>The <b>bat</b> is an administrative console"
438          " interface to the Director."));
439 }
440
441 void MainWin::help()
442 {
443    Help::displayFile("index.html");
444 }
445
446 void MainWin::set_statusf(const char *fmt, ...)
447 {
448    va_list arg_ptr;
449    char buf[1000];
450    int len;
451    va_start(arg_ptr, fmt);
452    len = bvsnprintf(buf, sizeof(buf), fmt, arg_ptr);
453    va_end(arg_ptr);
454    set_status(buf);
455 }
456
457 void MainWin::set_status_ready()
458 {
459    set_status(" Ready");
460 }
461
462 void MainWin::set_status(const char *buf)
463 {
464    statusBar()->showMessage(buf);
465 }
466
467 /*
468  * Function to respond to the button bar button to undock
469  */
470 void MainWin::undockWindowButton()
471 {
472    Pages* page = (Pages*)stackedWidget->currentWidget();
473    page->togglePageDocking();
474 }
475
476 /*
477  * Function to respond to action on page selector context menu to toggle the 
478  * dock status of the window associated with the page selectors current
479  * tree widget item.
480  */
481 void MainWin::toggleDockContextWindow()
482 {
483    QTreeWidgetItem *currentitem = treeWidget->currentItem();
484    
485    /* Is this a page that has been inserted into the hash  */
486    if (getFromHash(currentitem)) {
487       Pages* page = getFromHash(currentitem);
488       page->togglePageDocking();
489    }
490 }
491
492 /*
493  * This function is called when the stack item is changed.  Call
494  * the virtual function here.  Avoids a window being undocked leaving
495  * a window at the top of the stack unpopulated.
496  */
497 void MainWin::stackItemChanged(int)
498 {
499    Pages* page = (Pages*)stackedWidget->currentWidget();
500    /* run the virtual function in case this class overrides it */
501    page->currentStackItem();
502 }
503
504 /*
505  * Function to simplify insertion of QTreeWidgetItem <-> Page association
506  * into a double direction hash.
507  */
508 void MainWin::hashInsert(QTreeWidgetItem *item, Pages *page)
509 {
510    m_pagehash.insert(item, page);
511    m_widgethash.insert(page, item);
512 }
513
514 /*
515  * Function to simplify removal of QTreeWidgetItem <-> Page association
516  * into a double direction hash.
517  */
518 void MainWin::hashRemove(QTreeWidgetItem *item, Pages *page)
519 {
520    /* I had all sorts of return status checking code here.  Do we have a log
521     * level capability in bat.  I would have left it in but it used printf's
522     * and it should really be some kind of log level facility ???
523     * ******FIXME********/
524    m_pagehash.remove(item);
525    m_widgethash.remove(page);
526 }
527
528 /*
529  * Function to retrieve a Page* when the item in the page selector's tree is
530  * known.
531  */
532 Pages* MainWin::getFromHash(QTreeWidgetItem *item)
533 {
534    return m_pagehash.value(item);
535 }
536
537 /*
538  * Function to retrieve the page selectors tree widget item when the page is
539  * known.
540  */
541 QTreeWidgetItem* MainWin::getFromHash(Pages *page)
542 {
543    return m_widgethash.value(page);
544 }
545
546 /*
547  * Function to respond to action on page selector context menu to close the
548  * current window.
549  */
550 void MainWin::closePage()
551 {
552    QTreeWidgetItem *currentitem = treeWidget->currentItem();
553    
554    /* Is this a page that has been inserted into the hash  */
555    if (getFromHash(currentitem)) {
556       Pages* page = getFromHash(currentitem);
557       if (page->isCloseable()) {
558          page->closeStackPage();
559       }
560    }
561 }
562
563 /* Quick function to return the current console */
564 Console *MainWin::currentConsole()
565 {
566    return m_currentConsole;
567 }
568 /* Quick function to return the tree item for the director */
569 QTreeWidgetItem *MainWin::currentTopItem()
570 {
571    return m_currentConsole->directorTreeItem();
572 }
573
574 /* Preferences menu item clicked */
575 void MainWin::setPreferences()
576 {
577    prefsDialog prefs;
578    prefs.commDebug->setCheckState(m_commDebug ? Qt::Checked : Qt::Unchecked);
579    prefs.displayAll->setCheckState(m_displayAll ? Qt::Checked : Qt::Unchecked);
580    prefs.sqlDebug->setCheckState(m_sqlDebug ? Qt::Checked : Qt::Unchecked);
581    prefs.commandDebug->setCheckState(m_commandDebug ? Qt::Checked : Qt::Unchecked);
582    prefs.miscDebug->setCheckState(m_miscDebug ? Qt::Checked : Qt::Unchecked);
583    prefs.recordLimit->setCheckState(m_recordLimitCheck ? Qt::Checked : Qt::Unchecked);
584    prefs.recordSpinBox->setValue(m_recordLimitVal);
585    prefs.daysLimit->setCheckState(m_daysLimitCheck ? Qt::Checked : Qt::Unchecked);
586    prefs.daysSpinBox->setValue(m_daysLimitVal);
587    prefs.checkMessages->setCheckState(m_checkMessages ? Qt::Checked : Qt::Unchecked);
588    prefs.checkMessagesSpin->setValue(m_checkMessagesInterval);
589    prefs.executeLongCheckBox->setCheckState(m_longList ? Qt::Checked : Qt::Unchecked);
590
591    prefs.exec();
592 }
593
594 /* Preferences dialog */
595 prefsDialog::prefsDialog()
596 {
597    setupUi(this);
598 }
599
600 void prefsDialog::accept()
601 {
602    this->hide();
603    mainWin->m_commDebug = this->commDebug->checkState() == Qt::Checked;
604    mainWin->m_displayAll = this->displayAll->checkState() == Qt::Checked;
605    mainWin->m_sqlDebug = this->sqlDebug->checkState() == Qt::Checked;
606    mainWin->m_commandDebug = this->commandDebug->checkState() == Qt::Checked;
607    mainWin->m_miscDebug = this->miscDebug->checkState() == Qt::Checked;
608    mainWin->m_recordLimitCheck = this->recordLimit->checkState() == Qt::Checked;
609    mainWin->m_recordLimitVal = this->recordSpinBox->value();
610    mainWin->m_daysLimitCheck = this->daysLimit->checkState() == Qt::Checked;
611    mainWin->m_daysLimitVal = this->daysSpinBox->value();
612    mainWin->m_checkMessages = this->checkMessages->checkState() == Qt::Checked;
613    mainWin->m_checkMessagesInterval = this->checkMessagesSpin->value();
614    mainWin->m_longList = this->executeLongCheckBox->checkState() == Qt::Checked;
615    QSettings settings("www.bacula.org", "bat");
616    settings.beginGroup("Debug");
617    settings.setValue("commDebug", mainWin->m_commDebug);
618    settings.setValue("displayAll", mainWin->m_displayAll);
619    settings.setValue("sqlDebug", mainWin->m_sqlDebug);
620    settings.setValue("commandDebug", mainWin->m_commandDebug);
621    settings.setValue("miscDebug", mainWin->m_miscDebug);
622    settings.endGroup();
623    settings.beginGroup("JobList");
624    settings.setValue("recordLimitCheck", mainWin->m_recordLimitCheck);
625    settings.setValue("recordLimitVal", mainWin->m_recordLimitVal);
626    settings.setValue("daysLimitCheck", mainWin->m_daysLimitCheck);
627    settings.setValue("daysLimitVal", mainWin->m_daysLimitVal);
628    settings.endGroup();
629    settings.beginGroup("Messages");
630    settings.setValue("checkMessages", mainWin->m_checkMessages);
631    settings.setValue("checkMessagesInterval", mainWin->m_checkMessagesInterval);
632    settings.endGroup();
633    settings.beginGroup("Misc");
634    settings.setValue("longList", mainWin->m_longList);
635    settings.endGroup();
636    foreach(Console *console, mainWin->m_consoleHash) {
637       console->startTimer();
638    }
639 }
640
641 void prefsDialog::reject()
642 {
643    this->hide();
644    mainWin->set_status("Canceled");
645 }
646
647 /* read preferences for the prefences dialog box */
648 void MainWin::readPreferences()
649 {
650    QSettings settings("www.bacula.org", "bat");
651    settings.beginGroup("Debug");
652    m_commDebug = settings.value("commDebug", false).toBool();
653    m_displayAll = settings.value("displayAll", false).toBool();
654    m_sqlDebug = settings.value("sqlDebug", false).toBool();
655    m_commandDebug = settings.value("commandDebug", false).toBool();
656    m_miscDebug = settings.value("miscDebug", false).toBool();
657    settings.endGroup();
658    settings.beginGroup("JobList");
659    m_recordLimitCheck = settings.value("recordLimitCheck", true).toBool();
660    m_recordLimitVal = settings.value("recordLimitVal", 150).toInt();
661    m_daysLimitCheck = settings.value("daysLimitCheck", false).toBool();
662    m_daysLimitVal = settings.value("daysLimitVal", 28).toInt();
663    settings.endGroup();
664    settings.beginGroup("Messages");
665    m_checkMessages = settings.value("checkMessages", false).toBool();
666    m_checkMessagesInterval = settings.value("checkMessagesInterval", 28).toInt();
667    settings.endGroup();
668    settings.beginGroup("Misc");
669    m_longList = settings.value("longList", false).toBool();
670    settings.endGroup();
671 }