HEADERS += status/storstat.h
SOURCES += status/storstat.cpp
+# Utility sources
+HEADERS += util/fmtwidgetitem.h
+SOURCES += util/fmtwidgetitem.cpp
+
INSTALLS += bins
INSTALLS += confs
pm_strcat(cmd, "\"");
write(cmd.c_str());
while ((stat = read()) > 0) {
- if (mainWin->m_displayAll) display_text(msg());
+ if (mainWin->m_displayAll) {
+ display_text(msg());
+ display_text("\n");
+ }
strip_trailing_junk(msg());
results << msg();
}
#include <QAbstractEventDispatcher>
#include <QMenu>
+#include <math.h>
#include "bat.h"
#include "medialist.h"
#include "mediaedit/mediaedit.h"
#include "joblist/joblist.h"
#include "relabel/relabel.h"
#include "run/run.h"
+#include "util/fmtwidgetitem.h"
MediaList::MediaList()
{
*/
void MediaList::populateTree()
{
- QTreeWidgetItem *mediatreeitem, *pooltreeitem;
+ QTreeWidgetItem *pooltreeitem;
if (!m_console->preventInUseConnect())
return;
QStringList headerlist = (QStringList()
<< tr("Volume Name") << tr("Id") << tr("Status") << tr("Enabled") << tr("Bytes") << tr("Files")
<< tr("Jobs") << tr("Retention") << tr("Media Type") << tr("Slot") << tr("Use Duration")
- << tr("Max Jobs") << tr("Max Files") << tr("Max Bytes") << tr("Recycle") << tr("Enabled")
+ << tr("Max Jobs") << tr("Max Files") << tr("Max Bytes") << tr("Recycle")
<< tr("RecyclePool") << tr("Last Written"));
- int statusIndex = headerlist.indexOf("Status");
- QStringList flaglist = (QStringList()
- << "L" << "R" << "L" << "R" << "BR" << "R"
- << "R" << "RS" << "L" << "R" << "RS"
- << "R" << "R" << "BR" << "R" << "R"
- << "L" << "L");
m_checkcurwidget = false;
if (m_populated)
" Media.Enabled AS Enabled, Media.VolBytes AS Bytes,"
" Media.VolFiles AS FileCount, Media.VolJobs AS JobCount,"
" Media.VolRetention AS VolumeRetention, Media.MediaType AS MediaType,"
- " Media.Slot AS Slot, Media.VolUseDuration AS UseDuration,"
+ " Media.InChanger AS InChanger, Media.Slot AS Slot, "
+ " Media.VolUseDuration AS UseDuration,"
" Media.MaxVolJobs AS MaxJobs, Media.MaxVolFiles AS MaxFiles,"
" Media.MaxVolBytes AS MaxBytes, Media.Recycle AS Recycle,"
- " Media.Enabled AS enabled, Pol.Name AS RecyclePool,"
- " Media.LastWritten AS LastWritten"
+ " Pol.Name AS RecyclePool, Media.LastWritten AS LastWritten"
" FROM Media"
" JOIN Pool ON (Media.PoolId=Pool.PoolId)"
" LEFT OUTER JOIN Pool AS Pol ON (Media.RecyclePoolId=Pol.PoolId)"
}
QStringList results;
if (m_console->sql_cmd(query, results)) {
- QString field;
QStringList fieldlist;
/* Iterate through the lines of results. */
foreach (QString resultline, results) {
fieldlist = resultline.split("\t");
- int index = 0;
- mediatreeitem = new QTreeWidgetItem(pooltreeitem);
+ if (fieldlist.size() < 18)
+ continue; // some fields missing, ignore row
+
+ int index = 0;
+ ItemFormatter mediaitem(*pooltreeitem, 2);
+
/* Iterate through fields in the record */
- foreach (field, fieldlist) {
- field = field.trimmed(); /* strip leading & trailing spaces */
- if (field != "") {
- mediatreeitem->setData(index, Qt::UserRole, 2);
- mediatreeitem->setData(index, Qt::UserRole, 2);
- mediatreeitem->setText(index, field);
- if (index == statusIndex) {
- setStatusColor(mediatreeitem, field, index);
- }
- if (flaglist[index].contains("B")) {
- QString text;
- bool okay;
- qlonglong bytes = field.toULongLong(&okay);
- if (okay){
- QString test = QString("%1").arg(bytes);
- mainWin->hrConvert(text, bytes);
- mediatreeitem->setText(index, text);
- } else { Pmsg1(000, "conversion error %s\n", field.toUtf8().data()); }
- }
- if (flaglist[index].contains("S")) {
- QString text;
- bool okay;
- qlonglong seconds = field.toULongLong(&okay);
- if (okay){
- QString test = QString("%1").arg(seconds);
- mainWin->hrConvertSeconds(text, seconds);
- mediatreeitem->setText(index, text);
- } else { Pmsg1(000, "conversion error %s\n", field.toUtf8().data()); }
- }
- if (flaglist[index].contains("R"))
- mediatreeitem->setTextAlignment(index, Qt::AlignRight);
- }
- index++;
- } /* foreach field */
+ QStringListIterator fld(fieldlist);
+
+ /* volname */
+ mediaitem.setTextFld(index++, fld.next());
+
+ /* id */
+ mediaitem.setNumericFld(index++, fld.next());
+
+ /* status */
+ mediaitem.setVolStatusFld(index++, fld.next());
+
+ /* enabled */
+ mediaitem.setBoolFld(index++, fld.next());
+
+ /* bytes */
+ mediaitem.setBytesFld(index++, fld.next());
+
+ /* files */
+ mediaitem.setNumericFld(index++, fld.next());
+
+ /* jobs */
+ mediaitem.setNumericFld(index++, fld.next());
+
+ /* retention */
+ mediaitem.setDurationFld(index++, fld.next());
+
+ /* media type */
+ mediaitem.setTextFld(index++, fld.next());
+
+ /* inchanger + slot */
+ int inchanger = fld.next().toInt();
+ if (inchanger) {
+ mediaitem.setNumericFld(index++, fld.next());
+ }
+ else {
+ /* volume not in changer, show blank slot */
+ mediaitem.setNumericFld(index++, "");
+ fld.next();
+ }
+
+ /* use duration */
+ mediaitem.setDurationFld(index++, fld.next());
+
+ /* max jobs */
+ mediaitem.setNumericFld(index++, fld.next());
+
+ /* max files */
+ mediaitem.setNumericFld(index++, fld.next());
+
+ /* max bytes */
+ mediaitem.setBytesFld(index++, fld.next());
+
+ /* recycle */
+ mediaitem.setBoolFld(index++, fld.next());
+
+ /* recycle pool */
+ mediaitem.setTextFld(index++, fld.next());
+
+ /* last written */
+ mediaitem.setTextFld(index++, fld.next());
+
} /* foreach resultline */
} /* if results from query */
} /* foreach pool_listItem */
}
}
-void MediaList::setStatusColor(QTreeWidgetItem *item, QString &field, int &index)
-{
- if (field == "Append" ) {
- item->setBackground(index, Qt::green);
- } else if (field == "Error") {
- item->setBackground(index, Qt::red);
- } else if ((field == "Used") || ("Full")){
- item->setBackground(index, Qt::yellow);
- }
-}
-
/*
* Called from the signal of the context sensitive menu!
*/
private:
void createContextMenu();
- void setStatusColor(QTreeWidgetItem *, QString &, int &);
void writeExpandedSettings();
QString m_currentVolumeName;
QString m_currentVolumeId;
#include "label/label.h"
#include "mount/mount.h"
#include "status/storstat.h"
+#include "util/fmtwidgetitem.h"
Storage::Storage()
{
*/
void Storage::populateTree()
{
- QTreeWidgetItem *storageItem, *topItem;
+ QTreeWidgetItem *topItem;
if (!m_console->preventInUseConnect())
return;
mp_treeWidget->clear();
m_checkcurwidget = true;
- QStringList headerlist = (QStringList() << tr("Storage Name") << tr("Storage Id")
- << tr("Auto Changer"));
+ QStringList headerlist = (QStringList() << tr("Name") << tr("Id")
+ << tr("Changer") << tr("Slot") << tr("Status") << tr("Enabled") << tr("Pool")
+ << tr("Media Type") );
topItem = new QTreeWidgetItem(mp_treeWidget);
topItem->setText(0, tr("Storage"));
mp_treeWidget->setHeaderLabels(headerlist);
foreach(QString storageName, m_console->storage_list){
- storageItem = new QTreeWidgetItem(topItem);
- storageItem->setText(0, storageName);
- storageItem->setData(0, Qt::UserRole, 1);
- storageItem->setExpanded(true);
+ ItemFormatter storageItem(*topItem, 1);
+ storageItem.setTextFld(0, storageName);
+ storageItem.widget()->setExpanded(true);
/* Set up query QString and header QStringList */
QString query("SELECT StorageId AS ID, AutoChanger AS Changer"
/* there will only be one of these */
foreach (resultline, results) {
fieldlist = resultline.split("\t");
- int index = 0;
- /* Iterate through fields in the record */
- foreach (field, fieldlist) {
- field = field.trimmed(); /* strip leading & trailing spaces */
- storageItem->setData(index+1, Qt::UserRole, 1);
- /* Put media fields under the pool tree item */
- storageItem->setData(index+1, Qt::UserRole, 1);
- storageItem->setText(index+1, field);
- index++;
- }
+ int index = 1;
+ QStringListIterator fld(fieldlist);
+
+ /* storage id */
+ storageItem.setNumericFld(index++, fld.next() );
+
+ /* changer */
+ storageItem.setBoolFld(index++, fld.next() );
+
+ mediaList(storageItem.widget(), fieldlist.first());
}
}
}
mp_treeWidget->resizeColumnToContents(cnter);
}
}
+void Storage::mediaList(QTreeWidgetItem *parent, const QString &storageID)
+{
+ QString query("SELECT Media.VolumeName AS Media, Media.Slot AS Slot,"
+ " Media.VolStatus AS VolStatus, Media.Enabled AS Enabled,"
+ " Pool.Name AS MediaPool, Media.MediaType AS MediaType"
+ " From Media"
+ " JOIN Pool ON (Media.PoolId=Pool.PoolId)"
+ " WHERE Media.StorageId='" + storageID + "'"
+ " AND Media.InChanger<>0"
+ " ORDER BY Media.Slot");
+
+ QStringList results;
+ /* This could be a log item */
+ if (mainWin->m_sqlDebug) {
+ Pmsg1(000, "Storage query cmd : %s\n",query.toUtf8().data());
+ }
+ if (m_console->sql_cmd(query, results)) {
+ QString resultline;
+ QString field;
+ QStringList fieldlist;
+
+ foreach (resultline, results) {
+ fieldlist = resultline.split("\t");
+ if (fieldlist.size() < 6)
+ continue;
+
+ /* Iterate through fields in the record */
+ QStringListIterator fld(fieldlist);
+ int index = 0;
+ ItemFormatter fmt(*parent, 2);
+
+ /* volname */
+ fmt.setTextFld(index++, fld.next());
+
+ /* skip the next two columns, unused by media */
+ index += 2;
+
+ /* slot */
+ fmt.setNumericFld(index++, fld.next());
+
+ /* status */
+ fmt.setVolStatusFld(index++, fld.next());
+
+ /* enabled */
+ fmt.setBoolFld(index++, fld.next());
+
+ /* pool */
+ fmt.setTextFld(index++, fld.next());
+
+ /* media type */
+ fmt.setTextFld(index++, fld.next());
+
+ }
+ }
+}
/*
* When the treeWidgetItem in the page selector tree is singleclicked, Make sure
private:
void createContextMenu();
+ void mediaList(QTreeWidgetItem *parent, const QString &storageID);
QString m_currentStorage;
int m_currentAutoChanger;
bool m_populated;
--- /dev/null
+/*
+ Bacula® - The Network Backup Solution
+
+ Copyright (C) 2007-2007 Free Software Foundation Europe e.V.
+
+ The main author of Bacula is Kern Sibbald, with contributions from
+ many others, a complete list can be found in the file AUTHORS.
+ This program is Free Software; you can redistribute it and/or
+ modify it under the terms of version two of the GNU General Public
+ License as published by the Free Software Foundation and included
+ in the file LICENSE.
+
+ This program is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ 02110-1301, USA.
+
+ Bacula® is a registered trademark of John Walker.
+ The licensor of Bacula is the Free Software Foundation Europe
+ (FSFE), Fiduciary Program, Sumatrastrasse 25, 8006 Zürich,
+ Switzerland, email:ftf@fsfeurope.org.
+*/
+
+/*
+ * Version $Id$
+ *
+ * Helper functions for tree widget formatting
+ *
+ * Riccardo Ghetta, May 2008
+ *
+ */
+
+#include <QTreeWidgetItem>
+#include <QString>
+#include <QStringList>
+#include <math.h>
+#include "fmtwidgetitem.h"
+
+ItemFormatter::ItemFormatter(QTreeWidgetItem &parent, int indent_level):
+wdg(new QTreeWidgetItem(&parent)),
+level(indent_level)
+{
+}
+
+void ItemFormatter::setBoolFld(int index, const QString &fld, bool center)
+{
+ if (fld.trimmed().toInt())
+ setTextFld(index, "Yes", center);
+ else
+ setTextFld(index, "No", center);
+}
+
+void ItemFormatter::setBoolFld(int index, int fld, bool center)
+{
+ if (fld)
+ setTextFld(index, "Yes", center);
+ else
+ setTextFld(index, "No", center);
+}
+
+void ItemFormatter::setTextFld(int index, const QString &fld, bool center)
+{
+ wdg->setData(index, Qt::UserRole, level);
+ if (center) {
+ wdg->setTextAlignment(index, Qt::AlignHCenter);
+ }
+ wdg->setText(index, fld.trimmed());
+}
+
+void ItemFormatter::setNumericFld(int index, const QString &fld)
+{
+ wdg->setData(index, Qt::UserRole, level);
+ wdg->setTextAlignment(index, Qt::AlignRight);
+ wdg->setText(index, fld.trimmed());
+}
+
+void ItemFormatter::setBytesFld(int index, const QString &fld)
+{
+ static const double KB = 1024.0;
+ static const double MB = KB * KB;
+ static const double GB = MB * KB;
+ static const double TB = GB * KB;
+
+ double dfld = fld.trimmed().toDouble();
+ QString msg;
+ if (dfld >= TB)
+ msg = QString("%1TB").arg(dfld / TB, 0, 'f', 2);
+ else if (dfld >= GB)
+ msg = QString("%1GB").arg(dfld / GB, 0, 'f', 2);
+ else if (dfld >= MB)
+ msg = QString("%1MB").arg(dfld / MB, 0, 'f', 2);
+ else if (dfld >= KB)
+ msg = QString("%1KB").arg(dfld / KB, 0, 'f', 2);
+ else
+ msg = QString::number(dfld, 'f', 0);
+
+ wdg->setData(index, Qt::UserRole, level);
+ wdg->setTextAlignment(index, Qt::AlignRight);
+ wdg->setText(index, msg);
+}
+
+void ItemFormatter::setDurationFld(int index, const QString &fld)
+{
+ static const double HOUR = 3600;
+ static const double DAY = HOUR * 24;
+ static const double WEEK = DAY * 7;
+ static const double MONTH = DAY * 30;
+ static const double YEAR = DAY * 365;
+
+ double dfld = fld.trimmed().toDouble();
+ QString msg;
+ if (fmod(dfld, YEAR) == 0)
+ msg = QString("%1y").arg(dfld / YEAR, 0, 'f', 0);
+ else if (fmod(dfld, MONTH) == 0)
+ msg = QString("%1m").arg(dfld / MONTH, 0, 'f', 0);
+ else if (fmod(dfld, WEEK) == 0)
+ msg = QString("%1w").arg(dfld / WEEK, 0, 'f', 0);
+ else if (fmod(dfld, DAY) == 0)
+ msg = QString("%1d").arg(dfld / DAY, 0, 'f', 0);
+ else if (fmod(dfld, HOUR) == 0)
+ msg = QString("%1h").arg(dfld / HOUR, 0, 'f', 0);
+ else
+ msg = QString("%1s").arg(dfld, 0, 'f', 0);
+
+ wdg->setData(index, Qt::UserRole, level);
+ wdg->setTextAlignment(index, Qt::AlignRight);
+ wdg->setText(index, msg);
+}
+
+void ItemFormatter::setVolStatusFld(int index, const QString &fld, bool center)
+{
+ setTextFld(index, fld, center);
+
+ if (fld == "Append" ) {
+ wdg->setBackground(index, Qt::green);
+ } else if (fld == "Error") {
+ wdg->setBackground(index, Qt::red);
+ } else if (fld == "Used" || fld == "Full"){
+ wdg->setBackground(index, Qt::yellow);
+ }
+}
--- /dev/null
+#ifndef _FMTWIDGETITEM_H_
+#define _FMTWIDGETITEM_H_
+/*
+ Bacula® - The Network Backup Solution
+
+ Copyright (C) 2007-2007 Free Software Foundation Europe e.V.
+
+ The main author of Bacula is Kern Sibbald, with contributions from
+ many others, a complete list can be found in the file AUTHORS.
+ This program is Free Software; you can redistribute it and/or
+ modify it under the terms of version two of the GNU General Public
+ License as published by the Free Software Foundation and included
+ in the file LICENSE.
+
+ This program is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ 02110-1301, USA.
+
+ Bacula® is a registered trademark of John Walker.
+ The licensor of Bacula is the Free Software Foundation Europe
+ (FSFE), Fiduciary Program, Sumatrastrasse 25, 8006 Zürich,
+ Switzerland, email:ftf@fsfeurope.org.
+*/
+/*
+ * Version $Id$
+ *
+ * TreeView formatting helpers - Riccardo Ghetta, May 2008
+ */
+
+class QTreeWidgetItem;
+class QString;
+
+/*
+ * This class can be used instead of QTreeWidgetItem (it allocates one internally,
+ * to format data fields.
+ * All setXXXFld routines receive a column index and the unformatted string value.
+ */
+class ItemFormatter
+{
+public:
+
+ ItemFormatter(QTreeWidgetItem &parent, int indent_level);
+
+ /* Prints Yes if fld is != 0, No otherwise. Centers field if center true*/
+ void setBoolFld(int index, const QString &fld, bool center = true);
+ void setBoolFld(int index, int fld, bool center = true);
+
+ /* Normal text field. Centers field if center true*/
+ void setTextFld(int index, const QString &fld, bool center = false);
+
+ /* Right-aligned text field.*/
+ void setNumericFld(int index, const QString &fld);
+
+ /* fld value interpreted as bytes and formatted with size suffixes */
+ void setBytesFld(int index, const QString &fld);
+
+ /* fld value interpreted as seconds and formatted with y,m,w,h suffixes */
+ void setDurationFld(int index, const QString &fld);
+
+ /* fld value interpreted as volume status. Colored accordingly */
+ void setVolStatusFld(int index, const QString &fld, bool center = true);
+
+ /* access internal widget */
+ QTreeWidgetItem *widget() { return wdg; }
+ const QTreeWidgetItem *widget() const { return wdg; }
+
+private:
+ QTreeWidgetItem *wdg;
+ int level;
+};
+
+#endif /* _FMTWIDGETITEM_H_ */
+#ifndef _FMTWIDGETITEM_H_
+#define _FMTWIDGETITEM_H_
+/*
+ Bacula® - The Network Backup Solution
+
+ Copyright (C) 2007-2007 Free Software Foundation Europe e.V.
+
+ The main author of Bacula is Kern Sibbald, with contributions from
+ many others, a complete list can be found in the file AUTHORS.
+ This program is Free Software; you can redistribute it and/or
+ modify it under the terms of version two of the GNU General Public
+ License as published by the Free Software Foundation and included
+ in the file LICENSE.
+
+ This program is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ 02110-1301, USA.
+
+ Bacula® is a registered trademark of John Walker.
+ The licensor of Bacula is the Free Software Foundation Europe
+ (FSFE), Fiduciary Program, Sumatrastrasse 25, 8006 Zürich,
+ Switzerland, email:ftf@fsfeurope.org.
+*/
+/*
+ * Version $Id$
+ *
+ * TreeView formatting helpers - Riccardo Ghetta, May 2008
+ */
+
+class QTreeWidgetItem;
+class QString;
+
+/*
+ * This class can be used instead of QTreeWidgetItem (it allocates one internally,
+ * to format data fields.
+ * All setXXXFld routines receive a column index and the unformatted string value.
+ */
+class ItemFormatter
+{
+public:
+
+ ItemFormatter(QTreeWidgetItem &parent, int indent_level);
+
+ /* Prints Yes if fld is != 0, No otherwise. Centers field if center true*/
+ void setBoolFld(int index, const QString &fld, bool center = true);
+
+ /* Normal text field. Centers field if center true*/
+ void setTextFld(int index, const QString &fld, bool center = false);
+
+ /* Right-aligned text field.*/
+ void setNumericFld(int index, const QString &fld);
+
+ /* fld value interpreted as bytes and formatted with size suffixes */
+ void setBytesFld(int index, const QString &fld);
+
+ /* fld value interpreted as seconds and formatted with y,m,w,h suffixes */
+ void setDurationFld(int index, const QString &fld);
+
+ /* fld value interpreted as volume status. Colored accordingly */
+ void setVolStatusFld(int index, const QString &fld, bool center = true);
+
+ /* access internal widget */
+ QTreeWidgetItem *widget() { return wdg; }
+ const QTreeWidgetItem *widget() const { return wdg; }
+
+private:
+ QTreeWidgetItem *wdg;
+ int level;
+};
+
+#endif /* _FMTWIDGETITEM_H_ */