]> git.sur5r.net Git - bacula/bacula/blobdiff - bacula/src/qt-console/console/console.cpp
dhb Cleaned up populatetree in medialist with foreaches.
[bacula/bacula] / bacula / src / qt-console / console / console.cpp
index 9048774c5b360443d90110c34a8f66769da1f8c0..ea299258804c978cc550723714dbf35a1f3f16fd 100644 (file)
@@ -1,7 +1,7 @@
 /*
    Bacula® - The Network Backup Solution
 
-   Copyright (C) 2000-2007 Free Software Foundation Europe e.V.
+   Copyright (C) 2007-2007 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.
    (FSFE), Fiduciary Program, Sumatrastrasse 25, 8006 Zürich,
    Switzerland, email:ftf@fsfeurope.org.
 */
 /*
  *   Version $Id$
  *
  *  Console Class
  *
- *   Kern Sibbald, January MMVI
+ *   Kern Sibbald, January MMVII
  *
  */ 
 
 Console::Console(QStackedWidget *parent)
 {
    QFont font;
-   QTreeWidgetItem *item, *topItem;
-   QTreeWidget *treeWidget = mainWin->treeWidget;
+   m_parent=parent;
+   (void)parent;
 
    setupUi(this);
-   parent->addWidget(this);
    m_sock = NULL;
    m_at_prompt = false;
    m_textEdit = textEdit;   /* our console screen */
    m_cursor = new QTextCursor(m_textEdit->document());
    mainWin->actionConnect->setIcon(QIcon(QString::fromUtf8("images/disconnected.png")));
 
-   bRestore *brestore = new bRestore(parent);
-   brestore->setupUi(brestore);
-   parent->addWidget(brestore);
-
-   /* Just take the first Director */
-   LockRes();
-   m_dir = (DIRRES *)GetNextRes(R_DIRECTOR, NULL);
-   UnlockRes();
-
-   /* ***FIXME*** Dummy setup of treeWidget */
-   treeWidget->clear();
-   treeWidget->setColumnCount(1);
-   treeWidget->setHeaderLabel("Selection");
-   topItem = new QTreeWidgetItem(treeWidget);
-   topItem->setText(0, m_dir->name());
-   topItem->setIcon(0, QIcon(QString::fromUtf8("images/server.png")));
-   item = new QTreeWidgetItem(topItem);
-   m_consoleItem = item;
-   item->setText(0, "Console");
-   item->setText(1, "0");
-   QBrush redBrush(Qt::red);
-   item->setForeground(0, redBrush);
-   item = new QTreeWidgetItem(topItem);
-   item->setText(0, "brestore");
-   item->setText(1, "1");
-   treeWidget->expandItem(topItem);
-
    readSettings();
+   /* Check for messages every 5 seconds */
+// m_timer = new QTimer(this);
+// QWidget::connect(m_timer, SIGNAL(timeout()), this, SLOT(poll_messages()));
+// m_timer->start(5000);
 
 }
 
+void Console::poll_messages()
+{
+   m_messages_pending = true;
+}
+
 /* Terminate any open socket */
 void Console::terminate()
 {
@@ -91,6 +71,7 @@ void Console::terminate()
       m_sock->close();
       m_sock = NULL;
    }
+// m_timer->stop();
 }
 
 /*
@@ -104,17 +85,17 @@ void Console::connect()
    m_textEdit = textEdit;   /* our console screen */
 
    if (!m_dir) {          
-      mainWin->set_status(" No Director found.");
+      mainWin->set_status("No Director found.");
       return;
    }
    if (m_sock) {
-      mainWin->set_status(" Already connected.");
+      mainWin->set_status("Already connected.");
       return;
    }
 
    memset(&jcr, 0, sizeof(jcr));
 
-   mainWin->set_statusf(_(" Connecting to Director %s:%d"), m_dir->address, m_dir->DIRport);
+   mainWin->set_statusf(_("Connecting to Director %s:%d"), m_dir->address, m_dir->DIRport);
    display_textf(_("Connecting to Director %s:%d\n\n"), m_dir->address, m_dir->DIRport);
 
    /* Give GUI a chance */
