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