]> git.sur5r.net Git - bacula/bacula/blobdiff - bacula/src/qt-console/medialist/medialist.cpp
Apply win32-fixes patch from Riccardo that makes the Win32
[bacula/bacula] / bacula / src / qt-console / medialist / medialist.cpp
index 0e04993cea688843873c2168e2e982182cd28e86..bf891fa4c19399d868ce6a8f4b796e5199770c7a 100644 (file)
@@ -1,14 +1,14 @@
 /*
    Bacula® - The Network Backup Solution
 
-   Copyright (C) 2000-2007 Free Software Foundation Europe e.V.
+   Copyright (C) 2007-2008 Free Software Foundation Europe e.V.
 
    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 plus additions
-   that are listed in the file LICENSE.
+   License as published by the Free Software Foundation and included
+   in the file LICENSE.
 
    This program is distributed in the hope that it will be useful, but
    WITHOUT ANY WARRANTY; without even the implied warranty of
    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
    02110-1301, USA.
 
-   Bacula® is a registered trademark of John Walker.
+   Bacula® is a registered trademark of Kern Sibbald.
    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: medialist.cpp 4230 2007-02-21 20:07:37Z kerns $
+ *   Version $Id$
  *
  *  MediaList Class
  *
 
 #include <QAbstractEventDispatcher>
 #include <QMenu>
+#include <math.h>
 #include "bat.h"
 #include "medialist.h"
 #include "mediaedit/mediaedit.h"
 #include "joblist/joblist.h"
 #include "relabel/relabel.h"
 #include "run/run.h"
+#include "util/fmtwidgetitem.h"
 
 MediaList::MediaList()
 {
    setupUi(this);
-   m_name = "Media";
+   m_name = tr("Media");
    pgInitialize();
    QTreeWidgetItem* thisitem = mainWin->getFromHash(this);
-   thisitem->setIcon(0,QIcon(QString::fromUtf8(":images/cartridge.svg")));
+   thisitem->setIcon(0,QIcon(QString::fromUtf8(":images/cartridge.png")));
 
    /* mp_treeWidget, Storage Tree Tree Widget inherited from ui_medialist.h */
    m_populated = false;
@@ -64,6 +66,8 @@ MediaList::MediaList()
 
 MediaList::~MediaList()
 {
+   if (m_populated)
+      writeExpandedSettings();
 }
 
 /*
@@ -72,50 +76,60 @@ MediaList::~MediaList()
  */
 void MediaList::populateTree()
 {
-   QTreeWidgetItem *mediatreeitem, *pooltreeitem, *topItem;
+   if (m_populated)
+      writeExpandedSettings();
+   m_populated = true;
 
    if (!m_console->preventInUseConnect())
        return;
 
+   Freeze frz(*mp_treeWidget); /* disable updating*/
+
    QStringList headerlist = (QStringList()
-      << "Volume Name" << "Id" << "Status" << "Enabled" << "Bytes" << "Files"
-      << "Jobs" << "Retention" << "Media Type" << "Slot" << "Use Duration"
-      << "Max Jobs" << "Max Files" << "Max Bytes" << "Recycle" << "Enabled"
-      << "RecyclePool" << "Last Written");
-   int statusIndex = headerlist.indexOf("Status");
+      << tr("Volume Name") << tr("Id") << tr("Status") << tr("Enabled") << tr("Bytes") << tr("Files")
+      << tr("Jobs") << tr("Retention") << tr("Media Type") << tr("Slot") << tr("Use Duration")
+      << tr("Max Jobs") << tr("Max Files") << tr("Max Bytes") << tr("Recycle")
+      << tr("RecyclePool") << tr("Last Written"));
 
    m_checkcurwidget = false;
    mp_treeWidget->clear();
    m_checkcurwidget = true;
    mp_treeWidget->setColumnCount(headerlist.count());
-   topItem = new QTreeWidgetItem(mp_treeWidget);
-   topItem->setText(0, "Pools");
-   topItem->setData(0, Qt::UserRole, 0);
-   topItem->setExpanded(true);
+   m_topItem = new QTreeWidgetItem(mp_treeWidget);
+   m_topItem->setText(0, tr("Pools"));
+   m_topItem->setData(0, Qt::UserRole, 0);
+   m_topItem->setExpanded(true);
    
    mp_treeWidget->setHeaderLabels(headerlist);
 
