changeset 16551:6ae555fc8c43

Add questdlg dialog function and fix variety of dialog bugs. * octave-qt-link.cc (octave_qt_link::do_message_dialog): Change initializer from QString to QString::fromStdString(dlg). (octave_qt_link::do_question_dialog): New function. Make all buttons AcceptRole. Signal dialog creation. Go to wait state. Get dialog button result when awakened. (octave_qt_link::do_list_dialog): Change std string 'prompt_string' to std list of std string 'prompt'. Use make_qstring_list(prompt). (octave_qt_link::do_input_dialog): Change 'nr' and 'nc' to std list of float. Use QFloatList::fromStdList(nc). * octave-qt-link.h (octave_qt_link : QObject, public octave_link): Add member do_question_dialog. (octave_qt_link::do_list_dialog): Use std list of std string for prompt. (octave_qt_link::do_input_dialog): Change 'nr' and 'nc' to std list of float. * octave-link.cc (__octave_link_question_dialog__): New builtin. Translate args to inputs of octave_link::question_dialog function. (__octave_link_list_dialog__): Retain prompt string cell list as a std list of std string. (__octave_link_input_dialog__): Make 'nr' and 'nc' std list of float. * octave-link.h (octave_link::question_dialog, octave_link::do_question_dialog): Add. (octave_link::list_dialog, octave_link::do_list_dialog): Change prompt to std list of std string. (octave_link::input_dialog, octave_link::do_input_dialog): Change 'nr' and 'nc' to std list of float. * errordlg.m (errordlg): Make retval return variable. Add "error" icon as message_dialog input. * helpdlg.m (helpdlg): Make retval return variable. Add "help" icon as message_dialog input. * warndlg.m (warndlg): Add "warn" icon as message_dialog input. * message_dialog.m (message_dialog): Define default icon "none". Use dlg variable with icon variable as input to __octave_link_message_dialog__. Use __octave_link_enabled__ rather than return value. * inputdlg.m (inputdlg): Round up rowscols to integer. Replace iscell(cstr) with __octave_link_enabled__. * listdlg.m (listdlg): Correct indentation. Change default selmode from "multiple" to "Multiple". Make default prompt {}. Check valid selmode entry. Use __octave_link_enabled__ rather than ok return value. Remove FIXME note. Use Rich Text in prompt of demo. Add demo using ListSize. * questdlg.m (questdlg): Add case 0 to switch. Add error message for default button not matching options. In all cases, check that default button matches an button option. Add __octave_link_question_dialog__ call conditioned under __octave_link_enabled__. Add three demos. * dialog.cc (QUIWidgetCreator::dialog_finished): Remove. (QUIWidgetCreator::dialog_button_clicked): Test that button pointer is nonzero. Move dialog_result assignment and waitcondition.wakeAll here. (MessageDialog::MessageDialog): If title "", change to " ". Reverse order that buttons are installed. Remove signal 'finished' connection. (ListDialog::ListDialog): Change prompt from QString to QStringList. Make list items noneditable. Add Rich Text support to prompt, place RT <br> between prompt list lines. Use label for prompt. Disable select_all button if not "Multiple". Remove horizontal group box. If title "", change to " ". (InputDialog::InputDialog): Change 'nr' and 'nc' to QFloatList. Define pre-processor variables, then undefine. If title "", change to " ". * dialog.h (QUIWidgetCreator::signal_listviewQUI, WidgetCreator::create_listview): Change QString 'prompt_string' to QStringList 'prompt'. (QUIWidgetCreator::signal_inputlayout, QUIWidgetCreator::create_inputlayout): Use QFloatList for 'nr' and 'nc'. (QUIWidgetCreator::dialog_finished): Remove. (MessageDialog::closeEvent): New override, emitting buttonClicked(0). (ListDialog::ListDialog): Change QString 'prompt_string' to QStringList 'prompt'. (InputDialog::InputDialog): Use QFloatList for 'nr' and 'nc'. * main_window.cc, main_window.h: Make function call changes that match dialog.h changes. (main_window::find_files_finished): Remove unused 'button' variable.
author Daniel J Sebald <daniel.sebald@ieee.org>
date Mon, 22 Apr 2013 15:07:13 -0400
parents 94067a5d28ee
children 8fc1f6535380
files libgui/src/dialog.cc libgui/src/dialog.h libgui/src/main-window.cc libgui/src/main-window.h libgui/src/octave-qt-link.cc libgui/src/octave-qt-link.h libinterp/interpfcn/octave-link.cc libinterp/interpfcn/octave-link.h scripts/ui/errordlg.m scripts/ui/helpdlg.m scripts/ui/inputdlg.m scripts/ui/listdlg.m scripts/ui/private/message_dialog.m scripts/ui/questdlg.m scripts/ui/warndlg.m
diffstat 15 files changed, 372 insertions(+), 191 deletions(-) [+]
line wrap: on
line diff
--- a/libgui/src/dialog.cc	Mon Apr 22 11:50:40 2013 -0400
+++ b/libgui/src/dialog.cc	Mon Apr 22 15:07:13 2013 -0400
@@ -42,6 +42,7 @@
 
 QUIWidgetCreator uiwidget_creator;
 
+
 QUIWidgetCreator::QUIWidgetCreator (void)
   : QObject (), dialog_result (-1), dialog_button (),
     string_list (new QStringList ()), list_index (new QIntList ())
@@ -56,13 +57,13 @@
 
 
 void
