]> git.sur5r.net Git - bacula/bacula/blobdiff - bacula/src/qt-console/restore/restoretree.cpp
Backport from Bacula Enterprise
[bacula/bacula] / bacula / src / qt-console / restore / restoretree.cpp
index b410d3cf7d4c65a915b4f38489b3f8165beb2092..0bc9172d3de38cfa243911a3743a686829bcb023 100644 (file)
@@ -1,33 +1,24 @@
 /*
-   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-2015 Kern Sibbald
+   Copyright (C) 2007-2010 Free Software Foundation Europe e.V.
+
+   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.
 */
  
 /*
- *   Version $Id$
  *
  *  Restore Class 
  *
@@ -39,7 +30,7 @@
 #include "restoretree.h"
 #include "pages.h"
 
-restoreTree::restoreTree()
+restoreTree::restoreTree() : Pages()
 {
    setupUi(this);
    m_name = tr("Version Browser");
@@ -47,10 +38,8 @@ restoreTree::restoreTree()
    QTreeWidgetItem* thisitem = mainWin->getFromHash(this);
    thisitem->setIcon(0, QIcon(QString::fromUtf8(":images/browse.png")));
 
-   m_closeable = true;
    m_populated = false;
 
-   dockPage();
    m_debugCnt = 0;
    m_debugTrap = true;
 
@@ -64,9 +53,9 @@ restoreTree::restoreTree()
    area->setObjectName(QString::fromUtf8("area"));
    area->setWidget(widget);
    area->setWidgetResizable(true);
-   m_splitter->addWidget(splitter);
    m_splitter->addWidget(area);
-   splitter->setCollapsible(0, false);
+   m_splitter->addWidget(splitter);
+   splitter->setChildrenCollapsible(false);
 
    gridLayout->addWidget(m_splitter, 0, 0, 1, 1);
 
@@ -83,6 +72,8 @@ restoreTree::restoreTree()
    daysSpinBox->setValue(mainWin->m_daysLimitVal);
    readSettings();
    m_nullFileNameId = -1;
+   dockPage();
+   setCurrent();
 }
 
 restoreTree::~restoreTree()
@@ -233,8 +224,7 @@ void restoreTree::populateDirectoryTree()
          cmd += " WHERE File.FilenameId=" + QString("%1").arg(m_nullFileNameId);
       else
          cmd += " WHERE File.FilenameId IN (SELECT FilenameId FROM Filename WHERE Name='')";
-      cmd += " AND File.Jobid IN (" + m_checkedJobs + ")"
-         " ORDER BY Path";
+      cmd += " AND File.Jobid IN (" + m_checkedJobs + ")";
       if (mainWin->m_sqlDebug)
          Pmsg1(000, "Query cmd : %s\n", cmd.toUtf8().data());
       prBar1->setValue(ontask++);
@@ -256,16 +246,15 @@ void restoreTree::populateDirectoryTree()
          if (mainWin->m_miscDebug)
             Pmsg1(000, "Done with query %i results\n", results.count());
          QStringList fieldlist;
-         foreach(QString resultline, results) {
+         foreach(const QString &resultline, results) {
             /* Update progress bar periodically */
             if ((++m_debugCnt && 0x3FF) == 0) {
                prBar2->setValue(m_debugCnt);
             }
             fieldlist = resultline.split("\t");
             int fieldcnt = 0;
-            QString field;
             /* Iterate through fields in the record */
