2 Bacula® - The Network Backup Solution
4 Copyright (C) 2007-2008 Free Software Foundation Europe e.V.
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 and included
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.
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
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.
34 * Dirk Bartley, March 2007
38 #include <QAbstractEventDispatcher>
42 #include "label/label.h"
43 #include "mount/mount.h"
44 #include "status/storstat.h"
45 #include "util/fmtwidgetitem.h"
50 pgInitialize(tr("Storage"));
51 QTreeWidgetItem* thisitem = mainWin->getFromHash(this);
52 thisitem->setIcon(0,QIcon(QString::fromUtf8(":images/package-x-generic.png")));
54 /* mp_treeWidget, Storage Tree Tree Widget inherited from ui_storage.h */
56 m_checkcurwidget = true;
58 m_currentStorage = "";
59 /* add context sensitive menu items specific to this classto the page
60 * selector tree. m_contextActions is QList of QActions */
61 m_contextActions.append(actionRefreshStorage);
68 writeExpandedSettings();
72 * The main meat of the class!! The function that querries the director and
73 * creates the widgets with appropriate values.
75 void Storage::populateTree()
77 if (!m_console->preventInUseConnect())
81 writeExpandedSettings();
84 Freeze frz(*mp_treeWidget); /* disable updating*/
86 m_checkcurwidget = false;
87 mp_treeWidget->clear();
88 m_checkcurwidget = true;
90 QStringList headerlist = (QStringList() << tr("Name") << tr("Id")
91 << tr("Changer") << tr("Slot") << tr("Status") << tr("Enabled") << tr("Pool")
92 << tr("Media Type") );
94 m_topItem = new QTreeWidgetItem(mp_treeWidget);
95 m_topItem->setText(0, tr("Storage"));
96 m_topItem->setData(0, Qt::UserRole, 0);
97 m_topItem->setExpanded(true);
99 mp_treeWidget->setColumnCount(headerlist.count());
100 mp_treeWidget->setHeaderLabels(headerlist);
102 QSettings settings(m_console->m_dir->name(), "bat");
103 settings.beginGroup("StorageTreeExpanded");
105 foreach(QString storageName, m_console->storage_list){
106 TreeItemFormatter storageItem(*m_topItem, 1);
107 storageItem.setTextFld(0, storageName);
108 if(settings.contains(storageName)) {
109 storageItem.widget()->setExpanded(settings.value(storageName).toBool());
111 storageItem.widget()->setExpanded(true);
114 /* Set up query QString and header QStringList */
115 QString query("SELECT StorageId AS ID, AutoChanger AS Changer"
116 " FROM Storage WHERE");
117 query += " Name='" + storageName + "'"
121 /* This could be a log item */
122 if (mainWin->m_sqlDebug) {
123 Pmsg1(000, "Storage query cmd : %s\n",query.toUtf8().data());
125 if (m_console->sql_cmd(query, results)) {
126 int resultCount = results.count();
127 if (resultCount == 1){
130 QStringList fieldlist;
131 /* there will only be one of these */
132 foreach (resultline, results) {
133 fieldlist = resultline.split("\t");
135 QStringListIterator fld(fieldlist);
138 storageItem.setNumericFld(index++, fld.next() );
141 storageItem.setBoolFld(index++, fld.next() );
143 mediaList(storageItem.widget(), fieldlist.first());
148 /* Resize the columns */
149 for(int cnter=0; cnter<headerlist.size(); cnter++) {
150 mp_treeWidget->resizeColumnToContents(cnter);
153 void Storage::mediaList(QTreeWidgetItem *parent, const QString &storageID)
155 QString query("SELECT Media.VolumeName AS Media, Media.Slot AS Slot,"
156 " Media.VolStatus AS VolStatus, Media.Enabled AS Enabled,"
157 " Pool.Name AS MediaPool, Media.MediaType AS MediaType"
159 " JOIN Pool ON (Media.PoolId=Pool.PoolId)"
160 " WHERE Media.StorageId='" + storageID + "'"
161 " AND Media.InChanger<>0"
162 " ORDER BY Media.Slot");
165 /* This could be a log item */
166 if (mainWin->m_sqlDebug) {
167 Pmsg1(000, "Storage query cmd : %s\n",query.toUtf8().data());
169 if (m_console->sql_cmd(query, results)) {
172 QStringList fieldlist;
174 foreach (resultline, results) {
175 fieldlist = resultline.split("\t");
176 if (fieldlist.size() < 6)
179 /* Iterate through fields in the record */
180 QStringListIterator fld(fieldlist);
182 TreeItemFormatter fmt(*parent, 2);
185 fmt.setTextFld(index++, fld.next());
187 /* skip the next two columns, unused by media */
191 fmt.setNumericFld(index++, fld.next());
194 fmt.setVolStatusFld(index++, fld.next());
197 fmt.setBoolFld(index++, fld.next());
200 fmt.setTextFld(index++, fld.next());
203 fmt.setTextFld(index++, fld.next());
210 * When the treeWidgetItem in the page selector tree is singleclicked, Make sure
211 * The tree has been populated.
213 void Storage::PgSeltreeWidgetClicked()
222 * Added to set the context menu policy based on currently active treeWidgetItem
223 * signaled by currentItemChanged
225 void Storage::treeItemChanged(QTreeWidgetItem *currentwidgetitem, QTreeWidgetItem *previouswidgetitem )
227 /* m_checkcurwidget checks to see if this is during a refresh, which will segfault */
228 if (m_checkcurwidget) {
229 /* The Previous item */
230 if (previouswidgetitem) { /* avoid a segfault if first time */
231 int treedepth = previouswidgetitem->data(0, Qt::UserRole).toInt();
233 mp_treeWidget->removeAction(actionStatusStorageInConsole);
234 mp_treeWidget->removeAction(actionStatusStorageWindow);
235 mp_treeWidget->removeAction(actionLabelStorage);
236 mp_treeWidget->removeAction(actionMountStorage);
237 mp_treeWidget->removeAction(actionUnMountStorage);
238 mp_treeWidget->removeAction(actionUpdateSlots);
239 mp_treeWidget->removeAction(actionUpdateSlotsScan);
240 mp_treeWidget->removeAction(actionRelease);
244 int treedepth = currentwidgetitem->data(0, Qt::UserRole).toInt();
246 /* set a hold variable to the storage name in case the context sensitive
248 m_currentStorage = currentwidgetitem->text(0);
249 m_currentAutoChanger = currentwidgetitem->text(2) == tr("Yes");
250 mp_treeWidget->addAction(actionStatusStorageInConsole);
251 mp_treeWidget->addAction(actionStatusStorageWindow);
252 mp_treeWidget->addAction(actionLabelStorage);
253 mp_treeWidget->addAction(actionMountStorage);
254 mp_treeWidget->addAction(actionUnMountStorage);
255 mp_treeWidget->addAction(actionRelease);
257 text = tr("Status Storage \"%1\"").arg(m_currentStorage);;
258 actionStatusStorageInConsole->setText(text);
259 text = tr("Status Storage \"%1\" in Window").arg(m_currentStorage);;
260 actionStatusStorageWindow->setText(text);
261 text = tr("Label media in Storage \"%1\"").arg(m_currentStorage);
262 actionLabelStorage->setText(text);
263 text = tr("Mount media in Storage \"%1\"").arg(m_currentStorage);
264 actionMountStorage->setText(text);
265 text = tr("\"UN\" Mount media in Storage \"%1\"").arg(m_currentStorage);
266 text = tr("Release media in Storage \"%1\"").arg(m_currentStorage);
267 actionRelease->setText(text);
268 if (m_currentAutoChanger) {
269 mp_treeWidget->addAction(actionUpdateSlots);
270 mp_treeWidget->addAction(actionUpdateSlotsScan);
271 text = tr("Barcode Scan media in Storage \"%1\"").arg(m_currentStorage);
272 actionUpdateSlots->setText(text);
273 text = tr("Read scan media in Storage \"%1\"").arg( m_currentStorage);
274 actionUpdateSlotsScan->setText(text);
281 * Setup a context menu
282 * Made separate from populate so that it would not create context menu over and
283 * over as the tree is repopulated.
285 void Storage::createContextMenu()
287 mp_treeWidget->setContextMenuPolicy(Qt::ActionsContextMenu);
288 mp_treeWidget->addAction(actionRefreshStorage);
289 connect(mp_treeWidget, SIGNAL(
290 currentItemChanged(QTreeWidgetItem *, QTreeWidgetItem *)),
291 this, SLOT(treeItemChanged(QTreeWidgetItem *, QTreeWidgetItem *)));
292 /* connect to the action specific to this pages class */
293 connect(actionRefreshStorage, SIGNAL(triggered()), this,
294 SLOT(populateTree()));
295 connect(actionStatusStorageInConsole, SIGNAL(triggered()), this,
296 SLOT(consoleStatusStorage()));
297 connect(actionLabelStorage, SIGNAL(triggered()), this,
298 SLOT(consoleLabelStorage()));
299 connect(actionMountStorage, SIGNAL(triggered()), this,
300 SLOT(consoleMountStorage()));
301 connect(actionUnMountStorage, SIGNAL(triggered()), this,
302 SLOT(consoleUnMountStorage()));
303 connect(actionUpdateSlots, SIGNAL(triggered()), this,
304 SLOT(consoleUpdateSlots()));
305 connect(actionUpdateSlotsScan, SIGNAL(triggered()), this,
306 SLOT(consoleUpdateSlotsScan()));
307 connect(actionRelease, SIGNAL(triggered()), this,
308 SLOT(consoleRelease()));
309 connect(actionStatusStorageWindow, SIGNAL(triggered()), this,
310 SLOT(statusStorageWindow()));
314 * Virtual function which is called when this page is visible on the stack
316 void Storage::currentStackItem()
320 /* Create the context menu for the storage tree */
326 * Functions to respond to local context sensitive menu sending console commands
327 * If I could figure out how to make these one function passing a string, Yaaaaaa
329 void Storage::consoleStatusStorage()
331 QString cmd("status storage=");
332 cmd += m_currentStorage;
336 /* Label Media populating current storage by default */
337 void Storage::consoleLabelStorage()
339 new labelPage(m_currentStorage);
342 /* Mount currently selected storage */
343 void Storage::consoleMountStorage()
345 if (m_currentAutoChanger == 0){
346 /* no autochanger, just execute the command in the console */
347 QString cmd("mount storage=");
348 cmd += m_currentStorage;
352 /* if this storage is an autochanger, lets ask for the slot */
353 new mountDialog(m_console, m_currentStorage);
357 /* Unmount Currently selected storage */
358 void Storage::consoleUnMountStorage()
360 QString cmd("umount storage=");
361 cmd += m_currentStorage;
366 void Storage::consoleUpdateSlots()
368 QString cmd("update slots storage=");
369 cmd += m_currentStorage;
373 /* Update Slots Scan*/
374 void Storage::consoleUpdateSlotsScan()
376 QString cmd("update slots scan storage=");
377 cmd += m_currentStorage;
381 /* Release a tape in the drive */
382 void Storage::consoleRelease()
384 QString cmd("release storage=");
385 cmd += m_currentStorage;
390 * Open a status storage window
392 void Storage::statusStorageWindow()
394 QTreeWidgetItem *parentItem = mainWin->getFromHash(this);
395 new StorStat(m_currentStorage, parentItem);
399 * Write settings to save expanded states of the pools
401 void Storage::writeExpandedSettings()
403 QSettings settings(m_console->m_dir->name(), "bat");
404 settings.beginGroup("StorageTreeExpanded");
405 int childcount = m_topItem->childCount();
406 for (int cnt=0; cnt<childcount; cnt++) {
407 QTreeWidgetItem *item = m_topItem->child(cnt);
408 settings.setValue(item->text(0), item->isExpanded());