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 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 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::setInChanger(int index, const QString &InChanger)
198 QPixmap(":images/inflag"+InChanger+".png"));
199 setSortValue(index, InChanger.toInt() );
202 void ItemFormatterBase::setTextFld(int index, const QString &fld, bool center)
204 setText(index, fld.trimmed());
206 setTextAlignment(index, Qt::AlignCenter);
210 void ItemFormatterBase::setRightFld(int index, const QString &fld)
212 setText(index, fld.trimmed());
213 setTextAlignment(index, Qt::AlignRight | Qt::AlignVCenter);
216 void ItemFormatterBase::setBoolFld(int index, const QString &fld, bool center)
218 if (fld.trimmed().toInt())
219 setTextFld(index, QObject::tr("Yes"), center);
221 setTextFld(index, QObject::tr("No"), center);
224 void ItemFormatterBase::setBoolFld(int index, int fld, bool center)
227 setTextFld(index, QObject::tr("Yes"), center);
229 setTextFld(index, QObject::tr("No"), center);
232 void ItemFormatterBase::setNumericFld(int index, const QString &fld)
234 setRightFld(index, fld.trimmed());
235 setSortValue(index, fld.toDouble() );
238 void ItemFormatterBase::setNumericFld(int index, const QString &fld, const QVariant &sortval)
240 setRightFld(index, fld.trimmed());
241 setSortValue(index, sortval );
244 void ItemFormatterBase::setBytesFld(int index, const QString &fld)
246 qint64 qfld = fld.trimmed().toLongLong();
249 case BYTES_CONVERSION_NONE:
250 msg = QString::number(qfld);
252 case BYTES_CONVERSION_IEC:
253 msg = convertBytesIEC(qfld);
255 case BYTES_CONVERSION_SI:
256 msg = convertBytesSI(qfld);
260 setNumericFld(index, msg, qfld);
263 void ItemFormatterBase::setDurationFld(int index, const QString &fld)
265 static const qint64 HOUR = Q_INT64_C(3600);
266 static const qint64 DAY = HOUR * 24;
267 static const qint64 WEEK = DAY * 7;
268 static const qint64 MONTH = DAY * 30;
269 static const qint64 YEAR = DAY * 365;
270 static const qint64 divs[] = { YEAR, MONTH, WEEK, DAY, HOUR };
271 static const char sufs[] = { 'y', 'm', 'w', 'd', 'h', '\0' };
273 qint64 dfld = fld.trimmed().toLongLong();
277 for (int pos = 0 ; sufs[pos] ; ++pos) {
278 if (dfld % divs[pos] == 0) {
287 msg = QString("%1%2").arg(dfld).arg(suffix);
289 /* previous check returned a number too big. The original specification perhaps
290 was mixed, like 1d 2h, so we try to match with this routine */
291 dfld = fld.trimmed().toLongLong();
293 for (int pos = 0 ; sufs[pos] ; ++pos) {
294 if (dfld / divs[pos] != 0) {
295 msg += QString(" %1%2").arg(dfld / divs[pos]).arg(sufs[pos]);
300 msg += QString(" %1s").arg(dfld);
303 setNumericFld(index, msg, fld.trimmed().toLongLong());
306 void ItemFormatterBase::setVolStatusFld(int index, const QString &fld, bool center)
308 QString mp(fld.trimmed());
309 setTextFld(index, volume_status_to_str(mp.toUtf8()), center);
311 if (mp == "Append" ) {
312 setBackground(index, Qt::green);
313 } else if (mp == "Error") {
314 setBackground(index, Qt::red);
315 } else if (mp == "Used" || mp == "Full"){
316 setBackground(index, Qt::yellow);
317 } else if (mp == "Read-only" || mp == "Disabled"){
318 setBackground(index, Qt::lightGray);
322 void ItemFormatterBase::setJobStatusFld(int index, const QString &status, bool center)
324 /* C (created, not yet running) uses the default background */
325 static QString greenchars("TR");
326 static QString redchars("BEf");
327 static QString yellowchars("eDAFSMmsjdctp");
329 setTextFld(index, convertJobStatus(status), center);
331 QString st(status.trimmed());
332 if (greenchars.contains(st, Qt::CaseSensitive)) {
333 setBackground(index, Qt::green);
334 } else if (redchars.contains(st, Qt::CaseSensitive)) {
335 setBackground(index, Qt::red);
336 } else if (yellowchars.contains(st, Qt::CaseSensitive)){
337 setBackground(index, Qt::yellow);
341 void ItemFormatterBase::setJobTypeFld(int index, const QString &fld, bool center)
343 QByteArray jtype(fld.trimmed().toAscii());
345 setTextFld(index, job_type_to_str(jtype[0]), center);
347 setTextFld(index, "", center);
351 void ItemFormatterBase::setJobLevelFld(int index, const QString &fld, bool center)
353 QByteArray lvl(fld.trimmed().toAscii());
355 setTextFld(index, job_level_to_str(lvl[0]), center);
357 setTextFld(index, "", center);
363 /***********************************************
365 * treeitem formatting routines
367 ***********************************************/
368 TreeItemFormatter::TreeItemFormatter(QTreeWidgetItem &parent, int indent_level):
370 wdg(new QTreeWidgetItem(&parent)),
375 void TreeItemFormatter::setText(int index, const QString &fld)
377 wdg->setData(index, Qt::UserRole, level);
378 wdg->setText(index, fld);
381 void TreeItemFormatter::setTextAlignment(int index, int align)
383 wdg->setTextAlignment(index, align);
386 void TreeItemFormatter::setBackground(int index, const QBrush &qb)
388 wdg->setBackground(index, qb);
391 /* at this time we don't sort trees, so this method does nothing */
392 void TreeItemFormatter::setSortValue(int /* index */, const QVariant & /* value */)
396 void TreeItemFormatter::setPixmap(int index, const QPixmap &pix)
398 wdg->setIcon(index, QIcon(pix));
401 /***********************************************
403 * Specialized table widget used for sorting
405 ***********************************************/
406 TableItemFormatter::BatSortingTableItem::BatSortingTableItem():
411 void TableItemFormatter::BatSortingTableItem::setSortData(const QVariant &d)
413 setData(SORTDATA_ROLE, d);
416 bool TableItemFormatter::BatSortingTableItem::operator< ( const QTableWidgetItem & o ) const
418 QVariant my = data(SORTDATA_ROLE);
419 QVariant other = o.data(SORTDATA_ROLE);
420 if (!my.isValid() || !other.isValid() || my.type() != other.type())
421 return QTableWidgetItem::operator< (o); /* invalid combination, revert to default sorting */
423 /* 64bit integers must be handled separately, others can be converted to double */
424 if (QVariant::ULongLong == my.type()) {
425 return my.toULongLong() < other.toULongLong();
426 } else if (QVariant::LongLong == my.type()) {
427 return my.toLongLong() < other.toLongLong();
428 } else if (my.canConvert(QVariant::Double)) {
429 return my.toDouble() < other.toDouble();
431 return QTableWidgetItem::operator< (o); /* invalid combination, revert to default sorting */
435 /***********************************************
437 * tableitem formatting routines
439 ***********************************************/
440 TableItemFormatter::TableItemFormatter(QTableWidget &tparent, int trow):
448 void TableItemFormatter::setPixmap(int index, const QPixmap &pix)
450 last = new BatSortingTableItem;
451 parent->setItem(row, index, last);
455 void TableItemFormatter::setText(int col, const QString &fld)
457 last = new BatSortingTableItem;
458 parent->setItem(row, col, last);
462 void TableItemFormatter::setTextAlignment(int /*index*/, int align)
464 last->setTextAlignment(align);
467 void TableItemFormatter::setBackground(int /*index*/, const QBrush &qb)
469 last->setBackground(qb);
472 void TableItemFormatter::setSortValue(int /* index */, const QVariant &value )
474 last->setSortData(value);
477 QTableWidgetItem *TableItemFormatter::widget(int col)
479 return parent->item(row, col);
482 const QTableWidgetItem *TableItemFormatter::widget(int col) const
484 return parent->item(row, col);