]> git.sur5r.net Git - bacula/bacula/blobdiff - bacula/src/qt-console/clients/clients.cpp
ebl Add more tests in migration time test (like for copy time test)
[bacula/bacula] / bacula / src / qt-console / clients / clients.cpp
index af3b0614c3178377ef5b742238194b6d6e741bc1..ff30579a8240665625193e58caf015543a997959 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: client.cpp 4230 2007-02-21 20:07:37Z kerns $
+ *   Version $Id$
  *
  *  Clients Class
  *
 #include <QMenu>
 #include "bat.h"
 #include "clients/clients.h"
+#include "run/run.h"
+#include "status/clientstat.h"
+#include "util/fmtwidgetitem.h"
 
-Clients::Clients(QStackedWidget *parent, Console *console)
+Clients::Clients()
 {
    setupUi(this);
+   m_name = tr("Clients");
+   pgInitialize();
+   QTreeWidgetItem* thisitem = mainWin->getFromHash(this);
+   thisitem->setIcon(0,QIcon(QString::fromUtf8(":images/network-server.png")));
 
-   /* mp_treeWidget, Storage Tree Tree Widget inherited from ui_client.h */
-   mp_console = console;
-   m_parent = parent;
+   /* tableWidget, Storage Tree Tree Widget inherited from ui_client.h */
    m_populated = false;
    m_checkcurwidget = true;
    m_closeable = false;
+   /* add context sensitive menu items specific to this classto the page
+    * selector tree. m_contextActions is QList of QActions */
+   m_contextActions.append(actionRefreshClients);
+   createContextMenu();
+   dockPage();
 }
 
 Clients::~Clients()
@@ -60,67 +70,94 @@ Clients::~Clients()
  * The main meat of the class!!  The function that querries the director and 
  * creates the widgets with appropriate values.
  */
