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