+   QSettings settings(m_console->m_dir->name(), "bat");
+   settings.beginGroup("MediaListTreeExpanded");
    QString query;
 
+   QTreeWidgetItem *pooltreeitem;
    foreach (QString pool_listItem, m_console->pool_list) {
-      pooltreeitem = new QTreeWidgetItem(topItem);
+      pooltreeitem = new QTreeWidgetItem(m_topItem);
       pooltreeitem->setText(0, pool_listItem);
       pooltreeitem->setData(0, Qt::UserRole, 1);
-      pooltreeitem->setExpanded(true);
+      if(settings.contains(pool_listItem)) {
+         pooltreeitem->setExpanded(settings.value(pool_listItem).toBool());
+      } else {
+         pooltreeitem->setExpanded(true);
+      }
 
       query =  "SELECT Media.VolumeName AS Media, "
          " Media.MediaId AS Id, Media.VolStatus AS VolStatus,"
          " Media.Enabled AS Enabled, Media.VolBytes AS Bytes,"
          " Media.VolFiles AS FileCount, Media.VolJobs AS JobCount,"
          " Media.VolRetention AS VolumeRetention, Media.MediaType AS MediaType,"
-         " Media.Slot AS Slot, Media.VolUseDuration AS UseDuration,"
+         " Media.InChanger AS InChanger, Media.Slot AS Slot, "
+         " Media.VolUseDuration AS UseDuration,"
          " Media.MaxVolJobs AS MaxJobs, Media.MaxVolFiles AS MaxFiles,"
          " Media.MaxVolBytes AS MaxBytes, Media.Recycle AS Recycle,"
-         " Media.Enabled AS enabled, Pol.Name AS RecyclePool,"
-         " Media.LastWritten AS LastWritten"
+         " Pol.Name AS RecyclePool, Media.LastWritten AS LastWritten"
          " FROM Media"
-         " LEFT OUTER JOIN Pool ON (Media.PoolId=Pool.PoolId)"
-         " LEFT OUTER JOIN Pool AS Pol ON (Media.recyclepoolid=Pol.PoolId)"
+         " JOIN Pool ON (Media.PoolId=Pool.PoolId)"
+         " LEFT OUTER JOIN Pool AS Pol ON (Media.RecyclePoolId=Pol.PoolId)"
          " WHERE";
       query += " Pool.Name='" + pool_listItem + "'";
       query += " ORDER BY Media";
@@ -125,48 +139,90 @@ void MediaList::populateTree()
       }
       QStringList results;
       if (m_console->sql_cmd(query, results)) {
-         QString field;
          QStringList fieldlist;
 
          /* Iterate through the lines of results. */
          foreach (QString resultline, results) {
             fieldlist = resultline.split("\t");
-            int index = 0;
-            mediatreeitem = new QTreeWidgetItem(pooltreeitem);
 
+           if (fieldlist.size() < 18)
+              continue; // some fields missing, ignore row
+
+            int index = 0;
+           TreeItemFormatter mediaitem(*pooltreeitem, 2);
+  
             /* Iterate through fields in the record */
-            foreach (field, fieldlist) {
-               field = field.trimmed();  /* strip leading & trailing spaces */
-               if (field != "") {
-                  mediatreeitem->setData(index, Qt::UserRole, 2);
-                  mediatreeitem->setData(index, Qt::UserRole, 2);
-                  mediatreeitem->setText(index, field);
-                  if (index == statusIndex) {
-                     setStatusColor(mediatreeitem, field, index);
-                  }
-               }
-               index++;
-            } /* foreach field */
+           QStringListIterator fld(fieldlist);
+
+           /* volname */
+            mediaitem.setTextFld(index++, fld.next()); 
+
+           /* id */
+            mediaitem.setNumericFld(index++, fld.next()); 
+
+           /* status */
+            mediaitem.setVolStatusFld(index++, fld.next());
+
+           /* enabled */
+           mediaitem.setBoolFld(index++, fld.next());
+
+            /* bytes */
+           mediaitem.setBytesFld(index++, fld.next());
+
+           /* files */
+            mediaitem.setNumericFld(index++, fld.next()); 
+
+           /* jobs */
+            mediaitem.setNumericFld(index++, fld.next()); 
+
+           /* retention */
+           mediaitem.setDurationFld(index++, fld.next());
+
+           /* media type */
+            mediaitem.setTextFld(index++, fld.next()); 
+
+           /* inchanger + slot */
+           int inchanger = fld.next().toInt();
+            if (inchanger) {
+               mediaitem.setNumericFld(index++, fld.next()); 
+            }
+            else {
+               /* volume not in changer, show blank slot */
+               mediaitem.setNumericFld(index++, ""); 
+               fld.next();
+           }
+
+           /* use duration */
+           mediaitem.setDurationFld(index++, fld.next());
+
+           /* max jobs */
+            mediaitem.setNumericFld(index++, fld.next()); 
+
+           /* max files */
+            mediaitem.setNumericFld(index++, fld.next()); 
+
+            /* max bytes */
+           mediaitem.setBytesFld(index++, fld.next());
+
+           /* recycle */
+           mediaitem.setBoolFld(index++, fld.next());
+
+           /* recycle pool */
+            mediaitem.setTextFld(index++, fld.next()); 
+
+           /* last written */
+            mediaitem.setTextFld(index++, fld.next()); 
+
          } /* foreach resultline */
       } /* if results from query */
    } /* foreach pool_listItem */
