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