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