]> git.sur5r.net Git - bacula/bacula/blob - bacula/src/qt-console/mainwin.cpp
c81f286e505cae359c4d501def3911ff68b17fe9
[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("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; " 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(" Ready");
514 }
515
516 void MainWin::set_status(const char *buf)
517 {
518    statusBar()->showMessage(buf);
519 }
520
521 /*
522  * Function to respond to the button bar button to undock
523  */
524 void MainWin::undockWindowButton()
525 {
526    Pages* page = (Pages*)stackedWidget->currentWidget();
527    page->togglePageDocking();
528 }
529
530 /*
531  * Function to respond to action on page selector context menu to toggle the 
532  * dock status of the window associated with the page selectors current
533  * tree widget item.
534  */
535 void MainWin::toggleDockContextWindow()
536 {
537    QTreeWidgetItem *currentitem = treeWidget->currentItem();
538    
539    /* Is this a page that has been inserted into the hash  */
540    if (getFromHash(currentitem)) {
541       Pages* page = getFromHash(currentitem);
542       page->togglePageDocking();
543    }
544 }
545
546 /*
547  * This function is called when the stack item is changed.  Call
548  * the virtual function here.  Avoids a window being undocked leaving
549  * a window at the top of the stack unpopulated.
550  */
551 void MainWin::stackItemChanged(int)
552 {
553    if (m_isClosing) return; /* if closing the application, do nothing here */
554    Pages* page = (Pages*)stackedWidget->currentWidget();
555    /* run the virtual function in case this class overrides it */
556    page->currentStackItem();
557 }
558
559 /*
560  * Function to simplify insertion of QTreeWidgetItem <-> Page association
561  * into a double direction hash.
562  */
563 void MainWin::hashInsert(QTreeWidgetItem *item, Pages *page)
564 {
565    m_pagehash.insert(item, page);
566    m_widgethash.insert(page, item);
567 }
568
569 /*
570  * Function to simplify removal of QTreeWidgetItem <-> Page association
571  * into a double direction hash.
572  */
573 void MainWin::hashRemove(QTreeWidgetItem *item, Pages *page)
574 {
575    /* I had all sorts of return status checking code here.  Do we have a log
576     * level capability in bat.  I would have left it in but it used printf's
577     * and it should really be some kind of log level facility ???
578     * ******FIXME********/
579    m_pagehash.remove(item);
580    m_widgethash.remove(page);
581 }
582
583 /*
584  * Function to retrieve a Page* when the item in the page selector's tree is
585  * known.
586  */
587 Pages* MainWin::getFromHash(QTreeWidgetItem *item)
588 {
589    return m_pagehash.value(item);
590 }
591
592 /*
593  * Function to retrieve the page selectors tree widget item when the page is
594  * known.
595  */
596 QTreeWidgetItem* MainWin::getFromHash(Pages *page)
597 {
598    return m_widgethash.value(page);
599 }
600
601 /*
602  * Function to respond to action on page selector context menu to close the
603  * current window.
604  */
605 void MainWin::closePage()
606 {
607    QTreeWidgetItem *currentitem = treeWidget->currentItem();
608    
609    /* Is this a page that has been inserted into the hash  */
610    if (getFromHash(currentitem)) {
611       Pages* page = getFromHash(currentitem);
612       if (page->isCloseable()) {
613          page->closeStackPage();
614       }
615    }
616 }
617
618 /* Quick function to return the current console */
619 Console *MainWin::currentConsole()
620 {
621    return m_currentConsole;
622 }
623 /* Quick function to return the tree item for the director */
624 QTreeWidgetItem *MainWin::currentTopItem()
625 {
626    return m_currentConsole->directorTreeItem();
627 }
628
629 /* Preferences menu item clicked */
630 void MainWin::setPreferences()
631 {
632    prefsDialog prefs;
633    prefs.commDebug->setCheckState(m_commDebug ? Qt::Checked : Qt::Unchecked);
634    prefs.displayAll->setCheckState(m_displayAll ? Qt::Checked : Qt::Unchecked);
635    prefs.sqlDebug->setCheckState(m_sqlDebug ? Qt::Checked : Qt::Unchecked);
636    prefs.commandDebug->setCheckState(m_commandDebug ? Qt::Checked : Qt::Unchecked);
637    prefs.miscDebug->setCheckState(m_miscDebug ? Qt::Checked : Qt::Unchecked);
638    prefs.recordLimit->setCheckState(m_recordLimitCheck ? Qt::Checked : Qt::Unchecked);
639    prefs.recordSpinBox->setValue(m_recordLimitVal);
640    prefs.daysLimit->setCheckState(m_daysLimitCheck ? Qt::Checked : Qt::Unchecked);
641    prefs.daysSpinBox->setValue(m_daysLimitVal);
642    prefs.checkMessages->setCheckState(m_checkMessages ? Qt::Checked : Qt::Unchecked);
643    prefs.checkMessagesSpin->setValue(m_checkMessagesInterval);
644    prefs.executeLongCheckBox->setCheckState(m_longList ? Qt::Checked : Qt::Unchecked);
645    prefs.rtPopDirCheckBox->setCheckState(m_rtPopDirDebug ? Qt::Checked : Qt::Unchecked);
646    prefs.rtDirCurICCheckBox->setCheckState(m_rtDirCurICDebug ? Qt::Checked : Qt::Unchecked);
647    prefs.rtDirICCheckBox->setCheckState(m_rtDirICDebug ? Qt::Checked : Qt::Unchecked);
648    prefs.rtFileTabICCheckBox->setCheckState(m_rtFileTabICDebug ? Qt::Checked : Qt::Unchecked);
649    prefs.rtVerTabICCheckBox->setCheckState(m_rtVerTabICDebug ? Qt::Checked : Qt::Unchecked);
650    prefs.rtUpdateFTCheckBox->setCheckState(m_rtUpdateFTDebug ? Qt::Checked : Qt::Unchecked);
651    prefs.rtUpdateVTCheckBox->setCheckState(m_rtUpdateVTDebug ? Qt::Checked : Qt::Unchecked);
652    prefs.rtChecksCheckBox->setCheckState(m_rtChecksDebug ? Qt::Checked : Qt::Unchecked);
653    prefs.rtIconStateCheckBox->setCheckState(m_rtIconStateDebug ? Qt::Checked : Qt::Unchecked);
654    prefs.rtRestore1CheckBox->setCheckState(m_rtRestore1Debug ? Qt::Checked : Qt::Unchecked);
655    prefs.rtRestore2CheckBox->setCheckState(m_rtRestore2Debug ? Qt::Checked : Qt::Unchecked);
656    prefs.rtRestore3CheckBox->setCheckState(m_rtRestore3Debug ? Qt::Checked : Qt::Unchecked);
657    if (m_radioConvert == 0) {
658       prefs.radioConvertOff->setChecked(Qt::Checked);
659    } else if (m_radioConvert == 1){
660       prefs.radioConvertIEC->setChecked(Qt::Checked);
661    } else {
662       m_radioConvert = 2;
663       prefs.radioConvertStandard->setChecked(Qt::Checked);
664    }
665    prefs.openPlotCheckBox->setCheckState(m_openPlot ? Qt::Checked : Qt::Unchecked);
666    prefs.openBrowserCheckBox->setCheckState(m_openBrowser ? Qt::Checked : Qt::Unchecked);
667    prefs.openDirStatCheckBox->setCheckState(m_openDirStat ? Qt::Checked : Qt::Unchecked);
668    prefs.exec();
669 }
670
671 /* Preferences dialog */
672 prefsDialog::prefsDialog()
673 {
674    setupUi(this);
675 }
676
677 void prefsDialog::accept()
678 {
679    this->hide();
680    mainWin->m_commDebug = this->commDebug->checkState() == Qt::Checked;
681    mainWin->m_displayAll = this->displayAll->checkState() == Qt::Checked;
682    mainWin->m_sqlDebug = this->sqlDebug->checkState() == Qt::Checked;
683    mainWin->m_commandDebug = this->commandDebug->checkState() == Qt::Checked;
684    mainWin->m_miscDebug = this->miscDebug->checkState() == Qt::Checked;
685    mainWin->m_recordLimitCheck = this->recordLimit->checkState() == Qt::Checked;
686    mainWin->m_recordLimitVal = this->recordSpinBox->value();
687    mainWin->m_daysLimitCheck = this->daysLimit->checkState() == Qt::Checked;
688    mainWin->m_daysLimitVal = this->daysSpinBox->value();
689    mainWin->m_checkMessages = this->checkMessages->checkState() == Qt::Checked;
690    mainWin->m_checkMessagesInterval = this->checkMessagesSpin->value();
691    mainWin->m_longList = this->executeLongCheckBox->checkState() == Qt::Checked;
692
693    mainWin->m_rtPopDirDebug = this->rtPopDirCheckBox->checkState() == Qt::Checked;
694    mainWin->m_rtDirCurICDebug = this->rtDirCurICCheckBox->checkState() == Qt::Checked;
695    mainWin->m_rtDirICDebug = this->rtDirICCheckBox->checkState() == Qt::Checked;
696    mainWin->m_rtFileTabICDebug = this->rtFileTabICCheckBox->checkState() == Qt::Checked;
697    mainWin->m_rtVerTabICDebug = this->rtVerTabICCheckBox->checkState() == Qt::Checked;
698    mainWin->m_rtUpdateFTDebug = this->rtUpdateFTCheckBox->checkState() == Qt::Checked;
699    mainWin->m_rtUpdateVTDebug = this->rtUpdateVTCheckBox->checkState() == Qt::Checked;
700    mainWin->m_rtChecksDebug = this->rtChecksCheckBox->checkState() == Qt::Checked;
701    mainWin->m_rtIconStateDebug = this->rtIconStateCheckBox->checkState() == Qt::Checked;
702    mainWin->m_rtRestore1Debug = this->rtRestore1CheckBox->checkState() == Qt::Checked;
703    mainWin->m_rtRestore2Debug = this->rtRestore2CheckBox->checkState() == Qt::Checked;
704    mainWin->m_rtRestore3Debug = this->rtRestore3CheckBox->checkState() == Qt::Checked;
705    if (this->radioConvertOff->isChecked()) {
706       mainWin->m_radioConvert = 0;
707    } else if (this->radioConvertIEC->isChecked()){
708       mainWin->m_radioConvert = 1;
709    } else {
710       mainWin->m_radioConvert = 2;
711    }
712    mainWin->m_openPlot = this->openPlotCheckBox->checkState() == Qt::Checked;
713    mainWin->m_openBrowser = this->openBrowserCheckBox->checkState() == Qt::Checked;
714    mainWin->m_openDirStat = this->openDirStatCheckBox->checkState() == Qt::Checked;
715
716    QSettings settings("www.bacula.org", "bat");
717    settings.beginGroup("Debug");
718    settings.setValue("commDebug", mainWin->m_commDebug);
719    settings.setValue("displayAll", mainWin->m_displayAll);
720    settings.setValue("sqlDebug", mainWin->m_sqlDebug);
721    settings.setValue("commandDebug", mainWin->m_commandDebug);
722    settings.setValue("miscDebug", mainWin->m_miscDebug);
723    settings.endGroup();
724    settings.beginGroup("JobList");
725    settings.setValue("recordLimitCheck", mainWin->m_recordLimitCheck);
726    settings.setValue("recordLimitVal", mainWin->m_recordLimitVal);
727    settings.setValue("daysLimitCheck", mainWin->m_daysLimitCheck);
728    settings.setValue("daysLimitVal", mainWin->m_daysLimitVal);
729    settings.endGroup();
730    settings.beginGroup("Messages");
731    settings.setValue("checkMessages", mainWin->m_checkMessages);
732    settings.setValue("checkMessagesInterval", mainWin->m_checkMessagesInterval);
733    settings.endGroup();
734    settings.beginGroup("Misc");
735    settings.setValue("longList", mainWin->m_longList);
736    settings.setValue("byteConvert", mainWin->m_radioConvert);
737    settings.setValue("openplot", mainWin->m_openPlot);
738    settings.setValue("openbrowser", mainWin->m_openBrowser);
739    settings.setValue("opendirstat", mainWin->m_openDirStat);
740    settings.endGroup();
741    settings.beginGroup("RestoreTree");
742    settings.setValue("rtPopDirDebug", mainWin->m_rtPopDirDebug);
743    settings.setValue("rtDirCurICDebug", mainWin->m_rtDirCurICDebug);
744    settings.setValue("rtDirCurICRetDebug", mainWin->m_rtDirICDebug);
745    settings.setValue("rtFileTabICDebug", mainWin->m_rtFileTabICDebug);
746    settings.setValue("rtVerTabICDebug", mainWin->m_rtVerTabICDebug);
747    settings.setValue("rtUpdateFTDebug", mainWin->m_rtUpdateFTDebug);
748    settings.setValue("rtUpdateVTDebug", mainWin->m_rtUpdateVTDebug);
749    settings.setValue("rtChecksDebug", mainWin->m_rtChecksDebug);
750    settings.setValue("rtIconStateDebug", mainWin->m_rtIconStateDebug);
751    settings.setValue("rtRestore1Debug", mainWin->m_rtRestore1Debug);
752    settings.setValue("rtRestore2Debug", mainWin->m_rtRestore2Debug);
753    settings.setValue("rtRestore3Debug", mainWin->m_rtRestore3Debug);
754    settings.endGroup();
755    foreach(Console *console, mainWin->m_consoleHash) {
756       console->startTimer();
757    }
758 }
759
760 void prefsDialog::reject()
761 {
762    this->hide();
763    mainWin->set_status("Canceled");
764 }
765
766 /* read preferences for the prefences dialog box */
767 void MainWin::readPreferences()
768 {
769    QSettings settings("www.bacula.org", "bat");
770    settings.beginGroup("Debug");
771    m_commDebug = settings.value("commDebug", false).toBool();
772    m_displayAll = settings.value("displayAll", false).toBool();
773    m_sqlDebug = settings.value("sqlDebug", false).toBool();
774    m_commandDebug = settings.value("commandDebug", false).toBool();
775    m_miscDebug = settings.value("miscDebug", false).toBool();
776    settings.endGroup();
777    settings.beginGroup("JobList");
778    m_recordLimitCheck = settings.value("recordLimitCheck", true).toBool();
779    m_recordLimitVal = settings.value("recordLimitVal", 150).toInt();
780    m_daysLimitCheck = settings.value("daysLimitCheck", false).toBool();
781    m_daysLimitVal = settings.value("daysLimitVal", 28).toInt();
782    settings.endGroup();
783    settings.beginGroup("Messages");
784    m_checkMessages = settings.value("checkMessages", false).toBool();
785    m_checkMessagesInterval = settings.value("checkMessagesInterval", 28).toInt();
786    settings.endGroup();
787    settings.beginGroup("Misc");
788    m_longList = settings.value("longList", false).toBool();
789    m_radioConvert = settings.value("byteConvert", false).toInt();
790    m_openPlot = settings.value("openplot", false).toBool();
791    m_openBrowser = settings.value("openbrowser", false).toBool();
792    m_openDirStat = settings.value("opendirstat", false).toBool();
793    settings.endGroup();
794    settings.beginGroup("RestoreTree");
795    m_rtPopDirDebug = settings.value("rtPopDirDebug", false).toBool();
796    m_rtDirCurICDebug = settings.value("rtDirCurICDebug", false).toBool();
797    m_rtDirICDebug = settings.value("rtDirCurICRetDebug", false).toBool();
798    m_rtFileTabICDebug = settings.value("rtFileTabICDebug", false).toBool();
799    m_rtVerTabICDebug = settings.value("rtVerTabICDebug", false).toBool();
800    m_rtUpdateFTDebug = settings.value("rtUpdateFTDebug", false).toBool();
801    m_rtUpdateVTDebug = settings.value("rtUpdateVTDebug", false).toBool();
802    m_rtChecksDebug = settings.value("rtChecksDebug", false).toBool();
803    m_rtIconStateDebug = settings.value("rtIconStateDebug", false).toBool();
804    m_rtRestore1Debug = settings.value("rtRestore1Debug", false).toBool();
805    m_rtRestore2Debug = settings.value("rtRestore2Debug", false).toBool();
806    m_rtRestore3Debug = settings.value("rtRestore3Debug", false).toBool();
807    settings.endGroup();
808 }
809
810 void MainWin::hrConvert(QString &ret, qlonglong &inval)
811 {
812    double net = 0;
813    qlonglong base;
814    QStringList suflist;
815
816    if (m_radioConvert == 0) {
817       ret =  QString("%1").arg(inval);
818       return;
819    } else if (m_radioConvert == 1){
820       base = 1000;
821       suflist = (QStringList() << "B" << "KiB" << "MiB" << "GiB" << "TiB" << "PiB" << "EiB" << "ZiB");
822    } else {
823       base = 1024;
824       suflist = (QStringList() << "B" << "KB" << "MB" << "GB" << "TB" << "PB" << "EB" << "ZB");
825    }
826    qlonglong running = base;
827    bool done = false;
828    int count = 1;
829    while (done == false) {
830       QString test1 =  QString("%1").arg(inval);
831       QString test2 =  QString("%1").arg(running);
832       if (float(inval) < (float)(running)) {
833          done = true;
834          ret = suflist[count - 1];
835          net = (float)inval / (float)(running/base);
836       }
837       count += 1;
838       if (count > suflist.count()) done = true;
839       running *= base;
840    }
841    char format = 'f';
842    if (net != 0)
843       ret =  QString("%1 %2")
844                   .arg(net, 0, format, 2, QLatin1Char(' '))
845                   .arg(ret);
846    else ret = "0 B";
847 }
848
849 void MainWin::hrConvertSeconds(QString &ret, qlonglong &inval)
850 {
851    double net = 0;
852    QList<qlonglong> durations;
853    durations.append(1);
854    durations.append(60);
855    durations.append(3600);
856    durations.append(86400);
857    durations.append(2592000);
858    durations.append(31536000);
859    QStringList abbrlist = (QStringList() << "Sec" << "Min" << "Hrs" << "Days" << "Mnth" << "Yrs");
860    bool done = false;
861    int count = 1;
862    while (done == false) {
863       QString test1 =  QString("%1").arg(inval);
864       QString test2 =  QString("%1").arg(durations[count]);
865       if ((inval < durations[count]) || (count >= abbrlist.count() - 1)) { 
866          done = true;
867          net = (float)inval / (float)(durations[count - 1]);
868          if (net != 0)
869             ret =  QString("%1 %2")
870                   .arg(net, 0, 'f', 2, QLatin1Char(' '))
871                   .arg(abbrlist[count - 1]);
872          else ret = "0 S";
873       }
874       count += 1;
875    }
876 }