@@ -134,7 +115,7 @@ void Console::connect()
       /* Update page selector to green to indicate that Console is connected */
       mainWin->actionConnect->setIcon(QIcon(QString::fromUtf8("images/connected.png")));
       QBrush greenBrush(Qt::green);
-      m_consoleItem->setForeground(0, greenBrush);
+      m_treeItem->setForeground(0, greenBrush);
    }
 
    jcr.dir_bsock = m_sock;
@@ -147,12 +128,16 @@ void Console::connect()
    /* Give GUI a chance */
    app->processEvents();
 
-   mainWin->set_status(_(" Initializing ..."));
+   mainWin->set_status(_("Initializing ..."));
 
    /* Set up input notifier */
    m_notifier = new QSocketNotifier(m_sock->fd, QSocketNotifier::Read, 0);
    QObject::connect(m_notifier, SIGNAL(activated(int)), this, SLOT(read_dir(int)));
 
+   write(".api 1");
+   discardToPrompt();
+
+   beginNewCommand();
    job_list = get_list(".jobs");
    client_list = get_list(".clients");
    fileset_list = get_list(".filesets");
@@ -162,7 +147,7 @@ void Console::connect()
    type_list = get_list(".types");
    level_list = get_list(".levels");
 
-   mainWin->set_status(_(" Connected"));
+   mainWin->set_status(_("Connected"));
    return;
 }
 
@@ -176,14 +161,13 @@ QStringList Console::get_list(char *cmd)
    QStringList list;
    int stat;
 
-   setEnabled(false);
+   notify(false);
    write(cmd);
    while ((stat = read()) > 0) {
       strip_trailing_junk(msg());
       list << msg();
    }
-   setEnabled(true);
-   list.sort();
+   notify(true);
    return list;
 }
 
@@ -193,13 +177,14 @@ QStringList Console::get_list(char *cmd)
  */
 bool Console::get_job_defaults(struct job_defaults &job_defs)
 {
-   char cmd[1000];
+   QString scmd;
    int stat;
    char *def;
 
-   setEnabled(false);
-   bsnprintf(cmd, sizeof(cmd), ".defaults job=\"%s\"", job_defs.job_name.toUtf8().data());
-   write(cmd);
+   notify(false);
+   beginNewCommand();
+   scmd = QString(".defaults job=\"%1\"").arg(job_defs.job_name);
+   write(scmd);
    while ((stat = read()) > 0) {
       def = strchr(msg(), '=');
       if (!def) {
@@ -256,6 +241,8 @@ bool Console::get_job_defaults(struct job_defaults &job_defs)
          continue;
       }
    }
+
+#ifdef xxx
    bsnprintf(cmd, sizeof(cmd), "job=%s pool=%s client=%s storage=%s where=%s\n"
       "level=%s type=%s fileset=%s catalog=%s enabled=%d\n",
       job_defs.job_name.toUtf8().data(), job_defs.pool_name.toUtf8().data(), 
@@ -265,12 +252,13 @@ bool Console::get_job_defaults(struct job_defaults &job_defs)
       job_defs.where.toUtf8().data(), job_defs.level.toUtf8().data(), 
       job_defs.type.toUtf8().data(), job_defs.fileset_name.toUtf8().data(),
       job_defs.catalog_name.toUtf8().data(), job_defs.enabled);
+#endif
 
-   setEnabled(true);
+   notify(true);
    return true;
 
 bail_out:
-   setEnabled(true);
+   notify(true);
    return false;
 }
 
