]> git.sur5r.net Git - bacula/bacula/blob - bacula/src/qt-console/pages.cpp
update configure
[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
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  *   Dirk Bartley, March 2007
30  */
31
32 #include "bat.h"
33 #include "pages.h"
34
35 /* A global function */
36 bool isWin32Path(QString &fullPath) 
37 {
38    if (fullPath.size()<2) {
39       return false;
40    }
41
42    bool toret = fullPath[1].toAscii() == ':' && fullPath[0].isLetter();
43    if (mainWin->m_miscDebug) {
44       if (toret)
45          Pmsg1(000, "returning from isWin32Path true %s\n", fullPath.toUtf8().data());
46       else
47          Pmsg1(000, "returning from isWin32Path false %s\n", fullPath.toUtf8().data());
48    }
49    return toret;
50 }
51
52 /* Need to initialize variables here */
53 Pages::Pages() : QWidget()
54 {
55    m_docked = false;
56    m_onceDocked = false;
57    m_closeable = true;
58    m_dockOnFirstUse = true;
59    m_console = NULL;
60    m_parent = NULL;
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 void Pages::hidePage()
180 {
181    if (!m_parent || (m_parent->indexOf(this) <= 0)) {
182       return;
183    }
184    /* Remove any tab that may exist */
185    m_parent->removeTab(m_parent->indexOf(this));
186    hide();
187    /* Clear docked flag */
188    m_docked = false;
189    /* The window has been undocked, lets change the context menu */
190    setContextMenuDockText();
191 }
192
193 /*
194  * When a window is closed, this slot is called.  The idea is to put it back in the
195  * stack here, and it works.  I wanted to get it to the top of the stack so that the
196  * user immediately sees where his window went.  Also, if he undocks the window, then
197  * closes it with the tree item highlighted, it may be confusing that the highlighted
198  * treewidgetitem is not the stack item in the front.
199  */
200
201 void Pages::closeEvent(QCloseEvent* event)
202 {
203    /* A Widget was closed, lets toggle it back into the window, and set it in front. */
204    dockPage();
205
206    /* this fixes my woes of getting the widget to show up on top when closed */
207    event->ignore();
208
209    /* Set the current tree widget item in the Page Selector window to the item 
210     * which represents "this" 
211     * Which will also bring "this" to the top of the stacked widget */
212    setCurrent();
213 }
214
215 /*
216  * The next three are virtual functions.  The idea here is that each subclass will have the
217  * built in virtual function to override if the programmer wants to populate the window
218  * when it it is first clicked.
219  */
220 void Pages::PgSeltreeWidgetClicked()
221 {
222 }
223
224 /*
225  *  Virtual function which is called when this page is visible on the stack.
226  *  This will be overridden by classes that want to populate if they are on the
227  *  top.
228  */
229 void Pages::currentStackItem()
230 {
231 }
232
233 /*
234  * Function to close the stacked page and remove the widget from the
235  * Page selector window
236  */
237 void Pages::closeStackPage()
238 {
239    /* First get the tree widget item and destroy it */
240    QTreeWidgetItem *item=mainWin->getFromHash(this);
241    /* remove the QTreeWidgetItem <-> page from the hash */
242    if (item) {
243       mainWin->hashRemove(item, this);
244       /* remove the item from the page selector by destroying it */
245       delete item;
246    }
247    /* remove this */
248    delete this;
249 }
250
251 /*
252  * Function to set members from the external mainwin and it's overload being
253  * passed a specific QTreeWidgetItem to be it's parent on the tree
254  */
255 void Pages::pgInitialize()
256 {
257    pgInitialize(QString(), NULL);
258 }
259
260 void Pages::pgInitialize(const QString &name)
261 {
262    pgInitialize(name, NULL);
263 }
264
265 void Pages::pgInitialize(const QString &tname, QTreeWidgetItem *parentTreeWidgetItem)
266 {
267    m_docked = false;
268    m_onceDocked = false;
269    if (tname.size()) {
270       m_name = tname;
271    }
272    m_parent = mainWin->tabWidget;
273    m_console = mainWin->currentConsole();
274
275    if (!parentTreeWidgetItem) {
276       parentTreeWidgetItem = m_console->directorTreeItem();
277    }
278
279    QTreeWidgetItem *item = new QTreeWidgetItem(parentTreeWidgetItem);
280    QString name; 
281    treeWidgetName(name);
282    item->setText(0, name);
283    mainWin->hashInsert(item, this);
284    setTitle();
285 }
286
287 /*
288  * Virtual Function to return a name
289  * All subclasses should override this function
290  */
291 void Pages::treeWidgetName(QString &name)
292 {
293    name = m_name;
294 }
295
296 /*
297  * Function to simplify executing a console command and bringing the
298  * console to the front of the stack
299  */
300 void Pages::consoleCommand(QString &command)
301 {
302    consoleCommand(command, true);
303 }
304
305 void Pages::consoleCommand(QString &command, bool setCurrent)
306 {
307    int conn;
308    bool donotify = false;
309    if (m_console->getDirComm(conn))  {
310       if (m_console->is_notify_enabled(conn)) {
311          donotify = true;
312          m_console->notify(conn, false);
313       }
314       consoleCommand(command, conn, setCurrent);
315       if (donotify) { m_console->notify(conn, true); }
316    }
317 }
318
319 void Pages::consoleCommand(QString &command, int conn)
320 {
321    consoleCommand(command, conn, true);
322 }
323
324 void Pages::consoleCommand(QString &command, int conn, bool setCurrent)
325 {
326    /* Bring this director's console to the front of the stack */
327    if (setCurrent) { setConsoleCurrent(); }
328    QString displayhtml("<font color=\"blue\">");
329    displayhtml += command + "</font>\n";
330    m_console->display_html(displayhtml);
331    m_console->display_text("\n");
332    mainWin->waitEnter();
333    m_console->write_dir(conn, command.toUtf8().data(), false);
334    m_console->displayToPrompt(conn);
335    mainWin->waitExit();
336 }
337
338 /*
339  * Function for handling undocked windows becoming active.
340  * Change the currently selected item in the page selector window to the now
341  * active undocked window.  This will also make the console for the undocked
342  * window m_currentConsole.
343  */
344 void Pages::changeEvent(QEvent *event)
345 {
346    if ((event->type() ==  QEvent::ActivationChange) && (isActiveWindow())) {
347       setCurrent();
348    }
349 }
350
351 /*
352  * Function to simplify getting the name of the class and the director into
353  * the caption or title of the window
354  */
355 void Pages::setTitle()
356 {
357    QString wdgname, director;
358    treeWidgetName(wdgname);
359    m_console->getDirResName(director);
360    QString title = tr("%1 of Director %2").arg(wdgname).arg(director);
361    setWindowTitle(title);
362 }
363
364 /*
365  * Bring the current directors console window to the top of the stack.
366  */
367 void Pages::setConsoleCurrent()
368 {
369    mainWin->treeWidget->setCurrentItem(mainWin->getFromHash(m_console));
370 }
371
372 /*
373  * Bring this window to the top of the stack.
374  */
375 void Pages::setCurrent()
376 {
377    mainWin->treeWidget->setCurrentItem(mainWin->getFromHash(this));
378 }
379
380 /*
381  * Function to set the text of the toggle dock context menu when page and
382  * widget item are NOT known.  
383  */
384 void Pages::setContextMenuDockText()
385 {
386    QTreeWidgetItem *item = mainWin->getFromHash(this);
387    QString docktext;
388    if (isDocked()) {
389       docktext = tr("UnDock %1 Window").arg(item->text(0));
390    } else {
391       docktext = tr("ReDock %1 Window").arg(item->text(0));
392    }
393       
394    mainWin->actionToggleDock->setText(docktext);
395    setTreeWidgetItemDockColor();
396 }
397
398 /*
399  * Function to set the color of the tree widget item based on whether it is
400  * docked or not.
401  */
402 void Pages::setTreeWidgetItemDockColor()
403 {
404    QTreeWidgetItem* item = mainWin->getFromHash(this);
405    if (item) {
406       if (item->text(0) != tr("Console")) {
407          if (isDocked()) {
408          /* Set the brush to blue if undocked */
409             QBrush blackBrush(Qt::black);
410             item->setForeground(0, blackBrush);
411          } else {
412          /* Set the brush back to black if docked */
413             QBrush blueBrush(Qt::blue);
414             item->setForeground(0, blueBrush);
415          }
416       }
417    }
418 }
419
420 /* Function to get a list of volumes */
421 void Pages::getVolumeList(QStringList &volumeList)
422 {
423    QString query("SELECT VolumeName AS Media FROM Media ORDER BY Media");
424    if (mainWin->m_sqlDebug) {
425       Pmsg1(000, "Query cmd : %s\n",query.toUtf8().data());
426    }
427    QStringList results;
428    if (m_console->sql_cmd(query, results)) {
429       QString field;
430       QStringList fieldlist;
431       /* Iterate through the lines of results. */
432       foreach (QString resultline, results) {
433          fieldlist = resultline.split("\t");
434          volumeList.append(fieldlist[0]);
435       } /* foreach resultline */
436    } /* if results from query */
437 }
438
439 /* Function to get a list of volumes */
440 void Pages::getStatusList(QStringList &statusLongList)
441 {
442    QString statusQuery("SELECT JobStatusLong FROM Status");
443    if (mainWin->m_sqlDebug) {
444       Pmsg1(000, "Query cmd : %s\n",statusQuery.toUtf8().data());
445    }
446    QStringList statusResults;
447    if (m_console->sql_cmd(statusQuery, statusResults)) {
448       QString field;
449       QStringList fieldlist;
450       /* Iterate through the lines of results. */
451       foreach (QString resultline, statusResults) {
452          fieldlist = resultline.split("\t");
453          statusLongList.append(fieldlist[0]);
454       } /* foreach resultline */
455    } /* if results from statusquery */
456 }