-            foreach (field, fieldlist) {
+            foreach (const QString &field, fieldlist) {
                if (fieldcnt == 0 ) {
                   parseDirectory(field);
                } else if (fieldcnt == 1) {
@@ -277,6 +266,8 @@ void restoreTree::populateDirectoryTree()
                fieldcnt += 1;
             }
          }
+      } else {
+         return;
       }
    } else {
      QMessageBox::warning(this, "Bat",
@@ -322,141 +313,47 @@ void restoreTree::setJobsCheckedList()
  * Function to parse a directory into all possible subdirectories, then add to
  * The tree.
  */
-void restoreTree::parseDirectory(QString &dir_in)
+void restoreTree::parseDirectory(const QString &dir_in)
 {
-   /* m_debugTrap is to only print debugs for a few occurennces of calling parseDirectory
-    * instead of printing out what could potentially a whole bunch */
-   if (m_debugCnt > 2)
-      m_debugTrap = false;
-   /* Truncate everything after the last / */
-   if (dir_in.right(1) != "/") {
-      dir_in.truncate(dir_in.lastIndexOf("/") + 1);
-   }
-   if ((mainWin->m_miscDebug) && (m_debugTrap))
-      Pmsg1(000, "parsing %s\n", dir_in.toUtf8().data());
-
-   /* split and add if not in yet */
-   QString direct, path;
-   int index;
-   bool done = false;
-   QStringList pathAfter, dirAfter;
-   /* start from the end, turn /etc/somedir/subdir/ into /etc/somedir and subdir/ 
-    * if not added into tree, then try /etc/ and somedir/ if not added, then try
-    * / and etc/ .  That should succeed, then add the ones that failed in reverse */
-   while (((index = dir_in.lastIndexOf("/", -2)) != -1) && (!done)) {
-      direct = path = dir_in;
-      path.replace(index+1, dir_in.length()-index-1,"");
-      direct.replace(0, index+1, "");
-      if ((mainWin->m_miscDebug) && (m_debugTrap)) {
-         QString msg = QString("length = \"%1\" index = \"%2\" Adding \"%3\" \"%4\"\n")
-                    .arg(dir_in.length()).arg(index).arg(path).arg(direct);
-         Pmsg0(000, msg.toUtf8().data());
-      }
-      if (addDirectory(path, direct)) { done = true; }
-      else {
-         if ((mainWin->m_miscDebug) && (m_debugTrap)) {
-            Pmsg0(000, "Saving for later\n");
-         }
-         pathAfter.prepend(path);
-         dirAfter.prepend(direct);
-      }
-      dir_in = path;
-   }
-
-   for (int k=0; k<pathAfter.count(); k++) {
-      if (addDirectory(pathAfter[k], dirAfter[k])) {
-         if ((mainWin->m_miscDebug) && (m_debugTrap))
-            Pmsg2(000, "Adding After %s %s\n", pathAfter[k].toUtf8().data(), dirAfter[k].toUtf8().data());
-      } else {
-         if ((mainWin->m_miscDebug) && (m_debugTrap))
-            Pmsg2(000, "Error Adding %s %s\n", pathAfter[k].toUtf8().data(), dirAfter[k].toUtf8().data());
-      }
+   // bail out if already processed
+   if (m_dirPaths.contains(dir_in))
+     return;
+   // search for parent...
+   int pos=dir_in.lastIndexOf("/",-2);
+
+   if (pos != -1)
+   {
+     QString parent=dir_in.left(pos+1);
+     QString subdir=dir_in.mid(pos+1);
+
+     QTreeWidgetItem *item       = NULL;
+     QTreeWidgetItem *parentItem = m_dirPaths.value(parent);
+     
+     if (parentItem==0) {
+       // recurse to build parent...
+       parseDirectory(parent);
+       parentItem = m_dirPaths.value(parent);
+     }
+
+     /* new directories to add */
+     item = new QTreeWidgetItem(parentItem);
+     item->setText(0, subdir);
+     item->setData(0, Qt::UserRole, QVariant(dir_in));
+     item->setCheckState(0, Qt::Unchecked);
+     /* Store the current state of the check status in column 1, which at
+      * this point has no text*/
+     item->setData(1, Qt::UserRole, QVariant(Qt::Unchecked));
+     m_dirPaths.insert(dir_in,item);
    }
-}
-
-
-/*
- * Function called from fill directory when a directory is found to see if this
- * directory exists in the directory pane and then add it to the directory pane
- */
-bool restoreTree::addDirectory(QString &m_cwd, QString &newdirr)
-{
-   QString newdir = newdirr;
-   QString fullPath = m_cwd + newdirr;
-   bool ok = true, added = false;
-
-   if ((mainWin->m_miscDebug) && (m_debugTrap)) {
-      QString msg = QString("In addDirectory cwd \"%1\" newdir \"%2\"\n")
-                    .arg(m_cwd)
-                    .arg(newdir);
-      Pmsg0(000, msg.toUtf8().data());
-   }
-
-   if (!m_slashTrap) {
-      /* add unix '/' directory first */
-      if (m_dirPaths.empty() && !isWin32Path(fullPath)) {
-         m_slashTrap = true;
-         QTreeWidgetItem *item = new QTreeWidgetItem(directoryTree);
-         QString text("/");
-         item->setText(0, text.toUtf8().data());
-         item->setData(0, Qt::UserRole, QVariant(text));
-         item->setData(1, Qt::UserRole, QVariant(Qt::Unchecked));
-         item->setIcon(0, QIcon(QString::fromUtf8(":images/folder.png")));
-         if ((mainWin->m_miscDebug) && (m_debugTrap)) {
-            Pmsg1(000, "Pre Inserting %s\n", text.toUtf8().data());
-         }
-         m_dirPaths.insert(text, item);
-      }
-      /* no need to check for windows drive if unix */
-      if (isWin32Path(m_cwd)) {
-         if (!m_dirPaths.contains(m_cwd)) {
-            if (m_cwd.count('/') > 1) { return false; }
-            /* this is a windows drive add the base widget */
-            QTreeWidgetItem *item = new QTreeWidgetItem(directoryTree);
-            item->setText(0, m_cwd);
-            item->setData(0, Qt::UserRole, QVariant(fullPath));
-            item->setData(1, Qt::UserRole, QVariant(Qt::Unchecked));
-            item->setIcon(0, QIcon(QString::fromUtf8(":images/folder.png")));
-            if ((mainWin->m_miscDebug) && (m_debugTrap)) {
-               Pmsg0(000, "Added Base \"letter\":/\n");
-            }
-            m_dirPaths.insert(m_cwd, item);
-         }
-      }
-   }
-   /* is it already existent ?? */
-   if (!m_dirPaths.contains(fullPath)) {
-      QTreeWidgetItem *item = NULL;
-      QTreeWidgetItem *parent = m_dirPaths.value(m_cwd);
-      if (parent) {
-         /* new directories to add */
-         item = new QTreeWidgetItem(parent);
-         item->setText(0, newdir.toUtf8().data());
-         item->setData(0, Qt::UserRole, QVariant(fullPath));
-         item->setCheckState(0, Qt::Unchecked);
-         /* Store the current state of the check status in column 1, which at
-          * this point has no text*/
-         item->setData(1, Qt::UserRole, QVariant(Qt::Unchecked));
-      } else {
-         ok = false;
-         if ((mainWin->m_miscDebug) && (m_debugTrap)) {
-            QString msg = QString("In else of if parent cwd \"%1\" newdir \"%2\"\n")
-                 .arg(m_cwd)
-                 .arg(newdir);
-            Pmsg0(000, msg.toUtf8().data());
-         }
-      }
-      /* insert into hash */
-      if (ok) {
-         if ((mainWin->m_miscDebug) && (m_debugTrap)) {
-            Pmsg1(000, "Inserting %s\n", fullPath.toUtf8().data());
-         }
-         m_dirPaths.insert(fullPath, item);
-         added = true;
-      }
+   else
+   {
+     QTreeWidgetItem *item = new QTreeWidgetItem(directoryTree);
+     item->setText(0, dir_in);
+     item->setData(0, Qt::UserRole, QVariant(dir_in));
+     item->setData(1, Qt::UserRole, QVariant(Qt::Unchecked));
+     item->setIcon(0, QIcon(QString::fromUtf8(":images/folder.png")));
+     m_dirPaths.insert(dir_in,item);
    }
-   return added;
 }
 
 /*
@@ -533,10 +430,8 @@ void restoreTree::directoryCurrentItemChanged(QTreeWidgetItem *item, QTreeWidget
          " AND File.Jobid IN (" + m_checkedJobs + ")"
          " AND Filename.Name!=''"
          " ORDER BY FileName";
+      if (mainWin->m_sqlDebug) Pmsg1(000, "Query cmd : %s\n", cmd.toUtf8().data());
 
-      if (mainWin->m_sqlDebug) {
-         Pmsg1(000, "Query cmd : %s\n", cmd.toUtf8().data());
-      }
       QStringList results;
       if (m_console->sql_cmd(cmd, results)) {
       
@@ -559,6 +454,7 @@ void restoreTree::directoryCurrentItemChanged(QTreeWidgetItem *item, QTreeWidget
                 *  | Qt::ItemIsEnabled | Qt::ItemIsTristate; */
                tableItem->setForeground(blackBrush);
                /* Just in case a column ever gets added */
+               if (mainWin->m_sqlDebug) Pmsg1(000, "Column=%d\n", column);
                if (column == 0) {
                   Qt::ItemFlags flag = Qt::ItemIsUserCheckable | Qt::ItemIsEnabled | Qt::ItemIsTristate;
                   tableItem->setFlags(flag);
@@ -640,8 +536,7 @@ void restoreTree::fileCurrentItemChanged(QTableWidgetItem *currentFileTableItem,
          " AND Job.Jobid IN (" + m_checkedJobs + ")"
          " ORDER BY Job.EndTime DESC";
    
-      if (mainWin->m_sqlDebug)
-         Pmsg1(000, "Query cmd : %s\n", cmd.toUtf8().data());
+      if (mainWin->m_sqlDebug) Pmsg1(000, "Query cmd : %s\n", cmd.toUtf8().data());
       QStringList results;
       if (m_console->sql_cmd(cmd, results)) {
       
@@ -671,7 +566,7 @@ void restoreTree::fileCurrentItemChanged(QTableWidgetItem *currentFileTableItem,
                   tableItem->setForeground(blackBrush);
                   tableItem->setData(Qt::UserRole, QVariant(directory));
                   versionTable->setItem(row, column, tableItem);
-   
+                  if (mainWin->m_sqlDebug) Pmsg1(000, "Column=%d\n", column);
                   if (column == 0) {
                      Qt::ItemFlags flag = Qt::ItemIsUserCheckable | Qt::ItemIsEnabled | Qt::ItemIsTristate;
                      tableItem->setFlags(flag);
@@ -714,12 +609,12 @@ void restoreTree::writeSettings()
 void restoreTree::readSettings()
 {
    m_groupText = tr("RestoreTreePage");
-   m_splitText1 = "splitterSizes1_2";
-   m_splitText2 = "splitterSizes2_2";
+   m_splitText1 = "splitterSizes1_3";
+   m_splitText2 = "splitterSizes2_3";
    QSettings settings(m_console->m_dir->name(), "bat");
    settings.beginGroup(m_groupText);
-   m_splitter->restoreState(settings.value(m_splitText1).toByteArray());
-   splitter->restoreState(settings.value(m_splitText2).toByteArray());
+   if (settings.contains(m_splitText1)) { m_splitter->restoreState(settings.value(m_splitText1).toByteArray()); }
+   if (settings.contains(m_splitText2)) { splitter->restoreState(settings.value(m_splitText2).toByteArray()); }
    settings.endGroup();
 }
 
@@ -766,6 +661,7 @@ void restoreTree::populateJobTable()
       " INNER JOIN Client ON (Job.ClientId=Client.ClientId)"
       " INNER JOIN FileSet ON (Job.FileSetId=FileSet.FileSetId)"
       " WHERE"
+      " Job.JobStatus IN ('T','W') AND Job.Type='B' AND"
       " Client.Name='" + clientCombo->currentText() + "'";
    if ((jobCombo->currentIndex() >= 0) && (jobCombo->currentText() != tr("Any"))) {
       jobQuery += " AND Job.name = '" + jobCombo->currentText() + "'";
@@ -787,8 +683,8 @@ void restoreTree::populateJobTable()
       limit.setNum(limitSpinBox->value());
       jobQuery += " LIMIT " + limit;
    }
-   if (mainWin->m_sqlDebug)
-      Pmsg1(000, "Query cmd : %s\n", jobQuery.toUtf8().data());
+   if (mainWin->m_sqlDebug) Pmsg1(000, "Query cmd : %s\n", jobQuery.toUtf8().data());
+
 
    QStringList results;
    if (m_console->sql_cmd(jobQuery, results)) {
@@ -819,6 +715,7 @@ void restoreTree::populateJobTable()
                   tableItem->setFlags(0);
                   tableItem->setForeground(blackBrush);
                   jobTable->setItem(row, column, tableItem);
+                  if (mainWin->m_sqlDebug) Pmsg1(000, "Column=%d\n", column);
                   if (column == 0) {
                      bool ok;
                      int purged = fieldlist[purgedIndex].toInt(&ok, 10); 
@@ -1107,13 +1004,14 @@ void restoreTree::versionTableItemChanged(QTableWidgetItem *item)
 
    /* determine the default state */
    Qt::CheckState defState;
+   if (mainWin->m_sqlDebug) Pmsg1(000, "row=%d\n", row);
    if (row == 0) {
       defState = Qt::PartiallyChecked;
       if (fileState == Qt::Unchecked)
          defState = Qt::Unchecked;
-   }
-   else
+   } else {
       defState = Qt::Unchecked;
+   }
 
    /* determine if it is already in the versionExceptionHash */
    QString directory = directoryTree->currentItem()->data(0, Qt::UserRole).toString();
@@ -1146,7 +1044,7 @@ void restoreTree::versionTableItemChanged(QTableWidgetItem *item)
       m_versionExceptionHash.remove(fullPath);
    } else if (prevState != curState) {
       if (mainWin->m_rtVerTabICDebug) Pmsg2(000, "  THE STATE OF THE version Check has changed, Setting StateList[%i] to %i\n", row, curState);
-      if ((curState == Qt::Checked) || (curState == Qt::PartiallyChecked && row != 0)) {
+      if ((curState == Qt::Checked) || (curState == Qt::PartiallyChecked)) {
          if (mainWin->m_rtVerTabICDebug) Pmsg2(000, "Inserting into m_versionExceptionHash %s, %i\n", fullPath.toUtf8().data(), thisJobNum);
          m_versionExceptionHash.insert(fullPath, thisJobNum);
          if (fileState != Qt::Checked) {
@@ -1811,6 +1709,7 @@ int restoreTree::queryFileIndex(QString &fullPath, int jobId)
    int qfileIndex = 0;
    QString directory, fileName;
    int index = fullPath.lastIndexOf("/", -2);
+   if (mainWin->m_sqlDebug) Pmsg1(000, "Index=%d\n", index);
    if (index != -1) {
       directory = fileName = fullPath;
       directory.replace(index+1, fullPath.length()-index-1, "");
@@ -1833,7 +1732,6 @@ int restoreTree::queryFileIndex(QString &fullPath, int jobId)
              " AND Filename.Name='" + fileName + "'"
              " AND Job.Jobid='" + QString("%1").arg(jobId) + "'"
             " GROUP BY File.FileIndex";
-    
          if (mainWin->m_sqlDebug) Pmsg1(000, "Query cmd : %s\n", cmd.toUtf8().data());
          QStringList results;
          if (m_console->sql_cmd(cmd, results)) {
@@ -1855,5 +1753,14 @@ int restoreTree::queryFileIndex(QString &fullPath, int jobId)
          }
       }
    } /* if (index != -1) */
+   if (mainWin->m_sqlDebug) Pmsg1(000, "qfileIndex=%d\n", qfileIndex);
    return qfileIndex;
 }
+
+
+void restoreTree::PgSeltreeWidgetClicked()
+{
+   if (!isOnceDocked()) {
+      dockPage();
+   }
+}