]> git.sur5r.net Git - bacula/bacula/blob - bacula/src/qt-console/mainwin.cpp
dhb The changes in this commit are to make the right click in the page selector
[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
200    connect(actionQuit, SIGNAL(triggered()), app, SLOT(closeAllWindows()));
201    connect(actionConnect, SIGNAL(triggered()), m_console, SLOT(connect()));
202    connect(actionStatusDir, SIGNAL(triggered()), m_console, SLOT(status_dir()));
203    connect(actionSelectFont, SIGNAL(triggered()), m_console, SLOT(set_font()));
204    connect(actionLabel, SIGNAL(triggered()), this,  SLOT(labelDialogClicked()));
205    connect(actionRun, SIGNAL(triggered()), this,  SLOT(runDialogClicked()));
206    connect(actionRestore, SIGNAL(triggered()), this,  SLOT(restoreDialogClicked()));
207    connect(actionUndock, SIGNAL(triggered()), this,  SLOT(undockWindowButton()));
208    connect(actionToggleDock, SIGNAL(triggered()), this,  SLOT(toggleDockContextWindow()));
209 }
210
211 /* 
212  * Reimplementation of QWidget closeEvent virtual function   
213  */
214 void MainWin::closeEvent(QCloseEvent *event)
215 {
216    writeSettings();
217    m_console->writeSettings();
218    m_console->terminate();
219    event->accept();
220 }
221
222 void MainWin::writeSettings()
223 {
224    QSettings settings("bacula.org", "bat");
225
226    settings.beginGroup("MainWin");
227    settings.setValue("winSize", size());
228    settings.setValue("winPos", pos());
229    settings.endGroup();
230 }
231
232 void MainWin::readSettings()
233
234    QSettings settings("bacula.org", "bat");
235
236    settings.beginGroup("MainWin");
237    resize(settings.value("winSize", QSize(1041, 801)).toSize());
238    move(settings.value("winPos", QPoint(200, 150)).toPoint());
239    settings.endGroup();
240 }
241
242 /*
243  * This subroutine is called with an item in the Page Selection window
244  *   is clicked 
245  */
246 void MainWin::treeItemClicked(QTreeWidgetItem *item, int column)
247 {
248    /* Use tree item's Qt::UserRole to get treeindex */
249    int treeindex = item->data(column, Qt::UserRole).toInt();
250
251    /* Is this one of the first level pages */
252    if( m_pagehash.value(treeindex) ){
253       Pages* page = m_pagehash.value(treeindex);
254       int stackindex=stackedWidget->indexOf(page);
255
256       if( stackindex >= 0 ){
257          stackedWidget->setCurrentIndex(0);
258          stackedWidget->setCurrentWidget(page);
259       }
260       /* run the virtual function in case this class overrides it */
261       if( treeindex > 0 ){
262          page->PgSeltreeWidgetClicked();
263       }
264    }
265 }
266
267 /*
268  * This subroutine is called with an item in the Page Selection window
269  *   is double clicked
270  */
271 void MainWin::treeItemDoubleClicked(QTreeWidgetItem * /*item*/, int /*column*/)
272 {
273 }
274
275 /*
276  * Called with a change of the highlighed tree widget item in the page selector.
277  */
278
279 void MainWin::treeItemChanged(QTreeWidgetItem *currentitem, QTreeWidgetItem *previousitem)
280 {
281    int treeindex;
282    /* The Previous item */
283
284    /* Use tree item's Qt::UserRole to get treeindex now for the previousitem */
285    if ( previousitem ){
286       treeindex = previousitem->data(0, Qt::UserRole).toInt();
287       /* Is this one of the first level pages */
288       if( m_pagehash.value(treeindex) ){
289          Pages* page = m_pagehash.value(treeindex);
290          treeWidget->removeAction(actionToggleDock);
291          foreach( QAction* pageaction, page->m_contextActions ){
292             treeWidget->removeAction(pageaction);
293          } 
294       }
295    }
296
297    /* Use tree item's Qt::UserRole to get treeindex */
298    treeindex = currentitem->data(0, Qt::UserRole).toInt();
299
300    /* Is this one of the first level pages */
301    if( m_pagehash.value(treeindex) ){
302       Pages* page = m_pagehash.value(treeindex);
303       int stackindex = stackedWidget->indexOf(page);
304    
305       /* Is this page currently on the stack */
306       if( stackindex >= 0 ){
307          /* put this page on the top of the stack */
308          stackedWidget->setCurrentIndex(stackindex);
309       }
310       /* run the virtual function in case this class overrides it */
311       page->PgSeltreeWidgetCurrentItem();
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       /* Toggle the menu item.  The window's dock status has been toggled */
415       setContextMenuDockText(page, currentitem);
416    }
417 }
418
419 /*
420  * Function to set the text of the toggle dock context menu when page and
421  * widget item are NOT known.  This is an overoaded funciton.
422  * It is called from MainWin::undockWindowButton, it is not intended to change
423  * for the top pages tree widget, it is for the currently active tree widget
424  * item.  Which is why the page is not passed.
425  */
426 void MainWin::setContextMenuDockText()
427 {
428    QTreeWidgetItem *currentitem = treeWidget->currentItem();
429    
430    /* Use tree item's Qt::UserRole to get treeindex */
431    int treeindex = currentitem->data(0, Qt::UserRole).toInt();
432
433    /* Is this one of the first level pages */
434    if( m_pagehash.value(treeindex) ){
435       Pages* page = m_pagehash.value(treeindex);
436       setContextMenuDockText(page, currentitem);
437    }
438 }
439
440 /*
441  * Function to set the text of the toggle dock context menu when page and
442  * widget item are known.  This is the more commonly used.
443  */
444 void MainWin::setContextMenuDockText( Pages* page, QTreeWidgetItem* item )
445 {
446    QString docktext("");
447    if( page->isDocked() ){
448       docktext += "UnDock ";
449    } else {
450       docktext += "ReDock ";
451    }
452    docktext += item->text(0) += " Window";
453    
454    actionToggleDock->setText(docktext);
455 }