+   settings.endGroup();
    /* Resize the columns */
    for(int cnter=0; cnter<headerlist.count(); cnter++) {
       mp_treeWidget->resizeColumnToContents(cnter);
    }
 }
 
-void MediaList::setStatusColor(QTreeWidgetItem *item, QString &field, int &index)
-{
-   if (field == "Append" ) {
-      item->setBackground(index, Qt::green);
-   } else if (field == "Error") {
-      item->setBackground(index, Qt::red);
-   } else if ((field == "Used") || ("Full")){
-      item->setBackground(index, Qt::yellow);
-   }
-}
-
 /*
  * Called from the signal of the context sensitive menu!
  */
@@ -182,7 +238,7 @@ void MediaList::editVolume()
 void MediaList::showJobs()
 {
    QTreeWidgetItem *parentItem = mainWin->getFromHash(this);
-   mainWin->createPageJobList(m_currentVolumeName, "", "", parentItem);
+   mainWin->createPageJobList(m_currentVolumeName, "", "", "", parentItem);
 }
 
 /*
@@ -194,7 +250,6 @@ void MediaList::PgSeltreeWidgetClicked()
    if (!m_populated) {
       populateTree();
       createContextMenu();
-      m_populated=true;
    }
 }
 
@@ -208,17 +263,14 @@ void MediaList::treeItemChanged(QTreeWidgetItem *currentwidgetitem, QTreeWidgetI
    if (m_checkcurwidget) {
       /* The Previous item */
       if (previouswidgetitem) { /* avoid a segfault if first time */
-         mp_treeWidget->removeAction(actionEditVolume);
-         mp_treeWidget->removeAction(actionListJobsOnVolume);
-         mp_treeWidget->removeAction(actionDeleteVolume);
-         mp_treeWidget->removeAction(actionPruneVolume);
-         mp_treeWidget->removeAction(actionPurgeVolume);
-          mp_treeWidget->removeAction(actionRelabelVolume);
-         mp_treeWidget->removeAction(actionAllVolumesFromPool);
+         foreach(QAction* mediaAction, mp_treeWidget->actions()) {
+            mp_treeWidget->removeAction(mediaAction);
+         }
       }
 
       int treedepth = currentwidgetitem->data(0, Qt::UserRole).toInt();
       m_currentVolumeName=currentwidgetitem->text(0);
+      mp_treeWidget->addAction(actionRefreshMediaList);
       if (treedepth == 2){
          m_currentVolumeId=currentwidgetitem->text(1);
          mp_treeWidget->addAction(actionEditVolume);
@@ -227,12 +279,9 @@ void MediaList::treeItemChanged(QTreeWidgetItem *currentwidgetitem, QTreeWidgetI
          mp_treeWidget->addAction(actionPruneVolume);
          mp_treeWidget->addAction(actionPurgeVolume);
          mp_treeWidget->addAction(actionRelabelVolume);
+         mp_treeWidget->addAction(actionVolumeFromPool);
       } else if (treedepth == 1) {
-/*  *******FIXME******
- *  I can't seem to get "All volumes from pool" or "Volume from pool" to work
- *  in one sentence command.   Works when you do it one step at a time vi console
          mp_treeWidget->addAction(actionAllVolumesFromPool);
-*/
       }
    }
 }
