2 Bacula® - The Network Backup Solution
4 Copyright (C) 2007-2007 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.
32 * Helper functions for tree widget formatting
34 * Riccardo Ghetta, May 2008
38 #include <QTreeWidgetItem>
39 #include <QTableWidget>
40 #include <QTableWidgetItem>
43 #include <QStringList>
46 #include "fmtwidgetitem.h"
48 /***********************************************
52 ***********************************************/
54 QString convertJobStatus(const QString &sts)
56 QString code( sts.trimmed() );
57 if ( code.size() != 1) {
58 return QObject::tr("Invalid job status %1").arg(sts);
62 jobstatus_to_ascii_gui( code[0].toAscii(), buf, sizeof(buf));
66 /***********************************************
68 * ItemFormatterBase static members
70 ***********************************************/
72 ItemFormatterBase::BYTES_CONVERSION ItemFormatterBase::cnvFlag(BYTES_CONVERSION_IEC);
74 QString ItemFormatterBase::convertBytesIEC(qint64 qfld)
76 static const qint64 KB = Q_INT64_C(1024);
77 static const qint64 MB = (KB * KB);
78 static const qint64 GB = (MB * KB);
79 static const qint64 TB = (GB * KB);
80 static const qint64 PB = (TB * KB);
81 static const qint64 EB = (PB * KB);
83 /* note: division is integer, so to have some decimals we divide for a
84 smaller unit (e.g. GB for a TB number and so on) */
90 else if (qfld >= PB) {
94 else if (qfld >= TB) {
98 else if (qfld >= GB) {
102 else if (qfld >= MB) {
106 else if (qfld >= KB) {
110 /* plain bytes, no need to reformat */
111 return QString("%1 B").arg(qfld);
114 /* having divided for a smaller unit, now we can safely convert to double and
115 use the extra room for decimals */
116 return QString("%1 %2iB").arg(qfld / 1000.0, 0, 'f', 2).arg(suffix);
119 QString ItemFormatterBase::convertBytesSI(qint64 qfld)
121 static const qint64 KB = Q_INT64_C(1000);
122 static const qint64 MB = (KB * KB);
123 static const qint64 GB = (MB * KB);
124 static const qint64 TB = (GB * KB);
125 static const qint64 PB = (TB * KB);
126 static const qint64 EB = (PB * KB);
128 /* note: division is integer, so to have some decimals we divide for a
129 smaller unit (e.g. GB for a TB number and so on) */
135 else if (qfld >= PB) {
139 else if (qfld >= TB) {
143 else if (qfld >= GB) {
147 else if (qfld >= MB) {
151 else if (qfld >= KB) {
152 suffix = 'k'; /* SI uses lowercase k */
155 /* plain bytes, no need to reformat */
156 return QString("%1 B").arg(qfld);
159 /* having divided for a smaller unit, now we can safely convert to double and
160 use the extra room for decimals */
161 return QString("%1 %2B").arg(qfld / 1000.0, 0, 'f', 2).arg(suffix);
164 /***********************************************
166 * base formatting routines
168 ***********************************************/
170 ItemFormatterBase::ItemFormatterBase()
174 ItemFormatterBase::~ItemFormatterBase()
178 void ItemFormatterBase::setTextFld(int index, const QString &fld, bool center)
180 setText(index, fld.trimmed());
182 setTextAlignment(index, Qt::AlignCenter);
186 void ItemFormatterBase::setRightFld(int index, const QString &fld)
188 setText(index, fld.trimmed());
189 setTextAlignment(index, Qt::AlignRight | Qt::AlignVCenter);
192 void ItemFormatterBase::setBoolFld(int index, const QString &fld, bool center)
194 if (fld.trimmed().toInt())
195 setTextFld(index, QObject::tr("Yes"), center);
197 setTextFld(index, QObject::tr("No"), center);
200 void ItemFormatterBase::setBoolFld(int index, int fld, bool center)
203 setTextFld(index, QObject::tr("Yes"), center);
205 setTextFld(index, QObject::tr("No"), center);
208 void ItemFormatterBase::setNumericFld(int index, const QString &fld)
210 setRightFld(index, fld.trimmed());
211 setSortValue(index, fld.toDouble() );
214 void ItemFormatterBase::setNumericFld(int index, const QString &fld, const QVariant &sortval)
216 setRightFld(index, fld.trimmed());
217 setSortValue(index, sortval );
220 void ItemFormatterBase::setBytesFld(int index, const QString &fld)
222 qint64 qfld = fld.trimmed().toLongLong();
225 case BYTES_CONVERSION_NONE:
226 msg = QString::number(qfld);
228 case BYTES_CONVERSION_IEC:
229 msg = convertBytesIEC(qfld);
231 case BYTES_CONVERSION_SI:
232 msg = convertBytesSI(qfld);
236 setNumericFld(index, msg, qfld);
239 void ItemFormatterBase::setDurationFld(int index, const QString &fld)
241 static const qint64 HOUR = Q_INT64_C(3600);
242 static const qint64 DAY = HOUR * 24;
243 static const qint64 WEEK = DAY * 7;
244 static const qint64 MONTH = DAY * 30;
245 static const qint64 YEAR = DAY * 365;
246 static const qint64 divs[] = { YEAR, MONTH, WEEK, DAY, HOUR };
247 static const char sufs[] = { 'y', 'm', 'w', 'd', 'h', '\0' };
249 qint64 dfld = fld.trimmed().toLongLong();
253 for (int pos = 0 ; sufs[pos] ; ++pos) {
254 if (dfld % divs[pos] == 0) {
263 msg = QString("%1%2").arg(dfld).arg(suffix);
265 /* previous check returned a number too big. The original specification perhaps
266 was mixed, like 1d 2h, so we try to match with this routine */
267 dfld = fld.trimmed().toLongLong();
269 for (int pos = 0 ; sufs[pos] ; ++pos) {
270 if (dfld / divs[pos] != 0) {
271 msg += QString(" %1%2").arg(dfld / divs[pos]).arg(sufs[pos]);
276 msg += QString(" %1s").arg(dfld);
279 setNumericFld(index, msg, fld.trimmed().toLongLong());
282 void ItemFormatterBase::setVolStatusFld(int index, const QString &fld, bool center)
284 QString mp(fld.trimmed());
285 setTextFld(index, volume_status_to_str(mp.toUtf8()), center);
287 if (mp == "Append" ) {
288 setBackground(index, Qt::green);
289 } else if (mp == "Error") {
290 setBackground(index, Qt::red);
291 } else if (mp == "Used" || mp == "Full"){
292 setBackground(index, Qt::yellow);
293 } else if (mp == "Read-only" || mp == "Disabled"){
294 setBackground(index, Qt::lightGray);
298 void ItemFormatterBase::setJobStatusFld(int index, const QString &status, bool center)
300 /* C (created, not yet running) uses the default background */
301 static QString greenchars("TR");
302 static QString redchars("BEf");
303 static QString yellowchars("eDAFSMmsjdctp");
305 setTextFld(index, convertJobStatus(status), center);
307 QString st(status.trimmed());
308 if (greenchars.contains(st, Qt::CaseSensitive)) {
309 setBackground(index, Qt::green);
310 } else if (redchars.contains(st, Qt::CaseSensitive)) {
311 setBackground(index, Qt::red);
312 } else if (yellowchars.contains(st, Qt::CaseSensitive)){
313 setBackground(index, Qt::yellow);
317 void ItemFormatterBase::setJobTypeFld(int index, const QString &fld, bool center)
319 QByteArray jtype(fld.trimmed().toAscii());
321 setTextFld(index, job_type_to_str(jtype[0]), center);
323 setTextFld(index, "", center);
327 void ItemFormatterBase::setJobLevelFld(int index, const QString &fld, bool center)
329 QByteArray lvl(fld.trimmed().toAscii());
331 setTextFld(index, job_level_to_str(lvl[0]), center);
333 setTextFld(index, "", center);
339 /***********************************************
341 * treeitem formatting routines
343 ***********************************************/
344 TreeItemFormatter::TreeItemFormatter(QTreeWidgetItem &parent, int indent_level):
346 wdg(new QTreeWidgetItem(&parent)),
351 void TreeItemFormatter::setText(int index, const QString &fld)
353 wdg->setData(index, Qt::UserRole, level);
354 wdg->setText(index, fld);
357 void TreeItemFormatter::setTextAlignment(int index, int align)
359 wdg->setTextAlignment(index, align);
362 void TreeItemFormatter::setBackground(int index, const QBrush &qb)
364 wdg->setBackground(index, qb);
367 /* at this time we don't sort trees, so this method does nothing */
368 void TreeItemFormatter::setSortValue(int /* index */, const QVariant & /* value */)
372 /***********************************************
374 * Specialized table widget used for sorting
376 ***********************************************/
377 TableItemFormatter::BatSortingTableItem::BatSortingTableItem():
382 void TableItemFormatter::BatSortingTableItem::setSortData(const QVariant &d)
384 setData(SORTDATA_ROLE, d);
387 bool TableItemFormatter::BatSortingTableItem::operator< ( const QTableWidgetItem & o ) const
389 QVariant my = data(SORTDATA_ROLE);
390 QVariant other = o.data(SORTDATA_ROLE);
391 if (!my.isValid() || !other.isValid() || my.type() != other.type())
392 return QTableWidgetItem::operator< (o); /* invalid combination, revert to default sorting */
394 /* 64bit integers must be handled separately, others can be converted to double */
395 if (QVariant::ULongLong == my.type()) {
396 return my.toULongLong() < other.toULongLong();
397 } else if (QVariant::LongLong == my.type()) {
398 return my.toLongLong() < other.toLongLong();
399 } else if (my.canConvert(QVariant::Double)) {
400 return my.toDouble() < other.toDouble();
402 return QTableWidgetItem::operator< (o); /* invalid combination, revert to default sorting */
406 /***********************************************
408 * tableitem formatting routines
410 ***********************************************/
411 TableItemFormatter::TableItemFormatter(QTableWidget &tparent, int trow):
419 void TableItemFormatter::setText(int col, const QString &fld)
421 last = new BatSortingTableItem;
422 parent->setItem(row, col, last);
426 void TableItemFormatter::setTextAlignment(int /*index*/, int align)
428 last->setTextAlignment(align);
431 void TableItemFormatter::setBackground(int /*index*/, const QBrush &qb)
433 last->setBackground(qb);
436 void TableItemFormatter::setSortValue(int /* index */, const QVariant &value )
438 last->setSortData(value);
441 QTableWidgetItem *TableItemFormatter::widget(int col)
443 return parent->item(row, col);
446 const QTableWidgetItem *TableItemFormatter::widget(int col) const
448 return parent->item(row, col);