-QUIWidgetCreator::dialog_finished (int)
+QUIWidgetCreator::dialog_button_clicked (QAbstractButton *button)
 {
   // Store the value so that builtin functions can retrieve.
-  // The value should always be 1 for the Octave functions.
+  if (button)
+    dialog_button = button->text ();
 
-  // Value returned by message box is not quite always 1.  If the
-  // window upper-right close button is pressed, 'result' is 0.
+  // The value should always be 1 for the Octave functions.
   dialog_result = 1;
 
   // Wake up Octave process so that it continues.
@@ -71,15 +72,6 @@
 
 
 void
-QUIWidgetCreator::dialog_button_clicked (QAbstractButton *button)
-{
-  // Store information about what button was pressed so that builtin
-  // functions can retrieve.
-  dialog_button = button->text ();
-}
-
-
-void
 QUIWidgetCreator::list_select_finished (const QIntList& selected, const int button_pressed)
 {
   // Store the value so that builtin functions can retrieve.
@@ -103,12 +95,14 @@
 }
 
 
-MessageDialog::MessageDialog (const QString& message, const QString& title,
+MessageDialog::MessageDialog (const QString& message,
+                              const QString& title,
                               const QString& qsicon,
                               const QStringList& qsbutton,
                               const QString& defbutton,
                               const QStringList& role)
-  : QMessageBox (QMessageBox::NoIcon, title, message, 0, 0)
+  : QMessageBox (QMessageBox::NoIcon, title.isEmpty () ? " " : title,
+                 message, 0, 0)
 {
   // Create a NonModal message.
   setWindowModality (Qt::NonModal);
@@ -131,7 +125,7 @@
     addButton (QMessageBox::Ok);
   else
     {
-      for (int i = 0; i < N; i++)
+      for (int i = N-1; i >= 0; i--)
         {
           // Interpret the button role string, because enumeration
           // QMessageBox::ButtonRole can't be made to pass through a signal.
@@ -151,21 +145,26 @@
             setDefaultButton (pbutton);
           // Make the last button the button pressed when <esc> key activated.
           if (i == N-1)
-            setEscapeButton (pbutton);
+            {
+#define ACTIVE_ESCAPE true
+#if ACTIVE_ESCAPE
+              setEscapeButton (pbutton);
+#else
+              setEscapeButton (0);
+#endif
+#undef ACTIVE_ESCAPE
+            }
         }
     }
 
   connect (this, SIGNAL (buttonClicked (QAbstractButton *)),
            &uiwidget_creator, SLOT (dialog_button_clicked (QAbstractButton *)));
-
-  connect (this, SIGNAL (finished (int)),
-           &uiwidget_creator, SLOT (dialog_finished (int)));
 }
 
 
 ListDialog::ListDialog (const QStringList& list, const QString& mode,
                         int wd, int ht, const QList<int>& initial,
-                        const QString& name, const QString& prompt_string,
+                        const QString& title, const QStringList& prompt,
                         const QString& ok_string, const QString& cancel_string)
   : QDialog ()
 {
@@ -194,7 +193,6 @@
     {
       QModelIndex idx = model->index (initial.value (i++) - 1, 0,
                                       QModelIndex ());
-
       selector->select (idx, QItemSelectionModel::Select);
     }
 
@@ -205,17 +203,36 @@
       fixed_layout = true;
     }
 
-  QPushButton *select_all = new QPushButton (tr ("Select All"));
+  view->setEditTriggers (QAbstractItemView::NoEditTriggers);
+
   QVBoxLayout *listLayout = new QVBoxLayout;
+  if (! prompt.isEmpty ())
+    {
+      // For now, assume html-like Rich Text.  May be incompatible
+      // with something down the road, but just testing capability.
+      QString prompt_string;
+      for (int j = 0; j < prompt.length (); j++)
+        {
+          if (j > 0)
+#define RICH_TEXT true
+#if RICH_TEXT
+            prompt_string.append ("<br>");
+#else
+            prompt_string.append ("\n");
+#endif
+          prompt_string.append (prompt.at (j));
+        }
+      QLabel *plabel = new QLabel (prompt_string);
+#if RICH_TEXT
+      plabel->setTextFormat (Qt::RichText);
+#endif
+#undef RICH_TEXT
+      listLayout->addWidget (plabel);
+    }
   listLayout->addWidget (view);
+  QPushButton *select_all = new QPushButton (tr ("Select All"));
+  select_all->setEnabled (mode == "Multiple");
   listLayout->addWidget (select_all);
-  QGroupBox *listGroupBox = new QGroupBox (prompt_string);
-  listGroupBox->setLayout (listLayout);
-
-  //    QIcon *question_mark = new QIcon;
-  QHBoxLayout *horizontalLayout = new QHBoxLayout;
-  //    horizontalLayout->addWidget (question_mark);
-  horizontalLayout->addWidget (listGroupBox);
 
   QPushButton *buttonOk = new QPushButton (ok_string);
   QPushButton *buttonCancel = new QPushButton (cancel_string);
@@ -225,14 +242,15 @@
   buttonsLayout->addWidget (buttonCancel);
 
   QVBoxLayout *mainLayout = new QVBoxLayout;
-  mainLayout->addLayout (horizontalLayout);
+  mainLayout->addLayout (listLayout);
   mainLayout->addSpacing (12);
   mainLayout->addLayout (buttonsLayout);
   setLayout (mainLayout);
   if (fixed_layout)
     layout()->setSizeConstraint (QLayout::SetFixedSize);
 
-  setWindowTitle (name);
+  // If empty, make blank rather than use default OS behavior.
+  setWindowTitle (title.isEmpty () ? " " : title);
 
   connect (select_all, SIGNAL (clicked ()),
            view, SLOT (selectAll ()));
@@ -287,14 +305,14 @@
 
 
 InputDialog::InputDialog (const QStringList& prompt, const QString& title,
-                          const QIntList& nr, const QIntList& nc,
+                          const QFloatList& nr, const QFloatList& nc,
                           const QStringList& defaults)
   : QDialog ()
 {
 
-//#define LINE_EDIT_FOLLOWS_PROMPT
+#define LINE_EDIT_FOLLOWS_PROMPT false
 
-#ifdef LINE_EDIT_FOLLOWS_PROMPT
+#if LINE_EDIT_FOLLOWS_PROMPT
     // Prompt on left followed by input on right.
     QGridLayout *promptInputLayout = new QGridLayout;
 #else
@@ -318,7 +336,7 @@
               }
           }
         input_line << line_edit;
-#ifdef LINE_EDIT_FOLLOWS_PROMPT
+#if LINE_EDIT_FOLLOWS_PROMPT
         promptInputLayout->addWidget (label, i + 1, 0);
         promptInputLayout->addWidget (line_edit, i + 1, 1);
 #else
@@ -326,6 +344,7 @@
         promptInputLayout->addWidget (line_edit);
 #endif
       }
