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);
61 foreach(Console *console, m_consoleList){
66 void MainWin::createPages()
69 QTreeWidgetItem *item, *topItem;
72 foreach_res(dir, R_DIRECTOR) {
74 /* Create console tree stacked widget item */
75 m_currentConsole = new Console(stackedWidget);
76 m_consoleList.append(m_currentConsole);
77 m_currentConsole->setDirRes(dir);
79 /* The top tree item representing the director */
80 topItem = createTopPage(dir->name());
81 topItem->setIcon(0, QIcon(QString::fromUtf8("images/server.png")));
82 m_currentConsole->setDirectorTreeItem(topItem);
84 /* Create Tree Widget Item */
85 item = createPage("Console", topItem);
87 /* insert the cosole and tree widget item into the hashes */
88 hashInsert(item, m_currentConsole);
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_currentConsole->dockPage();
97 /* create instances of the rest of the classes that will by default exist
98 * under each director */
100 createPageMediaList();
101 QString emptymedia(""), emptyclient("");
102 createPageJobList(emptymedia, emptyclient);
105 treeWidget->expandItem(topItem);
106 stackedWidget->setCurrentWidget(m_currentConsole);
109 m_currentConsole = m_consoleList[0];
110 item = getFromHash(m_currentConsole);
111 treeWidget->setCurrentItem(item);
115 * create an instance of the the brestore class on the stack
117 void MainWin::createPagebRestore()
119 bRestore* brestore = new bRestore();
120 brestore->dockPage();
124 * create an instance of the the medialist class on the stack
126 void MainWin::createPageMediaList()
128 MediaList* medialist = new MediaList();
129 medialist->dockPage();
133 * create an instance of the the joblist class on the stack
135 void MainWin::createPageJobList(QString &media, QString &client)
137 QTreeWidgetItem *item, *holdItem;
139 /* save current tree widget item in case query produces no results */
140 holdItem = treeWidget->currentItem();
141 JobList* joblist = new JobList(media, client);
143 /* If this is a query of jobs on a specific media */
144 if ((media != "") || (client != "")) {
145 item = getFromHash(joblist);
146 treeWidget->setCurrentItem(item);
147 /* did query produce results, if not close window and set back to hold */
148 if (joblist->m_resultCount == 0) {
149 joblist->closeStackPage();
150 treeWidget->setCurrentItem(holdItem);
156 * create an instance of the the Clients class on the stack
158 void MainWin::createPageClients()
160 Clients* clients = new Clients();
165 /* Create a root Tree Widget */
166 QTreeWidgetItem *MainWin::createTopPage(char *name)
168 QTreeWidgetItem *item = new QTreeWidgetItem(treeWidget);
169 item->setText(0, name);
173 /* Create A Tree Widget Item which will be associated with a Page in the stacked widget */
174 QTreeWidgetItem *MainWin::createPage(char *name, QTreeWidgetItem *parent)
176 QTreeWidgetItem *item = new QTreeWidgetItem(parent);
177 item->setText(0, name);
182 * Handle up and down arrow keys for the command line
185 void MainWin::keyPressEvent(QKeyEvent *event)
187 if (m_cmd_history.size() == 0) {
191 switch (event->key()) {
193 if (m_cmd_last < 0 || m_cmd_last >= (m_cmd_history.size()-1)) {
200 if (m_cmd_last == 0) {
204 if (m_cmd_last < 0 || m_cmd_last > (m_cmd_history.size()-1)) {
205 m_cmd_last = m_cmd_history.size() - 1;
214 lineEdit->setText(m_cmd_history[m_cmd_last]);
217 void MainWin::createConnections()
219 /* Connect signals to slots */
220 connect(lineEdit, SIGNAL(returnPressed()), this, SLOT(input_line()));
221 connect(actionAbout_bat, SIGNAL(triggered()), this, SLOT(about()));
224 connect(treeWidget, SIGNAL(itemActivated(QTreeWidgetItem *, int)), this,
225 SLOT(treeItemClicked(QTreeWidgetItem *, int)));
226 connect(treeWidget, SIGNAL(itemPressed(QTreeWidgetItem *, int)), this,
227 SLOT(treeItemClicked(QTreeWidgetItem *, int)));
229 connect(treeWidget, SIGNAL(itemClicked(QTreeWidgetItem *, int)), this,
230 SLOT(treeItemClicked(QTreeWidgetItem *, int)));
231 connect(treeWidget, SIGNAL(itemDoubleClicked(QTreeWidgetItem *, int)), this,
232 SLOT(treeItemDoubleClicked(QTreeWidgetItem *, int)));
233 connect(treeWidget, SIGNAL(
234 currentItemChanged(QTreeWidgetItem *, QTreeWidgetItem *)),
235 this, SLOT(treeItemChanged(QTreeWidgetItem *, QTreeWidgetItem *)));
236 connect(stackedWidget, SIGNAL(currentChanged(int)),
237 this, SLOT(stackItemChanged(int)));
239 connect(actionQuit, SIGNAL(triggered()), app, SLOT(closeAllWindows()));
240 foreach(Console *console, m_consoleList){
241 connect(actionConnect, SIGNAL(triggered()), console, SLOT(connect()));
242 connect(actionStatusDir, SIGNAL(triggered()), console, SLOT(status_dir()));
243 connect(actionSelectFont, SIGNAL(triggered()), console, SLOT(set_font()));
245 connect(actionLabel, SIGNAL(triggered()), this, SLOT(labelDialogClicked()));
246 connect(actionRun, SIGNAL(triggered()), this, SLOT(runDialogClicked()));
247 connect(actionRestore, SIGNAL(triggered()), this, SLOT(restoreDialogClicked()));
248 connect(actionUndock, SIGNAL(triggered()), this, SLOT(undockWindowButton()));
249 connect(actionToggleDock, SIGNAL(triggered()), this, SLOT(toggleDockContextWindow()));
250 connect(actionClosePage, SIGNAL(triggered()), this, SLOT(closePage()));
254 * Reimplementation of QWidget closeEvent virtual function
256 void MainWin::closeEvent(QCloseEvent *event)
259 foreach(Console *console, m_consoleList){
260 console->writeSettings();
261 console->terminate();
264 foreach(Pages *page, m_pagehash) {
265 if (!page->isDocked())
270 void MainWin::writeSettings()
272 QSettings settings("bacula.org", "bat");
274 settings.beginGroup("MainWin");
275 settings.setValue("winSize", size());
276 settings.setValue("winPos", pos());
280 void MainWin::readSettings()
282 QSettings settings("bacula.org", "bat");
284 settings.beginGroup("MainWin");
285 resize(settings.value("winSize", QSize(1041, 801)).toSize());
286 move(settings.value("winPos", QPoint(200, 150)).toPoint());
291 * This subroutine is called with an item in the Page Selection window
294 void MainWin::treeItemClicked(QTreeWidgetItem *item, int /*column*/)
296 /* Is this a page that has been inserted into the hash */
297 if (getFromHash(item)) {
298 Pages* page = getFromHash(item);
299 int stackindex=stackedWidget->indexOf(page);
301 if (stackindex >= 0) {
302 stackedWidget->setCurrentWidget(page);
304 /* run the virtual function in case this class overrides it */
305 page->PgSeltreeWidgetClicked();
310 * This subroutine is called with an item in the Page Selection window
313 /* This could be removed from here and from pages and from medialist
314 * Do you agree dhb */
315 void MainWin::treeItemDoubleClicked(QTreeWidgetItem *item, int /*column*/)
317 Pages* page = getFromHash(item);
318 page->PgSeltreeWidgetDoubleClicked();
322 * Called with a change of the highlighed tree widget item in the page selector.
324 void MainWin::treeItemChanged(QTreeWidgetItem *currentitem, QTreeWidgetItem *previousitem)
326 /* The Previous item */
329 /* make sure the close window and toggle dock options are removed */
330 treeWidget->removeAction(actionClosePage);
331 treeWidget->removeAction(actionToggleDock);
332 /* Is this a page that has been inserted into the hash */
333 if (getFromHash(previousitem)) {
334 Pages* page = getFromHash(previousitem);
335 foreach(QAction* pageaction, page->m_contextActions) {
336 treeWidget->removeAction(pageaction);
341 /* Is this a page that has been inserted into the hash */
342 if (getFromHash(currentitem)) {
343 /* knowing the treeWidgetItem, get the page from the hash */
344 Pages* page = getFromHash(currentitem);
345 /* set the value for the currently active console */
346 m_currentConsole = page->console();
347 int stackindex = stackedWidget->indexOf(page);
349 /* Is this page currently on the stack */
350 if (stackindex >= 0) {
351 /* put this page on the top of the stack */
352 stackedWidget->setCurrentIndex(stackindex);
354 /* it is undocked, raise it to the front */
357 setContextMenuDockText(page, currentitem);
359 treeWidget->addAction(actionToggleDock);
360 /* if this page is closeable, then add that action */
361 if (page->isCloseable()) {
362 treeWidget->addAction(actionClosePage);
365 /* Add the actions to the Page Selectors tree widget that are part of the
366 * current items list of desired actions regardless of whether on top of stack*/
367 treeWidget->addActions(page->m_contextActions);
371 void MainWin::labelDialogClicked()
373 new labelDialog(m_currentConsole);
376 void MainWin::runDialogClicked()
378 new runDialog(m_currentConsole);
381 void MainWin::restoreDialogClicked()
383 new prerestoreDialog(m_currentConsole);
387 * The user just finished typing a line in the command line edit box
389 void MainWin::input_line()
391 QString cmdStr = lineEdit->text(); /* Get the text */
392 lineEdit->clear(); /* clear the lineEdit box */
393 if (m_currentConsole->is_connected()) {
394 m_currentConsole->display_text(cmdStr + "\n");
395 m_currentConsole->write_dir(cmdStr.toUtf8().data()); /* send to dir */
397 set_status("Director not connected. Click on connect button.");
399 m_cmd_history.append(cmdStr);
404 void MainWin::about()
406 QMessageBox::about(this, tr("About bat"),
407 tr("<br><h2>bat 0.2, by Kern Sibbald</h2>"
408 "<p>Copyright © " BYEAR " Free Software Foundation Europe e.V."
409 "<p>The <b>bat</b> is an administrative console"
410 " interface to the Director."));
413 void MainWin::set_statusf(const char *fmt, ...)
418 va_start(arg_ptr, fmt);
419 len = bvsnprintf(buf, sizeof(buf), fmt, arg_ptr);
424 void MainWin::set_status_ready()
426 set_status(" Ready");
429 void MainWin::set_status(const char *buf)
431 statusBar()->showMessage(buf);
435 * Function to respond to the button bar button to undock
437 void MainWin::undockWindowButton()
439 Pages* page = (Pages*)stackedWidget->currentWidget();
440 page->togglePageDocking();
441 /* The window has been undocked, lets change the context menu */
442 setContextMenuDockText();
446 * Function to respond to action on page selector context menu to toggle the
447 * dock status of the window associated with the page selectors current
450 void MainWin::toggleDockContextWindow()
452 QTreeWidgetItem *currentitem = treeWidget->currentItem();
454 /* Is this a page that has been inserted into the hash */
455 if (getFromHash(currentitem)) {
456 Pages* page = getFromHash(currentitem);
457 page->togglePageDocking();
458 if (page->isDocked()) {
459 stackedWidget->setCurrentWidget(page);
461 /* Toggle the menu item. The window's dock status has been toggled */
462 setContextMenuDockText(page, currentitem);
467 * Function to set the text of the toggle dock context menu when page and
468 * widget item are NOT known. This is an overoaded funciton.
469 * It is called from MainWin::undockWindowButton, it is not intended to change
470 * for the top pages tree widget, it is for the currently active tree widget
471 * item. Which is why the page is not passed.
473 void MainWin::setContextMenuDockText()
475 QTreeWidgetItem *currentitem = treeWidget->currentItem();
477 /* Is this a page that has been inserted into the hash */
478 if (getFromHash(currentitem)) {
479 Pages* page = getFromHash(currentitem);
480 setContextMenuDockText(page, currentitem);
485 * Function to set the text of the toggle dock context menu when page and
486 * widget item are known. This is the more commonly used.
488 void MainWin::setContextMenuDockText(Pages* page, QTreeWidgetItem* item)
490 QString docktext("");
491 if (page->isDocked()) {
492 docktext += "UnDock ";
494 docktext += "ReDock ";
496 docktext += item->text(0) += " Window";
498 actionToggleDock->setText(docktext);
499 setTreeWidgetItemDockColor(page, item);
503 * Function to set the color of the tree widget item based on whether it is
506 void MainWin::setTreeWidgetItemDockColor(Pages* page, QTreeWidgetItem* item)
508 if (item->text(0) != "Console") {
509 if (page->isDocked()) {
510 /* Set the brush to blue if undocked */
511 QBrush blackBrush(Qt::black);
512 item->setForeground(0, blackBrush);
514 /* Set the brush back to black if docked */
515 QBrush blueBrush(Qt::blue);
516 item->setForeground(0, blueBrush);
522 * Overload of previous function, use treeindex to get item from page
523 * This is called when an undocked window is closed.
525 void MainWin::setTreeWidgetItemDockColor(Pages* page)
527 QTreeWidgetItem* item = getFromHash(page);
529 setTreeWidgetItemDockColor(page, item);
534 * This function is called when the stack item is changed. Call
535 * the virtual function here. Avoids a window being undocked leaving
536 * a window at the top of the stack unpopulated.
538 void MainWin::stackItemChanged(int)
540 Pages* page = (Pages*)stackedWidget->currentWidget();
541 /* run the virtual function in case this class overrides it */
542 page->currentStackItem();
546 * Function to simplify insertion of QTreeWidgetItem <-> Page association
547 * into a double direction hash.
549 void MainWin::hashInsert(QTreeWidgetItem *item, Pages *page)
551 m_pagehash.insert(item, page);
552 m_widgethash.insert(page, item);
556 * Function to simplify removal of QTreeWidgetItem <-> Page association
557 * into a double direction hash.
559 void MainWin::hashRemove(QTreeWidgetItem *item, Pages *page)
561 /* I had all sorts of return status checking code here. Do we have a log
562 * level capability in bat. I would have left it in but it used printf's
563 * and it should really be some kind of log level facility ???
564 * ******FIXME********/
565 m_pagehash.remove(item);
566 m_widgethash.remove(page);
570 * Function to retrieve a Page* when the item in the page selector's tree is
573 Pages* MainWin::getFromHash(QTreeWidgetItem *item)
575 return m_pagehash.value(item);
579 * Function to retrieve the page selectors tree widget item when the page is
582 QTreeWidgetItem* MainWin::getFromHash(Pages *page)
584 return m_widgethash.value(page);
588 * Function to respond to action on page selector context menu to close the
591 void MainWin::closePage()
593 QTreeWidgetItem *currentitem = treeWidget->currentItem();
595 /* Is this a page that has been inserted into the hash */
596 if (getFromHash(currentitem)) {
597 Pages* page = getFromHash(currentitem);
598 if (page->isCloseable()) {
599 page->closeStackPage();