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