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;
137 item=createPage("All Jobs", m_topItem);
139 QString desc("Jobs on ");
141 item=createPage(desc.toUtf8().data(), m_topItem);
143 JobList* joblist = new JobList(stackedWidget, m_console, media);
144 hashInsert(item, joblist);
147 stackedWidget->setCurrentWidget(joblist);
148 treeWidget->setCurrentItem(item);
152 /* Create a root Tree Widget */
153 QTreeWidgetItem *MainWin::createTopPage(char *name)
155 QTreeWidgetItem *item = new QTreeWidgetItem(treeWidget);
156 item->setText(0, name);
160 /* Create A Tree Widget Item which will be associated with a Page in the stacked widget */
161 QTreeWidgetItem *MainWin::createPage(char *name, QTreeWidgetItem *parent)
163 QTreeWidgetItem *item = new QTreeWidgetItem(parent);
164 item->setText(0, name);
169 * Handle up and down arrow keys for the command line
172 void MainWin::keyPressEvent(QKeyEvent *event)
174 if (m_cmd_history.size() == 0) {
178 switch (event->key()) {
180 if (m_cmd_last < 0 || m_cmd_last >= (m_cmd_history.size()-1)) {
187 if (m_cmd_last == 0) {
191 if (m_cmd_last < 0 || m_cmd_last > (m_cmd_history.size()-1)) {
192 m_cmd_last = m_cmd_history.size() - 1;
201 lineEdit->setText(m_cmd_history[m_cmd_last]);
204 void MainWin::createConnections()
206 /* Connect signals to slots */
207 connect(lineEdit, SIGNAL(returnPressed()), this, SLOT(input_line()));
208 connect(actionAbout_bat, SIGNAL(triggered()), this, SLOT(about()));
211 connect(treeWidget, SIGNAL(itemActivated(QTreeWidgetItem *, int)), this,
212 SLOT(treeItemClicked(QTreeWidgetItem *, int)));
213 connect(treeWidget, SIGNAL(itemPressed(QTreeWidgetItem *, int)), this,
214 SLOT(treeItemClicked(QTreeWidgetItem *, int)));
216 connect(treeWidget, SIGNAL(itemClicked(QTreeWidgetItem *, int)), this,
217 SLOT(treeItemClicked(QTreeWidgetItem *, int)));
218 connect(treeWidget, SIGNAL(itemDoubleClicked(QTreeWidgetItem *, int)), this,
219 SLOT(treeItemDoubleClicked(QTreeWidgetItem *, int)));
220 connect(treeWidget, SIGNAL(
221 currentItemChanged(QTreeWidgetItem *, QTreeWidgetItem *)),
222 this, SLOT(treeItemChanged(QTreeWidgetItem *, QTreeWidgetItem *)));
223 connect(stackedWidget, SIGNAL(currentChanged(int)),
224 this, SLOT(stackItemChanged(int)));
226 connect(actionQuit, SIGNAL(triggered()), app, SLOT(closeAllWindows()));
227 connect(actionConnect, SIGNAL(triggered()), m_console, SLOT(connect()));
228 connect(actionStatusDir, SIGNAL(triggered()), m_console, SLOT(status_dir()));
229 connect(actionSelectFont, SIGNAL(triggered()), m_console, SLOT(set_font()));
230 connect(actionLabel, SIGNAL(triggered()), this, SLOT(labelDialogClicked()));
231 connect(actionRun, SIGNAL(triggered()), this, SLOT(runDialogClicked()));
232 connect(actionRestore, SIGNAL(triggered()), this, SLOT(restoreDialogClicked()));
233 connect(actionUndock, SIGNAL(triggered()), this, SLOT(undockWindowButton()));
234 connect(actionToggleDock, SIGNAL(triggered()), this, SLOT(toggleDockContextWindow()));
235 connect(actionClosePage, SIGNAL(triggered()), this, SLOT(closePage()));
239 * Reimplementation of QWidget closeEvent virtual function
241 void MainWin::closeEvent(QCloseEvent *event)
244 m_console->writeSettings();
245 m_console->terminate();
247 foreach(Pages *page, m_pagehash) {
248 if (!page->isDocked())
253 void MainWin::writeSettings()
255 QSettings settings("bacula.org", "bat");
257 settings.beginGroup("MainWin");
258 settings.setValue("winSize", size());
259 settings.setValue("winPos", pos());
263 void MainWin::readSettings()
265 QSettings settings("bacula.org", "bat");
267 settings.beginGroup("MainWin");
268 resize(settings.value("winSize", QSize(1041, 801)).toSize());
269 move(settings.value("winPos", QPoint(200, 150)).toPoint());
274 * This subroutine is called with an item in the Page Selection window
277 void MainWin::treeItemClicked(QTreeWidgetItem *item, int /*column*/)
279 /* Is this a page that has been inserted into the hash */
280 if (getFromHash(item)) {
281 Pages* page = getFromHash(item);
282 int stackindex=stackedWidget->indexOf(page);
284 if (stackindex >= 0) {
285 stackedWidget->setCurrentWidget(page);
287 /* run the virtual function in case this class overrides it */
288 page->PgSeltreeWidgetClicked();
293 * This subroutine is called with an item in the Page Selection window
296 /* This could be removed from here and from pages and from medialist
297 * Do you agree dhb */
298 void MainWin::treeItemDoubleClicked(QTreeWidgetItem *item, int /*column*/)
300 Pages* page = getFromHash(item);
301 page->PgSeltreeWidgetDoubleClicked();
305 * Called with a change of the highlighed tree widget item in the page selector.
307 void MainWin::treeItemChanged(QTreeWidgetItem *currentitem, QTreeWidgetItem *previousitem)
309 /* The Previous item */
312 /* Is this a page that has been inserted into the hash */
313 if (getFromHash(previousitem)) {
314 Pages* page = getFromHash(previousitem);
315 treeWidget->removeAction(actionToggleDock);
316 /* make sure the close window option is removed */
317 if (page->isCloseable()) {
318 treeWidget->removeAction(actionClosePage);
320 foreach(QAction* pageaction, page->m_contextActions) {
321 treeWidget->removeAction(pageaction);
326 /* Is this a page that has been inserted into the hash */
327 if (getFromHash(currentitem)) {
328 Pages* page = getFromHash(currentitem);
329 int stackindex = stackedWidget->indexOf(page);
331 /* Is this page currently on the stack */
332 if (stackindex >= 0) {
333 /* put this page on the top of the stack */
334 stackedWidget->setCurrentIndex(stackindex);
336 /* it is undocked, raise it to the front */
339 setContextMenuDockText(page, currentitem);
341 treeWidget->addAction(actionToggleDock);
342 /* if this page is closeable, then add that action */
343 if (page->isCloseable()) {
344 treeWidget->addAction(actionClosePage);
347 /* Add the actions to the Page Selectors tree widget that are part of the
348 * current items list of desired actions regardless of whether on top of stack*/
349 treeWidget->addActions(page->m_contextActions);
353 void MainWin::labelDialogClicked()
355 new labelDialog(m_console);
358 void MainWin::runDialogClicked()
360 new runDialog(m_console);
363 void MainWin::restoreDialogClicked()
365 new prerestoreDialog(m_console);
371 * The user just finished typing a line in the command line edit box
373 void MainWin::input_line()
375 QString cmdStr = lineEdit->text(); /* Get the text */
376 lineEdit->clear(); /* clear the lineEdit box */
377 if (m_console->is_connected()) {
378 m_console->display_text(cmdStr + "\n");
379 m_console->write_dir(cmdStr.toUtf8().data()); /* send to dir */
381 set_status("Director not connected. Click on connect button.");
383 m_cmd_history.append(cmdStr);
388 void MainWin::about()
390 QMessageBox::about(this, tr("About bat"),
391 tr("<br><h2>bat 0.2, by Kern Sibbald</h2>"
392 "<p>Copyright © " BYEAR " Free Software Foundation Europe e.V."
393 "<p>The <b>bat</b> is an administrative console"
394 " interface to the Director."));
397 void MainWin::set_statusf(const char *fmt, ...)
402 va_start(arg_ptr, fmt);
403 len = bvsnprintf(buf, sizeof(buf), fmt, arg_ptr);
408 void MainWin::set_status_ready()
410 set_status(" Ready");
413 void MainWin::set_status(const char *buf)
415 statusBar()->showMessage(buf);
419 * Function to respond to the button bar button to undock
421 void MainWin::undockWindowButton()
423 Pages* page = (Pages*)stackedWidget->currentWidget();
424 page->togglePageDocking();
425 /* The window has been undocked, lets change the context menu */
426 setContextMenuDockText();
430 * Function to respond to action on page selector context menu to toggle the
431 * dock status of the window associated with the page selectors current
434 void MainWin::toggleDockContextWindow()
436 QTreeWidgetItem *currentitem = treeWidget->currentItem();
438 /* Is this a page that has been inserted into the hash */
439 if (getFromHash(currentitem)) {
440 Pages* page = getFromHash(currentitem);
441 page->togglePageDocking();
442 if (page->isDocked()) {
443 stackedWidget->setCurrentWidget(page);
445 /* Toggle the menu item. The window's dock status has been toggled */
446 setContextMenuDockText(page, currentitem);
451 * Function to set the text of the toggle dock context menu when page and
452 * widget item are NOT known. This is an overoaded funciton.
453 * It is called from MainWin::undockWindowButton, it is not intended to change
454 * for the top pages tree widget, it is for the currently active tree widget
455 * item. Which is why the page is not passed.
457 void MainWin::setContextMenuDockText()
459 QTreeWidgetItem *currentitem = treeWidget->currentItem();
461 /* Is this a page that has been inserted into the hash */
462 if (getFromHash(currentitem)) {
463 Pages* page = getFromHash(currentitem);
464 setContextMenuDockText(page, currentitem);
469 * Function to set the text of the toggle dock context menu when page and
470 * widget item are known. This is the more commonly used.
472 void MainWin::setContextMenuDockText(Pages* page, QTreeWidgetItem* item)
474 QString docktext("");
475 if (page->isDocked()) {
476 docktext += "UnDock ";
478 docktext += "ReDock ";
480 docktext += item->text(0) += " Window";
482 actionToggleDock->setText(docktext);
483 setTreeWidgetItemDockColor(page, item);
487 * Function to set the color of the tree widget item based on whether it is
490 void MainWin::setTreeWidgetItemDockColor(Pages* page, QTreeWidgetItem* item)
492 if (item->text(0) != "Console") {
493 if (page->isDocked()) {
494 /* Set the brush to blue if undocked */
495 QBrush blackBrush(Qt::black);
496 item->setForeground(0, blackBrush);
498 /* Set the brush back to black if docked */
499 QBrush blueBrush(Qt::blue);
500 item->setForeground(0, blueBrush);
506 * Overload of previous function, use treeindex to get item from page
507 * This is called when an undocked window is closed.
509 void MainWin::setTreeWidgetItemDockColor(Pages* page)
511 QTreeWidgetItem* item = getFromHash(page);
513 setTreeWidgetItemDockColor(page, item);
518 * This function is called when the stack item is changed. Call
519 * the virtual function here. Avoids a window being undocked leaving
520 * a window at the top of the stack unpopulated.
522 void MainWin::stackItemChanged(int)
524 Pages* page = (Pages*)stackedWidget->currentWidget();
525 /* run the virtual function in case this class overrides it */
526 page->currentStackItem();
530 * Function to simplify insertion of QTreeWidgetItem <-> Page association
531 * into a double direction hash.
533 void MainWin::hashInsert(QTreeWidgetItem *item, Pages *page)
535 m_pagehash.insert(item, page);
536 m_widgethash.insert(page, item);
540 * Function to simplify removal of QTreeWidgetItem <-> Page association
541 * into a double direction hash.
543 void MainWin::hashRemove(QTreeWidgetItem *item, Pages *page)
545 /* I had all sorts of return status checking code here. Do we have a log
546 * level capability in bat. I would have left it in but it used printf's
547 * and it should really be some kind of log level facility ???
548 * ******FIXME********/
549 m_pagehash.remove(item);
550 m_widgethash.remove(page);
554 * Function to retrieve a Page* when the item in the page selector's tree is
557 Pages* MainWin::getFromHash(QTreeWidgetItem *item)
559 return m_pagehash.value(item);
563 * Function to retrieve the page selectors tree widget item when the page is
566 QTreeWidgetItem* MainWin::getFromHash(Pages *page)
568 return m_widgethash.value(page);
572 * Function to respond to action on page selector context menu to close the
575 void MainWin::closePage()
577 QTreeWidgetItem *currentitem = treeWidget->currentItem();
579 /* Is this a page that has been inserted into the hash */
580 if (getFromHash(currentitem)) {
581 Pages* page = getFromHash(currentitem);
582 if (page->isCloseable()) {
583 page->closeStackPage();