+#undef LINE_EDIT_FOLLOWS_PROMPT
 
     QPushButton *buttonOk = new QPushButton("OK");
     QPushButton *buttonCancel = new QPushButton("Cancel");
@@ -340,7 +359,8 @@
     mainLayout->addLayout (buttonsLayout);
     setLayout (mainLayout);
 
-    setWindowTitle (title);
+    // If empty, make blank rather than use default OS behavior.
+    setWindowTitle (title.isEmpty () ? " " : title);
 
     connect (buttonOk, SIGNAL (clicked ()),
              this, SLOT (buttonOk_clicked ()));
--- a/libgui/src/dialog.h	Mon Apr 22 11:50:40 2013 -0400
+++ b/libgui/src/dialog.h	Mon Apr 22 15:07:13 2013 -0400
@@ -58,7 +58,7 @@
   {
 
     // Use the last button in the list as the reject result, i.e., when no
-    // button is pressed such as in the case of <esc> and close button.
+    // button is pressed such as in the case of the upper right close tab.
     if (!button.isEmpty ())
       dialog_button = button.last ();
 
@@ -75,14 +75,14 @@
 
   bool signal_listview (const QStringList& list, const QString& mode,
                         int wd, int ht, const QList<int>& initial,
-                        const QString& name, const QString& prompt_string,
+                        const QString& name, const QStringList& prompt,
                         const QString& ok_string, const QString& cancel_string)
   {
     if (list.isEmpty ())
       return false;
 
     emit create_listview (list, mode, wd, ht, initial, name,
-                          prompt_string, ok_string, cancel_string);
+                          prompt, ok_string, cancel_string);
 
     return true;
   };
@@ -90,7 +90,7 @@
   const QIntList *get_list_index (void) { return list_index; }
 
   bool signal_inputlayout (const QStringList& prompt, const QString& title,
-                           const QIntList& nr, const QIntList& nc,
+                           const QFloatList& nr, const QFloatList& nc,
                            const QStringList& defaults)
   {
     if (prompt.isEmpty ())
@@ -126,19 +126,17 @@
                       const QStringList&, const QString&, const QStringList&);
 
   void create_listview (const QStringList&, const QString&, int, int,
-                        const QIntList&, const QString&, const QString&,
+                        const QIntList&, const QString&, const QStringList&,
                         const QString&, const QString&);
 
   void create_inputlayout (const QStringList&, const QString&,
-                           const QIntList&, const QIntList&,
+                           const QFloatList&, const QFloatList&,
                            const QStringList&);
 
   void create_debug_cd_or_addpath_dialog (const QString&, const QString&, bool);
 
 public slots:
 
-  void dialog_finished (int result);
-
   void dialog_button_clicked (QAbstractButton *button);
 
   void list_select_finished (const QIntList& selected,
@@ -167,6 +165,7 @@
 
 extern QUIWidgetCreator uiwidget_creator;
 
+
 class MessageDialog : public QMessageBox
 {
   Q_OBJECT
@@ -177,6 +176,15 @@
                           const QString& icon, const QStringList& button,
                           const QString& defbutton,
                           const QStringList& role);
+
+private:
+
+  void closeEvent (QCloseEvent *)
+  {
+    // Reroute the close tab to a button click so there is only a single
+    // route to waking the wait condition.
+    emit buttonClicked (0);
+  }
 };
 
 
@@ -190,7 +198,7 @@
 
   explicit ListDialog (const QStringList& list, const QString& mode,
                        int width, int height, const QList<int>& initial,
-                       const QString& name, const QString& prompt_string,
+                       const QString& name, const QStringList& prompt,
                        const QString& ok_string, const QString& cancel_string);
 
 signals:
@@ -216,7 +224,7 @@
 public:
 
   explicit InputDialog (const QStringList& prompt, const QString& title,
-                        const QIntList& nr, const QIntList& nc,
+                        const QFloatList& nr, const QFloatList& nc,
                         const QStringList& defaults);
 
 signals:
--- a/libgui/src/main-window.cc	Mon Apr 22 11:50:40 2013 -0400
+++ b/libgui/src/main-window.cc	Mon Apr 22 15:07:13 2013 -0400
@@ -574,23 +574,23 @@
   connect (&uiwidget_creator,
            SIGNAL (create_listview (const QStringList&, const QString&,
                                     int, int, const QIntList&,
-                                    const QString&, const QString&,
+                                    const QString&, const QStringList&,
                                     const QString&, const QString&)),
            this,
            SLOT (handle_create_listview (const QStringList&, const QString&,
                                          int, int, const QIntList&,
-                                         const QString&, const QString&,
+                                         const QString&, const QStringList&,
                                          const QString&, const QString&)));
 
