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
39 #include <QTreeWidgetItem>
40 #include <QTableWidget>
41 #include <QTableWidgetItem>
44 #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));
67 * disable widget updating
69 Freeze::Freeze(QWidget &q):
72 qw->setUpdatesEnabled(false);
78 qw->setUpdatesEnabled(true);
83 /***********************************************
85 * ItemFormatterBase static members
87 ***********************************************/
89 ItemFormatterBase::BYTES_CONVERSION ItemFormatterBase::cnvFlag(BYTES_CONVERSION_IEC);
91 QString ItemFormatterBase::convertBytesIEC(qint64 qfld)
93 static const qint64 KB = Q_INT64_C(1024);
94 static const qint64 MB = (KB * KB);
95 static const qint64 GB = (MB * KB);
96 static const qint64 TB = (GB * KB);
97 static const qint64 PB = (TB * KB);
98 static const qint64 EB = (PB * KB);
100 /* note: division is integer, so to have some decimals we divide for a
101 smaller unit (e.g. GB for a TB number and so on) */
107 else if (qfld >= PB) {
111 else if (qfld >= TB) {
115 else if (qfld >= GB) {
119 else if (qfld >= MB) {
123 else if (qfld >= KB) {
127 /* plain bytes, no need to reformat */
128 return QString("%1 B").arg(qfld);
131 /* having divided for a smaller unit, now we can safely convert to double and
132 use the extra room for decimals */
133 return QString("%1 %2iB").arg(qfld / 1000.0, 0, 'f', 2).arg(suffix);
136 QString ItemFormatterBase::convertBytesSI(qint64 qfld)
138 static const qint64 KB = Q_INT64_C(1000);
139 static const qint64 MB = (KB * KB);
140 static const qint64 GB = (MB * KB);
141 static const qint64 TB = (GB * KB);
142 static const qint64 PB = (TB * KB);
143 static const qint64 EB = (PB * KB);
145 /* note: division is integer, so to have some decimals we divide for a
146 smaller unit (e.g. GB for a TB number and so on) */
152 else if (qfld >= PB) {
156 else if (qfld >= TB) {
160 else if (qfld >= GB) {
164 else if (qfld >= MB) {
168 else if (qfld >= KB) {
169 suffix = 'k'; /* SI uses lowercase k */
172 /* plain bytes, no need to reformat */
173 return QString("%1 B").arg(qfld);
176 /* having divided for a smaller unit, now we can safely convert to double and
177 use the extra room for decimals */
178 return QString("%1 %2B").arg(qfld / 1000.0, 0, 'f', 2).arg(suffix);
181 /***********************************************
183 * base formatting routines
185 ***********************************************/
187 ItemFormatterBase::ItemFormatterBase()
191 ItemFormatterBase::~ItemFormatterBase()
195 void ItemFormatterBase::setTextFld(int index, const QString &fld, bool center)
197 setText(index, fld.trimmed());
199 setTextAlignment(index, Qt::AlignCenter);
203 void ItemFormatterBase::setRightFld(int index, const QString &fld)
205 setText(index, fld.trimmed());
206 setTextAlignment(index, Qt::AlignRight | Qt::AlignVCenter);
209 void ItemFormatterBase::setBoolFld(int index, const QString &fld, bool center)
211 if (fld.trimmed().toInt())
212 setTextFld(index, QObject::tr("Yes"), center);
214 setTextFld(index, QObject::tr("No"), center);
217 void ItemFormatterBase::setBoolFld(int index, int fld, bool center)
220 setTextFld(index, QObject::tr("Yes"), center);
222 setTextFld(index, QObject::tr("No"), center);
225 void ItemFormatterBase::setNumericFld(int index, const QString &fld)
227 setRightFld(index, fld.trimmed());
228 setSortValue(index, fld.toDouble() );
231 void ItemFormatterBase::setNumericFld(int index, const QString &fld, const QVariant &sortval)
233 setRightFld(index, fld.trimmed());
234 setSortValue(index, sortval );
237 void ItemFormatterBase::setBytesFld(int index, const QString &fld)
239 qint64 qfld = fld.trimmed().toLongLong();
242 case BYTES_CONVERSION_NONE:
243 msg = QString::number(qfld);
245 case BYTES_CONVERSION_IEC:
246 msg = convertBytesIEC(qfld);
248 case BYTES_CONVERSION_SI:
249 msg = convertBytesSI(qfld);
253 setNumericFld(index, msg, qfld);
256 void ItemFormatterBase::setDurationFld(int index, const QString &fld)
258 static const qint64 HOUR = Q_INT64_C(3600);
259 static const qint64 DAY = HOUR * 24;
260 static const qint64 WEEK = DAY * 7;
261 static const qint64 MONTH = DAY * 30;
262 static const qint64 YEAR = DAY * 365;
263 static const qint64 divs[] = { YEAR, MONTH, WEEK, DAY, HOUR };
264 static const char sufs[] = { 'y', 'm', 'w', 'd', 'h', '\0' };
266 qint64 dfld = fld.trimmed().toLongLong();
270 for (int pos = 0 ; sufs[pos] ; ++pos) {
271 if (dfld % divs[pos] == 0) {
280 msg = QString("%1%2").arg(dfld).arg(suffix);
282 /* previous check returned a number too big. The original specification perhaps
283 was mixed, like 1d 2h, so we try to match with this routine */
284 dfld = fld.trimmed().toLongLong();
286 for (int pos = 0 ; sufs[pos] ; ++pos) {
287 if (dfld / divs[pos] != 0) {
288 msg += QString(" %1%2").arg(dfld / divs[pos]).arg(sufs[pos]);
293 msg += QString(" %1s").arg(dfld);
296 setNumericFld(index, msg, fld.trimmed().toLongLong());
299 void ItemFormatterBase::setVolStatusFld(int index, const QString &fld, bool center)
301 QString mp(fld.trimmed());
302 setTextFld(index, volume_status_to_str(mp.toUtf8()), center);
304 if (mp == "Append" ) {
305 setBackground(index, Qt::green);
306 } else if (mp == "Error") {
307 setBackground(index, Qt::red);
308 } else if (mp == "Used" || mp == "Full"){
309 setBackground(index, Qt::yellow);
310 } else if (mp == "Read-only" || mp == "Disabled"){
311 setBackground(index, Qt::lightGray);
315 void ItemFormatterBase::setJobStatusFld(int index, const QString &status, bool center)
317 /* C (created, not yet running) uses the default background */
318 static QString greenchars("TR");
319 static QString redchars("BEf");
320 static QString yellowchars("eDAFSMmsjdctp");
322 setTextFld(index, convertJobStatus(status), center);
324 QString st(status.trimmed());
325 if (greenchars.contains(st, Qt::CaseSensitive)) {
326 setBackground(index, Qt::green);
327 } else if (redchars.contains(st, Qt::CaseSensitive)) {
328 setBackground(index, Qt::red);
329 } else if (yellowchars.contains(st, Qt::CaseSensitive)){
330 setBackground(index, Qt::yellow);
334 void ItemFormatterBase::setJobTypeFld(int index, const QString &fld, bool center)
336 QByteArray jtype(fld.trimmed().toAscii());
338 setTextFld(index, job_type_to_str(jtype[0]), center);
340 setTextFld(index, "", center);
344 void ItemFormatterBase::setJobLevelFld(int index, const QString &fld, bool center)
346 QByteArray lvl(fld.trimmed().toAscii());
348 setTextFld(index, job_level_to_str(lvl[0]), center);
350 setTextFld(index, "", center);
356 /***********************************************
358 * treeitem formatting routines
360 ***********************************************/
361 TreeItemFormatter::TreeItemFormatter(QTreeWidgetItem &parent, int indent_level):
363 wdg(new QTreeWidgetItem(&parent)),
368 void TreeItemFormatter::setText(int index, const QString &fld)
370 wdg->setData(index, Qt::UserRole, level);
371 wdg->setText(index, fld);
374 void TreeItemFormatter::setTextAlignment(int index, int align)
376 wdg->setTextAlignment(index, align);
379 void TreeItemFormatter::setBackground(int index, const QBrush &qb)
381 wdg->setBackground(index, qb);
384 /* at this time we don't sort trees, so this method does nothing */
385 void TreeItemFormatter::setSortValue(int /* index */, const QVariant & /* value */)
389 /***********************************************
391 * Specialized table widget used for sorting
393 ***********************************************/
394 TableItemFormatter::BatSortingTableItem::BatSortingTableItem():
399 void TableItemFormatter::BatSortingTableItem::setSortData(const QVariant &d)
401 setData(SORTDATA_ROLE, d);
404 bool TableItemFormatter::BatSortingTableItem::operator< ( const QTableWidgetItem & o ) const
406 QVariant my = data(SORTDATA_ROLE);
407 QVariant other = o.data(SORTDATA_ROLE);
408 if (!my.isValid() || !other.isValid() || my.type() != other.type())
409 return QTableWidgetItem::operator< (o); /* invalid combination, revert to default sorting */
411 /* 64bit integers must be handled separately, others can be converted to double */
412 if (QVariant::ULongLong == my.type()) {
413 return my.toULongLong() < other.toULongLong();
414 } else if (QVariant::LongLong == my.type()) {
415 return my.toLongLong() < other.toLongLong();
416 } else if (my.canConvert(QVariant::Double)) {
417 return my.toDouble() < other.toDouble();
419 return QTableWidgetItem::operator< (o); /* invalid combination, revert to default sorting */
423 /***********************************************
425 * tableitem formatting routines
427 ***********************************************/
428 TableItemFormatter::TableItemFormatter(QTableWidget &tparent, int trow):
436 void TableItemFormatter::setText(int col, const QString &fld)
438 last = new BatSortingTableItem;
439 parent->setItem(row, col, last);
443 void TableItemFormatter::setTextAlignment(int /*index*/, int align)
445 last->setTextAlignment(align);
448 void TableItemFormatter::setBackground(int /*index*/, const QBrush &qb)
450 last->setBackground(qb);
453 void TableItemFormatter::setSortValue(int /* index */, const QVariant &value )
455 last->setSortData(value);
458 QTableWidgetItem *TableItemFormatter::widget(int col)
460 return parent->item(row, col);
463 const QTableWidgetItem *TableItemFormatter::widget(int col) const
465 return parent->item(row, col);