]> git.sur5r.net Git - bacula/bacula/blob - bacula/src/qt-console/mainwin.cpp
Add a feature to have a menu item to allow a user to repopulate the lists
[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    connect(actionRepopLists, SIGNAL(triggered()), this,  SLOT(repopLists()));
258 }
259
260 void MainWin::disconnectSignals()
261 {
262    /* Connect signals to slots */
263    disconnect(lineEdit, SIGNAL(returnPressed()), this, SLOT(input_line()));
264    disconnect(actionAbout_bat, SIGNAL(triggered()), this, SLOT(about()));
265    disconnect(actionBat_Help, SIGNAL(triggered()), this, SLOT(help()));
266    disconnect(treeWidget, SIGNAL(itemClicked(QTreeWidgetItem *, int)), this, SLOT(treeItemClicked(QTreeWidgetItem *, int)));
267    disconnect(treeWidget, SIGNAL( currentItemChanged(QTreeWidgetItem *, QTreeWidgetItem *)), this, SLOT(treeItemChanged(QTreeWidgetItem *, QTreeWidgetItem *)));
268    disconnect(stackedWidget, SIGNAL(currentChanged(int)), this, SLOT(stackItemChanged(int)));
269    disconnect(actionQuit, SIGNAL(triggered()), app, SLOT(closeAllWindows()));
270    disconnect(actionLabel, SIGNAL(triggered()), this,  SLOT(labelButtonClicked()));
271    disconnect(actionRun, SIGNAL(triggered()), this,  SLOT(runButtonClicked()));
272    disconnect(actionEstimate, SIGNAL(triggered()), this,  SLOT(estimateButtonClicked()));
273    disconnect(actionBrowse, SIGNAL(triggered()), this,  SLOT(browseButtonClicked()));
274    disconnect(actionStatusDirPage, SIGNAL(triggered()), this,  SLOT(statusPageButtonClicked()));
275 #ifdef HAVE_QWT
276    disconnect(actionJobPlot, SIGNAL(triggered()), this,  SLOT(jobPlotButtonClicked()));
277 #endif
278    disconnect(actionRestore, SIGNAL(triggered()), this,  SLOT(restoreButtonClicked()));
279    disconnect(actionUndock, SIGNAL(triggered()), this,  SLOT(undockWindowButton()));
280    disconnect(actionToggleDock, SIGNAL(triggered()), this,  SLOT(toggleDockContextWindow()));
281    disconnect(actionClosePage, SIGNAL(triggered()), this,  SLOT(closePage()));
282    disconnect(actionPreferences, SIGNAL(triggered()), this,  SLOT(setPreferences()));
283    disconnect(actionRepopLists, SIGNAL(triggered()), this,  SLOT(repopLists()));
284 }
285
286 /*
287  *  Enter wait state
288  */
289 void MainWin::waitEnter()
290 {
291    app->setOverrideCursor(QCursor(Qt::WaitCursor));
292    disconnectSignals();
293    disconnectConsoleSignals(m_currentConsole);
294    m_waitTreeItem = treeWidget->currentItem();
295 }
296
297 /*
298  *  Leave wait state
299  */
300 void MainWin::waitExit()
301 {
302    app->restoreOverrideCursor();
303    if (m_waitTreeItem != treeWidget->currentItem())
304       treeWidget->setCurrentItem(m_waitTreeItem);
305    connectSignals();
306    connectConsoleSignals();
307 }
308
309 void MainWin::connectConsoleSignals()
310 {
311    connect(actionConnect, SIGNAL(triggered()), m_currentConsole, SLOT(connect_dir()));
312    connect(actionSelectFont, SIGNAL(triggered()), m_currentConsole, SLOT(set_font()));
313    connect(actionStatusDir, SIGNAL(triggered()), m_currentConsole, SLOT(status_dir()));
314    connect(actionMessages, SIGNAL(triggered()), m_currentConsole, SLOT(messages()));
315 }
316
317 void MainWin::disconnectConsoleSignals(Console *console)
318 {
319    disconnect(actionConnect, SIGNAL(triggered()), console, SLOT(connect_dir()));
320    disconnect(actionStatusDir, SIGNAL(triggered()), console, SLOT(status_dir()));
321    disconnect(actionMessages, SIGNAL(triggered()), console, SLOT(messages()));
322    disconnect(actionSelectFont, SIGNAL(triggered()), console, SLOT(set_font()));
323 }
324
325 void MainWin::repopLists()
326 {
327    m_currentConsole->populateLists(false);
328 }
329
330 /* 
331  * Reimplementation of QWidget closeEvent virtual function   
332  */
333 void MainWin::closeEvent(QCloseEvent *event)
334 {
335    m_isClosing = true;
336    writeSettings();
337    /* close all non console pages, this will call settings in destructors */
338    while (m_consoleHash.count() < m_pagehash.count()) {
339       foreach(Pages *page, m_pagehash) {
340          if (page !=  page->console()) {
341             QTreeWidgetItem* pageSelectorTreeWidgetItem = mainWin->getFromHash(page);
342             if (pageSelectorTreeWidgetItem->childCount() == 0) {
343                page->console()->setCurrent();
344                page->closeStackPage();
345             }
346          }
347       }
348    }
349    foreach(Console *console, m_consoleHash){
350       console->writeSettings();
351       console->terminate();
352       console->closeStackPage();
353    }
354    event->accept();
355 }
356
357 void MainWin::writeSettings()
358 {
359    QSettings settings("bacula.org", "bat");
360
361    settings.beginGroup("MainWin");
362    settings.setValue("winSize", size());
363    settings.setValue("winPos", pos());
364    settings.setValue("state", saveState());
365    settings.endGroup();
366 }
367
368 void MainWin::readSettings()
369
370    QSettings settings("bacula.org", "bat");
371
372    settings.beginGroup("MainWin");
373    resize(settings.value("winSize", QSize(1041, 801)).toSize());
374    move(settings.value("winPos", QPoint(200, 150)).toPoint());
375    restoreState(settings.value("state").toByteArray());
376    settings.endGroup();
377 }
378
379 /*
380  * This subroutine is called with an item in the Page Selection window
381  *   is clicked 
382  */
383 void MainWin::treeItemClicked(QTreeWidgetItem *item, int /*column*/)
384 {
385    /* Is this a page that has been inserted into the hash  */
386    if (getFromHash(item)) {
387       Pages* page = getFromHash(item);
388       int stackindex=stackedWidget->indexOf(page);
389
390       if (stackindex >= 0) {
391          stackedWidget->setCurrentWidget(page);
392       }
393       /* run the virtual function in case this class overrides it */
394       page->PgSeltreeWidgetClicked();
395    }
396 }
397
398 /*
399  * Called with a change of the highlighed tree widget item in the page selector.
400  */
401 void MainWin::treeItemChanged(QTreeWidgetItem *currentitem, QTreeWidgetItem *previousitem)
402 {
403    if (m_isClosing) return; /* if closing the application, do nothing here */
404
405    Pages *previousPage, *nextPage;
406    Console *previousConsole = NULL;
407    Console *nextConsole;
408
409    /* remove all actions before adding actions appropriate for new page */
410    foreach(QAction* pageAction, treeWidget->actions()) {
411       treeWidget->removeAction(pageAction);
412    }
413
414    /* first determine the next item */
415
416    /* knowing the treeWidgetItem, get the page from the hash */
417    nextPage = getFromHash(currentitem);
418    nextConsole = m_consoleHash.value(currentitem);
419    /* Is this a page that has been inserted into the hash  */
420    if (nextPage) {
421       nextConsole = nextPage->console();
422       /* then is it a treeWidgetItem representing a director */
423    } else if (nextConsole) {
424       /* let the next page BE the console */
425       nextPage = nextConsole;
426    } else {
427       /* Should never get here */
428       nextPage = NULL;
429       nextConsole = NULL;
430    }
431           
432    /* The Previous item */
433
434    /* this condition prevents a segfault.  The first time there is no previousitem*/
435    if (previousitem) {
436       /* knowing the treeWidgetItem, get the page from the hash */
437       previousPage = getFromHash(previousitem);
438       previousConsole = m_consoleHash.value(previousitem);
439       if (previousPage) {
440          previousConsole = previousPage->console();
441       } else if (previousConsole) {
442          previousPage = previousConsole;
443       }
444       if ((previousPage) || (previousConsole)) {
445          if (nextConsole != previousConsole) {
446             /* remove connections to the current console */
447             disconnectConsoleSignals(previousConsole);
448             QTreeWidgetItem *dirItem = previousConsole->directorTreeItem();
449             QBrush greyBrush(Qt::lightGray);
450             dirItem->setBackground(0, greyBrush);
451          }
452       }
453    }
454
455    /* process the current (next) item */
456    
457    if ((nextPage) || (nextConsole)) {
458       if (nextConsole != previousConsole) {
459          /* make connections to the current console */
460          m_currentConsole = nextConsole;
461          connectConsoleSignals();
462          setMessageIcon();
463          /* Set director's tree widget background to magenta for ease of identification */
464          QTreeWidgetItem *dirItem = m_currentConsole->directorTreeItem();
465          QBrush magentaBrush(Qt::magenta);
466          dirItem->setBackground(0, magentaBrush);
467       }
468       /* set the value for the currently active console */
469       int stackindex = stackedWidget->indexOf(nextPage);
470    
471       /* Is this page currently on the stack or is it undocked */
472       if (stackindex >= 0) {
473          /* put this page on the top of the stack */
474          stackedWidget->setCurrentIndex(stackindex);
475       } else {
476          /* it is undocked, raise it to the front */
477          nextPage->raise();
478       }
479       /* for the page selectors menu action to dock or undock, set the text */
480       nextPage->setContextMenuDockText();
481
482       treeWidget->addAction(actionToggleDock);
483       /* if this page is closeable, and it has no childern, then add that action */
484       if ((nextPage->isCloseable()) && (currentitem->child(0) == NULL))
485          treeWidget->addAction(actionClosePage);
486
487       /* Add the actions to the Page Selectors tree widget that are part of the
488        * current items list of desired actions regardless of whether on top of stack*/
489       treeWidget->addActions(nextPage->m_contextActions);
490    }
491 }
492
493 void MainWin::labelButtonClicked() 
494 {
495    new labelPage();
496 }
497
498 void MainWin::runButtonClicked() 
499 {
500    new runPage("");
501 }
502
503 void MainWin::estimateButtonClicked() 
504 {
505    new estimatePage();
506 }
507
508 void MainWin::browseButtonClicked() 
509 {
510    new restoreTree();
511 }
512
513 void MainWin::statusPageButtonClicked()
514 {
515    /* if one exists, then just set it current */
516    bool found = false;
517    foreach(Pages *page, m_pagehash) {
518       if (m_currentConsole == page->console()) {
519          if (page->name() == tr("Director Status")) {
520             found = true;
521             page->setCurrent();
522          }
523       }
524    }
525    if (!found)
526       new DirStat();
527 }
528
529 void MainWin::restoreButtonClicked() 
530 {
531    new prerestorePage();
532 }
533
534 void MainWin::jobPlotButtonClicked()
535 {
536 #ifdef HAVE_QWT
537    JobPlotPass pass;
538    pass.use = false;
539    new JobPlot(NULL, pass);
540 #endif
541 }
542
543 /*
544  * The user just finished typing a line in the command line edit box
545  */
546 void MainWin::input_line()
547 {
548    QString cmdStr = lineEdit->text();    /* Get the text */
549    lineEdit->clear();                    /* clear the lineEdit box */
550    if (m_currentConsole->is_connected()) {
551       /* Use consoleInput to allow typing anything */
552       m_currentConsole->consoleInput(cmdStr);
553    } else {
554       set_status(tr("Director not connected. Click on connect button."));
555    }
556    m_cmd_history.append(cmdStr);
557    m_cmd_last = -1;
558    if (treeWidget->currentItem() != getFromHash(m_currentConsole))
559       m_currentConsole->setCurrent();
560 }
561
562
563 void MainWin::about()
564 {
565    QMessageBox::about(this, tr("About bat"),
566       tr("<br><h2>bat %1 (%2), by Dirk H Bartley and Kern Sibbald</h2>"
567          "<p>Copyright &copy; 2007-%3 Free Software Foundation Europe e.V."
568          "<p>The <b>bat</b> is an administrative console"
569          " interface to the Director.").arg(VERSION).arg(BDATE).arg(BYEAR));
570 }
571
572 void MainWin::help()
573 {
574    Help::displayFile("index.html");
575 }
576
577 void MainWin::set_statusf(const char *fmt, ...)
578 {
579    va_list arg_ptr;
580    char buf[1000];
581    int len;
582    va_start(arg_ptr, fmt);
583    len = bvsnprintf(buf, sizeof(buf), fmt, arg_ptr);
584    va_end(arg_ptr);
585    set_status(buf);
586 }
587
588 void MainWin::set_status_ready()
589 {
590    set_status(tr(" Ready"));
591 }
592
593 void MainWin::set_status(const QString &str)
594 {
595    statusBar()->showMessage(str);
596 }
597
598 void MainWin::set_status(const char *buf)
599 {
600    statusBar()->showMessage(buf);
601 }
602
603 /*
604  * Function to respond to the button bar button to undock
605  */
606 void MainWin::undockWindowButton()
607 {
608    Pages* page = (Pages*)stackedWidget->currentWidget();
609    page->togglePageDocking();
610 }
611
612 /*
613  * Function to respond to action on page selector context menu to toggle the 
614  * dock status of the window associated with the page selectors current
615  * tree widget item.
616  */
617 void MainWin::toggleDockContextWindow()
618 {
619    QTreeWidgetItem *currentitem = treeWidget->currentItem();
620    
621    /* Is this a page that has been inserted into the hash  */
622    if (getFromHash(currentitem)) {
623       Pages* page = getFromHash(currentitem);
624       page->togglePageDocking();
625    }
626 }
627
628 /*
629  * This function is called when the stack item is changed.  Call
630  * the virtual function here.  Avoids a window being undocked leaving
631  * a window at the top of the stack unpopulated.
632  */
633 void MainWin::stackItemChanged(int)
634 {
635    if (m_isClosing) return; /* if closing the application, do nothing here */
636    Pages* page = (Pages*)stackedWidget->currentWidget();
637    /* run the virtual function in case this class overrides it */
638    page->currentStackItem();
639 }
640
641 /*
642  * Function to simplify insertion of QTreeWidgetItem <-> Page association
643  * into a double direction hash.
644  */
645 void MainWin::hashInsert(QTreeWidgetItem *item, Pages *page)
646 {
647    m_pagehash.insert(item, page);
648    m_widgethash.insert(page, item);
649 }
650
651 /*
652  * Function to simplify removal of QTreeWidgetItem <-> Page association
653  * into a double direction hash.
654  */
655 void MainWin::hashRemove(QTreeWidgetItem *item, Pages *page)
656 {
657    /* I had all sorts of return status checking code here.  Do we have a log
658     * level capability in bat.  I would have left it in but it used printf's
659     * and it should really be some kind of log level facility ???
660     * ******FIXME********/
661    m_pagehash.remove(item);
662    m_widgethash.remove(page);
663 }
664
665 /*
666  * Function to retrieve a Page* when the item in the page selector's tree is
667  * known.
668  */
669 Pages* MainWin::getFromHash(QTreeWidgetItem *item)
670 {
671    return m_pagehash.value(item);
672 }
673
674 /*
675  * Function to retrieve the page selectors tree widget item when the page is
676  * known.
677  */
678 QTreeWidgetItem* MainWin::getFromHash(Pages *page)
679 {
680    return m_widgethash.value(page);
681 }
682
683 /*
684  * Function to respond to action on page selector context menu to close the
685  * current window.
686  */
687 void MainWin::closePage()
688 {
689    QTreeWidgetItem *currentitem = treeWidget->currentItem();
690    
691    /* Is this a page that has been inserted into the hash  */
692    if (getFromHash(currentitem)) {
693       Pages* page = getFromHash(currentitem);
694       if (page->isCloseable()) {
695          page->closeStackPage();
696       }
697    }
698 }
699
700 /* Quick function to return the current console */
701 Console *MainWin::currentConsole()
702 {
703    return m_currentConsole;
704 }
705
706 /* Quick function to return the tree item for the director */
707 QTreeWidgetItem *MainWin::currentTopItem()
708 {
709    return m_currentConsole->directorTreeItem();
710 }
711
712 /* Preferences menu item clicked */
713 void MainWin::setPreferences()
714 {
715    prefsDialog prefs;
716    prefs.commDebug->setCheckState(m_commDebug ? Qt::Checked : Qt::Unchecked);
717    prefs.connDebug->setCheckState(m_connDebug ? Qt::Checked : Qt::Unchecked);
718    prefs.displayAll->setCheckState(m_displayAll ? Qt::Checked : Qt::Unchecked);
719    prefs.sqlDebug->setCheckState(m_sqlDebug ? Qt::Checked : Qt::Unchecked);
720    prefs.commandDebug->setCheckState(m_commandDebug ? Qt::Checked : Qt::Unchecked);
721    prefs.miscDebug->setCheckState(m_miscDebug ? Qt::Checked : Qt::Unchecked);
722    prefs.recordLimit->setCheckState(m_recordLimitCheck ? Qt::Checked : Qt::Unchecked);
723    prefs.recordSpinBox->setValue(m_recordLimitVal);
724    prefs.daysLimit->setCheckState(m_daysLimitCheck ? Qt::Checked : Qt::Unchecked);
725    prefs.daysSpinBox->setValue(m_daysLimitVal);
726    prefs.checkMessages->setCheckState(m_checkMessages ? Qt::Checked : Qt::Unchecked);
727    prefs.checkMessagesSpin->setValue(m_checkMessagesInterval);
728    prefs.refreshStatusDir->setCheckState(m_refreshStatusDir ? Qt::Checked : Qt::Unchecked);
729    prefs.refreshStatusDirSpin->setValue(m_refreshStatusDirInterval);
730    prefs.executeLongCheckBox->setCheckState(m_longList ? Qt::Checked : Qt::Unchecked);
731    prefs.rtPopDirCheckBox->setCheckState(m_rtPopDirDebug ? Qt::Checked : Qt::Unchecked);
732    prefs.rtDirCurICCheckBox->setCheckState(m_rtDirCurICDebug ? Qt::Checked : Qt::Unchecked);
733    prefs.rtDirICCheckBox->setCheckState(m_rtDirICDebug ? Qt::Checked : Qt::Unchecked);
734    prefs.rtFileTabICCheckBox->setCheckState(m_rtFileTabICDebug ? Qt::Checked : Qt::Unchecked);
735    prefs.rtVerTabICCheckBox->setCheckState(m_rtVerTabICDebug ? Qt::Checked : Qt::Unchecked);
736    prefs.rtUpdateFTCheckBox->setCheckState(m_rtUpdateFTDebug ? Qt::Checked : Qt::Unchecked);
737    prefs.rtUpdateVTCheckBox->setCheckState(m_rtUpdateVTDebug ? Qt::Checked : Qt::Unchecked);
738    prefs.rtChecksCheckBox->setCheckState(m_rtChecksDebug ? Qt::Checked : Qt::Unchecked);
739    prefs.rtIconStateCheckBox->setCheckState(m_rtIconStateDebug ? Qt::Checked : Qt::Unchecked);
740    prefs.rtRestore1CheckBox->setCheckState(m_rtRestore1Debug ? Qt::Checked : Qt::Unchecked);
741    prefs.rtRestore2CheckBox->setCheckState(m_rtRestore2Debug ? Qt::Checked : Qt::Unchecked);
742    prefs.rtRestore3CheckBox->setCheckState(m_rtRestore3Debug ? Qt::Checked : Qt::Unchecked);
743    switch (ItemFormatterBase::getBytesConversion()) {
744    case ItemFormatterBase::BYTES_CONVERSION_NONE:
745       prefs.radioConvertOff->setChecked(Qt::Checked);
746       break;
747    case ItemFormatterBase::BYTES_CONVERSION_IEC:
748       prefs.radioConvertIEC->setChecked(Qt::Checked);
749       break;
750    default:
751       prefs.radioConvertStandard->setChecked(Qt::Checked);
752       break;
753    }
754    prefs.openPlotCheckBox->setCheckState(m_openPlot ? Qt::Checked : Qt::Unchecked);
755 #ifndef HAVE_QWT
756    prefs.openPlotCheckBox->setVisible(false);
757 #endif
758    prefs.openBrowserCheckBox->setCheckState(m_openBrowser ? Qt::Checked : Qt::Unchecked);
759    prefs.openDirStatCheckBox->setCheckState(m_openDirStat ? Qt::Checked : Qt::Unchecked);
760    prefs.exec();
761 }
762
763 /* Preferences dialog */
764 prefsDialog::prefsDialog()
765 {
766    setupUi(this);
767 }
768
769 void prefsDialog::accept()
770 {
771    this->hide();
772    mainWin->m_commDebug = this->commDebug->checkState() == Qt::Checked;
773    mainWin->m_connDebug = this->connDebug->checkState() == Qt::Checked;
774    mainWin->m_displayAll = this->displayAll->checkState() == Qt::Checked;
775    mainWin->m_sqlDebug = this->sqlDebug->checkState() == Qt::Checked;
776    mainWin->m_commandDebug = this->commandDebug->checkState() == Qt::Checked;
777    mainWin->m_miscDebug = this->miscDebug->checkState() == Qt::Checked;
778    mainWin->m_recordLimitCheck = this->recordLimit->checkState() == Qt::Checked;
779    mainWin->m_recordLimitVal = this->recordSpinBox->value();
780    mainWin->m_daysLimitCheck = this->daysLimit->checkState() == Qt::Checked;
781    mainWin->m_daysLimitVal = this->daysSpinBox->value();
782    mainWin->m_checkMessages = this->checkMessages->checkState() == Qt::Checked;
783    mainWin->m_checkMessagesInterval = this->checkMessagesSpin->value();
784    mainWin->m_refreshStatusDir = this->refreshStatusDir->checkState() == Qt::Checked;
785    mainWin->m_refreshStatusDirInterval = this->refreshStatusDirSpin->value();
786    mainWin->m_longList = this->executeLongCheckBox->checkState() == Qt::Checked;
787
788    mainWin->m_rtPopDirDebug = this->rtPopDirCheckBox->checkState() == Qt::Checked;
789    mainWin->m_rtDirCurICDebug = this->rtDirCurICCheckBox->checkState() == Qt::Checked;
790    mainWin->m_rtDirICDebug = this->rtDirICCheckBox->checkState() == Qt::Checked;
791    mainWin->m_rtFileTabICDebug = this->rtFileTabICCheckBox->checkState() == Qt::Checked;
792    mainWin->m_rtVerTabICDebug = this->rtVerTabICCheckBox->checkState() == Qt::Checked;
793    mainWin->m_rtUpdateFTDebug = this->rtUpdateFTCheckBox->checkState() == Qt::Checked;
794    mainWin->m_rtUpdateVTDebug = this->rtUpdateVTCheckBox->checkState() == Qt::Checked;
795    mainWin->m_rtChecksDebug = this->rtChecksCheckBox->checkState() == Qt::Checked;
796    mainWin->m_rtIconStateDebug = this->rtIconStateCheckBox->checkState() == Qt::Checked;
797    mainWin->m_rtRestore1Debug = this->rtRestore1CheckBox->checkState() == Qt::Checked;
798    mainWin->m_rtRestore2Debug = this->rtRestore2CheckBox->checkState() == Qt::Checked;
799    mainWin->m_rtRestore3Debug = this->rtRestore3CheckBox->checkState() == Qt::Checked;
800    if (this->radioConvertOff->isChecked()) {
801       ItemFormatterBase::setBytesConversion(ItemFormatterBase::BYTES_CONVERSION_NONE);
802    } else if (this->radioConvertIEC->isChecked()){
803       ItemFormatterBase::setBytesConversion(ItemFormatterBase::BYTES_CONVERSION_IEC);
804    } else {
805       ItemFormatterBase::setBytesConversion(ItemFormatterBase::BYTES_CONVERSION_SI);
806    }
807    mainWin->m_openPlot = this->openPlotCheckBox->checkState() == Qt::Checked;
808    mainWin->m_openBrowser = this->openBrowserCheckBox->checkState() == Qt::Checked;
809    mainWin->m_openDirStat = this->openDirStatCheckBox->checkState() == Qt::Checked;
810
811    QSettings settings("www.bacula.org", "bat");
812    settings.beginGroup("Debug");
813    settings.setValue("commDebug", mainWin->m_commDebug);
814    settings.setValue("connDebug", mainWin->m_connDebug);
815    settings.setValue("displayAll", mainWin->m_displayAll);
816    settings.setValue("sqlDebug", mainWin->m_sqlDebug);
817    settings.setValue("commandDebug", mainWin->m_commandDebug);
818    settings.setValue("miscDebug", mainWin->m_miscDebug);
819    settings.endGroup();
820    settings.beginGroup("JobList");
821    settings.setValue("recordLimitCheck", mainWin->m_recordLimitCheck);
822    settings.setValue("recordLimitVal", mainWin->m_recordLimitVal);
823    settings.setValue("daysLimitCheck", mainWin->m_daysLimitCheck);
824    settings.setValue("daysLimitVal", mainWin->m_daysLimitVal);
825    settings.endGroup();
826    settings.beginGroup("Timers");
827    settings.setValue("checkMessages", mainWin->m_checkMessages);
828    settings.setValue("checkMessagesInterval", mainWin->m_checkMessagesInterval);
829    settings.setValue("refreshStatusDir", mainWin->m_refreshStatusDir);
830    settings.setValue("refreshStatusDirInterval", mainWin->m_refreshStatusDirInterval);
831    settings.endGroup();
832    settings.beginGroup("Misc");
833    settings.setValue("longList", mainWin->m_longList);
834    settings.setValue("byteConvert", ItemFormatterBase::getBytesConversion());
835    settings.setValue("openplot", mainWin->m_openPlot);
836    settings.setValue("openbrowser", mainWin->m_openBrowser);
837    settings.setValue("opendirstat", mainWin->m_openDirStat);
838    settings.endGroup();
839    settings.beginGroup("RestoreTree");
840    settings.setValue("rtPopDirDebug", mainWin->m_rtPopDirDebug);
841    settings.setValue("rtDirCurICDebug", mainWin->m_rtDirCurICDebug);
842    settings.setValue("rtDirCurICRetDebug", mainWin->m_rtDirICDebug);
843    settings.setValue("rtFileTabICDebug", mainWin->m_rtFileTabICDebug);
844    settings.setValue("rtVerTabICDebug", mainWin->m_rtVerTabICDebug);
845    settings.setValue("rtUpdateFTDebug", mainWin->m_rtUpdateFTDebug);
846    settings.setValue("rtUpdateVTDebug", mainWin->m_rtUpdateVTDebug);
847    settings.setValue("rtChecksDebug", mainWin->m_rtChecksDebug);
848    settings.setValue("rtIconStateDebug", mainWin->m_rtIconStateDebug);
849    settings.setValue("rtRestore1Debug", mainWin->m_rtRestore1Debug);
850    settings.setValue("rtRestore2Debug", mainWin->m_rtRestore2Debug);
851    settings.setValue("rtRestore3Debug", mainWin->m_rtRestore3Debug);
852    settings.endGroup();
853 }
854
855 void prefsDialog::reject()
856 {
857    this->hide();
858    mainWin->set_status(tr("Canceled"));
859 }
860
861 /* read preferences for the prefences dialog box */
862 void MainWin::readPreferences()
863 {
864    QSettings settings("www.bacula.org", "bat");
865    settings.beginGroup("Debug");
866    m_commDebug = settings.value("commDebug", false).toBool();
867    m_connDebug = settings.value("connDebug", false).toBool();
868    m_displayAll = settings.value("displayAll", false).toBool();
869    m_sqlDebug = settings.value("sqlDebug", false).toBool();
870    m_commandDebug = settings.value("commandDebug", false).toBool();
871    m_miscDebug = settings.value("miscDebug", false).toBool();
872    settings.endGroup();
873    settings.beginGroup("JobList");
874    m_recordLimitCheck = settings.value("recordLimitCheck", true).toBool();
875    m_recordLimitVal = settings.value("recordLimitVal", 150).toInt();
876    m_daysLimitCheck = settings.value("daysLimitCheck", false).toBool();
877    m_daysLimitVal = settings.value("daysLimitVal", 28).toInt();
878    settings.endGroup();
879    settings.beginGroup("Timers");
880    m_checkMessages = settings.value("checkMessages", false).toBool();
881    m_checkMessagesInterval = settings.value("checkMessagesInterval", 28).toInt();
882    m_refreshStatusDir = settings.value("refreshStatusDir", false).toBool();
883    m_refreshStatusDirInterval = settings.value("refreshStatusDirInterval", 28).toInt();
884    settings.endGroup();
885    settings.beginGroup("Misc");
886    m_longList = settings.value("longList", false).toBool();
887    ItemFormatterBase::setBytesConversion(
888          (ItemFormatterBase::BYTES_CONVERSION) settings.value("byteConvert", 
889          ItemFormatterBase::BYTES_CONVERSION_IEC).toInt());
890    m_openPlot = settings.value("openplot", false).toBool();
891    m_openBrowser = settings.value("openbrowser", false).toBool();
892    m_openDirStat = settings.value("opendirstat", false).toBool();
893    settings.endGroup();
894    settings.beginGroup("RestoreTree");
895    m_rtPopDirDebug = settings.value("rtPopDirDebug", false).toBool();
896    m_rtDirCurICDebug = settings.value("rtDirCurICDebug", false).toBool();
897    m_rtDirICDebug = settings.value("rtDirCurICRetDebug", false).toBool();
898    m_rtFileTabICDebug = settings.value("rtFileTabICDebug", false).toBool();
899    m_rtVerTabICDebug = settings.value("rtVerTabICDebug", false).toBool();
900    m_rtUpdateFTDebug = settings.value("rtUpdateFTDebug", false).toBool();
901    m_rtUpdateVTDebug = settings.value("rtUpdateVTDebug", false).toBool();
902    m_rtChecksDebug = settings.value("rtChecksDebug", false).toBool();
903    m_rtIconStateDebug = settings.value("rtIconStateDebug", false).toBool();
904    m_rtRestore1Debug = settings.value("rtRestore1Debug", false).toBool();
905    m_rtRestore2Debug = settings.value("rtRestore2Debug", false).toBool();
906    m_rtRestore3Debug = settings.value("rtRestore3Debug", false).toBool();
907    settings.endGroup();
908 }
909
910 void MainWin::setMessageIcon()
911 {
912    if (m_currentConsole->is_messagesPending())
913       actionMessages->setIcon(QIcon(QString::fromUtf8(":/images/mail-message-pending.png")));
914    else
915       actionMessages->setIcon(QIcon(QString::fromUtf8(":/images/mail-message-new.png")));
916 }