-  // Register QFloatList so that list of ints may be part of a signal.
+  // Register QFloatList so that list of floats may be part of a signal.
   qRegisterMetaType<QFloatList> ("QFloatList");
   connect (&uiwidget_creator,
            SIGNAL (create_inputlayout (const QStringList&, const QString&,
-                                       const QIntList&, const QIntList&,
+                                       const QFloatList&, const QFloatList&,
                                        const QStringList&)),
            this,
            SLOT (handle_create_inputlayout (const QStringList&, const QString&,
-                                            const QIntList&, const QIntList&,
+                                            const QFloatList&, const QFloatList&,
                                             const QStringList&)));
 
   connect (&uiwidget_creator,
@@ -628,12 +628,12 @@
                                      int wd, int ht,
                                      const QIntList& initial,
                                      const QString& name,
-                                     const QString& prompt_string,
+                                     const QStringList& prompt,
                                      const QString& ok_string,
                                      const QString& cancel_string)
 {
   ListDialog *list_dialog = new ListDialog (list, mode, wd, ht,
-                                            initial, name, prompt_string,
+                                            initial, name, prompt,
                                             ok_string, cancel_string);
 
   list_dialog->setAttribute (Qt::WA_DeleteOnClose);
@@ -645,8 +645,8 @@
 void
 main_window::handle_create_inputlayout (const QStringList& prompt,
                                         const QString& title,
-                                        const QIntList& nr,
-                                        const QIntList& nc,
+                                        const QFloatList& nr,
+                                        const QFloatList& nc,
                                         const QStringList& defaults)
 {
   InputDialog *input_dialog = new InputDialog (prompt, title, nr, nc,
@@ -1480,7 +1480,7 @@
 }
 
 void 
-main_window::find_files_finished(int button)
+main_window::find_files_finished(int)
 {
 
 }
--- a/libgui/src/main-window.h	Mon Apr 22 11:50:40 2013 -0400
+++ b/libgui/src/main-window.h	Mon Apr 22 15:07:13 2013 -0400
@@ -134,12 +134,12 @@
                                int width, int height,
                                const QIntList& initial,
                                const QString& name,
-                               const QString& prompt_string,
+                               const QStringList& prompt,
                                const QString& ok_string,
                                const QString& cancel_string);
 
   void handle_create_inputlayout (const QStringList&, const QString&,
-                                  const QIntList&, const QIntList&,
+                                  const QFloatList&, const QFloatList&,
                                   const QStringList&);
 
   void handle_create_debug_cd_or_addpath_dialog (const QString& file,
--- a/libgui/src/octave-qt-link.cc	Mon Apr 22 11:50:40 2013 -0400
+++ b/libgui/src/octave-qt-link.cc	Mon Apr 22 15:07:13 2013 -0400
@@ -71,8 +71,9 @@
 {
   uiwidget_creator.signal_dialog (QString::fromStdString (msg),
                                   QString::fromStdString (title),
-                                  QString (), QStringList (),
-                                  QString (), QStringList ());
+                                  QString::fromStdString (dlg),
+                                  QStringList (), QString (),
+                                  QStringList ());
 
   // Wait while the user is responding to message box.
   uiwidget_creator.wait ();
@@ -81,6 +82,38 @@
   return uiwidget_creator.get_dialog_result ();
 }
 
+std::string
+octave_qt_link::do_question_dialog (const std::string& msg,
+                                    const std::string& title,
+                                    const std::string& btn1,
+                                    const std::string& btn2,
+                                    const std::string& btn3,
+                                    const std::string& btndef)
+{
+  QStringList btn;
+  QStringList role;
+  role << "AcceptRole" << "AcceptRole" << "AcceptRole";
+  btn << QString::fromStdString (btn1);
+  if (btn2 == "")
+    role.removeAt (0);
+  else
+    btn << QString::fromStdString (btn2);
+  btn << QString::fromStdString (btn3);
+
+  uiwidget_creator.signal_dialog (QString::fromStdString (msg),
+                                  QString::fromStdString (title),
+                                  "quest",
+                                  btn,
+                                  QString::fromStdString (btndef),
+                                  role);
+
+  // Wait while the user is responding to message box.
+  uiwidget_creator.wait ();
+
+  // The GUI has sent a signal and the process has been awakened.
+  return uiwidget_creator.get_dialog_button ()->toStdString ();
+}
+
 static QStringList
 make_qstring_list (const std::list<std::string>& lst)
 {
@@ -102,7 +135,7 @@
                                 int width, int height,
                                 const std::list<int>& initial,
                                 const std::string& name,
-                                const std::string& prompt_string,
+                                const std::list<std::string>& prompt,
                                 const std::string& ok_string,
                                 const std::string& cancel_string)
 {
@@ -111,7 +144,7 @@
                                     width, height,
                                     QList<int>::fromStdList (initial),
                                     QString::fromStdString (name),
-                                    QString::fromStdString (prompt_string),
+                                    make_qstring_list (prompt),
                                     QString::fromStdString (ok_string),
                                     QString::fromStdString (cancel_string));
 
@@ -128,16 +161,16 @@
 std::list<std::string>
 octave_qt_link::do_input_dialog (const std::list<std::string>& prompt,
                                  const std::string& title,
-                                 const std::list<int>& nr,
-                                 const std::list<int>& nc,
+                                 const std::list<float>& nr,
+                                 const std::list<float>& nc,
                                  const std::list<std::string>& defaults)
 {
   std::list<std::string> retval;
 
   uiwidget_creator.signal_inputlayout (make_qstring_list (prompt),
                                        QString::fromStdString (title),
-                                       QList<int>::fromStdList (nr),
-                                       QList<int>::fromStdList (nc),
+                                       QFloatList::fromStdList (nr),
+                                       QFloatList::fromStdList (nc),
                                        make_qstring_list (defaults));
 
   // Wait while the user is responding to message box.
--- a/libgui/src/octave-qt-link.h	Mon Apr 22 11:50:40 2013 -0400
+++ b/libgui/src/octave-qt-link.h	Mon Apr 22 15:07:13 2013 -0400
@@ -62,21 +62,26 @@
   int do_message_dialog (const std::string& dlg, const std::string& msg,
                          const std::string& title);
 
+  std::string
+  do_question_dialog (const std::string& msg, const std::string& title,
+                      const std::string& btn1, const std::string& btn2,
+                      const std::string& btn3, const std::string& btndef);
+
   std::pair<std::list<int>, int>
   do_list_dialog (const std::list<std::string>& list,
                   const std::string& mode,
                   int width, int height,
                   const std::list<int>& initial_value,
                   const std::string& name,
-                  const std::string& prompt_string,
+                  const std::list<std::string>& prompt,
                   const std::string& ok_string,
                   const std::string& cancel_string);
 
   std::list<std::string>
   do_input_dialog (const std::list<std::string>& prompt,
                    const std::string& title,
-                   const std::list<int>& nr,
-                   const std::list<int>& nc,
+                   const std::list<float>& nr,
+                   const std::list<float>& nc,
                    const std::list<std::string>& defaults);
 
   int
--- a/libinterp/interpfcn/octave-link.cc	Mon Apr 22 11:50:40 2013 -0400
+++ b/libinterp/interpfcn/octave-link.cc	Mon Apr 22 15:07:13 2013 -0400
@@ -154,6 +154,36 @@
   return retval;
 }
 
+DEFUN (__octave_link_question_dialog__, args, ,
+  "-*- texinfo -*-\n\
+@deftypefn {Built-in Function} {} __octave_link_question_dialog__ (@var{msg}, @var{title}, @var{btn1}, @var{btn2}, @var{btn3}, @var{default})\n\
+Undocumented internal function.\n\
+@end deftypefn")
+{
+  octave_value retval;
+
+  if (args.length () == 6)
+    {
+      std::string msg = args(0).string_value ();
+      std::string title = args(1).string_value ();
+      std::string btn1 = args(2).string_value ();
+      std::string btn2 = args(3).string_value ();
+      std::string btn3 = args(4).string_value ();
+      std::string btndef = args(5).string_value ();
+
+      if (! error_state)
+        {
+          flush_octave_stdout ();
+
+          retval = octave_link::question_dialog (msg, title, btn1, btn2, btn3, btndef);
+        }
+      else
+        error ("invalid arguments");
+    }
+
+  return retval;
+}
+
 DEFUN (__octave_link_list_dialog__, args, ,
   "-*- texinfo -*-\n\
 @deftypefn {Built-in Function} {} __octave_link_list_dialog__ (@var{list}, @var{mode}, @var{size}, @var{intial}, @var{name}, @var{prompt}, @var{ok_string}, @var{cancel_string})\n\
@@ -165,7 +195,7 @@
   if (args.length () == 8)
     {
       Cell list = args(0).cell_value ();
-      const Array<std::string> tlist= list.cellstr_value ();
+      const Array<std::string> tlist = list.cellstr_value ();
       octave_idx_type nel = tlist.numel ();
       std::list<std::string> list_lst;
       for (octave_idx_type i = 0; i < nel; i++)
@@ -184,7 +214,12 @@
         initial_lst.push_back (initial_matrix(i));
 
       std::string name = args(4).string_value ();
-      std::string prompt_string = args(5).string_value ();
+      list = args(5).cell_value ();
+      const Array<std::string> plist = list.cellstr_value ();
+      nel = plist.numel ();
+      std::list<std::string> prompt_lst;
+      for (octave_idx_type i = 0; i < nel; i++)
+        prompt_lst.push_back (plist(i));
       std::string ok_string = args(6).string_value ();
       std::string cancel_string = args(7).string_value ();
 
@@ -194,7 +229,7 @@
 
           std::pair<std::list<int>, int> result
             = octave_link::list_dialog (list_lst, mode, width, height,
-                                        initial_lst, name, prompt_string,
+                                        initial_lst, name, prompt_lst,
                                         ok_string, cancel_string);
 
           std::list<int> items_lst = result.first;
@@ -238,8 +273,8 @@
 
       Matrix rc = args(2).matrix_value ();
       nel = rc.rows ();
-      std::list<int> nr;
-      std::list<int> nc;
+      std::list<float> nr;
+      std::list<float> nc;
       for (octave_idx_type i = 0; i < nel; i++)
         {
           nr.push_back (rc(i,0));
--- a/libinterp/interpfcn/octave-link.h	Mon Apr 22 11:50:40 2013 -0400
+++ b/libinterp/interpfcn/octave-link.h	Mon Apr 22 15:07:13 2013 -0400
@@ -141,19 +141,28 @@
     return enabled () ? instance->do_message_dialog (dlg, msg, title) : 0;
   }
 
+  static std::string
+  question_dialog (const std::string& msg, const std::string& title,
+                   const std::string& btn1, const std::string& btn2,
+                   const std::string& btn3, const std::string& btndef)
+  {
+    return enabled () ? instance->do_question_dialog (msg, title, btn1,
+                                                      btn2, btn3, btndef) : 0;
+  }
+
   static std::pair<std::list<int>, int>
   list_dialog (const std::list<std::string>& list,
                const std::string& mode,
                int width, int height,
                const std::list<int>& initial_value,
                const std::string& name,
-               const std::string& prompt_string,
+               const std::list<std::string>& prompt,
                const std::string& ok_string,
                const std::string& cancel_string)
   {
     return enabled ()
       ? instance->do_list_dialog (list, mode, width, height,
-                                  initial_value, name, prompt_string,
+                                  initial_value, name, prompt,
                                   ok_string, cancel_string)
       : std::pair<std::list<int>, int> ();
   }
@@ -161,8 +170,8 @@
   static std::list<std::string>
   input_dialog (const std::list<std::string>& prompt,
                 const std::string& title,
-                const std::list<int>& nr,
-                const std::list<int>& nc,
+                const std::list<float>& nr,
+                const std::list<float>& nc,
                 const std::list<std::string>& defaults)
   {
     return enabled ()
@@ -332,21 +341,26 @@
   do_message_dialog (const std::string& dlg, const std::string& msg,
                      const std::string& title) = 0;
 
+  virtual std::string
+  do_question_dialog (const std::string& msg, const std::string& title,
+                      const std::string& btn1, const std::string& btn2,
+                      const std::string& btn3, const std::string& btndef) = 0;
+
   virtual std::pair<std::list<int>, int>
   do_list_dialog (const std::list<std::string>& list,
                   const std::string& mode,
                   int width, int height,
                   const std::list<int>& initial_value,
                   const std::string& name,
-                  const std::string& prompt_string,
+                  const std::list<std::string>& prompt,
                   const std::string& ok_string,
                   const std::string& cancel_string) = 0;
 
   virtual std::list<std::string>
   do_input_dialog (const std::list<std::string>& prompt,
                    const std::string& title,
-                   const std::list<int>& nr,
-                   const std::list<int>& nc,
+                   const std::list<float>& nr,
+                   const std::list<float>& nc,
                    const std::list<std::string>& defaults) = 0;
 
   virtual int
--- a/scripts/ui/errordlg.m	Mon Apr 22 11:50:40 2013 -0400
+++ b/scripts/ui/errordlg.m	Mon Apr 22 15:07:13 2013 -0400
@@ -30,13 +30,13 @@
 ## @seealso{helpdlg, inputdlg, listdlg, msgbox, questdlg, warndlg}
 ## @end deftypefn
 
-function h = errordlg (msg, title = "Error Dialog")
+function retval = errordlg (msg, title = "Error Dialog")
 
   if (nargin < 1 || nargin > 2)
     print_usage ();
   endif
 
-  retval = message_dialog ("errdlg", msg, title);
+  retval = message_dialog ("errdlg", msg, title, "error");
 
 endfunction
 
--- a/scripts/ui/helpdlg.m	Mon Apr 22 11:50:40 2013 -0400
+++ b/scripts/ui/helpdlg.m	Mon Apr 22 15:07:13 2013 -0400
@@ -30,13 +30,13 @@
 ## @seealso{errordlg, inputdlg, listdlg, msgbox, questdlg, warndlg}
 ## @end deftypefn
 
-function h = helpdlg (msg, title = "Help Dialog")
+function retval = helpdlg (msg, title = "Help Dialog")
 
   if (nargin < 1 || nargin > 2)
     print_usage ();
   endif
 
-  retval = message_dialog ("helpdlg", msg, title);
+  retval = message_dialog ("helpdlg", msg, title, "help");
 
 endfunction
 
--- a/scripts/ui/inputdlg.m	Mon Apr 22 11:50:40 2013 -0400
+++ b/scripts/ui/inputdlg.m	Mon Apr 22 15:07:13 2013 -0400
@@ -116,40 +116,30 @@
     else
       error ("inputdlg: ROWSCOLS matrix does not match size of PROMPT");
     endif
-
   else
     ## dunno
     error ("inputdlg: unknown form of ROWSCOLS argument");
   endif
+  rowscols = ceil (rowscols);
   
   ## convert numeric values in defaults cell array to strings
   defs = cellfun (@num2str, defaults, "UniformOutput", false);
   rc = arrayfun (@num2str, rowscols, "UniformOutput", false);
 
-  cstr = __octave_link_input_dialog__ (prompt, title, rowscols, defs);
-
-  if (iscell (cstr))
-    return;
-  endif
-
-  if (__have_feature__ ("JAVA"))
+  if (__octave_link_enabled__ ())
+    cstr = __octave_link_input_dialog__ (prompt, title, rowscols, defs);
+  elseif (__have_feature__ ("JAVA"))
     user_inputs = javaMethod ("inputdlg", "org.octave.JDialogBox",
-                              prompt, title, rc, defs);
-    
+                              prompt, title, rc, defs);  
     if (isempty (user_inputs))
       cstr = {};
     else
       cstr = cellstr (user_inputs);
     endif
-
-    return;
-
+  else
+    error ("inputdlg is not available in this version of Octave");
   endif
 
-  ## FIXME -- provide terminal-based implementation here?
-
-  error ("inputdlg is not available in this version of Octave");
-
 endfunction
 
 %!demo
--- a/scripts/ui/listdlg.m	Mon Apr 22 11:50:40 2013 -0400
+++ b/scripts/ui/listdlg.m	Mon Apr 22 15:07:13 2013 -0400
@@ -79,82 +79,82 @@
 
 function [sel, ok] = listdlg (varargin)
 
-   if (nargin < 2)
-     print_usage ();
-   endif
-   
-   listcell = {""};
-   selmode = "multiple";
-   listsize = [160, 300];
-   initialvalue = 1;
-   name = "";
-   prompt = {""};
-   okstring = "OK";
-   cancelstring = "Cancel";
-   
-   ## handle key, value pairs
-   for i = 1:2:nargin-1
-     if strcmp (varargin{i}, "ListString")
-       listcell = varargin{i+1};
-     elseif strcmp (varargin{i}, "SelectionMode")
-       selmode = varargin{i+1};
-     elseif strcmp (varargin{i}, "ListSize")
-       listsize = varargin{i+1};
-     elseif strcmp (varargin{i}, "InitialValue")
-       initialvalue = varargin{i+1};
-     elseif strcmp (varargin{i}, "Name")
-       name = varargin{i+1};
-     elseif strcmp (varargin{i}, "PromptString")
-       prompt = varargin{i+1};
-     elseif strcmp (varargin{i}, "OKString")
-       okstring = varargin{i+1};
-     elseif strcmp (varargin{i}, "CancelString")
-       cancelstring = varargin{i+1};
-     endif
-   endfor
+  if (nargin < 2)
+    print_usage ();
+  endif
+
+  listcell = {""};
+  selmode = "Multiple";
+  listsize = [160, 300];
+  initialvalue = 1;
+  name = "";
+  prompt = {};
+  okstring = "OK";
+  cancelstring = "Cancel";
 
-   ## make sure prompt strings are a cell array
-   if (! iscell (prompt))
-     prompt = {prompt};
-   endif
+  ## handle key, value pairs
+  for i = 1:2:nargin-1
+    if strcmp (varargin{i}, "ListString")
+      listcell = varargin{i+1};
+    elseif strcmp (varargin{i}, "SelectionMode")
+      selmode = varargin{i+1};
+    elseif strcmp (varargin{i}, "ListSize")
+      listsize = varargin{i+1};
+    elseif strcmp (varargin{i}, "InitialValue")
+      initialvalue = varargin{i+1};
+    elseif strcmp (varargin{i}, "Name")
+      name = varargin{i+1};
+    elseif strcmp (varargin{i}, "PromptString")
+      prompt = varargin{i+1};
+    elseif strcmp (varargin{i}, "OKString")
+      okstring = varargin{i+1};
+    elseif strcmp (varargin{i}, "CancelString")
+      cancelstring = varargin{i+1};
+    endif
+  endfor
 
-   ## make sure listcell strings are a cell array
-   if (! iscell (listcell))
-     listcell = {listcell};
-   endif
+  ## make sure prompt strings are a cell array
+  if (! iscell (prompt))
+    prompt = {prompt};
+  endif
 
-   [sel, ok] = __octave_link_list_dialog__ (listcell, selmode, listsize,
+  ## make sure listcell strings are a cell array
+  if (! iscell (listcell))
+    listcell = {listcell};
+  endif
+
+  ## make sure valid selection mode
+  if (! strcmp (selmode, "Multiple") && ! strcmp (selmode, "Single"))
+    error ("invalid SelectionMode");
+  endif
+
+  if (__octave_link_enabled__ ())
+    [sel, ok] = __octave_link_list_dialog__ (listcell, selmode, listsize,
                                             initialvalue, name, prompt,
                                             okstring, cancelstring);
-   if (ok > 0)
-     return;
-   endif
-
-   if (__have_feature__ ("JAVA"))
-     ## transform matrices to cell arrays of strings
-     ## swap width and height to correct calling format for JDialogBox
-     listsize = {num2str(listsize(2)), num2str(listsize(1))};
-     initialvalue = arrayfun (@num2str, initialvalue, "UniformOutput", false);
-     
-     ret = javaMethod ("listdlg", "org.octave.JDialogBox", listcell,
-                       selmode, listsize, initialvalue, name, prompt,
-                       okstring, cancelstring);
+  elseif (__have_feature__ ("JAVA"))
+    ## transform matrices to cell arrays of strings
+    ## swap width and height to correct calling format for JDialogBox
+    listsize = {num2str(listsize(2)), num2str(listsize(1))};
+    initialvalue = arrayfun (@num2str, initialvalue, "UniformOutput", false);
+    if isempty(prompt)
+      prompt = {""};
+    endif
 
-     if (numel (ret) > 0)
-       sel = ret;
-       ok = 1;
-     else
-       sel = {};
-       ok = 0;
-     endif
+    ret = javaMethod ("listdlg", "org.octave.JDialogBox", listcell,
+                      selmode, listsize, initialvalue, name, prompt,
+                      okstring, cancelstring);
 
-     return;
-
-   endif
-
-   ## FIXME -- provide terminal-based implementation here?
-
-   error ("listdlg is not available in this version of Octave");
+    if (numel (ret) > 0)
+      sel = ret;
+      ok = 1;
+    else
+      sel = {};
+      ok = 0;
+    endif
+  else
+    error ("listdlg is not available in this version of Octave");
+  endif
 
 endfunction
 
@@ -174,8 +174,19 @@
 %!                'SelectionMode','Multiple', ...
 %!                'Name','Selection Dialog', ...
 %!                'InitialValue',[1,2,3,4],
-%!                'PromptString',{'Select an item...', '...or multiple items'} );
+%!                'PromptString',{'Select <b>an</b> item...', '...or <b>multiple</b> items'} );
 %!  imax = numel (s);
 %!  for i=1:1:imax
 %!     disp(['Selected: ',num2str(i),': ', itemlist{s(i)}]);
 %!  end
+
+%!demo
+%!  disp('- test listdlg with listsize.');
+%!  itemlist = {"Neutron","Electron","Quark","Proton","Neutrino"};
+%!  s = listdlg ( "ListString",itemlist,
+%!                "Name","Bits and Pieces",
+%!                "ListSize",[200 75] );
+%!  imax = numel (s);
+%!  for i=1:1:imax
+%!     disp(['Selected: ',num2str(i),': ', itemlist{s(i)}]);
+%!  end
--- a/scripts/ui/private/message_dialog.m	Mon Apr 22 11:50:40 2013 -0400
+++ b/scripts/ui/private/message_dialog.m	Mon Apr 22 15:07:13 2013 -0400
@@ -35,7 +35,7 @@
   if (! ischar (title))
     error ("%s: TITLE must be a character string", caller);
   endif
-  
+
   dlg = "emptydlg";
   if (nargin == 4)
     switch (icon)
@@ -50,23 +50,15 @@
       otherwise
         error ("%s: ICON is not a valid type", caller);
     endswitch
-  endif
-
-  retval = __octave_link_message_dialog__ (dlg, msg, title);
-  if (retval > 0)
-    return;
+  else
+    icon = "none";
   endif
 
-  if (__have_feature__ ("JAVA"))
+  if (__octave_link_enabled__ ())
+    retval = __octave_link_message_dialog__ (icon, msg, title);
+  elseif (__have_feature__ ("JAVA"))
     retval = javaMethod (dlg, "org.octave.JDialogBox", msg, title);
-    if (retval > 0)
-      return;
-    endif
-  endif
-
-  ## FIXME -- provide terminal-based implementation here?
-
-  if (retval <= 0)
+  else
     error ("%s is not available in this version of Octave", dlg);
   endif
 
--- a/scripts/ui/questdlg.m	Mon Apr 22 11:50:40 2013 -0400
+++ b/scripts/ui/questdlg.m	Mon Apr 22 15:07:13 2013 -0400
@@ -70,10 +70,18 @@
   options{3} = "Cancel";   # button3
   options{4} = "Yes";      # default
 
+  defbtn_error_msg = "questdlg: DEFAULT must match one of the button options";
+
   switch (numel (varargin))
+    case 0
+      ## use default default
+
     case 1
       ## default button string
       options{4} = varargin{1};  # default
+      if (! any (strcmp (options{4}, options(1:3))))
+        error (defbtn_error_msg);
+      end
 
     case 3
       ## two buttons and default button string
@@ -81,6 +89,9 @@
       options{2} = "";           # not used, no middle button
       options{3} = varargin{2};  # button3
       options{4} = varargin{3};  # default
+      if (! any (strcmp (options{4}, options([1 3]))))
+        error (defbtn_error_msg);
+      end
 
     case 4
       ## three buttons and default button string
@@ -88,14 +99,76 @@
       options{2} = varargin{2};  # button2
       options{3} = varargin{3};  # button3
       options{4} = varargin{4};  # default
+      if (! any (strcmp (options{4}, options(1:3))))
+        error (defbtn_error_msg);
+      end
 
     otherwise
       print_usage ();
 
   endswitch
 
-  btn = javaMethod ("questdlg", "org.octave.JDialogBox", msg,
-                     title, options);
+  if (__octave_link_enabled__ ())
+    btn = __octave_link_question_dialog__ (msg, title, options{1}, options{2},
+                                           options{3}, options{4});
+  elseif (__have_feature__ ("JAVA"))
+    btn = javaMethod ("questdlg", "org.octave.JDialogBox", msg,
+                      title, options);
+  else
+    error ("questdlg is not available in this version of Octave");
+  endif
 
 endfunction
 
+%!demo
+%!  disp('- test questdlg with two buttons');
+%!  a = questdlg('Would you like some free money?',...
+%!               '$ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $',...
+%!               'No', 'Cancel', 'Cancel');
+%!  if strcmp (a, 'No')
+%!    msgbox('Suit yourself.', 'Message Box');
+%!  endif
+
+%!demo
+%!  disp('- test questdlg with message and title only.');
+%!  a = 'No';
+%!  c = 0;
+%!  while (strcmp(a, 'No') || !c)
+%!    a = questdlg('Close this Question Dialog?', 'Reductio Ad Absurdum');
+%!    if strcmp(a, 'Yes')
+%!      q = 'Are you sure?';
+%!      while (strcmp(a, 'Yes') && !c)
+%!        a = questdlg(q, 'Reductio Ad Absurdum');
+%!        word = ' really';
+%!        i = strfind(q, word);
+%!        if isempty( i )
+%!          i = strfind(q, ' sure');
+%!          q = [q '!'];
+%!        else
+%!          word = [word ','];
+%!        endif
+%!        q = [q(1:i-1) word q(i:end)];
+%!      endwhile
+%!    endif
+%!    if strcmp(a, 'Cancel')
+%!      warndlg('Answer "Yes" or "No".', 'Warning Dialog');
+%!      a = 'No';
+%!      c = 1;
+%!    endif
+%!  endwhile
+%!  msgbox('Whew!');
+
+%!demo
+%!  disp('- test questdlg with five inputs');
+%!  ans = questdlg('Are you ready Steve?', 'Brian', 'No', 'Uh huh', 'Uh huh');
+%!  if !strcmp (ans, 'No')
+%!    ans = questdlg ('Andy?', 'Brian', 'No', 'Yeah', 'Yeah');
+%!    if !strcmp (ans, 'No')
+%!      ans = questdlg ('Mick?', 'Brian', 'No', 'Okay', 'Okay');
+%!      if !strcmp (ans, 'No')
+%!        ans = msgbox ("Well all right, fellas.    \n\n     Let''s GO!!!!!",...
+%!                      'Ballroom Blitz', 'none');
+%!      endif
+%!    endif
+%!  endif
+
--- a/scripts/ui/warndlg.m	Mon Apr 22 11:50:40 2013 -0400
+++ b/scripts/ui/warndlg.m	Mon Apr 22 15:07:13 2013 -0400
@@ -35,7 +35,7 @@
     print_usage ();
   endif
 
-  retval = message_dialog ("warndlg", msg, title);
+  retval = message_dialog ("warndlg", msg, title, "warn");
 
 endfunction