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