-void Clients::populateTree()
+void Clients::populateTable()
 {
-   QTreeWidgetItem *clientItem, *topItem;
+   if (!m_console->preventInUseConnect())
+      return;
+   m_populated = true;
 
-   m_checkcurwidget = false;
-   mp_treeWidget->clear();
-   m_checkcurwidget = true;
+   QBrush blackBrush(Qt::black);
 
-   QStringList headerlist = (QStringList() << "Client Name" << "File Retention"
-       << "Job Retention" << "AutoPrune" << "ClientId" << "Uname" );
+   QStringList headerlist = (QStringList() << tr("Client Name") << tr("File Retention")
+       << tr("Job Retention") << tr("AutoPrune") << tr("ClientId") << tr("Uname") );
 
-   topItem = new QTreeWidgetItem(mp_treeWidget);
-   topItem->setText(0, "Clients");
-   topItem->setData(0, Qt::UserRole, 0);
-   topItem->setExpanded(true);
+   int sortcol = headerlist.indexOf(tr("Client Name"));
+   Qt::SortOrder sortord = Qt::AscendingOrder;
+   if (tableWidget->rowCount()) {
+      sortcol = tableWidget->horizontalHeader()->sortIndicatorSection();
+      sortord = tableWidget->horizontalHeader()->sortIndicatorOrder();
+   }
 
-   mp_treeWidget->setColumnCount(headerlist.count());
-   mp_treeWidget->setHeaderLabels(headerlist);
-   /* This could be a log item */
-   //printf("In Clients::populateTree()\n");
+   m_checkcurwidget = false;
+   tableWidget->clear();
+   m_checkcurwidget = true;
 
-   foreach(QString clientName, mp_console->client_list){
-      clientItem = new QTreeWidgetItem(topItem);
-      clientItem->setText(0, clientName);
-      clientItem->setData(0, Qt::UserRole, 1);
-      clientItem->setExpanded(true);
+   tableWidget->setColumnCount(headerlist.count());
+   tableWidget->setHorizontalHeaderLabels(headerlist);
+   tableWidget->horizontalHeader()->setHighlightSections(false);
+   tableWidget->setRowCount(m_console->client_list.count());
+   tableWidget->verticalHeader()->hide();
+   tableWidget->setSelectionBehavior(QAbstractItemView::SelectRows);
+   tableWidget->setSelectionMode(QAbstractItemView::SingleSelection);
+   tableWidget->setSortingEnabled(false); /* rows move on insert if sorting enabled */
+   int row = 0;
 
+   foreach (QString clientName, m_console->client_list){
       /* Set up query QString and header QStringList */
       QString query("");
-      query += "SELECT FileRetention, JobRetention, AutoPrune, ClientId, Uname"
-           " FROM client"
+      query += "SELECT Name, FileRetention, JobRetention, AutoPrune, ClientId, Uname"
+           " FROM Client"
            " WHERE ";
       query += " Name='" + clientName + "'";
-      query += " ORDER BY Name";
+      query += " ORDER BY ClientId LIMIT 1";
 
       QStringList results;
       /* This could be a log item */
-      //printf("Clients query cmd : %s\n",query.toUtf8().data());
-      if (mp_console->sql_cmd(query, results)) {
+      if (mainWin->m_sqlDebug) {
+         Pmsg1(000, "Clients query cmd : %s\n",query.toUtf8().data());
+      }
+      if (m_console->sql_cmd(query, results)) {
          int resultCount = results.count();
-         if (resultCount == 1){
-            QString resultline;
-            QString field;
-            QStringList fieldlist;
-            /* there will only be one of these */
-            foreach (resultline, results) {
-               fieldlist = resultline.split("\t");
-               int index = 0;
-               /* Iterate through fields in the record */
-               foreach (field, fieldlist) {
-                  field = field.trimmed();  /* strip leading & trailing spaces */
-                  clientItem->setData(index+1, Qt::UserRole, 1);
-                  /* Put media fields under the pool tree item */
-                  clientItem->setData(index+1, Qt::UserRole, 1);
-                  clientItem->setText(index+1, field);
-                  index++;
-               }
-            }
+         if (resultCount){
+            /* only use the last one */
+            QString resultline = results[resultCount - 1];
+            QStringList fieldlist = resultline.split("\t");
+
+           TableItemFormatter item(*tableWidget, row);
+
+           /* Iterate through fields in the record */
+           QStringListIterator fld(fieldlist);
+           int col = 0;
+
+           /* name */
+           item.setTextFld(col++, fld.next());
+
+           /* file retention */
+           item.setDurationFld(col++, fld.next());
+
+           /* job retention */
+           item.setDurationFld(col++, fld.next());
+
+           /* autoprune */
+           item.setBoolFld(col++, fld.next());
+
+           /* client id */
+           item.setNumericFld(col++, fld.next());
+
+           /* uname */
+           item.setTextFld(col++, fld.next());
+
          }
       }
+      row ++;
    }
+   /* set default sorting */
+   tableWidget->sortByColumn(sortcol, sortord);
+   tableWidget->setSortingEnabled(true);
+   
+   /* Resize rows and columns */
+   tableWidget->resizeColumnsToContents();
+   tableWidget->resizeRowsToContents();
 }
 
 /*
@@ -130,9 +167,7 @@ void Clients::populateTree()
 void Clients::PgSeltreeWidgetClicked()
 {
    if(!m_populated) {
-      populateTree();
-      createContextMenu();
-      m_populated=true;
+      populateTable();
    }
 }
 
@@ -140,24 +175,31 @@ void Clients::PgSeltreeWidgetClicked()
  * Added to set the context menu policy based on currently active treeWidgetItem
  * signaled by currentItemChanged
  */
-void Clients::treeItemChanged(QTreeWidgetItem *currentwidgetitem, QTreeWidgetItem *previouswidgetitem )
+void Clients::tableItemChanged(QTableWidgetItem *currentwidgetitem, QTableWidgetItem *previouswidgetitem )
 {
    /* m_checkcurwidget checks to see if this is during a refresh, which will segfault */
    if (m_checkcurwidget) {
+      int currentRow = currentwidgetitem->row();
+      QTableWidgetItem *currentrowzeroitem = tableWidget->item(currentRow, 0);
+      m_currentlyselected = currentrowzeroitem->text();
+
       /* The Previous item */
       if (previouswidgetitem) { /* avoid a segfault if first time */
-         int treedepth = previouswidgetitem->data(0, Qt::UserRole).toInt();
-         if (treedepth == 1){
-//            mp_treeWidget->removeAction(actionEditVolume);
-         }
+         tableWidget->removeAction(actionListJobsofClient);
+         tableWidget->removeAction(actionStatusClientInConsole);
+         tableWidget->removeAction(actionStatusClientWindow);
+         tableWidget->removeAction(actionPurgeJobs);
+         tableWidget->removeAction(actionPrune);
       }
 
-      int treedepth = currentwidgetitem->data(0, Qt::UserRole).toInt();
-      if (treedepth == 1){
+      if (m_currentlyselected.length() != 0) {
          /* set a hold variable to the client name in case the context sensitive
           * menu is used */
-         m_currentlyselected=currentwidgetitem->text(1);
-//         mp_treeWidget->addAction(actionEditVolume);
+         tableWidget->addAction(actionListJobsofClient);
+         tableWidget->addAction(actionStatusClientInConsole);
+         tableWidget->addAction(actionStatusClientWindow);
+         tableWidget->addAction(actionPurgeJobs);
+         tableWidget->addAction(actionPrune);
       }
    }
 }
@@ -169,14 +211,47 @@ void Clients::treeItemChanged(QTreeWidgetItem *currentwidgetitem, QTreeWidgetIte
  */
 void Clients::createContextMenu()
 {
-   mp_treeWidget->setContextMenuPolicy(Qt::ActionsContextMenu);
-   mp_treeWidget->addAction(actionRefreshClients);
-   connect(mp_treeWidget, SIGNAL(
-           currentItemChanged(QTreeWidgetItem *, QTreeWidgetItem *)),
-           this, SLOT(treeItemChanged(QTreeWidgetItem *, QTreeWidgetItem *)));
+   tableWidget->setContextMenuPolicy(Qt::ActionsContextMenu);
+   tableWidget->addAction(actionRefreshClients);
+   /* for the tableItemChanged to maintain m_currentJob */
+   connect(tableWidget, SIGNAL(
+           currentItemChanged(QTableWidgetItem *, QTableWidgetItem *)),
+           this, SLOT(tableItemChanged(QTableWidgetItem *, QTableWidgetItem *)));
+
    /* connect to the action specific to this pages class */
    connect(actionRefreshClients, SIGNAL(triggered()), this,
-                SLOT(populateTree()));
+                SLOT(populateTable()));
+   connect(actionListJobsofClient, SIGNAL(triggered()), this,
+                SLOT(showJobs()));
+   connect(actionStatusClientInConsole, SIGNAL(triggered()), this,
+                SLOT(consoleStatusClient()));
+   connect(actionStatusClientWindow, SIGNAL(triggered()), this,
+                SLOT(statusClientWindow()));
+   connect(actionPurgeJobs, SIGNAL(triggered()), this,
+                SLOT(consolePurgeJobs()));
+   connect(actionPrune, SIGNAL(triggered()), this,
+                SLOT(prune()));
+}
+
+/*
+ * Function responding to actionListJobsofClient which calls mainwin function
+ * to create a window of a list of jobs of this client.
+ */
+void Clients::showJobs()
+{
+   QTreeWidgetItem *parentItem = mainWin->getFromHash(this);
+   mainWin->createPageJobList("", m_currentlyselected, "", "", parentItem);
+}
+
+/*
+ * Function responding to actionListJobsofClient which calls mainwin function
+ * to create a window of a list of jobs of this client.
+ */
+void Clients::consoleStatusClient()
+{
+   QString cmd("status client=");
+   cmd += m_currentlyselected;
+   consoleCommand(cmd);
 }
 
 /*
@@ -185,13 +260,50 @@ void Clients::createContextMenu()
 void Clients::currentStackItem()
 {
    if(!m_populated) {
-      populateTree();
-      /* add context sensitive menu items specific to this classto the page
-       * selector tree. m_m_contextActions is QList of QActions, so this is 
-       * only done once with the first population. */
-      m_contextActions.append(actionRefreshClients);
-      /* Create the context menu for the client tree */
-      createContextMenu();
-      m_populated=true;
+      populateTable();
+      /* Create the context menu for the client table */
    }
 }
+
+/*
+ * Function responding to actionPurgeJobs 
+ */
+void Clients::consolePurgeJobs()
+{
+   if (QMessageBox::warning(this, "Bat",
+      tr("Are you sure you want to purge all jobs of client \"%1\" ?\n"
+"The Purge command will delete associated Catalog database records from Jobs and"
+" Volumes without considering the retention period. Purge  works only on the"
+" Catalog database and does not affect data written to Volumes. This command can"
+" be dangerous because you can delete catalog records associated with current"
+" backups of files, and we recommend that you do not use it unless you know what"
+" you are doing.\n\n"
+" Is there any way I can get you to click Cancel here?  You really don't want to do"
+" this\n\n"
+        "Press OK to proceed with the purge operation?").arg(m_currentlyselected),
+        QMessageBox::Ok | QMessageBox::Cancel,
+        QMessageBox::Cancel)
+      == QMessageBox::Cancel) { return; }
+
+   QString cmd("purge jobs client=");
+   cmd += m_currentlyselected;
+   consoleCommand(cmd);
+}
+
+/*
+ * Function responding to actionPrune
+ */
+void Clients::prune()
+{
+   new prunePage("", m_currentlyselected);
+}
+
+/*
+ * Function responding to action to create new client status window
+ */
+void Clients::statusClientWindow()
+{
+   QTreeWidgetItem *parentItem = mainWin->getFromHash(this);
+   new ClientStat(m_currentlyselected, parentItem);
+}
+