]> git.sur5r.net Git - bacula/bacula/blob - bacula/src/qt-console/mainwin.cpp
dhb use the stack widget signal currentChanged to trigger function
[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 }
223
224 void MainWin::writeSettings()
225 {
226    QSettings settings("bacula.org", "bat");
227
228    settings.beginGroup("MainWin");
229    settings.setValue("winSize", size());
230    settings.setValue("winPos", pos());
231    settings.endGroup();
232 }
233
234 void MainWin::readSettings()
235
236    QSettings settings("bacula.org", "bat");
237
238    settings.beginGroup("MainWin");
239    resize(settings.value("winSize", QSize(1041, 801)).toSize());
240    move(settings.value("winPos", QPoint(200, 150)).toPoint());
241    settings.endGroup();
242 }
243
244 /*
245  * This subroutine is called with an item in the Page Selection window
246  *   is clicked 
247  */
248 void MainWin::treeItemClicked(QTreeWidgetItem *item, int column)
249 {
250    /* Use tree item's Qt::UserRole to get treeindex */
251    int treeindex = item->data(column, Qt::UserRole).toInt();
252
253    /* Is this one of the first level pages */
254    if( m_pagehash.value(treeindex) ){
255       Pages* page = m_pagehash.value(treeindex);
256       int stackindex=stackedWidget->indexOf(page);
257
258       if( stackindex >= 0 ){
259          stackedWidget->setCurrentIndex(0);
260          stackedWidget->setCurrentWidget(page);
261       }
262       /* run the virtual function in case this class overrides it */
263       if( treeindex > 0 ){
264          page->PgSeltreeWidgetClicked();
265       }
266    }
267 }
268
269 /*
270  * This subroutine is called with an item in the Page Selection window
271  *   is double clicked
272  */
273 void MainWin::treeItemDoubleClicked(QTreeWidgetItem * /*item*/, int /*column*/)
274 {
275 }
276
277 /*
278  * Called with a change of the highlighed tree widget item in the page selector.
279  */
280
281 void MainWin::treeItemChanged(QTreeWidgetItem *currentitem, QTreeWidgetItem *previousitem)
282 {
283    int treeindex;
284    /* The Previous item */
285
286    /* Use tree item's Qt::UserRole to get treeindex now for the previousitem */
287    if ( previousitem ){
288       treeindex = previousitem->data(0, Qt::UserRole).toInt();
289       /* Is this one of the first level pages */
290       if( m_pagehash.value(treeindex) ){
291          Pages* page = m_pagehash.value(treeindex);
292          treeWidget->removeAction(actionToggleDock);
293          foreach( QAction* pageaction, page->m_contextActions ){
294             treeWidget->removeAction(pageaction);
295          } 
296       }
297    }
298
299    /* Use tree item's Qt::UserRole to get treeindex */
300    treeindex = currentitem->data(0, Qt::UserRole).toInt();
301
302    /* Is this one of the first level pages */
303    if( m_pagehash.value(treeindex) ){
304       Pages* page = m_pagehash.value(treeindex);
305       int stackindex = stackedWidget->indexOf(page);
306    
307       /* Is this page currently on the stack */
308       if( stackindex >= 0 ){
309          /* put this page on the top of the stack */
310          stackedWidget->setCurrentIndex(stackindex);
311       }
312       setContextMenuDockText(page, currentitem);
313
314       treeWidget->addAction(actionToggleDock);
315
316       /* Add the actions to the Page Selectors tree widget that are part of the
317        * current items list of desired actions regardless of whether on top of stack*/
318       treeWidget->addActions(page->m_contextActions);
319    }
320 }
321
322 void MainWin::labelDialogClicked() 
323 {
324    new labelDialog(m_console);
325 }
326
327 void MainWin::runDialogClicked() 
328 {
329    new runDialog(m_console);
330 }
331
332 void MainWin::restoreDialogClicked() 
333 {
334    new prerestoreDialog(m_console);
335 }
336
337
338
339 /*
340  * The user just finished typing a line in the command line edit box
341  */
342 void MainWin::input_line()
343 {
344    QString cmdStr = lineEdit->text();    /* Get the text */
345    lineEdit->clear();                    /* clear the lineEdit box */
346    if (m_console->is_connected()) {
347       m_console->display_text(cmdStr + "\n");
348       m_console->write_dir(cmdStr.toUtf8().data());         /* send to dir */
349    } else {
350       set_status("Director not connected. Click on connect button.");
351    }
352    m_cmd_history.append(cmdStr);
353    m_cmd_last = -1;
354 }
355
356
357 void MainWin::about()
358 {
359    QMessageBox::about(this, tr("About bat"),
360             tr("<br><h2>bat 0.2, by Kern Sibbald</h2>"
361             "<p>Copyright &copy; " BYEAR " Free Software Foundation Europe e.V."
362             "<p>The <b>bat</b> is an administrative console"
363                " interface to the Director."));
364 }
365
366 void MainWin::set_statusf(const char *fmt, ...)
367 {
368    va_list arg_ptr;
369    char buf[1000];
370    int len;
371    va_start(arg_ptr, fmt);
372    len = bvsnprintf(buf, sizeof(buf), fmt, arg_ptr);
373    va_end(arg_ptr);
374    set_status(buf);
375 }
376
377 void MainWin::set_status_ready()
378 {
379    set_status(" Ready");
380 }
381
382 void MainWin::set_status(const char *buf)
383 {
384    statusBar()->showMessage(buf);
385 }
386
387 /*
388  * Function to respond to the button bar button to undock
389  */
390 void MainWin::undockWindowButton()
391 {
392    Pages* page = (Pages*)stackedWidget->currentWidget();
393    page->togglePageDocking();
394    /* The window has been undocked, lets change the context menu */
395    setContextMenuDockText();
396 }
397
398 /*
399  * Function to respond to action on page selector context menu to toggle the 
400  * dock status of the window associated with the page selectors current
401  * tree widget item.
402  */
403 void MainWin::toggleDockContextWindow()
404 {
405    QTreeWidgetItem *currentitem = treeWidget->currentItem();
406    
407    /* Use tree item's Qt::UserRole to get treeindex */
408    int treeindex = currentitem->data(0, Qt::UserRole).toInt();
409
410    /* Is this one of the first level pages */
411    if( m_pagehash.value(treeindex) ){
412       Pages* page = m_pagehash.value(treeindex);
413       page->togglePageDocking();
414       if ( page->isDocked() ){
415          stackedWidget->setCurrentWidget(page);
416       }
417       /* Toggle the menu item.  The window's dock status has been toggled */
418       setContextMenuDockText(page, currentitem);
419    }
420 }
421
422 /*
423  * Function to set the text of the toggle dock context menu when page and
424  * widget item are NOT known.  This is an overoaded funciton.
425  * It is called from MainWin::undockWindowButton, it is not intended to change
426  * for the top pages tree widget, it is for the currently active tree widget
427  * item.  Which is why the page is not passed.
428  */
429 void MainWin::setContextMenuDockText()
430 {
431    QTreeWidgetItem *currentitem = treeWidget->currentItem();
432    
433    /* Use tree item's Qt::UserRole to get treeindex */
434    int treeindex = currentitem->data(0, Qt::UserRole).toInt();
435
436    /* Is this one of the first level pages */
437    if( m_pagehash.value(treeindex) ){
438       Pages* page = m_pagehash.value(treeindex);
439       setContextMenuDockText(page, currentitem);
440    }
441 }
442
443 /*
444  * Function to set the text of the toggle dock context menu when page and
445  * widget item are known.  This is the more commonly used.
446  */
447 void MainWin::setContextMenuDockText( Pages* page, QTreeWidgetItem* item )
448 {
449    QString docktext("");
450    if( page->isDocked() ){
451       docktext += "UnDock ";
452    } else {
453       docktext += "ReDock ";
454    }
455    docktext += item->text(0) += " Window";
456    
457    actionToggleDock->setText(docktext);
458 }
459
460 void MainWin::stackItemChanged(int)
461 {
462    Pages* page = (Pages*)stackedWidget->currentWidget();
463    /* run the virtual function in case this class overrides it */
464    page->currentStackItem();
465 }