]> git.sur5r.net Git - bacula/bacula/commitdiff
Riccardo' patch for formatting text.
authorDirk H Bartley <dbartley@schupan.com>
Thu, 15 May 2008 01:54:01 +0000 (01:54 +0000)
committerDirk H Bartley <dbartley@schupan.com>
Thu, 15 May 2008 01:54:01 +0000 (01:54 +0000)
git-svn-id: https://bacula.svn.sourceforge.net/svnroot/bacula/trunk@6977 91ce42f0-d328-0410-95d8-f526ca767f89

bacula/src/qt-console/joblist/joblist.cpp
bacula/src/qt-console/joblist/joblist.h
bacula/src/qt-console/mainwin.cpp
bacula/src/qt-console/mainwin.h
bacula/src/qt-console/medialist/medialist.cpp
bacula/src/qt-console/storage/storage.cpp
bacula/src/qt-console/util/fmtwidgetitem.cpp
bacula/src/qt-console/util/fmtwidgetitem.h

index bb3e49d9cf2259e5820572d69d836b855f5f13a5..2f7f5f5d6fc3e8afbbd338236f5fc26a94f38195 100644 (file)
@@ -40,6 +40,7 @@
 #ifdef HAVE_QWT
 #include "jobgraphs/jobplot.h"
 #endif
+#include "util/fmtwidgetitem.h"
 
 /*
  * Constructor for the class
@@ -106,14 +107,120 @@ JobList::~JobList()
  */
 void JobList::populateTable()
 {
-   QStringList results;
-   QString resultline;
-   QBrush blackBrush(Qt::black);
-
    if (!m_console->preventInUseConnect())
        return;
 
    /* Can't do this in constructor because not neccesarily conected in constructor */
+   prepareFilterWidgets();
+
+   /* Set up query */
+   QString query;
+   fillQueryString(query);
+
+   /* Set up the Header for the table */
+   QStringList headerlist = (QStringList()
+      << tr("Job Id") << tr("Job Name") << tr("Client") << tr("Job Starttime") 
+      << tr("Job Type") << tr("Job Level") << tr("Job Files") 
+      << tr("Job Bytes") << tr("Job Status")  << tr("Purged") << tr("File Set"));
+
+   m_jobIdIndex = headerlist.indexOf(tr("Job Id"));
+   m_purgedIndex = headerlist.indexOf(tr("Purged"));
+   m_typeIndex = headerlist.indexOf(tr("Job Type"));
+   m_statusIndex = headerlist.indexOf(tr("Job Status"));
+   m_startIndex = headerlist.indexOf(tr("Job Starttime"));
+   m_filesIndex = headerlist.indexOf(tr("Job Files"));
+   m_bytesIndex = headerlist.indexOf(tr("Job Bytes"));
+
+   /* Initialize the QTableWidget */
+   m_checkCurrentWidget = false;
+   mp_tableWidget->clear();
+   m_checkCurrentWidget = true;
+   mp_tableWidget->setColumnCount(headerlist.size());
+   mp_tableWidget->setHorizontalHeaderLabels(headerlist);
+   mp_tableWidget->setSelectionBehavior(QAbstractItemView::SelectRows);
+   mp_tableWidget->setSelectionMode(QAbstractItemView::SingleSelection);
+
+   if (mainWin->m_sqlDebug) {
+      Pmsg1(000, "Query cmd : %s\n",query.toUtf8().data());
+   }
+
+   QStringList results;
+   if (m_console->sql_cmd(query, results)) {
+      m_resultCount = results.count();
+
+      QStringList fieldlist;
+      mp_tableWidget->setRowCount(results.size());
+
+      int row = 0;
+      /* Iterate through the record returned from the query */
+      QString resultline;
+      foreach (resultline, results) {
+         fieldlist = resultline.split("\t");
+         if (fieldlist.size() < 12)
+           continue; // some fields missing, ignore row
+
+        TableItemFormatter jobitem(*mp_tableWidget, row);
+  
+         /* Iterate through fields in the record */
+        QStringListIterator fld(fieldlist);
+         int col = 0;
+
+        /* job id */
+         jobitem.setNumericFld(col++, fld.next());
+
+        /* job name */
+         jobitem.setTextFld(col++, fld.next());
+
+        /* client */
+         jobitem.setTextFld(col++, fld.next());
+
+        /* job starttime */
+         jobitem.setTextFld(col++, fld.next(), true);
+
+        /* job type */
+         jobitem.setJobTypeFld(col++, fld.next());
+
+        /* job level */
+         jobitem.setJobLevelFld(col++, fld.next());
+
+        /* job files */
+         jobitem.setNumericFld(col++, fld.next());
+
+        /* job bytes */
+         jobitem.setBytesFld(col++, fld.next());
+
+        /* job status */
+        QString shortstatus(fld.next());
+        QString longstatus(fld.next());
+         jobitem.setJobStatusFld(col++, shortstatus, longstatus);
+
+        /* purged */
+         if (fld.next().toInt())
+           jobitem.setTextFld(col++, tr("IS"), true);
+        else
+           jobitem.setTextFld(col++, tr("NOT"), true);
+
+        /* fileset */
+         jobitem.setTextFld(col++, fld.next());
+
+         row++;
+      }
+   } 
+   /* Resize the columns */
+   mp_tableWidget->resizeColumnsToContents();
+   mp_tableWidget->resizeRowsToContents();
+   mp_tableWidget->verticalHeader()->hide();
+   if ((m_mediaName != tr("Any")) && (m_resultCount == 0)){
+      /* for context sensitive searches, let the user know if there were no
+       * results */
+      QMessageBox::warning(this, "Bat",
+          tr("The Jobs query returned no results.\n"
+         "Press OK to continue?"), QMessageBox::Ok );
+   }
+}
+
+void JobList::prepareFilterWidgets()
+{
    if (!m_populated) {
       clientComboBox->addItem(tr("Any"));
       clientComboBox->addItems(m_console->client_list);
@@ -150,9 +257,11 @@ void JobList::populateTable()
       statusComboBox->addItem(tr("Any"));
       statusComboBox->addItems(statusLongList);
    }
+}
 
