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