]> git.sur5r.net Git - bacula/bacula/blob - bacula/src/qt-console/mainwin.cpp
Add preference to have the status dir screen auto refresh.
[bacula/bacula] / bacula / src / qt-console / mainwin.cpp
1 /*
2    Bacula® - The Network Backup Solution
3
4    Copyright (C) 2007-2008 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 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 #include "jobgraphs/jobplot.h"
53 #include "status/dirstat.h"
54
55 /* 
56  * Daemon message callback
57  */
58 void message_callback(int /* type */, char *msg)
59 {
60    QMessageBox::warning(mainWin, "Bat", msg, QMessageBox::Ok);
61 }
62
63 MainWin::MainWin(QWidget *parent) : QMainWindow(parent)
64 {
65    m_isClosing = false;
66    m_dtformat = "yyyy-MM-dd HH:mm:ss";
67    mainWin = this;
68    setupUi(this);                     /* Setup UI defined by main.ui (designer) */
69    register_message_callback(message_callback);
70    readPreferences();
71    treeWidget->clear();
72    treeWidget->setColumnCount(1);
73    treeWidget->setHeaderLabel("Select Page");
74    treeWidget->setContextMenuPolicy(Qt::ActionsContextMenu);
75
76    createPages();
77
78    resetFocus();
79
80    createConnections();
81
82    this->show();
83
84    readSettings();
85
86    foreach(Console *console, m_consoleHash) {
87       console->connect_dir();
88    }
89    m_currentConsole = (Console*)getFromHash(m_firstItem);
90    m_currentConsole->setCurrent();
91    if (m_miscDebug) {
92       QString directoryResourceName;
93       m_currentConsole->getDirResName(directoryResourceName);
94       Pmsg1(000, "Setting initial window to %s\n", directoryResourceName.toUtf8().data());
95    }
96 }
97
98 void MainWin::createPages()
99 {
100    DIRRES *dir;
101    QTreeWidgetItem *item, *topItem;
102    m_firstItem = NULL;
103
104    LockRes();
105    foreach_res(dir, R_DIRECTOR) {
106
107       /* Create console tree stacked widget item */
108       m_currentConsole = new Console(stackedWidget);
109       m_currentConsole->setDirRes(dir);
110       m_currentConsole->readSettings();
111
112       /* The top tree item representing the director */
113       topItem = new QTreeWidgetItem(treeWidget);
114       topItem->setText(0, dir->name());
115       topItem->setIcon(0, QIcon(":images/server.png"));
116       /* Set background to grey for ease of identification of inactive Director */
117       QBrush greyBrush(Qt::lightGray);
118       topItem->setBackground(0, greyBrush);
119       m_currentConsole->setDirectorTreeItem(topItem);
120       m_consoleHash.insert(topItem, m_currentConsole);
121
122       /* Create Tree Widget Item */
123       item = new QTreeWidgetItem(topItem);
124       item->setText(0, "Console");
125       if (!m_firstItem){ m_firstItem = item; }
126       item->setIcon(0,QIcon(QString::fromUtf8(":images/utilities-terminal.png")));
127
128       /* insert the cosole and tree widget item into the hashes */
129       hashInsert(item, m_currentConsole);
130
131       /* Set Color of treeWidgetItem for the console
132       * It will be set to green in the console class if the connection is made.
133       */
134       QBrush redBrush(Qt::red);
135       item->setForeground(0, redBrush);
136       m_currentConsole->dockPage();
137
138       /*
139        * Create instances in alphabetic order of the rest 
140        *  of the classes that will by default exist under each Director.  
141        */
142 //      new bRestore();
143       new Clients();
144       new FileSet();
145       new Jobs();
146       createPageJobList("", "", "", "", NULL);
147       JobPlotPass pass;
148       pass.use = false;
149       if (m_openPlot)
150          new JobPlot(NULL, pass);
151       new MediaList();
152       new Storage();
153       if (m_openBrowser)
154          new restoreTree();
155       if (m_openDirStat)
156          new DirStat();
157
158       treeWidget->expandItem(topItem);
159       stackedWidget->setCurrentWidget(m_currentConsole);
160    }
161    UnlockRes();
162 }
163
164 /*
165  * create an instance of the the joblist class on the stack
166  */
167 void MainWin::createPageJobList(const QString &media, const QString &client,
168               const QString &job, const QString &fileset, QTreeWidgetItem *parentTreeWidgetItem)
169 {
170    QTreeWidgetItem *holdItem;
171
172    /* save current tree widget item in case query produces no results */
173    holdItem = treeWidget->currentItem();
174    JobList* joblist = new JobList(media, client, job, fileset, parentTreeWidgetItem);
175    /* If this is a query of jobs on a specific media */
176    if ((media != "") || (client != "") || (job != "") || (fileset != "")) {
177       joblist->setCurrent();
178       /* did query produce results, if not close window and set back to hold */
179       if (joblist->m_resultCount == 0) {
180          joblist->closeStackPage();
181          treeWidget->setCurrentItem(holdItem);
182       }
183    }
184 }
185
186 /*
187  * Handle up and down arrow keys for the command line
188  *  history.
189  */
190 void MainWin::keyPressEvent(QKeyEvent *event)
191 {
192    if (m_cmd_history.size() == 0) {
193       event->ignore();
194       return;
195    }
196    switch (event->key()) {
197    case Qt::Key_Down:
198       if (m_cmd_last < 0 || m_cmd_last >= (m_cmd_history.size()-1)) {
199          event->ignore();
200          return;
201       }
202       m_cmd_last++;
203       break;
204    case Qt::Key_Up:
205       if (m_cmd_last == 0) {
206          event->ignore();
207          return;
208       }
209       if (m_cmd_last < 0 || m_cmd_last > (m_cmd_history.size()-1)) {
210          m_cmd_last = m_cmd_history.size() - 1;
211       } else {
212          m_cmd_last--;
213       }
214       break;
215    default:
216       event->ignore();
217       return;
218    }
219    lineEdit->setText(m_cmd_history[m_cmd_last]);
220 }
221
222 void MainWin::createConnections()
223 {
224    /* Connect signals to slots */
225    connect(lineEdit, SIGNAL(returnPressed()), this, SLOT(input_line()));
226    connect(actionAbout_bat, SIGNAL(triggered()), this, SLOT(about()));
227    connect(actionBat_Help, SIGNAL(triggered()), this, SLOT(help()));
228    connect(treeWidget, SIGNAL(itemClicked(QTreeWidgetItem *, int)), this, 
229            SLOT(treeItemClicked(QTreeWidgetItem *, int)));
230    connect(treeWidget, SIGNAL(
231            currentItemChanged(QTreeWidgetItem *, QTreeWidgetItem *)),
232            this, SLOT(treeItemChanged(QTreeWidgetItem *, QTreeWidgetItem *)));
233    connect(stackedWidget, SIGNAL(currentChanged(int)),
234            this, SLOT(stackItemChanged(int)));
235    connect(actionQuit, SIGNAL(triggered()), app, SLOT(closeAllWindows()));
236    connect(actionLabel, SIGNAL(triggered()), this,  SLOT(labelButtonClicked()));
237    connect(actionRun, SIGNAL(triggered()), this,  SLOT(runButtonClicked()));
238    connect(actionEstimate, SIGNAL(triggered()), this,  SLOT(estimateButtonClicked()));
239    connect(actionBrowse, SIGNAL(triggered()), this,  SLOT(browseButtonClicked()));
240    connect(actionStatusDirPage, SIGNAL(triggered()), this,  SLOT(statusPageButtonClicked()));
241    connect(actionJobPlot, SIGNAL(triggered()), this,  SLOT(jobPlotButtonClicked()));
242    connect(actionRestore, SIGNAL(triggered()), this,  SLOT(restoreButtonClicked()));
243    connect(actionUndock, SIGNAL(triggered()), this,  SLOT(undockWindowButton()));
244    connect(actionToggleDock, SIGNAL(triggered()), this,  SLOT(toggleDockContextWindow()));
245    connect(actionClosePage, SIGNAL(triggered()), this,  SLOT(closePage()));
246    connect(actionPreferences, SIGNAL(triggered()), this,  SLOT(setPreferences()));
247 }
248
249 /* 
250  * Reimplementation of QWidget closeEvent virtual function   
251  */
252 void MainWin::closeEvent(QCloseEvent *event)
253 {
254    m_isClosing = true;
255    writeSettings();
256    /* close all non console pages, this will call settings in destructors */
257    while (m_consoleHash.count() < m_pagehash.count()) {
258       foreach(Pages *page, m_pagehash) {
259          if (page !=  page->console()) {
260             QTreeWidgetItem* pageSelectorTreeWidgetItem = mainWin->getFromHash(page);
261             if (pageSelectorTreeWidgetItem->childCount() == 0) {
262                page->console()->setCurrent();
263                page->closeStackPage();
264             }
265          }
266       }
267    }
268    /* close the console pages and terminate connection */
269    foreach(Console *console, m_consoleHash){
270       console->writeSettings();
271       console->terminate();
272       console->closeStackPage();
273    }
274    event->accept();
275 }
276
277 void MainWin::writeSettings()
278 {
279    QSettings settings("bacula.org", "bat");
280
281    settings.beginGroup("MainWin");
282    settings.setValue("winSize", size());
283    settings.setValue("winPos", pos());
284    settings.setValue("state", saveState());
285    settings.endGroup();
286 }
287
288 void MainWin::readSettings()
289
290    QSettings settings("bacula.org", "bat");
291
292    settings.beginGroup("MainWin");
293    resize(settings.value("winSize", QSize(1041, 801)).toSize());
294    move(settings.value("winPos", QPoint(200, 150)).toPoint());
295    restoreState(settings.value("state").toByteArray());
296    settings.endGroup();
297 }
298
299 /*
300  * This subroutine is called with an item in the Page Selection window
301  *   is clicked 
302  */
303 void MainWin::treeItemClicked(QTreeWidgetItem *item, int /*column*/)
304 {
305    /* Is this a page that has been inserted into the hash  */
306    if (getFromHash(item)) {
307       Pages* page = getFromHash(item);
308       int stackindex=stackedWidget->indexOf(page);
309
310       if (stackindex >= 0) {
311          stackedWidget->setCurrentWidget(page);
312       }
313       /* run the virtual function in case this class overrides it */
314       page->PgSeltreeWidgetClicked();
315    }
316 }
317
318 /*
319  * Called with a change of the highlighed tree widget item in the page selector.
320  */
321 void MainWin::treeItemChanged(QTreeWidgetItem *currentitem, QTreeWidgetItem *previousitem)
322 {
323    if (m_isClosing) return; /* if closing the application, do nothing here */
324
325    Pages *previousPage, *nextPage;
326    Console *previousConsole = NULL;
327    Console *nextConsole;
328
329    /* remove all actions before adding actions appropriate for new page */
330    foreach(QAction* pageAction, treeWidget->actions()) {
331       treeWidget->removeAction(pageAction);
332    }
333
334    /* first determine the next item */
335
336    /* knowing the treeWidgetItem, get the page from the hash */
337    nextPage = getFromHash(currentitem);
338    nextConsole = m_consoleHash.value(currentitem);
339    /* Is this a page that has been inserted into the hash  */
340    if (nextPage) {
341       nextConsole = nextPage->console();
342       /* then is it a treeWidgetItem representing a director */
343    } else if (nextConsole) {
344       /* let the next page BE the console */
345       nextPage = nextConsole;
346    } else {
347       /* Should never get here */
348       nextPage = NULL;
349       nextConsole = NULL;
350    }
351           
352    /* The Previous item */
353
354    /* this condition prevents a segfault.  The first time there is no previousitem*/
355    if (previousitem) {
356       /* knowing the treeWidgetItem, get the page from the hash */
357       previousPage = getFromHash(previousitem);
358       previousConsole = m_consoleHash.value(previousitem);
359       if (previousPage) {
360          previousConsole = previousPage->console();
361       } else if (previousConsole) {
362          previousPage = previousConsole;
363       }
364       if ((previousPage) || (previousConsole)) {
365          if (nextConsole != previousConsole) {
366             /* remove connections to the current console */
367             disconnect(actionConnect, SIGNAL(triggered()), previousConsole, SLOT(connect_dir()));
368             disconnect(actionStatusDir, SIGNAL(triggered()), previousConsole, SLOT(status_dir()));
369             disconnect(actionMessages, SIGNAL(triggered()), previousConsole, SLOT(messages()));
370             disconnect(actionSelectFont, SIGNAL(triggered()), previousConsole, SLOT(set_font()));
371             QTreeWidgetItem *dirItem = previousConsole->directorTreeItem();
372             QBrush greyBrush(Qt::lightGray);
373             dirItem->setBackground(0, greyBrush);
374          }
375       }
376    }
377
378    /* process the current (next) item */
379    
380    if ((nextPage) || (nextConsole)) {
381       if (nextConsole != previousConsole) {
382          /* make connections to the current console */
383          m_currentConsole = nextConsole;
384          connect(actionConnect, SIGNAL(triggered()), m_currentConsole, SLOT(connect_dir()));
385          connect(actionSelectFont, SIGNAL(triggered()), m_currentConsole, SLOT(set_font()));
386          connect(actionStatusDir, SIGNAL(triggered()), m_currentConsole, SLOT(status_dir()));
387          connect(actionMessages, SIGNAL(triggered()), m_currentConsole, SLOT(messages()));
388          /* Set director's tree widget background to magenta for ease of identification */
389          QTreeWidgetItem *dirItem = m_currentConsole->directorTreeItem();
390          QBrush magentaBrush(Qt::magenta);
391          dirItem->setBackground(0, magentaBrush);
392       }
393       /* set the value for the currently active console */
394       int stackindex = stackedWidget->indexOf(nextPage);
395    
396       /* Is this page currently on the stack or is it undocked */
397       if (stackindex >= 0) {
398          /* put this page on the top of the stack */
399          stackedWidget->setCurrentIndex(stackindex);
400       } else {
401          /* it is undocked, raise it to the front */
402          nextPage->raise();
403       }
404       /* for the page selectors menu action to dock or undock, set the text */
405       nextPage->setContextMenuDockText();
406
407       treeWidget->addAction(actionToggleDock);
408       /* if this page is closeable, and it has no childern, then add that action */
409       if ((nextPage->isCloseable()) && (currentitem->child(0) == NULL))
410          treeWidget->addAction(actionClosePage);
411
412       /* Add the actions to the Page Selectors tree widget that are part of the
413        * current items list of desired actions regardless of whether on top of stack*/
414       treeWidget->addActions(nextPage->m_contextActions);
415    }
416 }
417
418 void MainWin::labelButtonClicked() 
419 {
420    new labelPage();
421 }
422
423 void MainWin::runButtonClicked() 
424 {
425    new runPage("");
426 }
427
428 void MainWin::estimateButtonClicked() 
429 {
430    new estimatePage();
431 }
432
433 void MainWin::browseButtonClicked() 
434 {
435    new restoreTree();
436 }
437
438 void MainWin::statusPageButtonClicked()
439 {
440    /* if one exists, then just set it current */
441    bool found = false;
442    foreach(Pages *page, m_pagehash) {
443       if (m_currentConsole == page->console()) {
444          if (page->name() == "Director Status") {
445             found = true;
446             page->setCurrent();
447          }
448       }
449    }
450    if (!found)
451       new DirStat();
452 }
453
454 void MainWin::restoreButtonClicked() 
455 {
456    new prerestorePage();
457 }
458
459 void MainWin::jobPlotButtonClicked()
460 {
461    JobPlotPass pass;
462    pass.use = false;
463    new JobPlot(NULL, pass);
464 }
465
466 /*
467  * The user just finished typing a line in the command line edit box
468  */
469 void MainWin::input_line()
470 {
471    QString cmdStr = lineEdit->text();    /* Get the text */
472    lineEdit->clear();                    /* clear the lineEdit box */
473    if (m_currentConsole->is_connected()) {
474       /* Use consoleInput to allow typing anything */
475       m_currentConsole->consoleInput(cmdStr);
476    } else {
477       set_status(tr("Director not connected. Click on connect button."));
478    }
479    m_cmd_history.append(cmdStr);
480    m_cmd_last = -1;
481    if (treeWidget->currentItem() != getFromHash(m_currentConsole))
482       m_currentConsole->setCurrent();
483 }
484
485
486 void MainWin::about()
487 {
488    QMessageBox::about(this, tr("About bat"),
489       tr("<br><h2>bat 1.0, by Dirk H Bartley and Kern Sibbald</h2>"
490          "<p>Copyright &copy; 2007-" BYEAR " Free Software Foundation Europe e.V."
491          "<p>The <b>bat</b> is an administrative console"
492          " interface to the Director."));
493 }
494
495 void MainWin::help()
496 {
497    Help::displayFile("index.html");
498 }
499
500 void MainWin::set_statusf(const char *fmt, ...)
501 {
502    va_list arg_ptr;
503    char buf[1000];
504    int len;
505    va_start(arg_ptr, fmt);
506    len = bvsnprintf(buf, sizeof(buf), fmt, arg_ptr);
507    va_end(arg_ptr);
508    set_status(buf);
509 }
510
511 void MainWin::set_status_ready()
512 {
513    set_status(tr(" Ready"));
514 }
515
516 void MainWin::set_status(const QString &str)
517 {
518    statusBar()->showMessage(str);
519 }
520
521 void MainWin::set_status(const char *buf)
522 {
523    statusBar()->showMessage(buf);
524 }
525
526 /*
527  * Function to respond to the button bar button to undock
528  */
529 void MainWin::undockWindowButton()
530 {
531    Pages* page = (Pages*)stackedWidget->currentWidget();
532    page->togglePageDocking();
533 }
534
535 /*
536  * Function to respond to action on page selector context menu to toggle the 
537  * dock status of the window associated with the page selectors current
538  * tree widget item.
539  */
540 void MainWin::toggleDockContextWindow()
541 {
542    QTreeWidgetItem *currentitem = treeWidget->currentItem();
543    
544    /* Is this a page that has been inserted into the hash  */
545    if (getFromHash(currentitem)) {
546       Pages* page = getFromHash(currentitem);
547       page->togglePageDocking();
548    }
549 }
550
551 /*
552  * This function is called when the stack item is changed.  Call
553  * the virtual function here.  Avoids a window being undocked leaving
554  * a window at the top of the stack unpopulated.
555  */
556 void MainWin::stackItemChanged(int)
557 {
558    if (m_isClosing) return; /* if closing the application, do nothing here */
559    Pages* page = (Pages*)stackedWidget->currentWidget();
560    /* run the virtual function in case this class overrides it */
561    page->currentStackItem();
562 }
563
564 /*
565  * Function to simplify insertion of QTreeWidgetItem <-> Page association
566  * into a double direction hash.
567  */
568 void MainWin::hashInsert(QTreeWidgetItem *item, Pages *page)
569 {
570    m_pagehash.insert(item, page);
571    m_widgethash.insert(page, item);
572 }
573
574 /*
575  * Function to simplify removal of QTreeWidgetItem <-> Page association
576  * into a double direction hash.
577  */
578 void MainWin::hashRemove(QTreeWidgetItem *item, Pages *page)
579 {
580    /* I had all sorts of return status checking code here.  Do we have a log
581     * level capability in bat.  I would have left it in but it used printf's
582     * and it should really be some kind of log level facility ???
583     * ******FIXME********/
584    m_pagehash.remove(item);
585    m_widgethash.remove(page);
586 }
587
588 /*
589  * Function to retrieve a Page* when the item in the page selector's tree is
590  * known.
591  */
592 Pages* MainWin::getFromHash(QTreeWidgetItem *item)
593 {
594    return m_pagehash.value(item);
595 }
596
597 /*
598  * Function to retrieve the page selectors tree widget item when the page is
599  * known.
600  */
601 QTreeWidgetItem* MainWin::getFromHash(Pages *page)
602 {
603    return m_widgethash.value(page);
604 }
605
606 /*
607  * Function to respond to action on page selector context menu to close the
608  * current window.
609  */
610 void MainWin::closePage()
611 {
612    QTreeWidgetItem *currentitem = treeWidget->currentItem();
613    
614    /* Is this a page that has been inserted into the hash  */
615    if (getFromHash(currentitem)) {
616       Pages* page = getFromHash(currentitem);
617       if (page->isCloseable()) {
618          page->closeStackPage();
619       }
620    }
621 }
622
623 /* Quick function to return the current console */
624 Console *MainWin::currentConsole()
625 {
626    return m_currentConsole;
627 }
628 /* Quick function to return the tree item for the director */
629 QTreeWidgetItem *MainWin::currentTopItem()
630 {
631    return m_currentConsole->directorTreeItem();
632 }
633
634 /* Preferences menu item clicked */
635 void MainWin::setPreferences()
636 {
637    prefsDialog prefs;
638    prefs.commDebug->setCheckState(m_commDebug ? Qt::Checked : Qt::Unchecked);
639    prefs.displayAll->setCheckState(m_displayAll ? Qt::Checked : Qt::Unchecked);
640    prefs.sqlDebug->setCheckState(m_sqlDebug ? Qt::Checked : Qt::Unchecked);
641    prefs.commandDebug->setCheckState(m_commandDebug ? Qt::Checked : Qt::Unchecked);
642    prefs.miscDebug->setCheckState(m_miscDebug ? Qt::Checked : Qt::Unchecked);
643    prefs.recordLimit->setCheckState(m_recordLimitCheck ? Qt::Checked : Qt::Unchecked);
644    prefs.recordSpinBox->setValue(m_recordLimitVal);
645    prefs.daysLimit->setCheckState(m_daysLimitCheck ? Qt::Checked : Qt::Unchecked);
646    prefs.daysSpinBox->setValue(m_daysLimitVal);
647    prefs.checkMessages->setCheckState(m_checkMessages ? Qt::Checked : Qt::Unchecked);
648    prefs.checkMessagesSpin->setValue(m_checkMessagesInterval);
649    prefs.refreshStatusDir->setCheckState(m_refreshStatusDir ? Qt::Checked : Qt::Unchecked);
650    prefs.refreshStatusDirSpin->setValue(m_refreshStatusDirInterval);
651    prefs.executeLongCheckBox->setCheckState(m_longList ? Qt::Checked : Qt::Unchecked);
652    prefs.rtPopDirCheckBox->setCheckState(m_rtPopDirDebug ? Qt::Checked : Qt::Unchecked);
653    prefs.rtDirCurICCheckBox->setCheckState(m_rtDirCurICDebug ? Qt::Checked : Qt::Unchecked);
654    prefs.rtDirICCheckBox->setCheckState(m_rtDirICDebug ? Qt::Checked : Qt::Unchecked);
655    prefs.rtFileTabICCheckBox->setCheckState(m_rtFileTabICDebug ? Qt::Checked : Qt::Unchecked);
656    prefs.rtVerTabICCheckBox->setCheckState(m_rtVerTabICDebug ? Qt::Checked : Qt::Unchecked);
657    prefs.rtUpdateFTCheckBox->setCheckState(m_rtUpdateFTDebug ? Qt::Checked : Qt::Unchecked);
658    prefs.rtUpdateVTCheckBox->setCheckState(m_rtUpdateVTDebug ? Qt::Checked : Qt::Unchecked);
659    prefs.rtChecksCheckBox->setCheckState(m_rtChecksDebug ? Qt::Checked : Qt::Unchecked);
660    prefs.rtIconStateCheckBox->setCheckState(m_rtIconStateDebug ? Qt::Checked : Qt::Unchecked);
661    prefs.rtRestore1CheckBox->setCheckState(m_rtRestore1Debug ? Qt::Checked : Qt::Unchecked);
662    prefs.rtRestore2CheckBox->setCheckState(m_rtRestore2Debug ? Qt::Checked : Qt::Unchecked);
663    prefs.rtRestore3CheckBox->setCheckState(m_rtRestore3Debug ? Qt::Checked : Qt::Unchecked);
664    if (m_radioConvert == 0) {
665       prefs.radioConvertOff->setChecked(Qt::Checked);
666    } else if (m_radioConvert == 1){
667       prefs.radioConvertIEC->setChecked(Qt::Checked);
668    } else {
669       m_radioConvert = 2;
670       prefs.radioConvertStandard->setChecked(Qt::Checked);
671    }
672    prefs.openPlotCheckBox->setCheckState(m_openPlot ? Qt::Checked : Qt::Unchecked);
673    prefs.openBrowserCheckBox->setCheckState(m_openBrowser ? Qt::Checked : Qt::Unchecked);
674    prefs.openDirStatCheckBox->setCheckState(m_openDirStat ? Qt::Checked : Qt::Unchecked);
675    prefs.exec();
676 }
677
678 /* Preferences dialog */
679 prefsDialog::prefsDialog()
680 {
681    setupUi(this);
682 }
683
684 void prefsDialog::accept()
685 {
686    this->hide();
687    mainWin->m_commDebug = this->commDebug->checkState() == Qt::Checked;
688    mainWin->m_displayAll = this->displayAll->checkState() == Qt::Checked;
689    mainWin->m_sqlDebug = this->sqlDebug->checkState() == Qt::Checked;
690    mainWin->m_commandDebug = this->commandDebug->checkState() == Qt::Checked;
691    mainWin->m_miscDebug = this->miscDebug->checkState() == Qt::Checked;
692    mainWin->m_recordLimitCheck = this->recordLimit->checkState() == Qt::Checked;
693    mainWin->m_recordLimitVal = this->recordSpinBox->value();
694    mainWin->m_daysLimitCheck = this->daysLimit->checkState() == Qt::Checked;
695    mainWin->m_daysLimitVal = this->daysSpinBox->value();
696    mainWin->m_checkMessages = this->checkMessages->checkState() == Qt::Checked;
697    mainWin->m_checkMessagesInterval = this->checkMessagesSpin->value();
698    mainWin->m_refreshStatusDir = this->refreshStatusDir->checkState() == Qt::Checked;
699    mainWin->m_refreshStatusDirInterval = this->refreshStatusDirSpin->value();
700    mainWin->m_longList = this->executeLongCheckBox->checkState() == Qt::Checked;
701
702    mainWin->m_rtPopDirDebug = this->rtPopDirCheckBox->checkState() == Qt::Checked;
703    mainWin->m_rtDirCurICDebug = this->rtDirCurICCheckBox->checkState() == Qt::Checked;
704    mainWin->m_rtDirICDebug = this->rtDirICCheckBox->checkState() == Qt::Checked;
705    mainWin->m_rtFileTabICDebug = this->rtFileTabICCheckBox->checkState() == Qt::Checked;
706    mainWin->m_rtVerTabICDebug = this->rtVerTabICCheckBox->checkState() == Qt::Checked;
707    mainWin->m_rtUpdateFTDebug = this->rtUpdateFTCheckBox->checkState() == Qt::Checked;
708    mainWin->m_rtUpdateVTDebug = this->rtUpdateVTCheckBox->checkState() == Qt::Checked;
709    mainWin->m_rtChecksDebug = this->rtChecksCheckBox->checkState() == Qt::Checked;
710    mainWin->m_rtIconStateDebug = this->rtIconStateCheckBox->checkState() == Qt::Checked;
711    mainWin->m_rtRestore1Debug = this->rtRestore1CheckBox->checkState() == Qt::Checked;
712    mainWin->m_rtRestore2Debug = this->rtRestore2CheckBox->checkState() == Qt::Checked;
713    mainWin->m_rtRestore3Debug = this->rtRestore3CheckBox->checkState() == Qt::Checked;
714    if (this->radioConvertOff->isChecked()) {
715       mainWin->m_radioConvert = 0;
716    } else if (this->radioConvertIEC->isChecked()){
717       mainWin->m_radioConvert = 1;
718    } else {
719       mainWin->m_radioConvert = 2;
720    }
721    mainWin->m_openPlot = this->openPlotCheckBox->checkState() == Qt::Checked;
722    mainWin->m_openBrowser = this->openBrowserCheckBox->checkState() == Qt::Checked;
723    mainWin->m_openDirStat = this->openDirStatCheckBox->checkState() == Qt::Checked;
724
725    QSettings settings("www.bacula.org", "bat");
726    settings.beginGroup("Debug");
727    settings.setValue("commDebug", mainWin->m_commDebug);
728    settings.setValue("displayAll", mainWin->m_displayAll);
729    settings.setValue("sqlDebug", mainWin->m_sqlDebug);
730    settings.setValue("commandDebug", mainWin->m_commandDebug);
731    settings.setValue("miscDebug", mainWin->m_miscDebug);
732    settings.endGroup();
733    settings.beginGroup("JobList");
734    settings.setValue("recordLimitCheck", mainWin->m_recordLimitCheck);
735    settings.setValue("recordLimitVal", mainWin->m_recordLimitVal);
736    settings.setValue("daysLimitCheck", mainWin->m_daysLimitCheck);
737    settings.setValue("daysLimitVal", mainWin->m_daysLimitVal);
738    settings.endGroup();
739    settings.beginGroup("Timers");
740    settings.setValue("checkMessages", mainWin->m_checkMessages);
741    settings.setValue("checkMessagesInterval", mainWin->m_checkMessagesInterval);
742    settings.setValue("refreshStatusDir", mainWin->m_refreshStatusDir);
743    settings.setValue("refreshStatusDirInterval", mainWin->m_refreshStatusDirInterval);
744    settings.endGroup();
745    settings.beginGroup("Misc");
746    settings.setValue("longList", mainWin->m_longList);
747    settings.setValue("byteConvert", mainWin->m_radioConvert);
748    settings.setValue("openplot", mainWin->m_openPlot);
749    settings.setValue("openbrowser", mainWin->m_openBrowser);
750    settings.setValue("opendirstat", mainWin->m_openDirStat);
751    settings.endGroup();
752    settings.beginGroup("RestoreTree");
753    settings.setValue("rtPopDirDebug", mainWin->m_rtPopDirDebug);
754    settings.setValue("rtDirCurICDebug", mainWin->m_rtDirCurICDebug);
755    settings.setValue("rtDirCurICRetDebug", mainWin->m_rtDirICDebug);
756    settings.setValue("rtFileTabICDebug", mainWin->m_rtFileTabICDebug);
757    settings.setValue("rtVerTabICDebug", mainWin->m_rtVerTabICDebug);
758    settings.setValue("rtUpdateFTDebug", mainWin->m_rtUpdateFTDebug);
759    settings.setValue("rtUpdateVTDebug", mainWin->m_rtUpdateVTDebug);
760    settings.setValue("rtChecksDebug", mainWin->m_rtChecksDebug);
761    settings.setValue("rtIconStateDebug", mainWin->m_rtIconStateDebug);
762    settings.setValue("rtRestore1Debug", mainWin->m_rtRestore1Debug);
763    settings.setValue("rtRestore2Debug", mainWin->m_rtRestore2Debug);
764    settings.setValue("rtRestore3Debug", mainWin->m_rtRestore3Debug);
765    settings.endGroup();
766    foreach(Console *console, mainWin->m_consoleHash) {
767       console->startTimer();
768    }
769 }
770
771 void prefsDialog::reject()
772 {
773    this->hide();
774    mainWin->set_status(tr("Canceled"));
775 }
776
777 /* read preferences for the prefences dialog box */
778 void MainWin::readPreferences()
779 {
780    QSettings settings("www.bacula.org", "bat");
781    settings.beginGroup("Debug");
782    m_commDebug = settings.value("commDebug", false).toBool();
783    m_displayAll = settings.value("displayAll", false).toBool();
784    m_sqlDebug = settings.value("sqlDebug", false).toBool();
785    m_commandDebug = settings.value("commandDebug", false).toBool();
786    m_miscDebug = settings.value("miscDebug", false).toBool();
787    settings.endGroup();
788    settings.beginGroup("JobList");
789    m_recordLimitCheck = settings.value("recordLimitCheck", true).toBool();
790    m_recordLimitVal = settings.value("recordLimitVal", 150).toInt();
791    m_daysLimitCheck = settings.value("daysLimitCheck", false).toBool();
792    m_daysLimitVal = settings.value("daysLimitVal", 28).toInt();
793    settings.endGroup();
794    settings.beginGroup("Timers");
795    m_checkMessages = settings.value("checkMessages", false).toBool();
796    m_checkMessagesInterval = settings.value("checkMessagesInterval", 28).toInt();
797    m_refreshStatusDir = settings.value("refreshStatusDir", false).toBool();
798    m_refreshStatusDirInterval = settings.value("refreshStatusDirInterval", 28).toInt();
799    settings.endGroup();
800    settings.beginGroup("Misc");
801    m_longList = settings.value("longList", false).toBool();
802    m_radioConvert = settings.value("byteConvert", false).toInt();
803    m_openPlot = settings.value("openplot", false).toBool();
804    m_openBrowser = settings.value("openbrowser", false).toBool();
805    m_openDirStat = settings.value("opendirstat", false).toBool();
806    settings.endGroup();
807    settings.beginGroup("RestoreTree");
808    m_rtPopDirDebug = settings.value("rtPopDirDebug", false).toBool();
809    m_rtDirCurICDebug = settings.value("rtDirCurICDebug", false).toBool();
810    m_rtDirICDebug = settings.value("rtDirCurICRetDebug", false).toBool();
811    m_rtFileTabICDebug = settings.value("rtFileTabICDebug", false).toBool();
812    m_rtVerTabICDebug = settings.value("rtVerTabICDebug", false).toBool();
813    m_rtUpdateFTDebug = settings.value("rtUpdateFTDebug", false).toBool();
814    m_rtUpdateVTDebug = settings.value("rtUpdateVTDebug", false).toBool();
815    m_rtChecksDebug = settings.value("rtChecksDebug", false).toBool();
816    m_rtIconStateDebug = settings.value("rtIconStateDebug", false).toBool();
817    m_rtRestore1Debug = settings.value("rtRestore1Debug", false).toBool();
818    m_rtRestore2Debug = settings.value("rtRestore2Debug", false).toBool();
819    m_rtRestore3Debug = settings.value("rtRestore3Debug", false).toBool();
820    settings.endGroup();
821 }
822
823 void MainWin::hrConvert(QString &ret, qlonglong &inval)
824 {
825    double net = 0;
826    qlonglong base;
827    QStringList suflist;
828
829    if (m_radioConvert == 0) {
830       ret =  QString("%1").arg(inval);
831       return;
832    } else if (m_radioConvert == 1){
833       base = 1000;
834       suflist = (QStringList() << "B" << "KiB" << "MiB" << "GiB" << "TiB" << "PiB" << "EiB" << "ZiB");
835    } else {
836       base = 1024;
837       suflist = (QStringList() << "B" << "KB" << "MB" << "GB" << "TB" << "PB" << "EB" << "ZB");
838    }
839    qlonglong running = base;
840    bool done = false;
841    int count = 1;
842    while (done == false) {
843       QString test1 =  QString("%1").arg(inval);
844       QString test2 =  QString("%1").arg(running);
845       if (float(inval) < (float)(running)) {
846          done = true;
847          ret = suflist[count - 1];
848          net = (float)inval / (float)(running/base);
849       }
850       count += 1;
851       if (count > suflist.count()) done = true;
852       running *= base;
853    }
854    char format = 'f';
855    if (net != 0)
856       ret =  QString("%1 %2")
857                   .arg(net, 0, format, 2, QLatin1Char(' '))
858                   .arg(ret);
859    else ret = "0 B";
860 }
861
862 void MainWin::hrConvertSeconds(QString &ret, qlonglong &inval)
863 {
864    double net = 0;
865    QList<qlonglong> durations;
866    durations.append(1);
867    durations.append(60);
868    durations.append(3600);
869    durations.append(86400);
870    durations.append(2592000);
871    durations.append(31536000);
872    QStringList abbrlist = (QStringList() << "Sec" << "Min" << "Hrs" << "Days" << "Mnth" << "Yrs");
873    bool done = false;
874    int count = 1;
875    while (done == false) {
876       QString test1 =  QString("%1").arg(inval);
877       QString test2 =  QString("%1").arg(durations[count]);
878       if ((inval < durations[count]) || (count >= abbrlist.count() - 1)) { 
879          done = true;
880          net = (float)inval / (float)(durations[count - 1]);
881          if (net != 0)
882             ret =  QString("%1 %2")
883                   .arg(net, 0, 'f', 2, QLatin1Char(' '))
884                   .arg(abbrlist[count - 1]);
885          else ret = "0 S";
886       }
887       count += 1;
888    }
889 }