-   /* Set up query */
-   QString query("");
+void JobList::fillQueryString(QString &query)
+{
+   query = "";
    int volumeIndex = volumeComboBox->currentIndex();
    if (volumeIndex != -1)
       m_mediaName = volumeComboBox->itemText(volumeIndex);
@@ -221,124 +330,13 @@ void JobList::populateTable()
       }
    }
    /* Descending */
-   query += " ORDER BY Job.Starttime DESC, Job.JobId DESC";
+   query += " ORDER BY Job.Starttime=0 DESC, Job.Starttime DESC, Job.JobId DESC";
    /* If Limit check box for limit records returned is checked  */
    if (limitCheckBox->checkState() == Qt::Checked) {
       QString limit;
       limit.setNum(limitSpinBox->value());
       query += " LIMIT " + limit;
    }
-
-   /* Set up the Header for the table */
-   QStringList headerlist = (QStringList()
-      << tr("Job Id") << tr("Job Name") << tr("Client") << tr("Job Starttime") 
-      << tr("Job Type") << tr("Job Level") << tr("Job Files") 
-      << tr("Job Bytes") << tr("Job Status")  << tr("Purged") << tr("File Set"));
-   m_jobIdIndex = headerlist.indexOf(tr("Job Id"));
-   m_purgedIndex = headerlist.indexOf(tr("Purged"));
-   m_typeIndex = headerlist.indexOf(tr("Job Type"));
-   m_statusIndex = headerlist.indexOf(tr("Job Status"));
-   m_startIndex = headerlist.indexOf(tr("Job Starttime"));
-   m_filesIndex = headerlist.indexOf(tr("Job Files"));
-   m_bytesIndex = headerlist.indexOf(tr("Job Bytes"));
-   int jobLevelIndex = headerlist.indexOf(tr("Job Level"));
-
-   /* Initialize the QTableWidget */
-   m_checkCurrentWidget = false;
-   mp_tableWidget->clear();
-   m_checkCurrentWidget = true;
-   mp_tableWidget->setColumnCount(headerlist.size());
-   mp_tableWidget->setHorizontalHeaderLabels(headerlist);
-
-   if (mainWin->m_sqlDebug) {
-      Pmsg1(000, "Query cmd : %s\n",query.toUtf8().data());
-   }
-   if (m_console->sql_cmd(query, results)) {
-      m_resultCount = results.count();
-
-      QTableWidgetItem* p_tableitem;
-      QString field;
-      QStringList fieldlist;
-      mp_tableWidget->setRowCount(results.size());
-
-      int row = 0;
-      /* Iterate through the record returned from the query */
-      foreach (resultline, results) {
-         fieldlist = resultline.split("\t");
-         int column = 0;
-         bool m_statusIndexDone = false;
-         QString statusCode("");
-         /* Iterate through fields in the record */
-         foreach (field, fieldlist) {
-            field = field.trimmed();  /* strip leading & trailing spaces */
-            if ((column == m_statusIndex) && (!m_statusIndexDone)){
-               m_statusIndexDone = true;
-               statusCode = field;
-            } else {
-               p_tableitem = new QTableWidgetItem(field, 1);
-               p_tableitem->setFlags(Qt::ItemIsSelectable);
-               p_tableitem->setForeground(blackBrush);
-               mp_tableWidget->setItem(row, column, p_tableitem);
-               if (column == m_statusIndex)
-                  setStatusColor(p_tableitem, statusCode);
-               if (column == m_bytesIndex) {
-                  QString text;
-                  bool okay;
-                  qlonglong bytes = field.toULongLong(&okay);
-                  if (okay){
-                     QString test =  QString("%1").arg(bytes);
-                     mainWin->hrConvert(text, bytes);
-                     p_tableitem->setText(text);
-                  } else { Pmsg1(000, "conversion error %s\n", field.toUtf8().data()); }
-               } else if (column == m_purgedIndex) {
-                  bool okay;
-                  int isPurged = field.toInt(&okay);
-                  if (okay){
-                     if (isPurged) { p_tableitem->setText(tr("IS"));
-                     } else { p_tableitem->setText(tr("NOT")); }
-                  }
-               } else if (column == m_typeIndex) {
-                  if (field == "B") { p_tableitem->setText(tr("Backup")); }
-                  else if (field == "R") { p_tableitem->setText(tr("Restore")); }
-               } else if (column == jobLevelIndex) {
-                  if (field == "F") { p_tableitem->setText("Full"); }
-                  else if (field == "D") { p_tableitem->setText("Diff"); }
-                  else if (field == "I") { p_tableitem->setText("Incr"); }
-               }   
-               if ((column == m_bytesIndex) || (column == m_filesIndex)){
-                  p_tableitem->setTextAlignment(Qt::AlignRight);
-               }
-               column++;
-            }
-         }
-         row++;
-      }
-   } 
-   /* Resize the columns */
-   mp_tableWidget->resizeColumnsToContents();
-   mp_tableWidget->resizeRowsToContents();
-   mp_tableWidget->verticalHeader()->hide();
-   if ((m_mediaName != tr("Any")) && (m_resultCount == 0)){
-      /* for context sensitive searches, let the user know if there were no
-       * results */
-      QMessageBox::warning(this, "Bat",
-          tr("The Jobs query returned no results.\n"
-         "Press OK to continue?"), QMessageBox::Ok );
-   }
-}
-
-void JobList::setStatusColor(QTableWidgetItem *item, QString &field)
-{
-   QString greenchars("TCR");
-   QString redchars("BEf");
-   QString yellowchars("eDAFSMmsjdctp");
-   if (greenchars.contains(field, Qt::CaseSensitive)) {
-      item->setBackground(Qt::green);
-   } else if (redchars.contains(field, Qt::CaseSensitive)) {
-      item->setBackground(Qt::red);
-   } else if (yellowchars.contains(field, Qt::CaseSensitive)){ 
-      item->setBackground(Qt::yellow);
-   }
 }
 
 /*
index 19456bf687c586580d6dd028d4d8ed582f722276..18eaabeddf6c775213d7e4b6b69895703c028437 100644 (file)
@@ -73,9 +73,10 @@ private slots:
 
 private:
    void createConnections();
-   void setStatusColor(QTableWidgetItem *item, QString &field);
    void writeSettings();
    void readSettings();
+   void prepareFilterWidgets();
+   void fillQueryString(QString &query);
    void selectedJobsGet();
    QSplitter *m_splitter;
    QString m_groupText;
index 4a485b747e503d60ec05a14c5207552115ac3388..e52342b1ab6f04ed14ffbaf8bfe16068cc2d47a3 100644 (file)
@@ -54,6 +54,7 @@
 #include "jobgraphs/jobplot.h"
 #endif
 #include "status/dirstat.h"
+#include "util/fmtwidgetitem.h"
 
 /* 
  * Daemon message callback
@@ -674,13 +675,16 @@ void MainWin::setPreferences()
    prefs.rtRestore1CheckBox->setCheckState(m_rtRestore1Debug ? Qt::Checked : Qt::Unchecked);
    prefs.rtRestore2CheckBox->setCheckState(m_rtRestore2Debug ? Qt::Checked : Qt::Unchecked);
    prefs.rtRestore3CheckBox->setCheckState(m_rtRestore3Debug ? Qt::Checked : Qt::Unchecked);
-   if (m_radioConvert == 0) {
+   switch (ItemFormatterBase::getBytesConversion()) {
+   case ItemFormatterBase::BYTES_CONVERSION_NONE:
       prefs.radioConvertOff->setChecked(Qt::Checked);
-   } else if (m_radioConvert == 1){
+      break;
+   case ItemFormatterBase::BYTES_CONVERSION_IEC:
       prefs.radioConvertIEC->setChecked(Qt::Checked);
-   } else {
-      m_radioConvert = 2;
+      break;
+   default:
       prefs.radioConvertStandard->setChecked(Qt::Checked);
+      break;
    }
    prefs.openPlotCheckBox->setCheckState(m_openPlot ? Qt::Checked : Qt::Unchecked);
    prefs.openBrowserCheckBox->setCheckState(m_openBrowser ? Qt::Checked : Qt::Unchecked);
@@ -725,11 +729,11 @@ void prefsDialog::accept()
    mainWin->m_rtRestore2Debug = this->rtRestore2CheckBox->checkState() == Qt::Checked;
    mainWin->m_rtRestore3Debug = this->rtRestore3CheckBox->checkState() == Qt::Checked;
    if (this->radioConvertOff->isChecked()) {
-      mainWin->m_radioConvert = 0;
+      ItemFormatterBase::setBytesConversion(ItemFormatterBase::BYTES_CONVERSION_NONE);
    } else if (this->radioConvertIEC->isChecked()){
-      mainWin->m_radioConvert = 1;
+      ItemFormatterBase::setBytesConversion(ItemFormatterBase::BYTES_CONVERSION_IEC);
    } else {
-      mainWin->m_radioConvert = 2;
+      ItemFormatterBase::setBytesConversion(ItemFormatterBase::BYTES_CONVERSION_SI);
    }
    mainWin->m_openPlot = this->openPlotCheckBox->checkState() == Qt::Checked;
    mainWin->m_openBrowser = this->openBrowserCheckBox->checkState() == Qt::Checked;
@@ -757,7 +761,7 @@ void prefsDialog::accept()
    settings.endGroup();
    settings.beginGroup("Misc");
    settings.setValue("longList", mainWin->m_longList);
-   settings.setValue("byteConvert", mainWin->m_radioConvert);
+   settings.setValue("byteConvert", ItemFormatterBase::getBytesConversion());
    settings.setValue("openplot", mainWin->m_openPlot);
    settings.setValue("openbrowser", mainWin->m_openBrowser);
    settings.setValue("opendirstat", mainWin->m_openDirStat);
@@ -812,7 +816,9 @@ void MainWin::readPreferences()
    settings.endGroup();
    settings.beginGroup("Misc");
    m_longList = settings.value("longList", false).toBool();
-   m_radioConvert = settings.value("byteConvert", false).toInt();
+   ItemFormatterBase::setBytesConversion(
+        (ItemFormatterBase::BYTES_CONVERSION) settings.value("byteConvert", 
+        ItemFormatterBase::BYTES_CONVERSION_IEC).toInt());
    m_openPlot = settings.value("openplot", false).toBool();
    m_openBrowser = settings.value("openbrowser", false).toBool();
    m_openDirStat = settings.value("opendirstat", false).toBool();
@@ -833,70 +839,4 @@ void MainWin::readPreferences()
    settings.endGroup();
 }
 
-void MainWin::hrConvert(QString &ret, qlonglong &inval)
-{
-   double net = 0;
-   qlonglong base;
-   QStringList suflist;
 
-   if (m_radioConvert == 0) {
-      ret =  QString("%1").arg(inval);
-      return;
-   } else if (m_radioConvert == 1){
-      base = 1000;
-      suflist = (QStringList() << "B" << "KiB" << "MiB" << "GiB" << "TiB" << "PiB" << "EiB" << "ZiB");
-   } else {
-      base = 1024;
-      suflist = (QStringList() << "B" << "KB" << "MB" << "GB" << "TB" << "PB" << "EB" << "ZB");
-   }
-   qlonglong running = base;
-   bool done = false;
-   int count = 1;
-   while (done == false) {
-      QString test1 =  QString("%1").arg(inval);
-      QString test2 =  QString("%1").arg(running);
-      if (float(inval) < (float)(running)) {
-         done = true;
-         ret = suflist[count - 1];
-         net = (float)inval / (float)(running/base);
-      }
-      count += 1;
-      if (count > suflist.count()) done = true;
-      running *= base;
-   }
-   char format = 'f';
-   if (net != 0)
-      ret =  QString("%1 %2")
-                  .arg(net, 0, format, 2, QLatin1Char(' '))
-                  .arg(ret);
-   else ret = "0 B";
-}
-
-void MainWin::hrConvertSeconds(QString &ret, qlonglong &inval)
-{
-   double net = 0;
-   QList<qlonglong> durations;
-   durations.append(1);
-   durations.append(60);
-   durations.append(3600);
-   durations.append(86400);
-   durations.append(2592000);
-   durations.append(31536000);
-   QStringList abbrlist = (QStringList() << "Sec" << "Min" << "Hrs" << "Days" << "Mnth" << "Yrs");
-   bool done = false;
-   int count = 1;
-   while (done == false) {
-      QString test1 =  QString("%1").arg(inval);
-      QString test2 =  QString("%1").arg(durations[count]);
-      if ((inval < durations[count]) || (count >= abbrlist.count() - 1)) { 
-         done = true;
-         net = (float)inval / (float)(durations[count - 1]);
-         if (net != 0)
-            ret =  QString("%1 %2")
-                  .arg(net, 0, 'f', 2, QLatin1Char(' '))
-                  .arg(abbrlist[count - 1]);
-         else ret = "0 S";
-      }
-      count += 1;
-   }
-}
index 0316817d5a0ec67a1107dbff0ad3f36560302aa5..81ae9758fe7a757969cc125d0b5f3fe1bc041ea5 100644 (file)
@@ -59,8 +59,6 @@ public:
    void hashInsert(QTreeWidgetItem *, Pages *);
    void hashRemove(Pages *);
    void hashRemove(QTreeWidgetItem *, Pages *);
-   void hrConvert(QString &, qlonglong &);
-   void hrConvertSeconds(QString &, qlonglong &);
    Console *currentConsole();
    QTreeWidgetItem *currentTopItem();
    Pages* getFromHash(QTreeWidgetItem *);
@@ -101,7 +99,6 @@ public:
    bool m_rtRestore1Debug;
    bool m_rtRestore2Debug;
    bool m_rtRestore3Debug;
-   int m_radioConvert;
    bool m_openBrowser;
    bool m_openPlot;
    bool m_openDirStat;
index 10469ce83be39942353c105d7e717fbf1de732b6..09e434c765ffed9c63571b21b91b79ba68e26518 100644 (file)
@@ -146,7 +146,7 @@ void MediaList::populateTree()
               continue; // some fields missing, ignore row
 
             int index = 0;
-           ItemFormatter mediaitem(*pooltreeitem, 2);
+           TreeItemFormatter mediaitem(*pooltreeitem, 2);
   
             /* Iterate through fields in the record */
            QStringListIterator fld(fieldlist);
