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