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