index f6b45ccc9ac57dd01a40ed978b11bcb20d87003c..3a33e28a8edd2198fc33cae73dbe9ab509ee492f 100644 (file)
@@ -95,7 +95,7 @@ void Storage::populateTree()
    mp_treeWidget->setHeaderLabels(headerlist);
 
    foreach(QString storageName, m_console->storage_list){
-      ItemFormatter storageItem(*topItem, 1);
+      TreeItemFormatter storageItem(*topItem, 1);
       storageItem.setTextFld(0, storageName);
       storageItem.widget()->setExpanded(true);
 
@@ -167,7 +167,7 @@ void Storage::mediaList(QTreeWidgetItem *parent, const QString &storageID)
          /* Iterate through fields in the record */
          QStringListIterator fld(fieldlist);
          int index = 0;
-        ItemFormatter fmt(*parent, 2);
+        TreeItemFormatter fmt(*parent, 2);
 
          /* volname */
          fmt.setTextFld(index++, fld.next()); 
index 99cba815356cff7c201e3cc51faba179c052f325..f9314edf92d90d62c93839baf21abe6ff0f24e42 100644 (file)
  */ 
 
 #include <QTreeWidgetItem>
+#include <QTableWidget>
+#include <QTableWidgetItem>
+#include <QBrush>
 #include <QString>
 #include <QStringList>
 #include <math.h>
 #include "fmtwidgetitem.h"
 
-ItemFormatter::ItemFormatter(QTreeWidgetItem &parent, int indent_level):
-wdg(new QTreeWidgetItem(&parent)),
-level(indent_level)
+/***********************************************
+ *
+ * ItemFormatterBase static members
+ *
+ ***********************************************/
+
+ItemFormatterBase::BYTES_CONVERSION ItemFormatterBase::cnvFlag(BYTES_CONVERSION_IEC);
+
+QString ItemFormatterBase::convertBytesIEC(qint64 qfld)
 {
+   static const qint64 KB = Q_INT64_C(1024);
+   static const qint64 MB = (KB * KB);
+   static const qint64 GB = (MB * KB);
+   static const qint64 TB = (GB * KB);
+   static const qint64 PB = (TB * KB);
+   static const qint64 EB = (PB * KB);
+
+   /* note: division is integer, so to have some decimals we divide for a
+      smaller unit (e.g. GB for a TB number and so on) */
+   char suffix;
+   if (qfld >= EB) {
+      qfld /= PB; 
+      suffix = 'E';
+   }
+   else if (qfld >= PB) {
+      qfld /= TB; 
+      suffix = 'P';
+   }
+   else if (qfld >= TB) {
+      qfld /= GB; 
+      suffix = 'T';
+   }
+   else if (qfld >= GB) {
+      qfld /= MB;
+      suffix = 'G';
+   }
+   else if (qfld >= MB) {
+      qfld /= KB;
+      suffix = 'M';
+   }
+   else if (qfld >= KB) {
+      suffix = 'K';
+   }
+   else  {
+      /* plain bytes, no need to reformat */
+      return QString("%1 B").arg(qfld); 
+   }
+
+   /* having divided for a smaller unit, now we can safely convert to double and
+      use the extra room for decimals */
+   return QString("%1 %2iB").arg(qfld / 1000.0, 0, 'f', 2).arg(suffix);
 }
 
-void ItemFormatter::setBoolFld(int index, const QString &fld, bool center)
+QString ItemFormatterBase::convertBytesSI(qint64 qfld)
+{
+   static const qint64 KB = Q_INT64_C(1000);
+   static const qint64 MB = (KB * KB);
+   static const qint64 GB = (MB * KB);
+   static const qint64 TB = (GB * KB);
+   static const qint64 PB = (TB * KB);
+   static const qint64 EB = (PB * KB);
+
+   /* note: division is integer, so to have some decimals we divide for a
+      smaller unit (e.g. GB for a TB number and so on) */
+   char suffix;
+   if (qfld >= EB) {
+      qfld /= PB; 
+      suffix = 'E';
+   }
+   else if (qfld >= PB) {
+      qfld /= TB; 
+      suffix = 'P';
+   }
+   else if (qfld >= TB) {
+      qfld /= GB; 
+      suffix = 'T';
+   }
+   else if (qfld >= GB) {
+      qfld /= MB;
+      suffix = 'G';
+   }
+   else if (qfld >= MB) {
+      qfld /= KB;
+      suffix = 'M';
+   }
+   else if (qfld >= KB) {
+      suffix = 'k'; /* SI uses lowercase k */
+   }
+   else  {
+      /* plain bytes, no need to reformat */
+      return QString("%1 B").arg(qfld); 
+   }
+
+   /* having divided for a smaller unit, now we can safely convert to double and
+      use the extra room for decimals */
+   return QString("%1 %2B").arg(qfld / 1000.0, 0, 'f', 2).arg(suffix);
+}
+
+/***********************************************
+ *
+ * base formatting routines
+ *
+ ***********************************************/
+
+ItemFormatterBase::ItemFormatterBase()
+{
+}
+
+ItemFormatterBase::~ItemFormatterBase()
+{
+}
+
+void ItemFormatterBase::setBoolFld(int index, const QString &fld, bool center)
 {
    if (fld.trimmed().toInt())
      setTextFld(index, "Yes", center);
@@ -55,7 +164,7 @@ void ItemFormatter::setBoolFld(int index, const QString &fld, bool center)
      setTextFld(index, "No", center);
 }
 
-void ItemFormatter::setBoolFld(int index, int fld, bool center)
+void ItemFormatterBase::setBoolFld(int index, int fld, bool center)
 {
    if (fld)
      setTextFld(index, "Yes", center);
@@ -63,84 +172,234 @@ void ItemFormatter::setBoolFld(int index, int fld, bool center)
      setTextFld(index, "No", center);
 }
 
-void ItemFormatter::setTextFld(int index, const QString &fld, bool center)
+void ItemFormatterBase::setNumericFld(int index, const QString &fld)
+{
+   setTextFld(index, fld);
+   setTextAlignment(index, Qt::AlignRight | Qt::AlignVCenter);
+}
+
+void ItemFormatterBase::setBytesFld(int index, const QString &fld)
+{
+   qint64 qfld = fld.trimmed().toLongLong();
+   QString msg;
+   switch (cnvFlag) {
+   case BYTES_CONVERSION_NONE:
+      msg = QString::number(qfld);
+      break;
+   case BYTES_CONVERSION_IEC:
+      msg = convertBytesIEC(qfld);
+      break;
+   case BYTES_CONVERSION_SI:
+      msg = convertBytesSI(qfld);
+      break;
+   }
+   setNumericFld(index, msg);
+}
+
+void ItemFormatterBase::setDurationFld(int index, const QString &fld)
+{
+   static const qint64 HOUR = Q_INT64_C(3600);
+   static const qint64 DAY = HOUR * 24;
+   static const qint64 WEEK = DAY * 7;
+   static const qint64 MONTH = DAY * 30;
+   static const qint64 YEAR = DAY * 365;
+   static const qint64 divs[] = { YEAR, MONTH, WEEK, DAY, HOUR };
+   static const char sufs[] = { 'y', 'm', 'w', 'd', 'h', '\0' };
+
+   qint64 dfld = fld.trimmed().toLongLong();
+
+   char suffix = 's';
+   if (dfld) {
+      for (int pos = 0 ; sufs[pos] ; ++pos) {
+         if (dfld % divs[pos] == 0) {
+            dfld /= divs[pos];
+            suffix = sufs[pos];
+            break;
+         }
+      }
+   }
+   QString msg;
+   if (dfld < 100) {
+      msg = QString("%1%2").arg(dfld).arg(suffix);
+   } else {
+      /* previous check returned a number too big. The original specification perhaps
+         was mixed, like 1d 2h, so we try to match with this routine */
+      dfld = fld.trimmed().toLongLong();
+      msg = "";
+      for (int pos = 0 ; sufs[pos] ; ++pos) {
+         if (dfld / divs[pos] != 0) {
+            msg += QString(" %1%2").arg(dfld / divs[pos]).arg(sufs[pos]);
+            dfld %= divs[pos];
+         }
+      }
+      if (dfld)
+        msg += QString(" %1s").arg(dfld);
+           
+/*
+     double net = 0;
+     QList<qlonglong> durations;
+     durations.append(1);
+     durations.append(60);
+     durations.append(HOUR);
+     durations.append(DAY);
+     durations.append(MONTH);
+     durations.append(YEAR);
+     QStringList abbrlist = (QStringList() << "s" << "min" << "h" << "d" << "m" << "y");
+     bool done = false;
+     int count = 1;
+     while (done == false) {
+       if ((dfld < durations[count]) || (count >= abbrlist.count() - 1)) { 
+           done = true;
+          net = (double)dfld / (double)(durations[count - 1]);
+          if (net != 0) {
+              msg =  QString("%1%2")
+                  .arg(net, 0, 'f', 2, QLatin1Char(' '))
+                  .arg(abbrlist[count - 1]);
+          } else {
+            msg = "0s";
+          }
+       }
+        count += 1;
+     }
+*/   }
+
+   setNumericFld(index, msg);
+}
+
+void ItemFormatterBase::setVolStatusFld(int index, const QString &fld, bool center)
+{
+   setTextFld(index, fld, center);
+
+   if (fld == "Append" ) {
+      setBackground(index, Qt::green);
+   } else if (fld == "Error") {
+      setBackground(index, Qt::red);
+   } else if (fld == "Used" || fld == "Full"){
+      setBackground(index, Qt::yellow);
+   }
+}
+
+void ItemFormatterBase::setJobStatusFld(int index, const QString &shortstatus, 
+                                       const QString &longstatus, bool center)
+{
+   /* C (created, not yet running) uses the default background */
+   static QString greenchars("TR");
+   static QString redchars("BEf");
+   static QString yellowchars("eDAFSMmsjdctp");
+
+   setTextFld(index, longstatus, center);
+
+   QString st(shortstatus.trimmed());
+   if (greenchars.contains(st, Qt::CaseSensitive)) {
+      setBackground(index, Qt::green);
+   } else if (redchars.contains(st, Qt::CaseSensitive)) {
+      setBackground(index, Qt::red);
+   } else if (yellowchars.contains(st, Qt::CaseSensitive)){ 
+      setBackground(index, Qt::yellow);
+   }
+}
+
+void ItemFormatterBase::setJobTypeFld(int index, const QString &fld, bool center)
+{
+   static QHash<QString, QString> jobt;
+   if (jobt.isEmpty()) {
+      jobt.insert("B", QObject::tr("Backup"));
+      jobt.insert("R", QObject::tr("Restore"));
+      jobt.insert("V", QObject::tr("Verify"));
+      jobt.insert("A", QObject::tr("Admin"));
+   }
+
+   setTextFld(index, jobt.value(fld.trimmed(), fld.trimmed()), center);
+}
+
+void ItemFormatterBase::setJobLevelFld(int index, const QString &fld, bool center)
+{
+   static QHash<QString, QString> jobt;
+   if (jobt.isEmpty()) {
+      jobt.insert("F", QObject::tr("Full"));
+      jobt.insert("D", QObject::tr("Differential"));
+      jobt.insert("I", QObject::tr("Incremental"));
+      jobt.insert("C", QObject::tr("Catalog"));
+      jobt.insert("O", QObject::tr("VolToCatalog"));
+   }
+
+   setTextFld(index, jobt.value(fld.trimmed(), fld.trimmed()), center);
+}
+
+
+
+/***********************************************
+ *
+ * treeitem formatting routines
+ *
+ ***********************************************/
+TreeItemFormatter::TreeItemFormatter(QTreeWidgetItem &parent, int indent_level):
+ItemFormatterBase(),
+wdg(new QTreeWidgetItem(&parent)),
+level(indent_level)
+{
+}
+
+void TreeItemFormatter::setTextFld(int index, const QString &fld, bool center)
 {
    wdg->setData(index, Qt::UserRole, level);
    if (center) {
-      wdg->setTextAlignment(index, Qt::AlignHCenter);
+      setTextAlignment(index, Qt::AlignCenter);
    }
    wdg->setText(index, fld.trimmed());
 }
 
-void ItemFormatter::setNumericFld(int index, const QString &fld)
+void TreeItemFormatter::setTextAlignment(int index, int align)
 {
-   wdg->setData(index, Qt::UserRole, level);
-   wdg->setTextAlignment(index, Qt::AlignRight);
-   wdg->setText(index, fld.trimmed());
+   wdg->setTextAlignment(index, align);
 }
 
-void ItemFormatter::setBytesFld(int index, const QString &fld)
+void TreeItemFormatter::setBackground(int index, const QBrush &qb)
 {
-   static const double KB = 1024.0;
-   static const double MB = KB * KB;
-   static const double GB = MB * KB;
-   static const double TB = GB * KB;
+   wdg->setBackground(index, qb);
+}
 
-   double dfld = fld.trimmed().toDouble();
-   QString msg;
-   if (dfld >= TB)
-      msg = QString("%1TB").arg(dfld / TB, 0, 'f', 2);
-   else if (dfld >= GB)
-      msg = QString("%1GB").arg(dfld / GB, 0, 'f', 2);
-   else if (dfld >= MB)
-      msg = QString("%1MB").arg(dfld / MB, 0, 'f', 2);
-   else if (dfld >= KB)
-      msg = QString("%1KB").arg(dfld / KB, 0, 'f', 2);
-   else
-      msg = QString::number(dfld, 'f', 0);
-   wdg->setData(index, Qt::UserRole, level);
-   wdg->setTextAlignment(index, Qt::AlignRight);
-   wdg->setText(index, msg);
+
+/***********************************************
+ *
+ * tableitem formatting routines
+ *
+ ***********************************************/
+TableItemFormatter::TableItemFormatter(QTableWidget &tparent, int trow):
+ItemFormatterBase(),
+parent(&tparent),
+row(trow),
+last(NULL)
+{
+}
+
+void TableItemFormatter::setTextFld(int col, const QString &fld, bool center)
+{
+   last = new QTableWidgetItem(1);
+/*   last->setForeground(blackBrush); */
+   parent->setItem(row, col, last);
+   if (center) {
+      setTextAlignment(col, Qt::AlignCenter);
+   }
+   last->setText(fld.trimmed());
 }
 
-void ItemFormatter::setDurationFld(int index, const QString &fld)
+void TableItemFormatter::setTextAlignment(int /*index*/, int align)
 {
-   static const double HOUR = 3600;
-   static const double DAY = HOUR * 24;
-   static const double WEEK = DAY * 7;
-   static const double MONTH = DAY * 30;
-   static const double YEAR = DAY * 365;
+   last->setTextAlignment(align);
+}
 
-   double dfld = fld.trimmed().toDouble();
-   QString msg;
-   if (fmod(dfld, YEAR) == 0)
-      msg = QString("%1y").arg(dfld / YEAR, 0, 'f', 0);
-   else if (fmod(dfld, MONTH) == 0)
-      msg = QString("%1m").arg(dfld / MONTH, 0, 'f', 0);
-   else if (fmod(dfld, WEEK) == 0)
-      msg = QString("%1w").arg(dfld / WEEK, 0, 'f', 0);
-   else if (fmod(dfld, DAY) == 0)
-      msg = QString("%1d").arg(dfld / DAY, 0, 'f', 0);
-   else if (fmod(dfld, HOUR) == 0)
-      msg = QString("%1h").arg(dfld / HOUR, 0, 'f', 0);
-   else
-      msg = QString("%1s").arg(dfld, 0, 'f', 0);
-   wdg->setData(index, Qt::UserRole, level);
-   wdg->setTextAlignment(index, Qt::AlignRight);
-   wdg->setText(index, msg);
+void TableItemFormatter::setBackground(int /*index*/, const QBrush &qb)
+{
+   last->setBackground(qb);
 }
 
-void ItemFormatter::setVolStatusFld(int index, const QString &fld, bool center)
+QTableWidgetItem *TableItemFormatter::widget(int col)
 {
-  setTextFld(index, fld, center);
+  return parent->item(row, col);
+}
 
-   if (fld == "Append" ) {
-      wdg->setBackground(index, Qt::green);
-   } else if (fld == "Error") {
-      wdg->setBackground(index, Qt::red);
-   } else if (fld == "Used" || fld == "Full"){
-      wdg->setBackground(index, Qt::yellow);
-   }
+const QTableWidgetItem *TableItemFormatter::widget(int col) const
+{
+  return parent->item(row, col);
 }
index 2f6c35a73684e80c6a9ae354c6989c963a888ab0..f0761888d61a4f28c8246e22f1fb773ace5b203a 100644 (file)
  */
 
 class QTreeWidgetItem;
+class QTableWidget;
+class QTableWidgetItem;
 class QString;
+class QBrush;
 
 /*
- * This class can be used instead of QTreeWidgetItem (it allocates one internally,
- * to format data fields.
- * All setXXXFld routines receive a column index and the unformatted string value.
+ * base class for formatters
+ *
  */
-class ItemFormatter
+class ItemFormatterBase
 {
 public:
+  enum BYTES_CONVERSION {
+    BYTES_CONVERSION_NONE,
+    BYTES_CONVERSION_IEC,
+    BYTES_CONVERSION_SI,
+  };
 
-   ItemFormatter(QTreeWidgetItem &parent, int indent_level);
+public:
+   virtual ~ItemFormatterBase(); 
 
    /* Prints Yes if fld is != 0, No otherwise. Centers field if center true*/
    void setBoolFld(int index, const QString &fld, bool center = true);
    void setBoolFld(int index, int fld, bool center = true);
 
    /* Normal text field. Centers field if center true*/
-   void setTextFld(int index, const QString &fld, bool center = false);
+   virtual void setTextFld(int index, const QString &fld, bool center = false) = 0;
 
    /* Right-aligned text field.*/
    void setNumericFld(int index, const QString &fld);
@@ -65,91 +73,93 @@ public:
 
    /* fld value interpreted as volume status. Colored accordingly */
    void setVolStatusFld(int index, const QString &fld, bool center = true);
+  
+   /* fld value interpreted as job status. Colored accordingly */
+   void setJobStatusFld(int index, const QString &shortStatus, const QString &longstatus, 
+                       bool center = true);
+  
+   /* fld value interpreted as job type. */
+   void setJobTypeFld(int index, const QString &fld, bool center = false);
+  
+   /* fld value interpreted as job level. */
+   void setJobLevelFld(int index, const QString &fld, bool center = false);
+  
+   static void setBytesConversion(BYTES_CONVERSION b) {
+      cnvFlag = b;
+   }
+   static BYTES_CONVERSION getBytesConversion() {
+      return cnvFlag;
+   }
+
+protected:
+   /* only derived classes can create one of these */
+   ItemFormatterBase();
+
+   virtual void setTextAlignment(int index, int align) = 0;
+   virtual void setBackground(int index, const QBrush &) = 0;
 
-   /* access internal widget */
-   QTreeWidgetItem *widget() { return wdg; }
-   const QTreeWidgetItem *widget() const { return wdg; }
+private:
+   /* bytes formatted as power-of-two with IEC suffixes (KiB, MiB, and so on) */
+   static QString convertBytesIEC(qint64 fld);
+
+   /* bytes formatted as power-of-ten with SI suffixes (kB, MB, and so on) */
+   static QString convertBytesSI(qint64 fld);
 
 private:
-   QTreeWidgetItem *wdg;
-   int level;
+   static BYTES_CONVERSION cnvFlag;
 };
 
-#endif /* _FMTWIDGETITEM_H_ */
-#ifndef _FMTWIDGETITEM_H_
-#define _FMTWIDGETITEM_H_
 /*
-   Bacula® - The Network Backup Solution
-
-   Copyright (C) 2007-2007 Free Software Foundation Europe e.V.
+ * This class can be used instead of QTreeWidgetItem (it allocates one internally,
+ * to format data fields.
+ * All setXXXFld routines receive a column index and the unformatted string value.
+ */
+class TreeItemFormatter : public ItemFormatterBase
+{
+public:
 
-   The main author of Bacula is Kern Sibbald, with contributions from
-   many others, a complete list can be found in the file AUTHORS.
-   This program is Free Software; you can redistribute it and/or
-   modify it under the terms of version two of the GNU General Public
-   License as published by the Free Software Foundation and included
-   in the file LICENSE.
+   TreeItemFormatter(QTreeWidgetItem &parent, int indent_level);
 
-   This program is distributed in the hope that it will be useful, but
-   WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-   General Public License for more details.
+   virtual void setTextFld(int index, const QString &fld, bool center = false);
 
-   You should have received a copy of the GNU General Public License
-   along with this program; if not, write to the Free Software
-   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
-   02110-1301, USA.
+   /* access internal widget */
+   QTreeWidgetItem *widget() { return wdg; }
+   const QTreeWidgetItem *widget() const { return wdg; }
 
-   Bacula® is a registered trademark of John Walker.
-   The licensor of Bacula is the Free Software Foundation Europe
-   (FSFE), Fiduciary Program, Sumatrastrasse 25, 8006 Zürich,
-   Switzerland, email:ftf@fsfeurope.org.
-*/
-/*
- *   Version $Id$
- *
- *   TreeView formatting helpers - Riccardo Ghetta, May 2008 
- */
+protected:
+   virtual void setTextAlignment(int index, int align);
+   virtual void setBackground(int index, const QBrush &);
 
-class QTreeWidgetItem;
-class QString;
+private:
+   QTreeWidgetItem *wdg;
+   int level;
+};
 
 /*
- * This class can be used instead of QTreeWidgetItem (it allocates one internally,
+ * This class can be used instead of QTableWidgetItem (it allocates one internally,
  * to format data fields.
- * All setXXXFld routines receive a column index and the unformatted string value.
+ * All setXXXFld routines receive the column and the unformatted string value.
  */
-class ItemFormatter
+class TableItemFormatter : public ItemFormatterBase
 {
 public:
 
-   ItemFormatter(QTreeWidgetItem &parent, int indent_level);
+   TableItemFormatter(QTableWidget &parent, int row);
 
-   /* Prints Yes if fld is != 0, No otherwise. Centers field if center true*/
-   void setBoolFld(int index, const QString &fld, bool center = true);
-
-   /* Normal text field. Centers field if center true*/
-   void setTextFld(int index, const QString &fld, bool center = false);
-
-   /* Right-aligned text field.*/
-   void setNumericFld(int index, const QString &fld);
+   virtual void setTextFld(int col, const QString &fld, bool center = false);
 
-   /* fld value interpreted as bytes and formatted with size suffixes */
-   void setBytesFld(int index, const QString &fld);
+   /* access internal widget at column col*/
+   QTableWidgetItem *widget(int col);
+   const QTableWidgetItem *widget(int col) const;
 
-   /* fld value interpreted as seconds and formatted with y,m,w,h suffixes */
-   void setDurationFld(int index, const QString &fld);
-
-   /* fld value interpreted as volume status. Colored accordingly */
-   void setVolStatusFld(int index, const QString &fld, bool center = true);
-
-   /* access internal widget */
-   QTreeWidgetItem *widget() { return wdg; }
-   const QTreeWidgetItem *widget() const { return wdg; }
+protected:
+   virtual void setTextAlignment(int index, int align);
+   virtual void setBackground(int index, const QBrush &);
 
 private:
-   QTreeWidgetItem *wdg;
-   int level;
+   QTableWidget *parent;
+   int row;
+   QTableWidgetItem *last;
 };
 
 #endif /* _FMTWIDGETITEM_H_ */