]> git.sur5r.net Git - bacula/bacula/blobdiff - bacula/src/qt-console/storage/content.cpp
Change copyright as per agreement with FSFE
[bacula/bacula] / bacula / src / qt-console / storage / content.cpp
index 8c42aedd488d39d5b765d79afc17fa7d9e6f4362..f8e937dcfcfe22578432a24ff26c04af6c37188f 100644 (file)
@@ -1,29 +1,20 @@
 /*
-   Bacula® - The Network Backup Solution
-
-   Copyright (C) 2007-2009 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 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
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-   General Public License for more details.
-
-   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.
-
-   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.
+   Bacula(R) - The Network Backup Solution
+
+   Copyright (C) 2000-2016 Kern Sibbald
+
+   The original author of Bacula is Kern Sibbald, with contributions
+   from many others, a complete list can be found in the file AUTHORS.
+
+   You may use this file and others of this release according to the
+   license defined in the LICENSE file, which includes the Affero General
+   Public License, v3.0 ("AGPLv3") and some additional permissions and
+   terms pursuant to its AGPLv3 Section 7.
+
+   This notice must be preserved when any source code is 
+   conveyed and/or propagated.
+
+   Bacula(R) is a registered trademark of Kern Sibbald.
 */
  
 #include "bat.h"
 #include <QMenu>
 #include "content.h"
 #include "label/label.h"
+#include "mediainfo/mediainfo.h"
 #include "mount/mount.h"
 #include "util/fmtwidgetitem.h"
 #include "status/storstat.h"
 
-Content::Content(QString storage)
+// 
+// TODO: List tray
+//       List drives in autochanger
+//       use user selection to add slot= argument
+// 
+
+Content::Content(QString storage, QTreeWidgetItem *parentWidget) : Pages()
 {
    setupUi(this);
-   pgInitialize(tr("Storage Content"));
+   pgInitialize(storage, parentWidget);
    QTreeWidgetItem* thisitem = mainWin->getFromHash(this);
    thisitem->setIcon(0,QIcon(QString::fromUtf8(":images/package-x-generic.png")));
 
    m_populated = false;
    m_firstpopulation = true;
    m_checkcurwidget = true;
-   m_closeable = true;
    m_currentStorage = storage;
 
+   connect(pbUpdate, SIGNAL(clicked()), this,
+           SLOT(consoleUpdateSlots()));
+
+   connect(pbLabel, SIGNAL(clicked()), this,
+           SLOT(consoleLabelStorage()));
+
+   connect(pbMount, SIGNAL(clicked()), this,
+           SLOT(consoleMountStorage()));
+
+   connect(pbUnmount, SIGNAL(clicked()), this,
+           SLOT(consoleUnMountStorage()));
+
+   connect(pbStatus, SIGNAL(clicked()), this,
+           SLOT(statusStorageWindow()));
+
+   connect(pbRelease, SIGNAL(clicked()), this,
+           SLOT(consoleRelease()));
+
+   connect(tableContent, SIGNAL(itemDoubleClicked(QTableWidgetItem*)), this,
+           SLOT(showMediaInfo(QTableWidgetItem *)));
+
    dockPage();
    setCurrent();
 }
 
