]> git.sur5r.net Git - bacula/bacula/blob - bacula/src/qt-console/mainwin.cpp
dhb move functions that were not slots from the slots part of mainwin.h
[bacula/bacula] / bacula / src / qt-console / mainwin.cpp
1 /*
2    Bacula® - The Network Backup Solution
3
4    Copyright (C) 2007-2007 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 plus additions
11    that are listed 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 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.
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
40 MainWin::MainWin(QWidget *parent) : QMainWindow(parent)
41 {
42
43    mainWin = this;
44    setupUi(this);                     /* Setup UI defined by main.ui (designer) */
45    treeWidget->clear();
46    treeWidget->setColumnCount(1);
47    treeWidget->setHeaderLabel("Select Page");
48    treeWidget->setContextMenuPolicy(Qt::ActionsContextMenu);
49
50    m_pages = 0;
51    createPages();
52
53    resetFocus();
54
55    createConnections();
56
57    this->show();
58
59    readSettings();
60
61    m_console->connect();
62 }
63
64 void MainWin::createPages()
65 {
66    DIRRES *dir;
67    QTreeWidgetItem *item, *topItem;
68
69    /* Create console tree stacked widget item */
70    m_console = new Console(stackedWidget);
71
72    /* Console is special -> needs director*/
73    /* Just take the first Director */
74    LockRes();
75    dir = (DIRRES *)GetNextRes(R_DIRECTOR, NULL);
76    m_console->setDirRes(dir);
77    UnlockRes();
78
79    /* The top tree item representing the director */
80    topItem = createTopPage(dir->name());
81    topItem->setData(0, Qt::UserRole, QVariant(m_pages));
82    m_pages++;
83    topItem->setIcon(0, QIcon(QString::fromUtf8("images/server.png")));
84
85    /* Create Tree Widget Item */
86    item = createPage("Console", topItem);
87    m_console->SetPassedValues(stackedWidget, item, m_pages );
88
89    /* Append to pagelist */
90    m_pagehash.insert(m_pages, m_console);
91
92    /* Set Color of treeWidgetItem for the console
93    * It will be set to gree in the console class if the connection is made.
94    */
95    QBrush redBrush(Qt::red);
96    item->setForeground(0, redBrush);
97
98    /*
99     * Now with the console created, on with the rest, these are easy   
100     * All should be
101     * 1. create tree widget item
102     * 2. create object passing pointer to tree widget item (modified constructors to pass QTreeWidget pointers)
103     * 3. append to stackhash
104     */
105
106    /* brestore */
107    m_pages++;
108    item=createPage("brestore", topItem);
109    bRestore* brestore=new bRestore(stackedWidget, item, m_pages);
110    m_pagehash.insert(m_pages, brestore);
111
112
113    /* lastly for now, the medialist */
114    m_pages++;
115    item=createPage("Media", topItem );
116    MediaList* medialist=new MediaList(stackedWidget, m_console, item, m_pages);
117    m_pagehash.insert(m_pages, medialist);
118
119    /* Iterate through and add to the stack */
120    foreach(Pages *page, m_pagehash)
121       page->dockPage();
122
123    treeWidget->expandItem(topItem);
124    stackedWidget->setCurrentIndex(0);
125 }
126
127 /* Create a root Tree Widget */
128 QTreeWidgetItem *MainWin::createTopPage(char *name)
129 {
130    QTreeWidgetItem *item = new QTreeWidgetItem(treeWidget);
131    item->setText(0, name);
132    return item;
133 }
134
135 /* Create A Tree Widget Item which will be associated with a Page in the stacked widget */
136 QTreeWidgetItem *MainWin::createPage(char *name, QTreeWidgetItem *parent)
137 {
138    QTreeWidgetItem *item = new QTreeWidgetItem(parent);
139    item->setText(0, name);
140    return item;
141 }
142
143 /*
144  * Handle up and down arrow keys for the command line
145  *  history.
146  */
147 void MainWin::keyPressEvent(QKeyEvent *event)
148 {
149    if (m_cmd_history.size() == 0) {
150       event->ignore();
151       return;
152    }
153    switch (event->key()) {
154    case Qt::Key_Down:
155       if (m_cmd_last < 0 || m_cmd_last >= (m_cmd_history.size()-1)) {
156          event->ignore();
157          return;
158       }
159       m_cmd_last++;
160       break;
161    case Qt::Key_Up:
162       if (m_cmd_last == 0) {
163          event->ignore();
164          return;
165       }
166       if (m_cmd_last < 0 || m_cmd_last > (m_cmd_history.size()-1)) {
167          m_cmd_last = m_cmd_history.size() - 1;
168       } else {
169          m_cmd_last--;
170       }
171       break;
172    default:
173       event->ignore();
174       return;
175    }
176    lineEdit->setText(m_cmd_history[m_cmd_last]);
177 }
178
179 void MainWin::createConnections()
180 {
181    /* Connect signals to slots */
182    connect(lineEdit, SIGNAL(returnPressed()), this, SLOT(input_line()));
183    connect(actionAbout_bat, SIGNAL(triggered()), this, SLOT(about()));
184
185 #ifdef xxx
186      connect(treeWidget, SIGNAL(itemActivated(QTreeWidgetItem *, int)), this, 
187            SLOT(treeItemClicked(QTreeWidgetItem *, int)));
188    connect(treeWidget, SIGNAL(itemPressed(QTreeWidgetItem *, int)), this, 
189            SLOT(treeItemClicked(QTreeWidgetItem *, int)));  
190 #endif
191    connect(treeWidget, SIGNAL(itemClicked(QTreeWidgetItem *, int)), this, 
192            SLOT(treeItemClicked(QTreeWidgetItem *, int)));
193    connect(treeWidget, SIGNAL(itemDoubleClicked(QTreeWidgetItem *, int)), this, 
194            SLOT(treeItemDoubleClicked(QTreeWidgetItem *, int)));
195    connect(treeWidget, SIGNAL(
196            currentItemChanged(QTreeWidgetItem *, QTreeWidgetItem *)),
197            this, SLOT(treeItemChanged(QTreeWidgetItem *, QTreeWidgetItem *)));
198    connect(stackedWidget, SIGNAL(currentChanged(int)),
199            this, SLOT(stackItemChanged(int)));
200
201    connect(actionQuit, SIGNAL(triggered()), app, SLOT(closeAllWindows()));
202    connect(actionConnect, SIGNAL(triggered()), m_console, SLOT(connect()));
203    connect(actionStatusDir, SIGNAL(triggered()), m_console, SLOT(status_dir()));
204    connect(actionSelectFont, SIGNAL(triggered()), m_console, SLOT(set_font()));
205    connect(actionLabel, SIGNAL(triggered()), this,  SLOT(labelDialogClicked()));
206    connect(actionRun, SIGNAL(triggered()), this,  SLOT(runDialogClicked()));
207    connect(actionRestore, SIGNAL(triggered()), this,  SLOT(restoreDialogClicked()));
208    connect(actionUndock, SIGNAL(triggered()), this,  SLOT(undockWindowButton()));
209    connect(actionToggleDock, SIGNAL(triggered()), this,  SLOT(toggleDockContextWindow()));
210 }
211
212 /* 
213  * Reimplementation of QWidget closeEvent virtual function   
214  */
215 void MainWin::closeEvent(QCloseEvent *event)
216 {
217    writeSettings();
218    m_console->writeSettings();
219    m_console->terminate();
220    event->accept();
221    foreach(Pages *page, m_pagehash){
222       if( !page->isDocked() )
223          page->close();
224    }
225 }
226
227 void MainWin::writeSettings()
228 {
229    QSettings settings("bacula.org", "bat");
230
231    settings.beginGroup("MainWin");
232    settings.setValue("winSize", size());
233    settings.setValue("winPos", pos());
234    settings.endGroup();
235 }
236
237 void MainWin::readSettings()
238
239    QSettings settings("bacula.org", "bat");
240
241    settings.beginGroup("MainWin");
242    resize(settings.value("winSize", QSize(1041, 801)).toSize());
243    move(settings.value("winPos", QPoint(200, 150)).toPoint());
244    settings.endGroup();
245 }
246
247 /*
248  * This subroutine is called with an item in the Page Selection window
249  *   is clicked 
250  */
251 void MainWin::treeItemClicked(QTreeWidgetItem *item, int column)
252 {
253    /* Use tree item's Qt::UserRole to get treeindex */
254    int treeindex = item->data(column, Qt::UserRole).toInt();
255
256    /* Is this one of the first level pages */
257    if( m_pagehash.value(treeindex) ){
258       Pages* page = m_pagehash.value(treeindex);
259       int stackindex=stackedWidget->indexOf(page);
260
261       if( stackindex >= 0 ){
262          stackedWidget->setCurrentIndex(0);
263          stackedWidget->setCurrentWidget(page);
264       }
265       /* run the virtual function in case this class overrides it */
266       if( treeindex > 0 ){
267          page->PgSeltreeWidgetClicked();
268       }
269    }
270 }
271
272 /*
273  * This subroutine is called with an item in the Page Selection window
274  *   is double clicked
275  */
276 void MainWin::treeItemDoubleClicked(QTreeWidgetItem * /*item*/, int /*column*/)
277 {
278 }
279
280 /*
281  * Called with a change of the highlighed tree widget item in the page selector.
282  */
283 void MainWin::treeItemChanged(QTreeWidgetItem *currentitem, QTreeWidgetItem *previousitem)
284 {
285    int treeindex;
286    /* The Previous item */
287
288    /* Use tree item's Qt::UserRole to get treeindex now for the previousitem */
289    if ( previousitem ){
290       treeindex = previousitem->data(0, Qt::UserRole).toInt();
291       /* Is this one of the first level pages */
292       if( m_pagehash.value(treeindex) ){
293          Pages* page = m_pagehash.value(treeindex);
294          treeWidget->removeAction(actionToggleDock);
295          foreach( QAction* pageaction, page->m_contextActions ){
296             treeWidget->removeAction(pageaction);
297          } 
298       }
299    }
300
301    /* Use tree item's Qt::UserRole to get treeindex */
302    treeindex = currentitem->data(0, Qt::UserRole).toInt();
303
304    /* Is this one of the first level pages */
305    if( m_pagehash.value(treeindex) ){
306       Pages* page = m_pagehash.value(treeindex);
307       int stackindex = stackedWidget->indexOf(page);
308    
309       /* Is this page currently on the stack */
310       if( stackindex >= 0 ){
311          /* put this page on the top of the stack */
312          stackedWidget->setCurrentIndex(stackindex);
313       }
314       setContextMenuDockText(page, currentitem);
315
316       treeWidget->addAction(actionToggleDock);
317
318       /* Add the actions to the Page Selectors tree widget that are part of the
319        * current items list of desired actions regardless of whether on top of stack*/
320       treeWidget->addActions(page->m_contextActions);
321    }
322 }
323
324 void MainWin::labelDialogClicked() 
325 {
326    new labelDialog(m_console);
327 }
328
329 void MainWin::runDialogClicked() 
330 {
331    new runDialog(m_console);
332 }
333
334 void MainWin::restoreDialogClicked() 
335 {
336    new prerestoreDialog(m_console);
337 }
338
339
340
341 /*
342  * The user just finished typing a line in the command line edit box
343  */
344 void MainWin::input_line()
345 {
346    QString cmdStr = lineEdit->text();    /* Get the text */
347    lineEdit->clear();                    /* clear the lineEdit box */
348    if (m_console->is_connected()) {
349       m_console->display_text(cmdStr + "\n");
350       m_console->write_dir(cmdStr.toUtf8().data());         /* send to dir */
351    } else {
352       set_status("Director not connected. Click on connect button.");
353    }
354    m_cmd_history.append(cmdStr);
355    m_cmd_last = -1;
356 }
357
358
359 void MainWin::about()
360 {
361    QMessageBox::about(this, tr("About bat"),
362             tr("<br><h2>bat 0.2, by Kern Sibbald</h2>"
363             "<p>Copyright &copy; " BYEAR " Free Software Foundation Europe e.V."
364             "<p>The <b>bat</b> is an administrative console"
365                " interface to the Director."));
366 }
367
368 void MainWin::set_statusf(const char *fmt, ...)
369 {
370    va_list arg_ptr;
371    char buf[1000];
372    int len;
373    va_start(arg_ptr, fmt);
374    len = bvsnprintf(buf, sizeof(buf), fmt, arg_ptr);
375    va_end(arg_ptr);
376    set_status(buf);
377 }
378
379 void MainWin::set_status_ready()
380 {
381    set_status(" Ready");
382 }
383
384 void MainWin::set_status(const char *buf)
385 {
386    statusBar()->showMessage(buf);
387 }
388
389 /*
390  * Function to respond to the button bar button to undock
391  */
392 void MainWin::undockWindowButton()
393 {
394    Pages* page = (Pages*)stackedWidget->currentWidget();
395    page->togglePageDocking();
396    /* The window has been undocked, lets change the context menu */
397    setContextMenuDockText();
398 }
399
400 /*
401  * Function to respond to action on page selector context menu to toggle the 
402  * dock status of the window associated with the page selectors current
403  * tree widget item.
404  */
405 void MainWin::toggleDockContextWindow()
406 {
407    QTreeWidgetItem *currentitem = treeWidget->currentItem();
408    
409    /* Use tree item's Qt::UserRole to get treeindex */
410    int treeindex = currentitem->data(0, Qt::UserRole).toInt();
411
412    /* Is this one of the first level pages */
413    if( m_pagehash.value(treeindex) ){
414       Pages* page = m_pagehash.value(treeindex);
415       page->togglePageDocking();
416       if ( page->isDocked() ){
417          stackedWidget->setCurrentWidget(page);
418       }
419       /* Toggle the menu item.  The window's dock status has been toggled */
420       setContextMenuDockText(page, currentitem);
421    }
422 }
423
424 /*
425  * Function to set the text of the toggle dock context menu when page and
426  * widget item are NOT known.  This is an overoaded funciton.
427  * It is called from MainWin::undockWindowButton, it is not intended to change
428  * for the top pages tree widget, it is for the currently active tree widget
429  * item.  Which is why the page is not passed.
430  */
431 void MainWin::setContextMenuDockText()
432 {
433    QTreeWidgetItem *currentitem = treeWidget->currentItem();
434    
435    /* Use tree item's Qt::UserRole to get treeindex */
436    int treeindex = currentitem->data(0, Qt::UserRole).toInt();
437
438    /* Is this one of the first level pages */
439    if( m_pagehash.value(treeindex) ){
440       Pages* page = m_pagehash.value(treeindex);
441       setContextMenuDockText(page, currentitem);
442    }
443 }
444
445 /*
446  * Function to set the text of the toggle dock context menu when page and
447  * widget item are known.  This is the more commonly used.
448  */
449 void MainWin::setContextMenuDockText( Pages* page, QTreeWidgetItem* item )
450 {
451    QString docktext("");
452    if( page->isDocked() ){
453       docktext += "UnDock ";
454    } else {
455       docktext += "ReDock ";
456    }
457    docktext += item->text(0) += " Window";
458    
459    actionToggleDock->setText(docktext);
460    setTreeWidgetItemDockColor(page, item);
461 }
462
463 /*
464  * Function to set the color of the tree widget item based on whether it is
465  * docked or not.
466  */
467 void MainWin::setTreeWidgetItemDockColor( Pages* page, QTreeWidgetItem* item )
468 {
469    if( item->text(0) != "Console" ){
470       if( page->isDocked() ){
471       /* Set the brush to blue if undocked */
472          QBrush blackBrush(Qt::black);
473          item->setForeground(0, blackBrush);
474       } else {
475       /* Set the brush back to black if docked */
476          QBrush blueBrush(Qt::blue);
477          item->setForeground(0, blueBrush);
478       }
479    }
480 }
481
482 void MainWin::stackItemChanged(int)
483 {
484    Pages* page = (Pages*)stackedWidget->currentWidget();
485    /* run the virtual function in case this class overrides it */
486    page->currentStackItem();
487 }