2 Bacula® - The Network Backup Solution
4 Copyright (C) 2007-2007 Free Software Foundation Europe e.V.
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 plus additions
11 that are listed in the file LICENSE.
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.
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
23 Bacula® is a registered trademark of John Walker.
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.
32 * Main Window control for bat (qt-console)
34 * Kern Sibbald, January MMVII
39 #include "joblist/joblist.h"
41 MainWin::MainWin(QWidget *parent) : QMainWindow(parent)
45 setupUi(this); /* Setup UI defined by main.ui (designer) */
47 treeWidget->setColumnCount(1);
48 treeWidget->setHeaderLabel("Select Page");
49 treeWidget->setContextMenuPolicy(Qt::ActionsContextMenu);
64 void MainWin::createPages()
67 QTreeWidgetItem *item;
69 /* Create console tree stacked widget item */
70 m_console = new Console(stackedWidget);
72 /* Console is special -> needs director*/
73 /* Just take the first Director */
75 dir = (DIRRES *)GetNextRes(R_DIRECTOR, NULL);
76 m_console->setDirRes(dir);
79 /* The top tree item representing the director */
80 m_topItem = createTopPage(dir->name());
81 m_topItem->setIcon(0, QIcon(QString::fromUtf8("images/server.png")));
83 /* Create Tree Widget Item */
84 item = createPage("Console", m_topItem);
85 m_console->setTreeItem(item);
87 /* insert the cosole and tree widget item into the hashes */
88 hashInsert(item, m_console);
90 /* Set Color of treeWidgetItem for the console
91 * It will be set to green in the console class if the connection is made.
93 QBrush redBrush(Qt::red);
94 item->setForeground(0, redBrush);
95 m_console->dockPage();
97 /* create instances of the rest of the classes that will by default exist
98 * under each director */
100 createPagemedialist();
101 QString emptymedia("");
102 createPagejoblist(emptymedia);
104 treeWidget->expandItem(m_topItem);
105 stackedWidget->setCurrentWidget(m_console);
109 * create an instance of the the brestore class on the stack
111 void MainWin::createPagebrestore()
113 QTreeWidgetItem *item=createPage("brestore", m_topItem);
114 bRestore* brestore = new bRestore(stackedWidget);
115 hashInsert(item, brestore);
116 brestore->dockPage();
120 * create an instance of the the medialist class on the stack
122 void MainWin::createPagemedialist()
124 QTreeWidgetItem *item=createPage("Media", m_topItem);
125 MediaList* medialist = new MediaList(stackedWidget, m_console);
126 hashInsert(item, medialist);
127 medialist->dockPage();
131 * create an instance of the the joblist class on the stack
133 void MainWin::createPagejoblist(QString &media)
135 QTreeWidgetItem *item, *holdItem;
136 /* save current tree widget item in case query produces no results */
137 holdItem = treeWidget->currentItem();
139 item=createPage("All Jobs", m_topItem);
141 QString desc("Jobs on ");
143 item=createPage(desc.toUtf8().data(), m_topItem);
145 JobList* joblist = new JobList(stackedWidget, m_console, media);
146 hashInsert(item, joblist);
148 /* If this is a query of jobs on a specific media */
150 stackedWidget->setCurrentWidget(joblist);
151 treeWidget->setCurrentItem(item);
152 /* did query produce results, if not close window and set back to hold */
153 if (joblist->m_resultCount == 0) {
154 joblist->closeStackPage();
155 treeWidget->setCurrentItem(holdItem);
160 /* Create a root Tree Widget */
161 QTreeWidgetItem *MainWin::createTopPage(char *name)
163 QTreeWidgetItem *item = new QTreeWidgetItem(treeWidget);
164 item->setText(0, name);
168 /* Create A Tree Widget Item which will be associated with a Page in the stacked widget */
169 QTreeWidgetItem *MainWin::createPage(char *name, QTreeWidgetItem *parent)
171 QTreeWidgetItem *item = new QTreeWidgetItem(parent);
172 item->setText(0, name);
177 * Handle up and down arrow keys for the command line
180 void MainWin::keyPressEvent(QKeyEvent *event)
182 if (m_cmd_history.size() == 0) {
186 switch (event->key()) {
188 if (m_cmd_last < 0 || m_cmd_last >= (m_cmd_history.size()-1)) {
195 if (m_cmd_last == 0) {
199 if (m_cmd_last < 0 || m_cmd_last > (m_cmd_history.size()-1)) {
200 m_cmd_last = m_cmd_history.size() - 1;
209 lineEdit->setText(m_cmd_history[m_cmd_last]);
212 void MainWin::createConnections()
214 /* Connect signals to slots */
215 connect(lineEdit, SIGNAL(returnPressed()), this, SLOT(input_line()));
216 connect(actionAbout_bat, SIGNAL(triggered()), this, SLOT(about()));
219 connect(treeWidget, SIGNAL(itemActivated(QTreeWidgetItem *, int)), this,
220 SLOT(treeItemClicked(QTreeWidgetItem *, int)));
221 connect(treeWidget, SIGNAL(itemPressed(QTreeWidgetItem *, int)), this,
222 SLOT(treeItemClicked(QTreeWidgetItem *, int)));
224 connect(treeWidget, SIGNAL(itemClicked(QTreeWidgetItem *, int)), this,
225 SLOT(treeItemClicked(QTreeWidgetItem *, int)));
226 connect(treeWidget, SIGNAL(itemDoubleClicked(QTreeWidgetItem *, int)), this,
227 SLOT(treeItemDoubleClicked(QTreeWidgetItem *, int)));
228 connect(treeWidget, SIGNAL(
229 currentItemChanged(QTreeWidgetItem *, QTreeWidgetItem *)),
230 this, SLOT(treeItemChanged(QTreeWidgetItem *, QTreeWidgetItem *)));
231 connect(stackedWidget, SIGNAL(currentChanged(int)),
232 this, SLOT(stackItemChanged(int)));
234 connect(actionQuit, SIGNAL(triggered()), app, SLOT(closeAllWindows()));
235 connect(actionConnect, SIGNAL(triggered()), m_console, SLOT(connect()));
236 connect(actionStatusDir, SIGNAL(triggered()), m_console, SLOT(status_dir()));
237 connect(actionSelectFont, SIGNAL(triggered()), m_console, SLOT(set_font()));
238 connect(actionLabel, SIGNAL(triggered()), this, SLOT(labelDialogClicked()));
239 connect(actionRun, SIGNAL(triggered()), this, SLOT(runDialogClicked()));
240 connect(actionRestore, SIGNAL(triggered()), this, SLOT(restoreDialogClicked()));
241 connect(actionUndock, SIGNAL(triggered()), this, SLOT(undockWindowButton()));
242 connect(actionToggleDock, SIGNAL(triggered()), this, SLOT(toggleDockContextWindow()));
243 connect(actionClosePage, SIGNAL(triggered()), this, SLOT(closePage()));
247 * Reimplementation of QWidget closeEvent virtual function
249 void MainWin::closeEvent(QCloseEvent *event)
252 m_console->writeSettings();
253 m_console->terminate();
255 foreach(Pages *page, m_pagehash) {
256 if (!page->isDocked())
261 void MainWin::writeSettings()
263 QSettings settings("bacula.org", "bat");
265 settings.beginGroup("MainWin");
266 settings.setValue("winSize", size());
267 settings.setValue("winPos", pos());
271 void MainWin::readSettings()
273 QSettings settings("bacula.org", "bat");
275 settings.beginGroup("MainWin");
276 resize(settings.value("winSize", QSize(1041, 801)).toSize());
277 move(settings.value("winPos", QPoint(200, 150)).toPoint());
282 * This subroutine is called with an item in the Page Selection window
285 void MainWin::treeItemClicked(QTreeWidgetItem *item, int /*column*/)
287 /* Is this a page that has been inserted into the hash */
288 if (getFromHash(item)) {
289 Pages* page = getFromHash(item);
290 int stackindex=stackedWidget->indexOf(page);
292 if (stackindex >= 0) {
293 stackedWidget->setCurrentWidget(page);
295 /* run the virtual function in case this class overrides it */
296 page->PgSeltreeWidgetClicked();
301 * This subroutine is called with an item in the Page Selection window
304 /* This could be removed from here and from pages and from medialist
305 * Do you agree dhb */
306 void MainWin::treeItemDoubleClicked(QTreeWidgetItem *item, int /*column*/)
308 Pages* page = getFromHash(item);
309 page->PgSeltreeWidgetDoubleClicked();
313 * Called with a change of the highlighed tree widget item in the page selector.
315 void MainWin::treeItemChanged(QTreeWidgetItem *currentitem, QTreeWidgetItem *previousitem)
317 /* The Previous item */
320 /* make sure the close window and toggle dock options are removed */
321 treeWidget->removeAction(actionClosePage);
322 treeWidget->removeAction(actionToggleDock);
323 /* Is this a page that has been inserted into the hash */
324 if (getFromHash(previousitem)) {
325 Pages* page = getFromHash(previousitem);
326 foreach(QAction* pageaction, page->m_contextActions) {
327 treeWidget->removeAction(pageaction);
332 /* Is this a page that has been inserted into the hash */
333 if (getFromHash(currentitem)) {
334 Pages* page = getFromHash(currentitem);
335 int stackindex = stackedWidget->indexOf(page);
337 /* Is this page currently on the stack */
338 if (stackindex >= 0) {
339 /* put this page on the top of the stack */
340 stackedWidget->setCurrentIndex(stackindex);
342 /* it is undocked, raise it to the front */
345 setContextMenuDockText(page, currentitem);
347 treeWidget->addAction(actionToggleDock);
348 /* if this page is closeable, then add that action */
349 if (page->isCloseable()) {
350 treeWidget->addAction(actionClosePage);
353 /* Add the actions to the Page Selectors tree widget that are part of the
354 * current items list of desired actions regardless of whether on top of stack*/
355 treeWidget->addActions(page->m_contextActions);
359 void MainWin::labelDialogClicked()
361 new labelDialog(m_console);
364 void MainWin::runDialogClicked()
366 new runDialog(m_console);
369 void MainWin::restoreDialogClicked()
371 new prerestoreDialog(m_console);
377 * The user just finished typing a line in the command line edit box
379 void MainWin::input_line()
381 QString cmdStr = lineEdit->text(); /* Get the text */
382 lineEdit->clear(); /* clear the lineEdit box */
383 if (m_console->is_connected()) {
384 m_console->display_text(cmdStr + "\n");
385 m_console->write_dir(cmdStr.toUtf8().data()); /* send to dir */
387 set_status("Director not connected. Click on connect button.");
389 m_cmd_history.append(cmdStr);
394 void MainWin::about()
396 QMessageBox::about(this, tr("About bat"),
397 tr("<br><h2>bat 0.2, by Kern Sibbald</h2>"
398 "<p>Copyright © " BYEAR " Free Software Foundation Europe e.V."
399 "<p>The <b>bat</b> is an administrative console"
400 " interface to the Director."));
403 void MainWin::set_statusf(const char *fmt, ...)
408 va_start(arg_ptr, fmt);
409 len = bvsnprintf(buf, sizeof(buf), fmt, arg_ptr);
414 void MainWin::set_status_ready()
416 set_status(" Ready");
419 void MainWin::set_status(const char *buf)
421 statusBar()->showMessage(buf);
425 * Function to respond to the button bar button to undock
427 void MainWin::undockWindowButton()
429 Pages* page = (Pages*)stackedWidget->currentWidget();
430 page->togglePageDocking();
431 /* The window has been undocked, lets change the context menu */
432 setContextMenuDockText();
436 * Function to respond to action on page selector context menu to toggle the
437 * dock status of the window associated with the page selectors current
440 void MainWin::toggleDockContextWindow()
442 QTreeWidgetItem *currentitem = treeWidget->currentItem();
444 /* Is this a page that has been inserted into the hash */
445 if (getFromHash(currentitem)) {
446 Pages* page = getFromHash(currentitem);
447 page->togglePageDocking();
448 if (page->isDocked()) {
449 stackedWidget->setCurrentWidget(page);
451 /* Toggle the menu item. The window's dock status has been toggled */
452 setContextMenuDockText(page, currentitem);
457 * Function to set the text of the toggle dock context menu when page and
458 * widget item are NOT known. This is an overoaded funciton.
459 * It is called from MainWin::undockWindowButton, it is not intended to change
460 * for the top pages tree widget, it is for the currently active tree widget
461 * item. Which is why the page is not passed.
463 void MainWin::setContextMenuDockText()
465 QTreeWidgetItem *currentitem = treeWidget->currentItem();
467 /* Is this a page that has been inserted into the hash */
468 if (getFromHash(currentitem)) {
469 Pages* page = getFromHash(currentitem);
470 setContextMenuDockText(page, currentitem);
475 * Function to set the text of the toggle dock context menu when page and
476 * widget item are known. This is the more commonly used.
478 void MainWin::setContextMenuDockText(Pages* page, QTreeWidgetItem* item)
480 QString docktext("");
481 if (page->isDocked()) {
482 docktext += "UnDock ";
484 docktext += "ReDock ";
486 docktext += item->text(0) += " Window";
488 actionToggleDock->setText(docktext);
489 setTreeWidgetItemDockColor(page, item);
493 * Function to set the color of the tree widget item based on whether it is
496 void MainWin::setTreeWidgetItemDockColor(Pages* page, QTreeWidgetItem* item)
498 if (item->text(0) != "Console") {
499 if (page->isDocked()) {
500 /* Set the brush to blue if undocked */
501 QBrush blackBrush(Qt::black);
502 item->setForeground(0, blackBrush);
504 /* Set the brush back to black if docked */
505 QBrush blueBrush(Qt::blue);
506 item->setForeground(0, blueBrush);
512 * Overload of previous function, use treeindex to get item from page
513 * This is called when an undocked window is closed.
515 void MainWin::setTreeWidgetItemDockColor(Pages* page)
517 QTreeWidgetItem* item = getFromHash(page);
519 setTreeWidgetItemDockColor(page, item);
524 * This function is called when the stack item is changed. Call
525 * the virtual function here. Avoids a window being undocked leaving
526 * a window at the top of the stack unpopulated.
528 void MainWin::stackItemChanged(int)
530 Pages* page = (Pages*)stackedWidget->currentWidget();
531 /* run the virtual function in case this class overrides it */
532 page->currentStackItem();
536 * Function to simplify insertion of QTreeWidgetItem <-> Page association
537 * into a double direction hash.
539 void MainWin::hashInsert(QTreeWidgetItem *item, Pages *page)
541 m_pagehash.insert(item, page);
542 m_widgethash.insert(page, item);
546 * Function to simplify removal of QTreeWidgetItem <-> Page association
547 * into a double direction hash.
549 void MainWin::hashRemove(QTreeWidgetItem *item, Pages *page)
551 /* I had all sorts of return status checking code here. Do we have a log
552 * level capability in bat. I would have left it in but it used printf's
553 * and it should really be some kind of log level facility ???
554 * ******FIXME********/
555 m_pagehash.remove(item);
556 m_widgethash.remove(page);
560 * Function to retrieve a Page* when the item in the page selector's tree is
563 Pages* MainWin::getFromHash(QTreeWidgetItem *item)
565 return m_pagehash.value(item);
569 * Function to retrieve the page selectors tree widget item when the page is
572 QTreeWidgetItem* MainWin::getFromHash(Pages *page)
574 return m_widgethash.value(page);
578 * Function to respond to action on page selector context menu to close the
581 void MainWin::closePage()
583 QTreeWidgetItem *currentitem = treeWidget->currentItem();
585 /* Is this a page that has been inserted into the hash */
586 if (getFromHash(currentitem)) {
587 Pages* page = getFromHash(currentitem);
588 if (page->isCloseable()) {
589 page->closeStackPage();