]> git.sur5r.net Git - bacula/bacula/blob - bacula/src/qt-console/mainwin.cpp
20335059c6f0a3cc3d1506c530b795fa8694dac5
[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.executeLongCheckBox->setCheckState(m_longList ? Qt::Checked : Qt::Unchecked);
650    prefs.rtPopDirCheckBox->setCheckState(m_rtPopDirDebug ? Qt::Checked : Qt::Unchecked);
651    prefs.rtDirCurICCheckBox->setCheckState(m_rtDirCurICDebug ? Qt::Checked : Qt::Unchecked);
652    prefs.rtDirICCheckBox->setCheckState(m_rtDirICDebug ? Qt::Checked : Qt::Unchecked);
653    prefs.rtFileTabICCheckBox->setCheckState(m_rtFileTabICDebug ? Qt::Checked : Qt::Unchecked);
654    prefs.rtVerTabICCheckBox->setCheckState(m_rtVerTabICDebug ? Qt::Checked : Qt::Unchecked);
655    prefs.rtUpdateFTCheckBox->setCheckState(m_rtUpdateFTDebug ? Qt::Checked : Qt::Unchecked);
656    prefs.rtUpdateVTCheckBox->setCheckState(m_rtUpdateVTDebug ? Qt::Checked : Qt::Unchecked);
657    prefs.rtChecksCheckBox->setCheckState(m_rtChecksDebug ? Qt::Checked : Qt::Unchecked);
658    prefs.rtIconStateCheckBox->setCheckState(m_rtIconStateDebug ? Qt::Checked : Qt::Unchecked);
659    prefs.rtRestore1CheckBox->setCheckState(m_rtRestore1Debug ? Qt::Checked : Qt::Unchecked);
660    prefs.rtRestore2CheckBox->setCheckState(m_rtRestore2Debug ? Qt::Checked : Qt::Unchecked);
661    prefs.rtRestore3CheckBox->setCheckState(m_rtRestore3Debug ? Qt::Checked : Qt::Unchecked);
662    if (m_radioConvert == 0) {
663       prefs.radioConvertOff->setChecked(Qt::Checked);
664    } else if (m_radioConvert == 1){
665       prefs.radioConvertIEC->setChecked(Qt::Checked);
666    } else {
667       m_radioConvert = 2;
668       prefs.radioConvertStandard->setChecked(Qt::Checked);
669    }
670    prefs.openPlotCheckBox->setCheckState(m_openPlot ? Qt::Checked : Qt::Unchecked);
671    prefs.openBrowserCheckBox->setCheckState(m_openBrowser ? Qt::Checked : Qt::Unchecked);
672    prefs.openDirStatCheckBox->setCheckState(m_openDirStat ? Qt::Checked : Qt::Unchecked);
673    prefs.exec();
674 }
675
676 /* Preferences dialog */
677 prefsDialog::prefsDialog()
678 {
679    setupUi(this);
680 }
681
682 void prefsDialog::accept()
683 {
684    this->hide();
685    mainWin->m_commDebug = this->commDebug->checkState() == Qt::Checked;
686    mainWin->m_displayAll = this->displayAll->checkState() == Qt::Checked;
687    mainWin->m_sqlDebug = this->sqlDebug->checkState() == Qt::Checked;
688    mainWin->m_commandDebug = this->commandDebug->checkState() == Qt::Checked;
689    mainWin->m_miscDebug = this->miscDebug->checkState() == Qt::Checked;
690    mainWin->m_recordLimitCheck = this->recordLimit->checkState() == Qt::Checked;
691    mainWin->m_recordLimitVal = this->recordSpinBox->value();
692    mainWin->m_daysLimitCheck = this->daysLimit->checkState() == Qt::Checked;
693    mainWin->m_daysLimitVal = this->daysSpinBox->value();
694    mainWin->m_checkMessages = this->checkMessages->checkState() == Qt::Checked;
695    mainWin->m_checkMessagesInterval = this->checkMessagesSpin->value();
696    mainWin->m_longList = this->executeLongCheckBox->checkState() == Qt::Checked;
697
698    mainWin->m_rtPopDirDebug = this->rtPopDirCheckBox->checkState() == Qt::Checked;
699    mainWin->m_rtDirCurICDebug = this->rtDirCurICCheckBox->checkState() == Qt::Checked;
700    mainWin->m_rtDirICDebug = this->rtDirICCheckBox->checkState() == Qt::Checked;
701    mainWin->m_rtFileTabICDebug = this->rtFileTabICCheckBox->checkState() == Qt::Checked;
702    mainWin->m_rtVerTabICDebug = this->rtVerTabICCheckBox->checkState() == Qt::Checked;
703    mainWin->m_rtUpdateFTDebug = this->rtUpdateFTCheckBox->checkState() == Qt::Checked;
704    mainWin->m_rtUpdateVTDebug = this->rtUpdateVTCheckBox->checkState() == Qt::Checked;
705    mainWin->m_rtChecksDebug = this->rtChecksCheckBox->checkState() == Qt::Checked;
706    mainWin->m_rtIconStateDebug = this->rtIconStateCheckBox->checkState() == Qt::Checked;
707    mainWin->m_rtRestore1Debug = this->rtRestore1CheckBox->checkState() == Qt::Checked;
708    mainWin->m_rtRestore2Debug = this->rtRestore2CheckBox->checkState() == Qt::Checked;
709    mainWin->m_rtRestore3Debug = this->rtRestore3CheckBox->checkState() == Qt::Checked;
710    if (this->radioConvertOff->isChecked()) {
711       mainWin->m_radioConvert = 0;
712    } else if (this->radioConvertIEC->isChecked()){
713       mainWin->m_radioConvert = 1;
714    } else {
715       mainWin->m_radioConvert = 2;
716    }
717    mainWin->m_openPlot = this->openPlotCheckBox->checkState() == Qt::Checked;
718    mainWin->m_openBrowser = this->openBrowserCheckBox->checkState() == Qt::Checked;
719    mainWin->m_openDirStat = this->openDirStatCheckBox->checkState() == Qt::Checked;
720
721    QSettings settings("www.bacula.org", "bat");
722    settings.beginGroup("Debug");
723    settings.setValue("commDebug", mainWin->m_commDebug);
724    settings.setValue("displayAll", mainWin->m_displayAll);
725    settings.setValue("sqlDebug", mainWin->m_sqlDebug);
726    settings.setValue("commandDebug", mainWin->m_commandDebug);
727    settings.setValue("miscDebug", mainWin->m_miscDebug);
728    settings.endGroup();
729    settings.beginGroup("JobList");
730    settings.setValue("recordLimitCheck", mainWin->m_recordLimitCheck);
731    settings.setValue("recordLimitVal", mainWin->m_recordLimitVal);
732    settings.setValue("daysLimitCheck", mainWin->m_daysLimitCheck);
733    settings.setValue("daysLimitVal", mainWin->m_daysLimitVal);
734    settings.endGroup();
735    settings.beginGroup("Messages");
736    settings.setValue("checkMessages", mainWin->m_checkMessages);
737    settings.setValue("checkMessagesInterval", mainWin->m_checkMessagesInterval);
738    settings.endGroup();
739    settings.beginGroup("Misc");
740    settings.setValue("longList", mainWin->m_longList);
741    settings.setValue("byteConvert", mainWin->m_radioConvert);
742    settings.setValue("openplot", mainWin->m_openPlot);
743    settings.setValue("openbrowser", mainWin->m_openBrowser);
744    settings.setValue("opendirstat", mainWin->m_openDirStat);
745    settings.endGroup();
746    settings.beginGroup("RestoreTree");
747    settings.setValue("rtPopDirDebug", mainWin->m_rtPopDirDebug);
748    settings.setValue("rtDirCurICDebug", mainWin->m_rtDirCurICDebug);
749    settings.setValue("rtDirCurICRetDebug", mainWin->m_rtDirICDebug);
750    settings.setValue("rtFileTabICDebug", mainWin->m_rtFileTabICDebug);
751    settings.setValue("rtVerTabICDebug", mainWin->m_rtVerTabICDebug);
752    settings.setValue("rtUpdateFTDebug", mainWin->m_rtUpdateFTDebug);
753    settings.setValue("rtUpdateVTDebug", mainWin->m_rtUpdateVTDebug);
754    settings.setValue("rtChecksDebug", mainWin->m_rtChecksDebug);
755    settings.setValue("rtIconStateDebug", mainWin->m_rtIconStateDebug);
756    settings.setValue("rtRestore1Debug", mainWin->m_rtRestore1Debug);
757    settings.setValue("rtRestore2Debug", mainWin->m_rtRestore2Debug);
758    settings.setValue("rtRestore3Debug", mainWin->m_rtRestore3Debug);
759    settings.endGroup();
760    foreach(Console *console, mainWin->m_consoleHash) {
761       console->startTimer();
762    }
763 }
764
765 void prefsDialog::reject()
766 {
767    this->hide();
768    mainWin->set_status(tr("Canceled"));
769 }
770
771 /* read preferences for the prefences dialog box */
772 void MainWin::readPreferences()
773 {
774    QSettings settings("www.bacula.org", "bat");
775    settings.beginGroup("Debug");
776    m_commDebug = settings.value("commDebug", false).toBool();
777    m_displayAll = settings.value("displayAll", false).toBool();
778    m_sqlDebug = settings.value("sqlDebug", false).toBool();
779    m_commandDebug = settings.value("commandDebug", false).toBool();
780    m_miscDebug = settings.value("miscDebug", false).toBool();
781    settings.endGroup();
782    settings.beginGroup("JobList");
783    m_recordLimitCheck = settings.value("recordLimitCheck", true).toBool();
784    m_recordLimitVal = settings.value("recordLimitVal", 150).toInt();
785    m_daysLimitCheck = settings.value("daysLimitCheck", false).toBool();
786    m_daysLimitVal = settings.value("daysLimitVal", 28).toInt();
787    settings.endGroup();
788    settings.beginGroup("Messages");
789    m_checkMessages = settings.value("checkMessages", false).toBool();
790    m_checkMessagesInterval = settings.value("checkMessagesInterval", 28).toInt();
791    settings.endGroup();
792    settings.beginGroup("Misc");
793    m_longList = settings.value("longList", false).toBool();
794    m_radioConvert = settings.value("byteConvert", false).toInt();
795    m_openPlot = settings.value("openplot", false).toBool();
796    m_openBrowser = settings.value("openbrowser", false).toBool();
797    m_openDirStat = settings.value("opendirstat", false).toBool();
798    settings.endGroup();
799    settings.beginGroup("RestoreTree");
800    m_rtPopDirDebug = settings.value("rtPopDirDebug", false).toBool();
801    m_rtDirCurICDebug = settings.value("rtDirCurICDebug", false).toBool();
802    m_rtDirICDebug = settings.value("rtDirCurICRetDebug", false).toBool();
803    m_rtFileTabICDebug = settings.value("rtFileTabICDebug", false).toBool();
804    m_rtVerTabICDebug = settings.value("rtVerTabICDebug", false).toBool();
805    m_rtUpdateFTDebug = settings.value("rtUpdateFTDebug", false).toBool();
806    m_rtUpdateVTDebug = settings.value("rtUpdateVTDebug", false).toBool();
807    m_rtChecksDebug = settings.value("rtChecksDebug", false).toBool();
808    m_rtIconStateDebug = settings.value("rtIconStateDebug", false).toBool();
809    m_rtRestore1Debug = settings.value("rtRestore1Debug", false).toBool();
810    m_rtRestore2Debug = settings.value("rtRestore2Debug", false).toBool();
811    m_rtRestore3Debug = settings.value("rtRestore3Debug", false).toBool();
812    settings.endGroup();
813 }
814
815 void MainWin::hrConvert(QString &ret, qlonglong &inval)
816 {
817    double net = 0;
818    qlonglong base;
819    QStringList suflist;
820
821    if (m_radioConvert == 0) {
822       ret =  QString("%1").arg(inval);
823       return;
824    } else if (m_radioConvert == 1){
825       base = 1000;
826       suflist = (QStringList() << "B" << "KiB" << "MiB" << "GiB" << "TiB" << "PiB" << "EiB" << "ZiB");
827    } else {
828       base = 1024;
829       suflist = (QStringList() << "B" << "KB" << "MB" << "GB" << "TB" << "PB" << "EB" << "ZB");
830    }
831    qlonglong running = base;
832    bool done = false;
833    int count = 1;
834    while (done == false) {
835       QString test1 =  QString("%1").arg(inval);
836       QString test2 =  QString("%1").arg(running);
837       if (float(inval) < (float)(running)) {
838          done = true;
839          ret = suflist[count - 1];
840          net = (float)inval / (float)(running/base);
841       }
842       count += 1;
843       if (count > suflist.count()) done = true;
844       running *= base;
845    }
846    char format = 'f';
847    if (net != 0)
848       ret =  QString("%1 %2")
849                   .arg(net, 0, format, 2, QLatin1Char(' '))
850                   .arg(ret);
851    else ret = "0 B";
852 }
853
854 void MainWin::hrConvertSeconds(QString &ret, qlonglong &inval)
855 {
856    double net = 0;
857    QList<qlonglong> durations;
858    durations.append(1);
859    durations.append(60);
860    durations.append(3600);
861    durations.append(86400);
862    durations.append(2592000);
863    durations.append(31536000);
864    QStringList abbrlist = (QStringList() << "Sec" << "Min" << "Hrs" << "Days" << "Mnth" << "Yrs");
865    bool done = false;
866    int count = 1;
867    while (done == false) {
868       QString test1 =  QString("%1").arg(inval);
869       QString test2 =  QString("%1").arg(durations[count]);
870       if ((inval < durations[count]) || (count >= abbrlist.count() - 1)) { 
871          done = true;
872          net = (float)inval / (float)(durations[count - 1]);
873          if (net != 0)
874             ret =  QString("%1 %2")
875                   .arg(net, 0, 'f', 2, QLatin1Char(' '))
876                   .arg(abbrlist[count - 1]);
877          else ret = "0 S";
878       }
879       count += 1;
880    }
881 }