]> git.sur5r.net Git - bacula/bacula/blob - bacula/src/qt-console/pages.cpp
Backport from BEE
[bacula/bacula] / bacula / src / qt-console / pages.cpp
1 /*
2    Bacula® - The Network Backup Solution
3
4    Copyright (C) 2007-2011 Free Software Foundation Europe e.V.
5
6    The main author of Bacula is Kern Sibbald, with contributions from many
7    others, a complete list can be found in the file AUTHORS.
8
9    You may use this file and others of this release according to the
10    license defined in the LICENSE file, which includes the Affero General
11    Public License, v3.0 ("AGPLv3") and some additional permissions and
12    terms pursuant to its AGPLv3 Section 7.
13
14    Bacula® is a registered trademark of Kern Sibbald.
15 */
16 /*
17  *   Dirk Bartley, March 2007
18  */
19
20 #include "bat.h"
21 #include "pages.h"
22
23 /* A global function */
24 bool isWin32Path(QString &fullPath)
25 {
26    if (fullPath.size()<2) {
27       return false;
28    }
29
30    bool toret = fullPath[1].toAscii() == ':' && fullPath[0].isLetter();
31    if (mainWin->m_miscDebug) {
32       if (toret)
33          Pmsg1(000, "returning from isWin32Path true %s\n", fullPath.toUtf8().data());
34       else
35          Pmsg1(000, "returning from isWin32Path false %s\n", fullPath.toUtf8().data());
36    }
37    return toret;
38 }
39
40 /* Need to initialize variables here */
41 Pages::Pages() : QWidget()
42 {
43    m_docked = false;
44    m_onceDocked = false;
45    m_closeable = true;
46    m_dockOnFirstUse = true;
47    m_console = NULL;
48    m_parent = NULL;
49 }
50
51 /* first Use Dock */
52 void Pages::firstUseDock()
53 {
54    if (!m_onceDocked && m_dockOnFirstUse) {
55       dockPage();
56    }
57 }
58
59 /*
60  * dockPage
61  * This function is intended to be called from within the Pages class to pull
62  * a window from floating to in the stack widget.
63  */
64
65 void Pages::dockPage()
66 {
67    if (isDocked()) {
68       return;
69    }
70
71    /* These two lines are for making sure if it is being changed from a window
72     * that it has the proper window flag and parent.
73     */
74    setWindowFlags(Qt::Widget);
75
76    /* calculate the index that the tab should be inserted into */
77    int tabPos = 0;
78    QTreeWidgetItemIterator it(mainWin->treeWidget);
79    while (*it) {
80       Pages *somepage = mainWin->getFromHash(*it);
81       if (this == somepage) {
82          tabPos += 1;
83          break;
84       }
85       int pageindex = mainWin->tabWidget->indexOf(somepage);
86       if (pageindex != -1) { tabPos = pageindex; }
87       ++it;
88    }
89
90    /* This was being done already */
91    m_parent->insertTab(tabPos, this, m_name);
92
93    /* Set docked flag */
94    m_docked = true;
95    m_onceDocked = true;
96    mainWin->tabWidget->setCurrentWidget(this);
97    /* lets set the page selectors action for docking or undocking */
98    setContextMenuDockText();
99 }
100
101 /*
102  * undockPage
103  * This function is intended to be called from within the Pages class to put
104  * a window from the stack widget to a floating window.
105  */
106
107 void Pages::undockPage()
108 {
109    if (!isDocked()) {
110       return;
111    }
112
113    /* Change from a stacked widget to a normal window */
114    m_parent->removeTab(m_parent->indexOf(this));
115    setWindowFlags(Qt::Window);
116    show();
117    /* Clear docked flag */
118    m_docked = false;
119    /* The window has been undocked, lets change the context menu */
120    setContextMenuDockText();
121 }
122
123 /*
124  * This function is intended to be called with the subclasses.  When it is
125  * called the specific sublclass does not have to be known to Pages.  When it
126  * is called this function will change the page from it's current state of being
127  * docked or undocked and change it to the other.
128  */
129
130 void Pages::togglePageDocking()
131 {
132    if (m_docked) {
133       undockPage();
134    } else {
135       dockPage();
136    }
137 }
138
139 /*
140  * This function is because I wanted for some reason to keep it protected but still
141  * give any subclasses the ability to find out if it is currently stacked or not.
142  */
143 bool Pages::isDocked()
144 {
145    return m_docked;
146 }
147
148 /*
149  * This function is because after the tabbed widget was added I could not tell
150  * from is docked if it had been docked yet.  To prevent status pages from requesting
151  * status from the director
152  */
153 bool Pages::isOnceDocked()
154 {
155    return m_onceDocked;
156 }
157
158
159 /*
160  * To keep m_closeable protected as well
161  */
162 bool Pages::isCloseable()
163 {
164    return m_closeable;
165 }
166
167 void Pages::hidePage()
168 {
169    if (!m_parent || (m_parent->indexOf(this) <= 0)) {
170       return;
171    }
172    /* Remove any tab that may exist */
173    m_parent->removeTab(m_parent->indexOf(this));
174    hide();
175    /* Clear docked flag */
176    m_docked = false;
177    /* The window has been undocked, lets change the context menu */
178    setContextMenuDockText();
179 }
180
181 /*
182  * When a window is closed, this slot is called.  The idea is to put it back in the
183  * stack here, and it works.  I wanted to get it to the top of the stack so that the
184  * user immediately sees where his window went.  Also, if he undocks the window, then
185  * closes it with the tree item highlighted, it may be confusing that the highlighted
186  * treewidgetitem is not the stack item in the front.
187  */
188
189 void Pages::closeEvent(QCloseEvent* event)
190 {
191    /* A Widget was closed, lets toggle it back into the window, and set it in front. */
192    dockPage();
193
194    /* this fixes my woes of getting the widget to show up on top when closed */
195    event->ignore();
196
197    /* Set the current tree widget item in the Page Selector window to the item
198     * which represents "this"
199     * Which will also bring "this" to the top of the stacked widget */
200    setCurrent();
201 }
202
203 /*
204  * The next three are virtual functions.  The idea here is that each subclass will have the
205  * built in virtual function to override if the programmer wants to populate the window
206  * when it it is first clicked.
207  */
208 void Pages::PgSeltreeWidgetClicked()
209 {
210 }
211
212 /*
213  *  Virtual function which is called when this page is visible on the stack.
214  *  This will be overridden by classes that want to populate if they are on the
215  *  top.
216  */
217 void Pages::currentStackItem()
218 {
219 }
220
221 /*
222  * Function to close the stacked page and remove the widget from the
223  * Page selector window
224  */
225 void Pages::closeStackPage()
226 {
227    /* First get the tree widget item and destroy it */
228    QTreeWidgetItem *item=mainWin->getFromHash(this);
229    /* remove the QTreeWidgetItem <-> page from the hash */
230    if (item) {
231       mainWin->hashRemove(item, this);
232       /* remove the item from the page selector by destroying it */
233       delete item;
234    }
235    /* remove this */
236    delete this;
237 }
238
239 /*
240  * Function to set members from the external mainwin and it's overload being
241  * passed a specific QTreeWidgetItem to be it's parent on the tree
242  */
243 void Pages::pgInitialize()
244 {
245    pgInitialize(QString(), NULL);
246 }
247
248 void Pages::pgInitialize(const QString &name)
249 {
250    pgInitialize(name, NULL);
251 }
252
253 void Pages::pgInitialize(const QString &tname, QTreeWidgetItem *parentTreeWidgetItem)
254 {
255    m_docked = false;
256    m_onceDocked = false;
257    if (tname.size()) {
258       m_name = tname;
259    }
260    m_parent = mainWin->tabWidget;
261    m_console = mainWin->currentConsole();
262
263    if (!parentTreeWidgetItem) {
264       parentTreeWidgetItem = m_console->directorTreeItem();
265    }
266
267    QTreeWidgetItem *item = new QTreeWidgetItem(parentTreeWidgetItem);
268    QString name;
269    treeWidgetName(name);
270    item->setText(0, name);
271    mainWin->hashInsert(item, this);
272    setTitle();
273 }
274
275 /*
276  * Virtual Function to return a name
277  * All subclasses should override this function
278  */
279 void Pages::treeWidgetName(QString &name)
280 {
281    name = m_name;
282 }
283
284 /*
285  * Function to simplify executing a console command and bringing the
286  * console to the front of the stack
287  */
288 void Pages::consoleCommand(QString &command)
289 {
290    consoleCommand(command, true);
291 }
292
293 void Pages::consoleCommand(QString &command, bool setCurrent)
294 {
295    int conn;
296    bool donotify = false;
297    if (m_console->getDirComm(conn))  {
298       if (m_console->is_notify_enabled(conn)) {
299          donotify = true;
300          m_console->notify(conn, false);
301       }
302       consoleCommand(command, conn, setCurrent);
303       if (donotify) { m_console->notify(conn, true); }
304    }
305 }
306
307 void Pages::consoleCommand(QString &command, int conn)
308 {
309    consoleCommand(command, conn, true);
310 }
311
312 void Pages::consoleCommand(QString &command, int conn, bool setCurrent)
313 {
314    /* Bring this director's console to the front of the stack */
315    if (setCurrent) { setConsoleCurrent(); }
316    QString displayhtml("<font color=\"blue\">");
317    displayhtml += command + "</font>\n";
318    m_console->display_html(displayhtml);
319    m_console->display_text("\n");
320    mainWin->waitEnter();
321    m_console->write_dir(conn, command.toUtf8().data(), false);
322    m_console->displayToPrompt(conn);
323    mainWin->waitExit();
324 }
325
326 /*
327  * Function for handling undocked windows becoming active.
328  * Change the currently selected item in the page selector window to the now
329  * active undocked window.  This will also make the console for the undocked
330  * window m_currentConsole.
331  */
332 void Pages::changeEvent(QEvent *event)
333 {
334    if ((event->type() ==  QEvent::ActivationChange) && (isActiveWindow())) {
335       setCurrent();
336    }
337 }
338
339 /*
340  * Function to simplify getting the name of the class and the director into
341  * the caption or title of the window
342  */
343 void Pages::setTitle()
344 {
345    QString wdgname, director;
346    treeWidgetName(wdgname);
347    m_console->getDirResName(director);
348    QString title = tr("%1 of Director %2").arg(wdgname).arg(director);
349    setWindowTitle(title);
350 }
351
352 /*
353  * Bring the current directors console window to the top of the stack.
354  */
355 void Pages::setConsoleCurrent()
356 {
357    mainWin->treeWidget->setCurrentItem(mainWin->getFromHash(m_console));
358 }
359
360 /*
361  * Bring this window to the top of the stack.
362  */
363 void Pages::setCurrent()
364 {
365    mainWin->treeWidget->setCurrentItem(mainWin->getFromHash(this));
366 }
367
368 /*
369  * Function to set the text of the toggle dock context menu when page and
370  * widget item are NOT known.
371  */
372 void Pages::setContextMenuDockText()
373 {
374    QTreeWidgetItem *item = mainWin->getFromHash(this);
375    QString docktext;
376    if (isDocked()) {
377       docktext = tr("UnDock %1 Window").arg(item->text(0));
378    } else {
379       docktext = tr("ReDock %1 Window").arg(item->text(0));
380    }
381
382    mainWin->actionToggleDock->setText(docktext);
383    setTreeWidgetItemDockColor();
384 }
385
386 /*
387  * Function to set the color of the tree widget item based on whether it is
388  * docked or not.
389  */
390 void Pages::setTreeWidgetItemDockColor()
391 {
392    QTreeWidgetItem* item = mainWin->getFromHash(this);
393    if (item) {
394       if (item->text(0) != tr("Console")) {
395          if (isDocked()) {
396          /* Set the brush to blue if undocked */
397             QBrush blackBrush(Qt::black);
398             item->setForeground(0, blackBrush);
399          } else {
400          /* Set the brush back to black if docked */
401             QBrush blueBrush(Qt::blue);
402             item->setForeground(0, blueBrush);
403          }
404       }
405    }
406 }
407
408 /* Function to get a list of volumes */
409 void Pages::getVolumeList(QStringList &volumeList)
410 {
411    QString query("SELECT VolumeName AS Media FROM Media ORDER BY Media");
412    if (mainWin->m_sqlDebug) {
413       Pmsg1(000, "Query cmd : %s\n",query.toUtf8().data());
414    }
415    QStringList results;
416    if (m_console->sql_cmd(query, results)) {
417       QString field;
418       QStringList fieldlist;
419       /* Iterate through the lines of results. */
420       foreach (QString resultline, results) {
421          fieldlist = resultline.split("\t");
422          volumeList.append(fieldlist[0]);
423       } /* foreach resultline */
424    } /* if results from query */
425 }
426
427 /* Function to get a list of volumes */
428 void Pages::getStatusList(QStringList &statusLongList)
429 {
430    QString statusQuery("SELECT JobStatusLong FROM Status");
431    if (mainWin->m_sqlDebug) {
432       Pmsg1(000, "Query cmd : %s\n",statusQuery.toUtf8().data());
433    }
434    QStringList statusResults;
435    if (m_console->sql_cmd(statusQuery, statusResults)) {
436       QString field;
437       QStringList fieldlist;
438       /* Iterate through the lines of results. */
439       foreach (QString resultline, statusResults) {
440          fieldlist = resultline.split("\t");
441          statusLongList.append(fieldlist[0]);
442       } /* foreach resultline */
443    } /* if results from statusquery */
444 }