+
+/*
+ * Subroutine to call class to show the log in the database from that job
+ */
+void Content::showMediaInfo(QTableWidgetItem * item)
+{
+   QTreeWidgetItem* pageSelectorTreeWidgetItem = mainWin->getFromHash(this);
+   int row = item->row();
+   QString vol = tableContent->item(row, 1)->text();
+   if (vol != "") {
+      new MediaInfo(pageSelectorTreeWidgetItem, vol);
+   }
+}
+
+void table_get_selection(QTableWidget *table, QString &sel)
+{
+   QTableWidgetItem *item;
+   int current;
+
+   /* The QT selection returns each cell, so you
+    * have x times the same row number...
+    * We take only one instance
+    */
+   int s = table->rowCount();
+   if (s == 0) {
+      /* No selection?? */
+      return;
+   }
+   bool *tab = (bool *)malloc(s * sizeof(bool));
+   memset(tab, 0, s); 
+
+   foreach (item, table->selectedItems()) {
+      current = item->row();
+      tab[current]=true;
+   }
+
+   sel += "=";
+
+   for(int i=0; i<s; i++) {
+      if (tab[i]) {
+         sel += table->item(i, 0)->text();
+         sel += ",";
+      }
+   }
+   sel.chop(1);                 // remove trailing , or useless =
+   free(tab);
+}
+
+/* Label Media populating current storage by default */
+void Content::consoleLabelStorage()
+{
+   QString sel;
+   table_get_selection(tableContent, sel);
+   if (sel == "") {
+      new labelPage(m_currentStorage);
+   } else {
+      QString cmd = "label barcodes slots";
+      cmd += sel;
+      cmd += " storage=" + m_currentStorage;
+      consoleCommand(cmd);
+   }
+}
+
+/* Mount currently selected storage */
+void Content::consoleMountStorage()
+{
+   setConsoleCurrent();
+   /* if this storage is an autochanger, lets ask for the slot */
+   new mountDialog(m_console, m_currentStorage);
+}
+
+/* Unmount Currently selected storage */
+void Content::consoleUnMountStorage()
+{
+   QString cmd("umount storage=");
+   cmd += m_currentStorage;
+   consoleCommand(cmd);
+}
+
+void Content::statusStorageWindow()
+{
+   /* if one exists, then just set it current */
+   bool found = false;
+   foreach(Pages *page, mainWin->m_pagehash) {
+      if (mainWin->currentConsole() == page->console()) {
+         if (page->name() == tr("Storage Status %1").arg(m_currentStorage)) {
+            found = true;
+            page->setCurrent();
+         }
+      }
+   }
+   if (!found) {
+      QTreeWidgetItem *parentItem = mainWin->getFromHash(this);
+      new StorStat(m_currentStorage, parentItem);
+   }
+}
+
 /*
  * The main meat of the class!!  The function that querries the director and 
  * creates the widgets with appropriate values.
@@ -59,7 +174,7 @@ Content::Content(QString storage)
 void Content::populateContent()
 {
    char buf[200];
-   time_t t;
+   time_t tim;
    struct tm tm;
 
    QStringList results_all;
@@ -67,25 +182,42 @@ void Content::populateContent()
    m_console->dir_cmd(cmd, results_all);
 
    Freeze frz(*tableContent); /* disable updating*/
+   Freeze frz2(*tableTray);
+   Freeze frz3(*tableDrive);
+
    tableContent->clearContents();
+   tableTray->clearContents();
+   tableTray->clearContents();
 
-   // take only valid records
-   QStringList results = results_all.filter(QRegExp("^[0-9]+\\|"));
+   // take only valid records, TODO: Add D to get drive status
+   QStringList results = results_all.filter(QRegExp("^[IS]\\|[0-9]+\\|"));
    tableContent->setRowCount(results.size());
 
+   QStringList io_results = results_all.filter(QRegExp("^I\\|[0-9]+\\|"));
+   tableTray->setRowCount(io_results.size());
+
    QString resultline;
    QStringList fieldlist;
