Hi,
the attached patch adds formatting to fields in bat media and storage trees.
It's purely cosmetical, no functional changes.
Highlights:
- bytes columns are shown as TB,GB,MB,KB instead of plain bytes
- durations which are an exact multiple of years,months,weeks,days or
hours are formatted accordingly, with a trailing y,m,w,d,h
- slot column shown only for in-changer media
- storage view shows also in-changer media
Patch against 2.2 branch (rev 6850)
Regards,
Riccardo Ghetta
Index: bacula/src/qt-console/storage/storage.cpp
===================================================================
--- bacula/src/qt-console/storage/storage.cpp (revision 6850)
+++ bacula/src/qt-console/storage/storage.cpp (working copy)
@@ -41,6 +41,7 @@
#include "storage.h"
#include "label/label.h"
#include "../mount/mount.h"
+#include "util/fmtwidgetitem.h"
Storage::Storage()
{
@@ -71,7 +72,7 @@
*/
void Storage::populateTree()
{
- QTreeWidgetItem *storageItem, *topItem;
+ QTreeWidgetItem *topItem;
if (!m_console->preventInUseConnect())
return;
@@ -80,8 +81,9 @@
mp_treeWidget->clear();
m_checkcurwidget = true;
- QStringList headerlist = (QStringList() << "Storage Name" << "Storage Id"
- << "Auto Changer");
+ QStringList headerlist = (QStringList() << "Name" << "Id"
+ << "Changer" << "Slot" << "Status" << "Enabled" << "Pool"
+ << "Media Type");
topItem = new QTreeWidgetItem(mp_treeWidget);
topItem->setText(0, "Storage");
@@ -92,10 +94,9 @@
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"
@@ -117,26 +118,83 @@
/* 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());
}
}
}
}
/* Resize the columns */
- for(int cnter=1; cnter<headerlist.size(); cnter++) {
+ for(int cnter=0; cnter<headerlist.size(); cnter++) {
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
* The tree has been populated.
Index: bacula/src/qt-console/storage/storage.h
===================================================================
--- bacula/src/qt-console/storage/storage.h (revision 6850)
+++ bacula/src/qt-console/storage/storage.h (working copy)
@@ -63,6 +63,7 @@
private:
void createContextMenu();
+ void mediaList(QTreeWidgetItem *parent, const QString &storageID);
QString m_currentStorage;
int m_currentAutoChanger;
bool m_populated;
Index: bacula/src/qt-console/medialist/medialist.h
===================================================================
--- bacula/src/qt-console/medialist/medialist.h (revision 6850)
+++ bacula/src/qt-console/medialist/medialist.h (working copy)
@@ -65,7 +65,6 @@
private:
void createContextMenu();
- void setStatusColor(QTreeWidgetItem *, QString &, int &);
QString m_currentVolumeName;
QString m_currentVolumeId;
bool m_populated;
Index: bacula/src/qt-console/medialist/medialist.cpp
===================================================================
--- bacula/src/qt-console/medialist/medialist.cpp (revision 6850)
+++ bacula/src/qt-console/medialist/medialist.cpp (working copy)
@@ -37,12 +37,14 @@
#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()
{
@@ -66,13 +68,14 @@
{
}
+
/*
* The main meat of the class!! The function that querries the director and
* creates the widgets with appropriate values.
*/
void MediaList::populateTree()
{
- QTreeWidgetItem *mediatreeitem, *pooltreeitem, *topItem;
+ QTreeWidgetItem *pooltreeitem, *topItem;
if (!m_console->preventInUseConnect())
return;
@@ -80,9 +83,8 @@
QStringList headerlist = (QStringList()
<< "Volume Name" << "Id" << "Status" << "Enabled" << "Bytes" << "Files"
<< "Jobs" << "Retention" << "Media Type" << "Slot" << "Use Duration"
- << "Max Jobs" << "Max Files" << "Max Bytes" << "Recycle" << "Enabled"
+ << "Max Jobs" << "Max Files" << "Max Bytes" << "Recycle"
<< "RecyclePool" << "Last Written");
- int statusIndex = headerlist.indexOf("Status");
m_checkcurwidget = false;
mp_treeWidget->clear();
@@ -108,11 +110,11 @@
" 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)"
@@ -125,28 +127,80 @@
}
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");
+
+ if (fieldlist.size() < 18)
+ continue; // some fields missing, ignore row
+
int index = 0;
- mediatreeitem = new QTreeWidgetItem(pooltreeitem);
+ 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);
- }
- }
- 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 */
@@ -156,17 +210,6 @@
}
}
-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!
*/
Index: bacula/src/qt-console/console/console.cpp
===================================================================
--- bacula/src/qt-console/console/console.cpp (revision 6850)
+++ bacula/src/qt-console/console/console.cpp (working copy)
@@ -314,7 +314,10 @@
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();
}
Index: bacula/src/qt-console/bat.pro.in
===================================================================
--- bacula/src/qt-console/bat.pro.in (revision 6850)
+++ bacula/src/qt-console/bat.pro.in (working copy)
@@ -124,6 +124,10 @@
HEADERS += help/help.h
SOURCES += help/help.cpp
+# Utility sources
+HEADERS += util/fmtwidgetitem.h
+SOURCES += util/fmtwidgetitem.cpp
+
INSTALLS += bins
INSTALLS += confs
Index: bacula/src/qt-console/util/fmtwidgetitem.h
===================================================================
--- bacula/src/qt-console/util/fmtwidgetitem.h (revision 0)
+++ bacula/src/qt-console/util/fmtwidgetitem.h (revision 0)
@@ -0,0 +1,77 @@
+#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:[EMAIL PROTECTED]
+*/
+/*
+ * 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_ */
Property changes on: bacula/src/qt-console/util/fmtwidgetitem.h
___________________________________________________________________
Name: svn:eol-style
+ native
Index: bacula/src/qt-console/util/fmtwidgetitem.cpp
===================================================================
--- bacula/src/qt-console/util/fmtwidgetitem.cpp (revision 0)
+++ bacula/src/qt-console/util/fmtwidgetitem.cpp (revision 0)
@@ -0,0 +1,139 @@
+/*
+ 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:[EMAIL PROTECTED]
+*/
+
+/*
+ * 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::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);
+ }
+}
+
Property changes on: bacula/src/qt-console/util/fmtwidgetitem.cpp
___________________________________________________________________
Name: svn:eol-style
+ native
-------------------------------------------------------------------------
This SF.net email is sponsored by the 2008 JavaOne(SM) Conference
Don't miss this year's exciting event. There's still time to save $100.
Use priority code J8TL2D2.
http://ad.doubleclick.net/clk;198757673;13503038;p?http://java.sun.com/javaone
_______________________________________________
Bacula-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/bacula-devel