2 Bacula® - The Network Backup Solution
4 Copyright (C) 2007-2010 Free Software Foundation Europe e.V.
6 The main author of Bacula is Kern Sibbald, with contributions from many
7 others, a complete list can be found in the file AUTHORS.
9 You may use this file and others of this release according to the
10 license defined in the LICENSE file, which includes the Affero General
11 Public License, v3.0 ("AGPLv3") and some additional permissions and
12 terms pursuant to its AGPLv3 Section 7.
14 Bacula® is a registered trademark of Kern Sibbald.
19 * Helper functions for tree widget formatting
21 * Riccardo Ghetta, May 2008
26 #include <QTreeWidgetItem>
27 #include <QTableWidget>
28 #include <QTableWidgetItem>
31 #include <QStringList>
33 #include "fmtwidgetitem.h"
35 /***********************************************
39 ***********************************************/
41 QString convertJobStatus(const QString &sts)
43 QString code( sts.trimmed() );
44 if ( code.size() != 1) {
45 return QObject::tr("Invalid job status %1").arg(sts);
49 jobstatus_to_ascii_gui( code[0].toAscii(), buf, sizeof(buf));
54 * disable widget updating
56 Freeze::Freeze(QWidget &q):
59 qw->setUpdatesEnabled(false);
65 qw->setUpdatesEnabled(true);
70 /***********************************************
72 * ItemFormatterBase static members
74 ***********************************************/
76 ItemFormatterBase::BYTES_CONVERSION ItemFormatterBase::cnvFlag(BYTES_CONVERSION_IEC);
78 /* String to Electronic value based on K=1024 */
79 QString convertBytesIEC(qint64 qfld)
81 static const qint64 KB = Q_INT64_C(1024);
82 static const qint64 MB = (KB * KB);
83 static const qint64 GB = (MB * KB);
84 static const qint64 TB = (GB * KB);
85 static const qint64 PB = (TB * KB);
86 static const qint64 EB = (PB * KB);
88 /* note: division is integer, so to have some decimals we divide for a
89 smaller unit (e.g. GB for a TB number and so on) */
95 else if (qfld >= PB) {
99 else if (qfld >= TB) {
103 else if (qfld >= GB) {
107 else if (qfld >= MB) {
111 else if (qfld >= KB) {
115 /* plain bytes, no need to reformat */
116 return QString("%1 B").arg(qfld);
119 /* having divided for a smaller unit, now we can safely convert to double and
120 use the extra room for decimals */
121 return QString("%1 %2iB").arg(qfld / 1024.0, 0, 'f', 2).arg(suffix);
124 /* String to human value based on k=1000 */
125 QString convertBytesSI(qint64 qfld)
127 static const qint64 KB = Q_INT64_C(1000);
128 static const qint64 MB = (KB * KB);
129 static const qint64 GB = (MB * KB);
130 static const qint64 TB = (GB * KB);
131 static const qint64 PB = (TB * KB);
132 static const qint64 EB = (PB * KB);
134 /* note: division is integer, so to have some decimals we divide for a
135 smaller unit (e.g. GB for a TB number and so on) */
141 else if (qfld >= PB) {
145 else if (qfld >= TB) {
149 else if (qfld >= GB) {
153 else if (qfld >= MB) {
157 else if (qfld >= KB) {
158 suffix = 'k'; /* SI uses lowercase k */
161 /* plain bytes, no need to reformat */
162 return QString("%1 B").arg(qfld);
165 /* having divided for a smaller unit, now we can safely convert to double and
166 use the extra room for decimals */
167 return QString("%1 %2B").arg(qfld / 1000.0, 0, 'f', 2).arg(suffix);
170 /***********************************************
172 * base formatting routines
174 ***********************************************/
176 ItemFormatterBase::ItemFormatterBase()
180 ItemFormatterBase::~ItemFormatterBase()
184 void ItemFormatterBase::setPercent(int index, float value)
187 bsnprintf(buf, sizeof(buf), "%.2f%%", value);
191 pix = ":images/0p.png";
192 } else if (value < 24) {
193 pix = ":images/16p.png";
194 } else if (value < 40) {
195 pix = ":images/32p.png";
196 } else if (value < 56) {
197 pix = ":images/48p.png";
198 } else if (value < 72) {
199 pix = ":images/64p.png";
200 } else if (value < 88) {
201 pix = ":images/80p.png";
203 pix = ":images/96p.png";
205 setPixmap(index, QPixmap(pix), val);
206 //setSortValue(index, (int) value);
207 //setBackground(index, Qt::green);
210 /* By default, the setPixmap implementation with tooltip don't implement
213 void ItemFormatterBase::setPixmap(int index, const QPixmap &pix,
214 const QString & /* tip */)
216 setPixmap(index, pix);
219 void ItemFormatterBase::setInChanger(int index, const QString &InChanger)
221 setPixmap(index, QPixmap(":images/inflag"+InChanger+".png"));
222 //setSortValue(index, InChanger.toInt() );
225 void ItemFormatterBase::setFileType(int index, const QString &type)
227 setPixmap(index, QPixmap(":images/"+type+".png"));
228 //setSortValue(index, InChanger.toInt() );
231 void ItemFormatterBase::setTextFld(int index, const QString &fld, bool center)
233 setText(index, fld.trimmed());
235 setTextAlignment(index, Qt::AlignCenter);
239 void ItemFormatterBase::setDateFld(int index, utime_t fld, bool center)
242 bstrutime(buf, sizeof(buf), fld);
243 setText(index, QString(buf).trimmed());
245 setTextAlignment(index, Qt::AlignCenter);
249 void ItemFormatterBase::setRightFld(int index, const QString &fld)
251 setText(index, fld.trimmed());
252 setTextAlignment(index, Qt::AlignRight | Qt::AlignVCenter);
255 void ItemFormatterBase::setBoolFld(int index, const QString &fld, bool center)
257 if (fld.trimmed().toInt())
258 setTextFld(index, QObject::tr("Yes"), center);
260 setTextFld(index, QObject::tr("No"), center);
263 void ItemFormatterBase::setBoolFld(int index, int fld, bool center)
266 setTextFld(index, QObject::tr("Yes"), center);
268 setTextFld(index, QObject::tr("No"), center);
271 void ItemFormatterBase::setNumericFld(int index, const QString &fld)
273 setRightFld(index, fld.trimmed());
274 setSortValue(index, fld.toDouble());
277 void ItemFormatterBase::setNumericFld(int index, const QString &fld, const QVariant &sortval)
279 setRightFld(index, fld.trimmed());
280 setSortValue(index, sortval);
283 void ItemFormatterBase::setBytesFld(int index, const QString &fld)
285 qint64 qfld = fld.trimmed().toLongLong();
288 case BYTES_CONVERSION_NONE:
289 msg = QString::number(qfld);
291 case BYTES_CONVERSION_IEC:
292 msg = convertBytesIEC(qfld);
294 case BYTES_CONVERSION_SI:
295 msg = convertBytesSI(qfld);
302 setNumericFld(index, msg, QVariant(qfld));
305 void ItemFormatterBase::setDurationFld(int index, const QString &fld)
307 static const qint64 HOUR = Q_INT64_C(3600);
308 static const qint64 DAY = HOUR * 24;
309 static const qint64 WEEK = DAY * 7;
310 static const qint64 MONTH = DAY * 30;
311 static const qint64 YEAR = DAY * 365;
312 static const qint64 divs[] = { YEAR, MONTH, WEEK, DAY, HOUR };
313 static const char sufs[] = { 'y', 'm', 'w', 'd', 'h', '\0' };
315 qint64 dfld = fld.trimmed().toLongLong();
319 for (int pos = 0 ; sufs[pos] ; ++pos) {
320 if (dfld % divs[pos] == 0) {
329 msg = QString("%1%2").arg(dfld).arg(suffix);
331 /* previous check returned a number too big. The original specification perhaps
332 was mixed, like 1d 2h, so we try to match with this routine */
333 dfld = fld.trimmed().toLongLong();
335 for (int pos = 0 ; sufs[pos] ; ++pos) {
336 if (dfld / divs[pos] != 0) {
337 msg += QString(" %1%2").arg(dfld / divs[pos]).arg(sufs[pos]);
342 msg += QString(" %1s").arg(dfld);
345 setNumericFld(index, msg, QVariant(fld.trimmed().toLongLong()));
348 void ItemFormatterBase::setVolStatusFld(int index, const QString &fld, bool center)
350 QString mp(fld.trimmed());
351 setTextFld(index, volume_status_to_str(mp.toUtf8()), center);
353 if (mp == "Append" ) {
354 setBackground(index, Qt::green);
355 } else if (mp == "Error") {
356 setBackground(index, Qt::red);
357 } else if (mp == "Used" || mp == "Full"){
358 setBackground(index, Qt::yellow);
359 } else if (mp == "Read-only" || mp == "Disabled"){
360 setBackground(index, Qt::lightGray);
364 void ItemFormatterBase::setJobStatusFld(int index, const QString &status, bool center)
366 /* C (created, not yet running) uses the default background */
367 static QString greenchars("TR");
368 static QString redchars("BEf");
369 static QString yellowchars("eDAFSMmsjdctp");
371 setTextFld(index, convertJobStatus(status), center);
373 QString st(status.trimmed());
374 if (greenchars.contains(st, Qt::CaseSensitive)) {
375 setBackground(index, Qt::green);
376 } else if (redchars.contains(st, Qt::CaseSensitive)) {
377 setBackground(index, Qt::red);
378 } else if (yellowchars.contains(st, Qt::CaseSensitive)){
379 setBackground(index, Qt::yellow);
383 void ItemFormatterBase::setJobTypeFld(int index, const QString &fld, bool center)
385 QByteArray jtype(fld.trimmed().toAscii());
387 setTextFld(index, job_type_to_str(jtype[0]), center);
389 setTextFld(index, "", center);
393 void ItemFormatterBase::setJobLevelFld(int index, const QString &fld, bool center)
395 QByteArray lvl(fld.trimmed().toAscii());
397 setTextFld(index, job_level_to_str(lvl[0]), center);
399 setTextFld(index, "", center);
405 /***********************************************
407 * treeitem formatting routines
409 ***********************************************/
410 TreeItemFormatter::TreeItemFormatter(QTreeWidgetItem &parent, int indent_level):
412 wdg(new QTreeWidgetItem(&parent)),
417 void TreeItemFormatter::setText(int index, const QString &fld)
419 wdg->setData(index, Qt::UserRole, level);
420 wdg->setText(index, fld);
423 void TreeItemFormatter::setTextAlignment(int index, int align)
425 wdg->setTextAlignment(index, align);
428 void TreeItemFormatter::setBackground(int index, const QBrush &qb)
430 wdg->setBackground(index, qb);
433 /* at this time we don't sort trees, so this method does nothing */
434 void TreeItemFormatter::setSortValue(int /* index */, const QVariant & /* value */)
438 void TreeItemFormatter::setPixmap(int index, const QPixmap &pix)
440 wdg->setIcon(index, QIcon(pix));
443 /***********************************************
445 * Specialized table widget used for sorting
447 ***********************************************/
448 TableItemFormatter::BatSortingTableItem::BatSortingTableItem():
453 void TableItemFormatter::BatSortingTableItem::setSortData(const QVariant &d)
455 setData(SORTDATA_ROLE, d);
458 bool TableItemFormatter::BatSortingTableItem::operator< ( const QTableWidgetItem & o ) const
460 QVariant my = data(SORTDATA_ROLE);
461 QVariant other = o.data(SORTDATA_ROLE);
462 if (!my.isValid() || !other.isValid() || my.type() != other.type())
463 return QTableWidgetItem::operator< (o); /* invalid combination, revert to default sorting */
465 /* 64bit integers must be handled separately, others can be converted to double */
466 if (QVariant::ULongLong == my.type()) {
467 return my.toULongLong() < other.toULongLong();
468 } else if (QVariant::LongLong == my.type()) {
469 return my.toLongLong() < other.toLongLong();
470 } else if (my.canConvert(QVariant::Double)) {
471 return my.toDouble() < other.toDouble();
473 return QTableWidgetItem::operator< (o); /* invalid combination, revert to default sorting */
477 /***********************************************
479 * tableitem formatting routines
481 ***********************************************/
482 TableItemFormatter::TableItemFormatter(QTableWidget &tparent, int trow):
490 void TableItemFormatter::setPixmap(int index, const QPixmap &pix)
492 // Centered, but not sortable !
493 QLabel *lbl = new QLabel();
494 lbl->setAlignment(Qt::AlignCenter);
496 parent->setCellWidget(row, index, lbl);
499 void TableItemFormatter::setPixmap(int index, const QPixmap &pix,
502 // Centered, but not sortable !
503 QLabel *lbl = new QLabel();
504 lbl->setAlignment(Qt::AlignCenter);
506 if (!tips.isEmpty()) {
507 lbl->setToolTip(tips);
509 parent->setCellWidget(row, index, lbl);
511 // last = new BatSortingTableItem;
512 // parent->setItem(row, index, last);
513 // last->setIcon(pix);
516 void TableItemFormatter::setText(int col, const QString &fld)
518 last = new BatSortingTableItem;
519 parent->setItem(row, col, last);
523 void TableItemFormatter::setTextAlignment(int /*index*/, int align)
525 last->setTextAlignment(align);
528 void TableItemFormatter::setBackground(int /*index*/, const QBrush &qb)
530 last->setBackground(qb);
533 void TableItemFormatter::setSortValue(int /* index */, const QVariant &value )
535 last->setSortData(value);
538 QTableWidgetItem *TableItemFormatter::widget(int col)
540 return parent->item(row, col);
543 const QTableWidgetItem *TableItemFormatter::widget(int col) const
545 return parent->item(row, col);