-   int row = 0;
+   int row = 0, row_io=0;
 
    foreach (resultline, results) {
       fieldlist = resultline.split("|");
-      if (fieldlist.size() < 9)
+      if (fieldlist.size() < 10) {
+         Pmsg1(0, "Discarding %s\n", resultline.data());
          continue; /* some fields missing, ignore row */
+      }
 
       int index=0;
       QStringListIterator fld(fieldlist);
       TableItemFormatter slotitem(*tableContent, row);
 
+      /* Slot type */
+      if (fld.next() == "I") {
+         TableItemFormatter ioitem(*tableTray, row_io++);
+         ioitem.setNumericFld(0, fieldlist[1]);
+         ioitem.setTextFld(1, fieldlist[3]);
+      }
+
       /* Slot */
       slotitem.setNumericFld(index++, fld.next()); 
 
@@ -107,16 +239,16 @@ void Content::populateContent()
          /* Pool */
          slotitem.setTextFld(index++, fld.next());
          
-         t = fld.next().toInt();
-         if (t > 0) {
+         tim = fld.next().toInt();
+         if (tim > 0) {
             /* LastW */
-            localtime_r(&t, &tm);
+            localtime_r(&tim, &tm);
             strftime(buf, sizeof(buf), "%Y-%m-%d %H:%M:%S", &tm);
             slotitem.setTextFld(index++, QString(buf));
             
             /* Expire */
-            t = fld.next().toInt();
-            localtime_r(&t, &tm);
+            tim = fld.next().toInt();
+            localtime_r(&tim, &tm);
             strftime(buf, sizeof(buf), "%Y-%m-%d %H:%M:%S", &tm);
             slotitem.setTextFld(index++, QString(buf));
          }
@@ -131,21 +263,44 @@ void Content::populateContent()
    tableContent->resizeColumnsToContents();
    tableContent->resizeRowsToContents();
 
-   /* make read only */
-   int rcnt = tableContent->rowCount();
-   int ccnt = tableContent->columnCount();
-   for(int r=0; r < rcnt; r++) {
-      for(int c=0; c < ccnt; c++) {
-         QTableWidgetItem* item = tableContent->item(r, c);
-         if (item) {
-            item->setFlags(Qt::ItemFlags(item->flags() & (~Qt::ItemIsEditable)));
-         }
-      }
-   }
+   tableContent->setEditTriggers(QAbstractItemView::NoEditTriggers);
    m_populated = true;
 
    tableTray->verticalHeader()->hide();
+   tableTray->setEditTriggers(QAbstractItemView::NoEditTriggers);
+
    tableDrive->verticalHeader()->hide();
+   /* Get count of rows needed (Drives) */
+   QStringList drives = results_all.filter(QRegExp("^D\\|[0-9]+\\|"));
+   /* Ensure we have sufficient rows for Drive display */
+   tableDrive->setRowCount(drives.size()); 
+   row = 0;
+   foreach (resultline, drives) {
+      fieldlist = resultline.split("|");
+      if (fieldlist.size() < 4) { 
+         continue; /* some fields missing, ignore row */
+      } 
+      int index=0;
+      QStringListIterator fld(fieldlist);
+      TableItemFormatter slotitem(*tableDrive, row);
+
+      /* Drive type */
+      fld.next();
+
+      /* Number */
+      slotitem.setNumericFld(index++, fld.next()); 
+
+      /* Slot */
+      fld.next();
+      
+      /* Volume */
+      slotitem.setTextFld(index++, fld.next());
+         
+      row++;
+   }
+
+   tableDrive->resizeRowsToContents();
+   tableDrive->setEditTriggers(QAbstractItemView::NoEditTriggers);
 }
 
 /*
@@ -158,66 +313,27 @@ void Content::currentStackItem()
    }
 }
 
-/*
- *  Functions to respond to local context sensitive menu sending console
- *  commands If I could figure out how to make these one function passing a
- *  string, Yaaaaaa
- */
-void Content::consoleStatusStorage()
-{
-   QString cmd("status storage=");
-   cmd += m_currentStorage;
-   consoleCommand(cmd);
-}
-
-/* Label Media populating current storage by default */
-void Content::consoleLabelStorage()
-{
-   new labelPage(m_currentStorage);
-}
-
 void Content::treeItemChanged(QTreeWidgetItem *, QTreeWidgetItem *)
 {
 
 }
 
-/* Mount currently selected storage */
-void Content::consoleMountStorage()
-{
-   if (m_currentAutoChanger == 0){
-      /* no autochanger, just execute the command in the console */
-      QString cmd("mount storage=");
-      cmd += m_currentStorage;
-      consoleCommand(cmd);
-   } else {
-      setConsoleCurrent();
-      /* if this storage is an autochanger, lets ask for the slot */
-      new mountDialog(m_console, m_currentStorage);
-   }
-}
-
-/* Unmount Currently selected storage */
-void Content::consoleUnMountStorage()
-{
-   QString cmd("umount storage=");
-   cmd += m_currentStorage;
-   consoleCommand(cmd);
-}
-
 /* Update Slots */
 void Content::consoleUpdateSlots()
 {
-   QString cmd("update slots storage=");
-   cmd += m_currentStorage;
-   consoleCommand(cmd);
-}
+   QString sel = "";
+   table_get_selection(tableContent, sel);
+   
+   QString cmd("update slots");
+   if (sel != "") {
+      cmd += sel;
+   }
+   cmd += " drive=0 storage=" + m_currentStorage;
+
+   Pmsg1(0, "cmd=%s\n", cmd.toUtf8().data());
 
-/* Update Slots Scan*/
-void Content::consoleUpdateSlotsScan()
-{
-   QString cmd("update slots scan storage=");
-   cmd += m_currentStorage;
    consoleCommand(cmd);
+   populateContent();
 }
 
 /* Release a tape in the drive */
@@ -227,24 +343,3 @@ void Content::consoleRelease()
    cmd += m_currentStorage;
    consoleCommand(cmd);
 }
-
-/*
- *  Open a status storage window
- */
-void Content::statusStorageWindow()
-{
-   /* if one exists, then just set it current */
-   bool found = false;
-   foreach(Pages *page, mainWin->m_pagehash) {
-      if (mainWin->currentConsole() == page->console()) {
-         if (page->name() == tr("Storage Status %1").arg(m_currentStorage)) {
-            found = true;
-            page->setCurrent();
-         }
-      }
-   }
-   if (!found) {
-      QTreeWidgetItem *parentItem = mainWin->getFromHash(this);
-      new StorStat(m_currentStorage, parentItem);
-   }
-}