@@ -245,7 +294,6 @@ void MediaList::treeItemChanged(QTreeWidgetItem *currentwidgetitem, QTreeWidgetI
 void MediaList::createContextMenu()
 {
    mp_treeWidget->setContextMenuPolicy(Qt::ActionsContextMenu);
-   mp_treeWidget->addAction(actionRefreshMediaList);
    connect(actionEditVolume, SIGNAL(triggered()), this, SLOT(editVolume()));
    connect(actionListJobsOnVolume, SIGNAL(triggered()), this, SLOT(showJobs()));
    connect(actionDeleteVolume, SIGNAL(triggered()), this, SLOT(deleteVolume()));
@@ -258,7 +306,9 @@ void MediaList::createContextMenu()
    /* connect to the action specific to this pages class */
    connect(actionRefreshMediaList, SIGNAL(triggered()), this,
                 SLOT(populateTree()));
+   connect(actionAllVolumes, SIGNAL(triggered()), this, SLOT(allVolumes()));
    connect(actionAllVolumesFromPool, SIGNAL(triggered()), this, SLOT(allVolumesFromPool()));
+   connect(actionVolumeFromPool, SIGNAL(triggered()), this, SLOT(volumeFromPool()));
 }
 
 /*
@@ -270,7 +320,6 @@ void MediaList::currentStackItem()
       populateTree();
       /* Create the context menu for the medialist tree */
       createContextMenu();
-      m_populated=true;
    }
 }
 
@@ -279,7 +328,7 @@ void MediaList::currentStackItem()
  */
 void MediaList::deleteVolume()
 {
-   if (QMessageBox::warning(this, tr("Bat"),
+   if (QMessageBox::warning(this, "Bat",
       tr("Are you sure you want to delete??  !!!.\n"
 "This delete command is used to delete a Volume record and all associated catalog"
 " records that were created. This command operates only on the Catalog"
@@ -301,7 +350,7 @@ void MediaList::deleteVolume()
  */
 void MediaList::purgeVolume()
 {
-   if (QMessageBox::warning(this, tr("Bat"),
+   if (QMessageBox::warning(this, "Bat",
       tr("Are you sure you want to purge ??  !!!.\n"
 "The Purge command will delete associated Catalog database records from Jobs and"
 " Volumes without considering the retention period. Purge  works only on the"
@@ -341,8 +390,45 @@ void MediaList::relabelVolume()
  */
 void MediaList::allVolumesFromPool()
 {
-   QString cmd("update pool=");
-   cmd += m_currentVolumeName + " All Volumes From Pool";
+   QString cmd = "update volume AllFromPool=" + m_currentVolumeName;
+   consoleCommand(cmd);
+   populateTree();
+}
+
+void MediaList::allVolumes()
+{
+   QString cmd = "update volume allfrompools";
+   consoleCommand(cmd);
+   populateTree();
+}
+
+/*
+ * Called from the signal of the context sensitive menu to purge!
+ */
+void MediaList::volumeFromPool()
+{
+   QTreeWidgetItem *currentItem = mp_treeWidget->currentItem();
+   QTreeWidgetItem *parent = currentItem->parent();
+   QString pool = parent->text(0);
+   QString cmd;
+   cmd = "update volume=" + m_currentVolumeName + " frompool=" + pool;
    consoleCommand(cmd);
    populateTree();
 }
+
+/*
+ * Write settings to save expanded states of the pools
+ */
+void MediaList::writeExpandedSettings()
+{
+   if (m_topItem) {
+      QSettings settings(m_console->m_dir->name(), "bat");
+      settings.beginGroup("MediaListTreeExpanded");
+      int childcount = m_topItem->childCount();
+      for (int cnt=0; cnt<childcount; cnt++) {
+         QTreeWidgetItem *poolitem = m_topItem->child(cnt);
+         settings.setValue(poolitem->text(0), poolitem->isExpanded());
+      }
+      settings.endGroup();
+   }
+}