@@ -331,6 +319,7 @@ const QFont Console::get_font()
 void Console::status_dir()
 {
    write_dir("status dir\n");
+   displayToPrompt();
 }
 
 /*
@@ -383,46 +372,179 @@ char *Console::msg()
 void Console::write_dir(const char *msg)
 {
    if (m_sock) {
-      m_at_prompt = false;
-      mainWin->set_status(_(" Processing command ..."));
+      mainWin->set_status(_("Processing command ..."));
       QApplication::setOverrideCursor(Qt::WaitCursor);
-      m_sock->msglen = strlen(msg);
-      pm_strcpy(&m_sock->msg, msg);
-      bnet_send(m_sock);
+      write(msg);
    } else {
       mainWin->set_status(" Director not connected. Click on connect button.");
       mainWin->actionConnect->setIcon(QIcon(QString::fromUtf8("images/disconnected.png")));
       QBrush redBrush(Qt::red);
-      m_consoleItem->setForeground(0, redBrush);
+      m_treeItem->setForeground(0, redBrush);
+      m_at_prompt = false;
    }
 }
 
+int Console::write(const QString msg)
+{
+   return write(msg.toUtf8().data());
+}
+
 int Console::write(const char *msg)
 {
    m_sock->msglen = strlen(msg);
    pm_strcpy(&m_sock->msg, msg);
-   return bnet_send(m_sock);
+   m_at_prompt = false;
+   if (commDebug) Pmsg1(000, "send: %s\n", msg);
+   return m_sock->send();
 }
 
+/*
+ * Get to main command prompt 
+ */
+void Console::beginNewCommand()
+{
+   write(".\n");
+   while (read() > 0) {
+   }
+   write(".\n");
+   while (read() > 0) {
+   }
+   write(".\n");
+   while (read() > 0) {
+   }
+   display_text("\n");
+}
+
+void Console::displayToPrompt()
+{ 
+   int stat;
+   if (commDebug) Pmsg0(000, "DisplaytoPrompt\n");
+   while (!m_at_prompt) {
+      if ((stat=read()) > 0) {
+         display_text(msg());
+      }
+   }
+   if (commDebug) Pmsg1(000, "endDisplaytoPrompt=%d\n", stat);
+}
+
+void Console::discardToPrompt()
+{ 
+   int stat;
+   if (commDebug) Pmsg0(000, "discardToPrompt\n");
+   while (!m_at_prompt) {
+      stat = read();
+   }
+   if (commDebug) Pmsg1(000, "endDisplayToPrompt=%d\n", stat);
+}
+
+
 /* 
- * Blocking read from director */
+ * Blocking read from director
+ */
 int Console::read()
 {
-   int stat;
-   if (m_sock) {
+   int stat = 0;
+   while (m_sock) {
       for (;;) {
          stat = bnet_wait_data_intr(m_sock, 1);
          if (stat > 0) {
             break;
          } 
          app->processEvents();
-         if (stat < 0) {
-            return BNET_ERROR;
+         if (m_api_set && m_messages_pending) {
+            write_dir(".messages");
+            m_messages_pending = false;
          }
       }
-      return bnet_recv(m_sock);
+      stat = m_sock->recv();
+      if (stat >= 0) {
+         if (m_at_prompt) {
+            display_text("\n");
+            m_at_prompt = false;
+         }
+         if (commDebug) Pmsg1(000, "got: %s", m_sock->msg);
+      }
+      switch (m_sock->msglen) {
+      case BNET_SERVER_READY:
+         if (m_api_set && m_messages_pending) {
+            write_dir(".messages");
+            m_messages_pending = false;
+         }
+         m_at_prompt = true;
+         continue;
+      case BNET_MSGS_PENDING:
+         if (commDebug) Pmsg0(000, "MSGS PENDING\n");
+         m_messages_pending = true;
+         continue;
+      case BNET_CMD_OK:
+         if (commDebug) Pmsg0(000, "CMD OK\n");
+         m_at_prompt = false;
+         continue;
+      case BNET_CMD_BEGIN:
+         if (commDebug) Pmsg0(000, "CMD BEGIN\n");
+         m_at_prompt = false;
+         continue;
+      case BNET_PROMPT:
+         if (commDebug) Pmsg0(000, "PROMPT\n");
+         m_at_prompt = true;
+         mainWin->set_status(_("At prompt waiting for input ..."));
+         update_cursor();
+         QApplication::restoreOverrideCursor();
+         break;
+      case BNET_CMD_FAILED:
+         if (commDebug) Pmsg0(000, "CMD FAIL\n");
+         mainWin->set_status(_("Command failed. At prompt waiting for input ..."));
+         update_cursor();
+         QApplication::restoreOverrideCursor();
+         break;
+      /* We should not get this one */
+      case BNET_EOD:
+         if (commDebug) Pmsg0(000, "EOD\n");
+         mainWin->set_status_ready();
+         update_cursor();
+         QApplication::restoreOverrideCursor();
+         if (!m_api_set) {
+            break;
+         }
+         continue;
+      case BNET_START_SELECT:
+         new selectDialog(this);    
+         break;
+      case BNET_RUN_CMD:
+         new runCmdDialog(this);
+         break;
+      case BNET_ERROR_MSG:
+         m_sock->recv();              /* get the message */
+         display_text(msg());
+         QMessageBox::critical(this, "Error", msg(), QMessageBox::Ok);
+         break;
+      case BNET_WARNING_MSG:
+         m_sock->recv();              /* get the message */
+         display_text(msg());
+         QMessageBox::critical(this, "Warning", msg(), QMessageBox::Ok);
+         break;
+      case BNET_INFO_MSG:
+         m_sock->recv();              /* get the message */
+         display_text(msg());
+         mainWin->set_status(msg());
+         break;
+      }
+      if (is_bnet_stop(m_sock)) {         /* error or term request */
+         m_sock->close();
+         m_sock = NULL;
+         mainWin->actionConnect->setIcon(QIcon(QString::fromUtf8("images/disconnected.png")));
+         QBrush redBrush(Qt::red);
+         m_treeItem->setForeground(0, redBrush);
+         m_notifier->setEnabled(false);
+         delete m_notifier;
+         m_notifier = NULL;
+         mainWin->set_status(_("Director disconnected."));
+         QApplication::restoreOverrideCursor();
+         stat = BNET_HARDEOF;
+      }
+      break;
    } 
-   return BNET_HARDEOF;
+   return stat;
 }
 
 /* Called by signal when the Director has output for us */
@@ -431,40 +553,51 @@ void Console::read_dir(int fd)
    int stat;
    (void)fd;
 
-   if (!m_sock) {
-      return;
+   if (commDebug) Pmsg0(000, "read_dir\n");
+   while ((stat = read()) >= 0) {
+      display_text(msg());
    }
-   stat = bnet_recv(m_sock);
-   if (stat >= 0) {
-      if (m_at_prompt) {
-         display_text("\n");
-         m_at_prompt = false;
+}
+
+/*
+ * When the notifier is enabled, read_dir() will automatically be
+ * called by the Qt event loop when ever there is any output 
+ * from the Directory, and read_dir() will then display it on
+ * the console.
+ *
+ * When we are in a bat dialog, we want to control *all* output
+ * from the Directory, so we set notify to off.
+ *    m_console->notifiy(false);
+ */
+void Console::notify(bool enable) 
+{ 
+   m_notifier->setEnabled(enable);   
+}
+
+void Console::setTreeItem(QTreeWidgetItem *item)
+{
+   m_treeItem = item;
+}
+
+void Console::setDirRes(DIRRES *dir) 
+{ 
+   m_dir = dir;
+}
+
+void Console::dosql(QString* sqlcmd, QStringList& strlstret)
+{
+   int stat;
+   /* don't effect the string coming in */
+   QString cmd(*sqlcmd);
+
+   cmd = ".sql \"" + cmd + "\"";
+
+   write_dir(cmd.toUtf8().data());
+   while ((stat=read()) > 0) {
+      QString line = msg();
+      QRegExp regex("^Using Catalog");
+      if ( regex.indexIn(line) < 0 ){
+        strlstret.append(line);
       }
-      display_text(m_sock->msg);
-      return;
-   }
-   if (is_bnet_stop(m_sock)) {         /* error or term request */
-      m_sock->close();
-      m_sock = NULL;
-      mainWin->actionConnect->setIcon(QIcon(QString::fromUtf8("images/disconnected.png")));
-      QBrush redBrush(Qt::red);
-      m_consoleItem->setForeground(0, redBrush);
-      m_notifier->setEnabled(false);
-      delete m_notifier;
-      m_notifier = NULL;
-      mainWin->set_status(_(" Director disconnected."));
-      QApplication::restoreOverrideCursor();
-      return;
-   }
-   /* Must be a signal -- either do something or ignore it */
-   if (m_sock->msglen == BNET_PROMPT) {
-      m_at_prompt = true;
-      mainWin->set_status(_(" At prompt waiting for input ..."));
-      update_cursor();
    }
-   if (m_sock->msglen == BNET_EOD) {
-      mainWin->set_status_ready();
-      update_cursor();
-   }
-   return;
 }