]> git.sur5r.net Git - bacula/bacula/blob - bacula/src/qt-console/util/fmtwidgetitem.cpp
f9314edf92d90d62c93839baf21abe6ff0f24e42
[bacula/bacula] / bacula / src / qt-console / util / fmtwidgetitem.cpp
1 /*
2    Bacula® - The Network Backup Solution
3
4    Copyright (C) 2007-2007 Free Software Foundation Europe e.V.
5
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
11    in the file LICENSE.
12
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.
17
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
21    02110-1301, USA.
22
23    Bacula® is a registered trademark of John Walker.
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.
27 */
28  
29 /*
30  *   Version $Id$
31  *
32  *  Helper functions for tree widget formatting
33  *
34  *   Riccardo Ghetta, May 2008
35  *
36  */ 
37
38 #include <QTreeWidgetItem>
39 #include <QTableWidget>
40 #include <QTableWidgetItem>
41 #include <QBrush>
42 #include <QString>
43 #include <QStringList>
44 #include <math.h>
45 #include "fmtwidgetitem.h"
46
47 /***********************************************
48  *
49  * ItemFormatterBase static members
50  *
51  ***********************************************/
52
53 ItemFormatterBase::BYTES_CONVERSION ItemFormatterBase::cnvFlag(BYTES_CONVERSION_IEC);
54
55 QString ItemFormatterBase::convertBytesIEC(qint64 qfld)
56 {
57    static const qint64 KB = Q_INT64_C(1024);
58    static const qint64 MB = (KB * KB);
59    static const qint64 GB = (MB * KB);
60    static const qint64 TB = (GB * KB);
61    static const qint64 PB = (TB * KB);
62    static const qint64 EB = (PB * KB);
63
64    /* note: division is integer, so to have some decimals we divide for a
65       smaller unit (e.g. GB for a TB number and so on) */
66    char suffix;
67    if (qfld >= EB) {
68       qfld /= PB; 
69       suffix = 'E';
70    }
71    else if (qfld >= PB) {
72       qfld /= TB; 
73       suffix = 'P';
74    }
75    else if (qfld >= TB) {
76       qfld /= GB; 
77       suffix = 'T';
78    }
79    else if (qfld >= GB) {
80       qfld /= MB;
81       suffix = 'G';
82    }
83    else if (qfld >= MB) {
84       qfld /= KB;
85       suffix = 'M';
86    }
87    else if (qfld >= KB) {
88       suffix = 'K';
89    }
90    else  {
91       /* plain bytes, no need to reformat */
92       return QString("%1 B").arg(qfld); 
93    }
94
95    /* having divided for a smaller unit, now we can safely convert to double and
96       use the extra room for decimals */
97    return QString("%1 %2iB").arg(qfld / 1000.0, 0, 'f', 2).arg(suffix);
98 }
99
100 QString ItemFormatterBase::convertBytesSI(qint64 qfld)
101 {
102    static const qint64 KB = Q_INT64_C(1000);
103    static const qint64 MB = (KB * KB);
104    static const qint64 GB = (MB * KB);
105    static const qint64 TB = (GB * KB);
106    static const qint64 PB = (TB * KB);
107    static const qint64 EB = (PB * KB);
108
109    /* note: division is integer, so to have some decimals we divide for a
110       smaller unit (e.g. GB for a TB number and so on) */
111    char suffix;
112    if (qfld >= EB) {
113       qfld /= PB; 
114       suffix = 'E';
115    }
116    else if (qfld >= PB) {
117       qfld /= TB; 
118       suffix = 'P';
119    }
120    else if (qfld >= TB) {
121       qfld /= GB; 
122       suffix = 'T';
123    }
124    else if (qfld >= GB) {
125       qfld /= MB;
126       suffix = 'G';
127    }
128    else if (qfld >= MB) {
129       qfld /= KB;
130       suffix = 'M';
131    }
132    else if (qfld >= KB) {
133       suffix = 'k'; /* SI uses lowercase k */
134    }
135    else  {
136       /* plain bytes, no need to reformat */
137       return QString("%1 B").arg(qfld); 
138    }
139
140    /* having divided for a smaller unit, now we can safely convert to double and
141       use the extra room for decimals */
142    return QString("%1 %2B").arg(qfld / 1000.0, 0, 'f', 2).arg(suffix);
143 }
144
145 /***********************************************
146  *
147  * base formatting routines
148  *
149  ***********************************************/
150
151 ItemFormatterBase::ItemFormatterBase()
152 {
153 }
154
155 ItemFormatterBase::~ItemFormatterBase()
156 {
157 }
158
159 void ItemFormatterBase::setBoolFld(int index, const QString &fld, bool center)
160 {
161    if (fld.trimmed().toInt())
162      setTextFld(index, "Yes", center);
163    else
164      setTextFld(index, "No", center);
165 }
166
167 void ItemFormatterBase::setBoolFld(int index, int fld, bool center)
168 {
169    if (fld)
170      setTextFld(index, "Yes", center);
171    else
172      setTextFld(index, "No", center);
173 }
174
175 void ItemFormatterBase::setNumericFld(int index, const QString &fld)
176 {
177    setTextFld(index, fld);
178    setTextAlignment(index, Qt::AlignRight | Qt::AlignVCenter);
179 }
180
181 void ItemFormatterBase::setBytesFld(int index, const QString &fld)
182 {
183    qint64 qfld = fld.trimmed().toLongLong();
184    QString msg;
185    switch (cnvFlag) {
186    case BYTES_CONVERSION_NONE:
187       msg = QString::number(qfld);
188       break;
189    case BYTES_CONVERSION_IEC:
190       msg = convertBytesIEC(qfld);
191       break;
192    case BYTES_CONVERSION_SI:
193       msg = convertBytesSI(qfld);
194       break;
195    }
196    setNumericFld(index, msg);
197 }
198
199 void ItemFormatterBase::setDurationFld(int index, const QString &fld)
200 {
201    static const qint64 HOUR = Q_INT64_C(3600);
202    static const qint64 DAY = HOUR * 24;
203    static const qint64 WEEK = DAY * 7;
204    static const qint64 MONTH = DAY * 30;
205    static const qint64 YEAR = DAY * 365;
206    static const qint64 divs[] = { YEAR, MONTH, WEEK, DAY, HOUR };
207    static const char sufs[] = { 'y', 'm', 'w', 'd', 'h', '\0' };
208
209    qint64 dfld = fld.trimmed().toLongLong();
210
211    char suffix = 's';
212    if (dfld) {
213       for (int pos = 0 ; sufs[pos] ; ++pos) {
214           if (dfld % divs[pos] == 0) {
215              dfld /= divs[pos];
216              suffix = sufs[pos];
217              break;
218           }
219       }
220    }
221    QString msg;
222    if (dfld < 100) {
223       msg = QString("%1%2").arg(dfld).arg(suffix);
224    } else {
225       /* previous check returned a number too big. The original specification perhaps
226          was mixed, like 1d 2h, so we try to match with this routine */
227       dfld = fld.trimmed().toLongLong();
228       msg = "";
229       for (int pos = 0 ; sufs[pos] ; ++pos) {
230           if (dfld / divs[pos] != 0) {
231              msg += QString(" %1%2").arg(dfld / divs[pos]).arg(sufs[pos]);
232              dfld %= divs[pos];
233           }
234       }
235       if (dfld)
236          msg += QString(" %1s").arg(dfld);
237            
238 /*
239      double net = 0;
240      QList<qlonglong> durations;
241      durations.append(1);
242      durations.append(60);
243      durations.append(HOUR);
244      durations.append(DAY);
245      durations.append(MONTH);
246      durations.append(YEAR);
247      QStringList abbrlist = (QStringList() << "s" << "min" << "h" << "d" << "m" << "y");
248      bool done = false;
249      int count = 1;
250      while (done == false) {
251         if ((dfld < durations[count]) || (count >= abbrlist.count() - 1)) { 
252            done = true;
253            net = (double)dfld / (double)(durations[count - 1]);
254            if (net != 0) {
255               msg =  QString("%1%2")
256                   .arg(net, 0, 'f', 2, QLatin1Char(' '))
257                   .arg(abbrlist[count - 1]);
258            } else {
259              msg = "0s";
260            }
261         }
262         count += 1;
263      }
264 */   }
265
266    setNumericFld(index, msg);
267 }
268
269 void ItemFormatterBase::setVolStatusFld(int index, const QString &fld, bool center)
270 {
271    setTextFld(index, fld, center);
272
273    if (fld == "Append" ) {
274       setBackground(index, Qt::green);
275    } else if (fld == "Error") {
276       setBackground(index, Qt::red);
277    } else if (fld == "Used" || fld == "Full"){
278       setBackground(index, Qt::yellow);
279    }
280 }
281
282 void ItemFormatterBase::setJobStatusFld(int index, const QString &shortstatus, 
283                                         const QString &longstatus, bool center)
284 {
285    /* C (created, not yet running) uses the default background */
286    static QString greenchars("TR");
287    static QString redchars("BEf");
288    static QString yellowchars("eDAFSMmsjdctp");
289
290    setTextFld(index, longstatus, center);
291
292    QString st(shortstatus.trimmed());
293    if (greenchars.contains(st, Qt::CaseSensitive)) {
294       setBackground(index, Qt::green);
295    } else if (redchars.contains(st, Qt::CaseSensitive)) {
296       setBackground(index, Qt::red);
297    } else if (yellowchars.contains(st, Qt::CaseSensitive)){ 
298       setBackground(index, Qt::yellow);
299    }
300 }
301
302 void ItemFormatterBase::setJobTypeFld(int index, const QString &fld, bool center)
303 {
304    static QHash<QString, QString> jobt;
305    if (jobt.isEmpty()) {
306       jobt.insert("B", QObject::tr("Backup"));
307       jobt.insert("R", QObject::tr("Restore"));
308       jobt.insert("V", QObject::tr("Verify"));
309       jobt.insert("A", QObject::tr("Admin"));
310    }
311
312    setTextFld(index, jobt.value(fld.trimmed(), fld.trimmed()), center);
313 }
314
315 void ItemFormatterBase::setJobLevelFld(int index, const QString &fld, bool center)
316 {
317    static QHash<QString, QString> jobt;
318    if (jobt.isEmpty()) {
319       jobt.insert("F", QObject::tr("Full"));
320       jobt.insert("D", QObject::tr("Differential"));
321       jobt.insert("I", QObject::tr("Incremental"));
322       jobt.insert("C", QObject::tr("Catalog"));
323       jobt.insert("O", QObject::tr("VolToCatalog"));
324    }
325
326    setTextFld(index, jobt.value(fld.trimmed(), fld.trimmed()), center);
327 }
328
329
330
331 /***********************************************
332  *
333  * treeitem formatting routines
334  *
335  ***********************************************/
336 TreeItemFormatter::TreeItemFormatter(QTreeWidgetItem &parent, int indent_level):
337 ItemFormatterBase(),
338 wdg(new QTreeWidgetItem(&parent)),
339 level(indent_level)
340 {
341 }
342
343 void TreeItemFormatter::setTextFld(int index, const QString &fld, bool center)
344 {
345    wdg->setData(index, Qt::UserRole, level);
346    if (center) {
347       setTextAlignment(index, Qt::AlignCenter);
348    }
349    wdg->setText(index, fld.trimmed());
350 }
351
352 void TreeItemFormatter::setTextAlignment(int index, int align)
353 {
354    wdg->setTextAlignment(index, align);
355 }
356
357 void TreeItemFormatter::setBackground(int index, const QBrush &qb)
358 {
359    wdg->setBackground(index, qb);
360 }
361
362
363 /***********************************************
364  *
365  * tableitem formatting routines
366  *
367  ***********************************************/
368 TableItemFormatter::TableItemFormatter(QTableWidget &tparent, int trow):
369 ItemFormatterBase(),
370 parent(&tparent),
371 row(trow),
372 last(NULL)
373 {
374 }
375
376 void TableItemFormatter::setTextFld(int col, const QString &fld, bool center)
377 {
378    last = new QTableWidgetItem(1);
379 /*   last->setForeground(blackBrush); */
380    parent->setItem(row, col, last);
381    if (center) {
382       setTextAlignment(col, Qt::AlignCenter);
383    }
384    last->setText(fld.trimmed());
385 }
386
387 void TableItemFormatter::setTextAlignment(int /*index*/, int align)
388 {
389    last->setTextAlignment(align);
390 }
391
392 void TableItemFormatter::setBackground(int /*index*/, const QBrush &qb)
393 {
394    last->setBackground(qb);
395 }
396
397 QTableWidgetItem *TableItemFormatter::widget(int col)
398 {
399   return parent->item(row, col);
400 }
401
402 const QTableWidgetItem *TableItemFormatter::widget(int col) const
403 {
404   return parent->item(row, col);
405 }