Mercurial > hg > octave-lyh
changeset 16512:7f2395651a1c
dialog boxes with Qt widgets
* dialog.h, dialog.cc: New files.
* libgui/src/module.mk: Update file lists.
* main-window.h, main-window.ccmain_window::connect_uiwidget_links,
main_window::handle_create_dialog,
main_window::handle_create_listview,
main_window::handle_create_inputlayout): New functions.
(main_window::construct): Call connect_uiwidget_links.
* octave-link.h, octave-link.cc (octave_link::message_dialog,
octave_link::do_message_dialog, octave_link::list_dialog,
octave_link::do_list_dialog, octave_link::input_dialog,
octave_link::do_input_dialog): New functions.
* octave-qt-link.h, octave-qt-link.cc (octave_qt_link::message_dialog,
octave_qt_link::do_message_dialog, octave_qt_link::list_dialog,
octave_qt_link::do_list_dialog, octave_qt_link::input_dialog,
octave_qt_link::do_input_dialog, make_qstring_list): New functions.
* octave-link.cc (F__octave_link_edit_file__): Call
flush_octave_stdout before running the edit file action.
(F__octave_link_message_dialog__, F__octave_link_list_dialog__,
__octave_link_input_dialog__): New functions.
* errordlg.m, helpdlg.m, inputdlg.m, listdlg.m, msgbox.m, warndlg.m:
New demos adapted from dlgtest.m
* dlgtest.m: Delete.
* scripts/java/module.mk: Remove it from the list of files.
* inputdlg.m: Try __octave_link_input_dialog__ first. Only try java
method if JAVA feature is available.
* listdlg.m: Likwise, for __octave_link_list_dialog__.
* private/message_dialog.m: Likewise, for
__octave_link_message_dialog__.
author | Daniel J Sebald <daniel.sebald@ieee.org>, John W. Eaton <jwe@octave.org> |
---|---|
date | Sat, 13 Apr 2013 15:22:34 -0400 |
parents | eee1b78d031f |
children | 44f3a9f6e791 |
files | libgui/src/dialog.cc libgui/src/dialog.h libgui/src/main-window.cc libgui/src/main-window.h libgui/src/module.mk libgui/src/octave-qt-link.cc libgui/src/octave-qt-link.h libinterp/interpfcn/octave-link.cc libinterp/interpfcn/octave-link.h scripts/java/dlgtest.m scripts/java/module.mk scripts/ui/errordlg.m scripts/ui/helpdlg.m scripts/ui/inputdlg.m scripts/ui/listdlg.m scripts/ui/msgbox.m scripts/ui/private/message_dialog.m scripts/ui/warndlg.m |
diffstat | 18 files changed, 1226 insertions(+), 231 deletions(-) [+] |
line wrap: on
line diff
new file mode 100644 --- /dev/null +++ b/libgui/src/dialog.cc @@ -0,0 +1,385 @@ +/* + +Copyright (C) 2013 John W. Eaton +Copyright (C) 2013 Daniel J. Sebald + +This file is part of Octave. + +Octave is free software; you can redistribute it and/or modify it +under the terms of the GNU General Public License as published by the +Free Software Foundation; either version 3 of the License, or (at your +option) any later version. + +Octave 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 Octave; see the file COPYING. If not, see +<http://www.gnu.org/licenses/>. + +*/ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + +#include "dialog.h" + +#include <QString> +#include <QStringList> +#include <QStringListModel> +#include <QListView> +// Could replace most of these with #include <QtGui> +#include <QMessageBox> +#include <QHBoxLayout> +#include <QVBoxLayout> +#include <QPushButton> +#include <QGroupBox> +#include <QGridLayout> +#include <QLabel> + +QUIWidgetCreator uiwidget_creator; + +QUIWidgetCreator::QUIWidgetCreator (void) + : QObject (), dialog_result (-1), dialog_button (), + string_list (new QStringList ()), list_index (new QIntList ()) +{ } + + +QUIWidgetCreator::~QUIWidgetCreator (void) +{ + delete string_list; + delete list_index; +} + + +void +QUIWidgetCreator::dialog_finished (int) +{ + // Store the value so that builtin functions can retrieve. + // The value should always be 1 for the Octave functions. + + // Value returned by message box is not quite always 1. If the + // window upper-right close button is pressed, 'result' is 0. + dialog_result = 1; + + // Wake up Octave process so that it continues. + waitcondition.wakeAll (); +} + + +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. + *list_index = selected; + dialog_result = button_pressed; + + // Wake up Octave process so that it continues. + waitcondition.wakeAll (); +} + + +void +QUIWidgetCreator::input_finished (const QStringList& input, const int button_pressed) +{ + // Store the value so that builtin functions can retrieve. + *string_list = input; + dialog_result = button_pressed; + + // Wake up Octave process so that it continues. + waitcondition.wakeAll (); +} + + +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) +{ + // Create a NonModal message. + setWindowModality (Qt::NonModal); + + // Interpret the icon string, because enumeration QMessageBox::Icon can't + // easily be made to pass through a signal. + QMessageBox::Icon eicon = QMessageBox::NoIcon; + if (qsicon == "error") + eicon = QMessageBox::Critical; + else if (qsicon == "warn") + eicon = QMessageBox::Warning; + else if (qsicon == "help") + eicon = QMessageBox::Information; + else if (qsicon == "quest") + eicon = QMessageBox::Question; + setIcon (eicon); + + int N = qsbutton.size () < role.size () ? qsbutton.size () : role.size (); + if (N == 0) + addButton (QMessageBox::Ok); + else + { + for (int i = 0; i < N; i++) + { + // Interpret the button role string, because enumeration + // QMessageBox::ButtonRole can't be made to pass through a signal. + QString srole = role.at (i); + QMessageBox::ButtonRole erole = QMessageBox::InvalidRole; + if (srole == "YesRole") + erole = QMessageBox::YesRole; + else if (srole == "NoRole") + erole = QMessageBox::NoRole; + else if (srole == "RejectRole") + erole = QMessageBox::RejectRole; + else if (srole == "AcceptRole") + erole = QMessageBox::AcceptRole; + + QPushButton *pbutton = addButton (qsbutton.at (i), erole); + if (qsbutton.at (i) == defbutton) + setDefaultButton (pbutton); + // Make the last button the button pressed when <esc> key activated. + if (i == N-1) + setEscapeButton (pbutton); + } + } + + 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& ok_string, const QString& cancel_string) + : QDialog () +{ + // Put the list of items into a model. Keep this off of the stack + // because this conceivably could be a very large list. + QAbstractItemModel *model = new QStringListModel (list); + + QListView *view = new QListView; + view->setModel (model); + + if (mode == "Single") + view->setSelectionMode (QAbstractItemView::SingleSelection); + else if (mode == "Multiple") + view->setSelectionMode (QAbstractItemView::ExtendedSelection); +// else if () +// view->setSelectionMode (QAbstractItemView::ContiguousSelection); +// else if () +// view->setSelectionMode (QAbstractItemView::MultiSelection); + else + view->setSelectionMode (QAbstractItemView::NoSelection); + + selector = view->selectionModel (); + int i = 0; + for (QList<int>::const_iterator it = initial.begin (); + it != initial.end (); it++) + { + QModelIndex idx = model->index (initial.value (i++) - 1, 0, + QModelIndex ()); + + selector->select (idx, QItemSelectionModel::Select); + } + + bool fixed_layout = false; + if (wd > 0 && ht > 0) + { + view->setFixedSize (wd, ht); + fixed_layout = true; + } + + QPushButton *select_all = new QPushButton (tr ("Select All")); + QVBoxLayout *listLayout = new QVBoxLayout; + listLayout->addWidget (view); + 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); + QHBoxLayout *buttonsLayout = new QHBoxLayout; + buttonsLayout->addStretch (1); + buttonsLayout->addWidget (buttonOk); + buttonsLayout->addWidget (buttonCancel); + + QVBoxLayout *mainLayout = new QVBoxLayout; + mainLayout->addLayout (horizontalLayout); + mainLayout->addSpacing (12); + mainLayout->addLayout (buttonsLayout); + setLayout (mainLayout); + if (fixed_layout) + layout()->setSizeConstraint (QLayout::SetFixedSize); + + setWindowTitle (name); + + connect (select_all, SIGNAL (clicked ()), + view, SLOT (selectAll ())); + + connect (buttonOk, SIGNAL (clicked ()), + this, SLOT (buttonOk_clicked ())); + + connect (buttonCancel, SIGNAL (clicked ()), + this, SLOT (buttonCancel_clicked ())); + + connect (this, SIGNAL (finish_selection (const QIntList&, const int)), + &uiwidget_creator, + SLOT (list_select_finished (const QIntList&, const int))); +} + + +void +ListDialog::buttonOk_clicked (void) +{ + // Store information about what button was pressed so that builtin + // functions can retrieve. + QModelIndexList selected_index = selector->selectedIndexes (); + QIntList selected_int; + + for (int i = 0; i < selected_index.size (); i++) + selected_int << selected_index.at (i).row () + 1; + + emit finish_selection (selected_int, 1); + + done (QDialog::Accepted); +} + + +void +ListDialog::buttonCancel_clicked (void) +{ + // Store information about what button was pressed so that builtin + // functions can retrieve. + QIntList empty; + + emit finish_selection (empty, 0); + + done (QDialog::Rejected); +} + + +void +ListDialog::reject (void) +{ + buttonCancel_clicked (); +} + + +InputDialog::InputDialog (const QStringList& prompt, const QString& title, + const QIntList& nr, const QIntList& nc, + const QStringList& defaults) + : QDialog () +{ + +//#define LINE_EDIT_FOLLOWS_PROMPT + +#ifdef LINE_EDIT_FOLLOWS_PROMPT + // Prompt on left followed by input on right. + QGridLayout *promptInputLayout = new QGridLayout; +#else + // Prompt aligned above input. + QVBoxLayout *promptInputLayout = new QVBoxLayout; +#endif + int N_gridrows = prompt.size (); + for (int i = 0; i < N_gridrows; i++) + { + QLabel *label = new QLabel (prompt.at (i)); + QLineEdit *line_edit = new QLineEdit (defaults.at (i)); + if (nr.at (i) > 0) + { + QSize qsize = line_edit->sizeHint (); + int intval = qsize.height () * nr.at (i); + line_edit->setFixedHeight (intval); + if (nc.at (i) > 0) + { + intval = qsize.height () * nc.at (i) / 2; + line_edit->setFixedWidth (intval); + } + } + input_line << line_edit; +#ifdef LINE_EDIT_FOLLOWS_PROMPT + promptInputLayout->addWidget (label, i + 1, 0); + promptInputLayout->addWidget (line_edit, i + 1, 1); +#else + promptInputLayout->addWidget (label); + promptInputLayout->addWidget (line_edit); +#endif + } + + QPushButton *buttonOk = new QPushButton("OK"); + QPushButton *buttonCancel = new QPushButton("Cancel"); + QHBoxLayout *buttonsLayout = new QHBoxLayout; + buttonsLayout->addStretch (1); + buttonsLayout->addWidget (buttonOk); + buttonsLayout->addWidget (buttonCancel); + + QVBoxLayout *mainLayout = new QVBoxLayout; + mainLayout->addLayout (promptInputLayout); + mainLayout->addSpacing (12); + mainLayout->addLayout (buttonsLayout); + setLayout (mainLayout); + + setWindowTitle (title); + + connect (buttonOk, SIGNAL (clicked ()), + this, SLOT (buttonOk_clicked ())); + + connect (buttonCancel, SIGNAL (clicked ()), + this, SLOT (buttonCancel_clicked ())); + + connect (this, SIGNAL (finish_input (const QStringList&, const int)), + &uiwidget_creator, + SLOT (input_finished (const QStringList&, const int))); +} + + +void +InputDialog::buttonOk_clicked (void) +{ + // Store information about what button was pressed so that builtin + // functions can retrieve. + QStringList string_result; + for (int i = 0; i < input_line.size (); i++) + string_result << input_line.at (i)->text (); + emit finish_input (string_result, 1); + done (QDialog::Accepted); +} + + +void +InputDialog::buttonCancel_clicked (void) +{ + // Store information about what button was pressed so that builtin + // functions can retrieve. + QStringList empty; + emit finish_input (empty, 0); + done (QDialog::Rejected); +} + + +void +InputDialog::reject (void) +{ + buttonCancel_clicked (); +}
new file mode 100644 --- /dev/null +++ b/libgui/src/dialog.h @@ -0,0 +1,222 @@ +/* + +Copyright (C) 2013 John W. Eaton +Copyright (C) 2013 Daniel J. Sebald + +This file is part of Octave. + +Octave is free software; you can redistribute it and/or modify it +under the terms of the GNU General Public License as published by the +Free Software Foundation; either version 3 of the License, or (at your +option) any later version. + +Octave 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 Octave; see the file COPYING. If not, see +<http://www.gnu.org/licenses/>. + +*/ + +#if !defined (octave_guifcn_dialog_h) +#define octave_guifcn_dialog_h 1 + +#include <QMutex> +#include <QWaitCondition> +#include <QAbstractButton> +#include <QList> +#include <QItemSelectionModel> +#include <QDialog> +#include <QMessageBox> +#include <QLineEdit> + +// Defined for purposes of sending QList<int> as part of signal. +typedef QList<int> QIntList; + +// Defined for purposes of sending QList<float> as part of signal. +typedef QList<float> QFloatList; + + +class QUIWidgetCreator : public QObject +{ + Q_OBJECT + +public: + + QUIWidgetCreator (void); + + ~QUIWidgetCreator (void); + +public: + + void signal_dialog (const QString& message, const QString& title, + const QString& icon, const QStringList& button, + const QString& defbutton, const QStringList& role) + { + + // 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. + if (!button.isEmpty ()) + dialog_button = button.last (); + + QString xicon = icon; + if (xicon.isEmpty ()) + xicon = "none"; + + emit create_dialog (message, title, xicon, button, defbutton, role); + }; + + int get_dialog_result (void) { return dialog_result; } + + const QString *get_dialog_button (void) { return &dialog_button; } + + 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& 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); + + return true; + }; + + 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 QStringList& defaults) + { + if (prompt.isEmpty ()) + return false; + + emit create_inputlayout (prompt, title, nr, nc, defaults); + + return true; + }; + + const QStringList *get_string_list (void) { return string_list; } + + void wait (void) + { + // Wait while the user is responding to message box. + waitcondition.wait (&mutex); + } + +signals: + + void create_dialog (const QString&, const QString&, const QString&, + const QStringList&, const QString&, const QStringList&); + + void create_listview (const QStringList&, const QString&, int, int, + const QIntList&, const QString&, const QString&, + const QString&, const QString&); + + void create_inputlayout (const QStringList&, const QString&, + const QIntList&, const QIntList&, + const QStringList&); + +public slots: + + void dialog_finished (int result); + + void dialog_button_clicked (QAbstractButton *button); + + void list_select_finished (const QIntList& selected, + const int button_pressed); + + void input_finished (const QStringList& input, const int button_pressed); + +private: + + int dialog_result; + QString dialog_button; + + // The list could conceivably be big. Not sure how things are + // stored internally, so keep off of the stack. + QStringList *string_list; + QIntList *list_index; + + // GUI objects cannot be accessed in the non-GUI thread. However, + // signals can be sent to slots across threads with proper + // synchronization. Hence, the use of QWaitCondition. + + QMutex mutex; + + QWaitCondition waitcondition; +}; + +extern QUIWidgetCreator uiwidget_creator; + +class MessageDialog : public QMessageBox +{ + Q_OBJECT + +public: + + explicit MessageDialog (const QString& message, const QString& title, + const QString& icon, const QStringList& button, + const QString& defbutton, + const QStringList& role); +}; + + +class ListDialog : public QDialog +{ + Q_OBJECT + + QItemSelectionModel *selector; + +public: + + 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& ok_string, const QString& cancel_string); + +signals: + + void finish_selection (const QIntList&, const int); + +public slots: + + void buttonOk_clicked (void); + + void buttonCancel_clicked (void); + + void reject (void); +}; + + +class InputDialog : public QDialog +{ + Q_OBJECT + + QList<QLineEdit *> input_line; + +public: + + explicit InputDialog (const QStringList& prompt, const QString& title, + const QIntList& nr, const QIntList& nc, + const QStringList& defaults); + +signals: + + void finish_input (const QStringList&, const int); + +public slots: + + void buttonOk_clicked (void); + + void buttonCancel_clicked (void); + + void reject (void); +}; + +#endif
--- a/libgui/src/main-window.cc +++ b/libgui/src/main-window.cc @@ -533,6 +533,101 @@ workspace_window->connect_visibility_changed (); } +// Connect the signals emitted when the Octave thread wants to create +// a dialog box of some sort. Perhaps a better place for this would be +// as part of the QUIWidgetCreator class. However, mainWindow currently +// is not a global variable and not accessible for connecting. + +void +main_window::connect_uiwidget_links () +{ + connect (&uiwidget_creator, + SIGNAL (create_dialog (const QString&, const QString&, + const QString&, const QStringList&, + const QString&, const QStringList&)), + this, + SLOT (handle_create_dialog (const QString&, const QString&, + const QString&, const QStringList&, + const QString&, const QStringList&))); + + // Register QIntList so that list of ints may be part of a signal. + qRegisterMetaType<QIntList> ("QIntList"); + connect (&uiwidget_creator, + SIGNAL (create_listview (const QStringList&, const QString&, + int, int, const QIntList&, + const QString&, const QString&, + const QString&, const QString&)), + this, + SLOT (handle_create_listview (const QStringList&, const QString&, + int, int, const QIntList&, + const QString&, const QString&, + const QString&, const QString&))); + + // Register QFloatList so that list of ints may be part of a signal. + qRegisterMetaType<QFloatList> ("QFloatList"); + connect (&uiwidget_creator, + SIGNAL (create_inputlayout (const QStringList&, const QString&, + const QIntList&, const QIntList&, + const QStringList&)), + this, + SLOT (handle_create_inputlayout (const QStringList&, const QString&, + const QIntList&, const QIntList&, + const QStringList&))); +} + +// Create a message dialog with specified string, buttons and decorative +// text. + +void +main_window::handle_create_dialog (const QString& message, + const QString& title, + const QString& icon, + const QStringList& button, + const QString& defbutton, + const QStringList& role) +{ + MessageDialog *message_dialog = new MessageDialog (message, title, icon, + button, defbutton, role); + message_dialog->setAttribute (Qt::WA_DeleteOnClose); + message_dialog->show (); +} + +// Create a list dialog with specified list, initially selected, mode, +// view size and decorative text. + +void +main_window::handle_create_listview (const QStringList& list, + const QString& mode, + int wd, int ht, + const QIntList& initial, + const QString& name, + const QString& prompt_string, + const QString& ok_string, + const QString& cancel_string) +{ + ListDialog *list_dialog = new ListDialog (list, mode, wd, ht, + initial, name, prompt_string, + ok_string, cancel_string); + + list_dialog->setAttribute (Qt::WA_DeleteOnClose); + list_dialog->show (); +} + +// Create an input dialog with specified prompts and defaults, title and +// row/column size specifications. +void +main_window::handle_create_inputlayout (const QStringList& prompt, + const QString& title, + const QIntList& nr, + const QIntList& nc, + const QStringList& defaults) +{ + InputDialog *input_dialog = new InputDialog (prompt, title, nr, nc, + defaults); + + input_dialog->setAttribute (Qt::WA_DeleteOnClose); + input_dialog->show (); +} // Main subroutine of the constructor void @@ -567,6 +662,8 @@ connect (file_browser_window, SIGNAL (load_file_signal (const QString&)), this, SLOT (handle_load_workspace_request (const QString&))); + connect_uiwidget_links (); + setWindowTitle ("Octave"); setDockOptions (QMainWindow::AnimatedDocks
--- a/libgui/src/main-window.h +++ b/libgui/src/main-window.h @@ -44,6 +44,7 @@ #include "QTerminal.h" // Own includes +#include "dialog.h" #include "resource-manager.h" #include "workspace-model.h" #include "workspace-view.h" @@ -119,6 +120,25 @@ void write_settings (void); void connect_visibility_changed (void); + void connect_uiwidget_links (); + + void handle_create_dialog (const QString& message, const QString& title, + const QString& icon, const QStringList& button, + const QString& defbutton, + const QStringList& role); + + void handle_create_listview (const QStringList& list, const QString& mode, + int width, int height, + const QIntList& initial, + const QString& name, + const QString& prompt_string, + const QString& ok_string, + const QString& cancel_string); + + void handle_create_inputlayout (const QStringList&, const QString&, + const QIntList&, const QIntList&, + const QStringList&); + protected: void closeEvent (QCloseEvent * closeEvent);
--- a/libgui/src/module.mk +++ b/libgui/src/module.mk @@ -72,6 +72,7 @@ endif octave_gui_MOC += \ + src/moc-dialog.cc \ src/moc-documentation-dock-widget.cc \ src/moc-files-dock-widget.cc \ src/moc-history-dock-widget.cc \ @@ -98,6 +99,7 @@ BUILT_SOURCES += $(octave_gui_UI_H) noinst_HEADERS += \ + src/dialog.h \ src/octave-dock-widget.h \ src/documentation-dock-widget.h \ src/files-dock-widget.h \ @@ -122,6 +124,7 @@ src/workspace-view.h src_libgui_src_la_SOURCES = \ + src/dialog.cc \ src/documentation-dock-widget.cc \ src/files-dock-widget.cc \ src/history-dock-widget.cc \
--- a/libgui/src/octave-qt-link.cc +++ b/libgui/src/octave-qt-link.cc @@ -30,6 +30,7 @@ #include "str-vec.h" +#include "dialog.h" #include "workspace-element.h" #include "octave-qt-link.h" @@ -62,6 +63,97 @@ return true; } +int +octave_qt_link::do_message_dialog (const std::string& dlg, + const std::string& msg, + const std::string& title) +{ + uiwidget_creator.signal_dialog (QString::fromStdString (msg), + QString::fromStdString (title), + QString (), QStringList (), + QString (), QStringList ()); + + // 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_result (); +} + +static QStringList +make_qstring_list (const std::list<std::string>& lst) +{ + QStringList retval; + + for (std::list<std::string>::const_iterator it = lst.begin (); + it != lst.end (); it++) + { + retval.append (QString::fromStdString (*it)); + } + + return retval; +} + + +std::pair<std::list<int>, int> +octave_qt_link::do_list_dialog (const std::list<std::string>& list, + const std::string& mode, + int width, int height, + const std::list<int>& initial, + const std::string& name, + const std::string& prompt_string, + const std::string& ok_string, + const std::string& cancel_string) +{ + uiwidget_creator.signal_listview (make_qstring_list (list), + QString::fromStdString (mode), + width, height, + QList<int>::fromStdList (initial), + QString::fromStdString (name), + QString::fromStdString (prompt_string), + QString::fromStdString (ok_string), + QString::fromStdString (cancel_string)); + + // Wait while the user is responding to message box. + uiwidget_creator.wait (); + + // The GUI has sent a signal and the process has been awakened. + const QIntList *selected = uiwidget_creator.get_list_index (); + int ok = uiwidget_creator.get_dialog_result (); + + return std::pair<std::list<int>, int> (selected->toStdList (), ok); +} + +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<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), + make_qstring_list (defaults)); + + // Wait while the user is responding to message box. + uiwidget_creator.wait (); + + // The GUI has sent a signal and the process has been awakened. + const QStringList *inputLine = uiwidget_creator.get_string_list (); + + for (QStringList::const_iterator it = inputLine->begin (); + it != inputLine->end (); it++) + { + retval.push_back (it->toStdString ()); + } + + return retval; +} + void octave_qt_link::do_change_directory (const std::string& dir) {
--- a/libgui/src/octave-qt-link.h +++ b/libgui/src/octave-qt-link.h @@ -59,6 +59,26 @@ bool do_edit_file (const std::string& file); + int do_message_dialog (const std::string& dlg, const std::string& msg, + const std::string& title); + + 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::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<std::string>& defaults); + void do_change_directory (const std::string& dir); void do_set_workspace (bool top_level,
--- a/libinterp/interpfcn/octave-link.cc +++ b/libinterp/interpfcn/octave-link.cc @@ -106,10 +106,166 @@ std::string file = args(0).string_value (); if (! error_state) - retval = octave_link::edit_file (file); + { + flush_octave_stdout (); + + retval = octave_link::edit_file (file); + } else error ("expecting file name as argument"); } return retval; } + +DEFUN (__octave_link_message_dialog__, args, , + "-*- texinfo -*-\n\ +@deftypefn {Built-in Function} {} __octave_link_message_dialog__ (@var{dlg}, @var{msg}, @var{title})\n\ +Undocumented internal function.\n\ +@end deftypefn") +{ + octave_value retval; + + if (args.length () == 3) + { + std::string dlg = args(0).string_value (); + std::string msg = args(1).string_value (); + std::string title = args(2).string_value (); + + if (! error_state) + { + flush_octave_stdout (); + + retval = octave_link::message_dialog (dlg, msg, title); + } + 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\ +Undocumented internal function.\n\ +@end deftypefn") +{ + octave_value_list retval; + + if (args.length () == 8) + { + Cell list = args(0).cell_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++) + list_lst.push_back (tlist(i)); + + std::string mode = args(1).string_value (); + + Matrix size_matrix = args(2).matrix_value (); + int width = size_matrix(0); + int height = size_matrix(1); + + Matrix initial_matrix = args(3).matrix_value (); + nel = initial_matrix.numel (); + std::list<int> initial_lst; + for (octave_idx_type i = 0; i < nel; i++) + initial_lst.push_back (initial_matrix(i)); + + std::string name = args(4).string_value (); + std::string prompt_string = args(5).string_value (); + std::string ok_string = args(6).string_value (); + std::string cancel_string = args(7).string_value (); + + if (! error_state) + { + flush_octave_stdout (); + + std::pair<std::list<int>, int> result + = octave_link::list_dialog (list_lst, mode, width, height, + initial_lst, name, prompt_string, + ok_string, cancel_string); + + std::list<int> items_lst = result.first; + nel = items_lst.size (); + Matrix items (dim_vector (1, nel)); + octave_idx_type i = 0; + for (std::list<int>::iterator it = items_lst.begin (); + it != items_lst.end (); it++) + { + items.xelem(i++) = *it; + } + + retval(1) = result.second; + retval(0) = items; + } + else + error ("invalid arguments"); + } + + return retval; +} + +DEFUN (__octave_link_input_dialog__, args, , + "-*- texinfo -*-\n\ +@deftypefn {Built-in Function} {} __octave_link_input_dialog__ (@var{prompt}, @var{title}, @var{rowscols}, @var{defaults})\n\ +Undocumented internal function.\n\ +@end deftypefn") +{ + octave_value retval; + + if (args.length () == 4) + { + Cell prompt = args(0).cell_value (); + Array<std::string> tmp = prompt.cellstr_value (); + octave_idx_type nel = tmp.numel (); + std::list<std::string> prompt_lst; + for (octave_idx_type i = 0; i < nel; i++) + prompt_lst.push_back (tmp(i)); + + std::string title = args(1).string_value (); + + Matrix rc = args(2).matrix_value (); + nel = rc.rows (); + std::list<int> nr; + std::list<int> nc; + for (octave_idx_type i = 0; i < nel; i++) + { + nr.push_back (rc(i,0)); + nc.push_back (rc(i,1)); + } + + Cell defaults = args(3).cell_value (); + tmp = defaults.cellstr_value (); + nel = tmp.numel (); + std::list<std::string> defaults_lst; + for (octave_idx_type i = 0; i < nel; i++) + defaults_lst.push_back (tmp(i)); + + if (! error_state) + { + flush_octave_stdout (); + + std::list<std::string> items_lst + = octave_link::input_dialog (prompt_lst, title, nr, nc, + defaults_lst); + + nel = items_lst.size (); + Cell items (dim_vector (1, nel)); + octave_idx_type i = 0; + for (std::list<std::string>::iterator it = items_lst.begin (); + it != items_lst.end (); it++) + { + items.xelem(i++) = *it; + } + + retval = items; + } + else + error ("invalid arguments"); + } + + return retval; +}
--- a/libinterp/interpfcn/octave-link.h +++ b/libinterp/interpfcn/octave-link.h @@ -134,6 +134,42 @@ return enabled () ? instance->do_edit_file (file) : false; } + static int + message_dialog (const std::string& dlg, const std::string& msg, + const std::string& title) + { + return enabled () ? instance->do_message_dialog (dlg, msg, title) : 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::string& ok_string, + const std::string& cancel_string) + { + return enabled () + ? instance->do_list_dialog (list, mode, width, height, + initial_value, name, prompt_string, + ok_string, cancel_string) + : std::pair<std::list<int>, int> (); + } + + 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<std::string>& defaults) + { + return enabled () + ? instance->do_input_dialog (prompt, title, nr, nc, defaults) + : std::list<std::string> (); + } + static void change_directory (const std::string& dir) { if (enabled ()) @@ -275,6 +311,27 @@ virtual bool do_edit_file (const std::string& file) = 0; + virtual int + do_message_dialog (const std::string& dlg, const std::string& msg, + const std::string& title) = 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::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<std::string>& defaults) = 0; + virtual void do_change_directory (const std::string& dir) = 0; virtual void
deleted file mode 100644 --- a/scripts/java/dlgtest.m +++ /dev/null @@ -1,205 +0,0 @@ -% -% Test the dlg... functions of the Octave-Java bridge -% -% Once the Java bridge works OK this function should be dropped from core octave -% -% Author: Martin Hepperle -% Version August 2010 -% Adapted for core Octave Philip Nienhuis 2012 -% -function dlgtest - - answer = 1; - while (answer > 0 ) - - disp(''); - disp('0 ... STOP'); - disp('1 ... listdlg tests'); - disp('2 ... errordlg tests'); - disp('3 ... warndlg tests'); - disp('4 ... helpdlg tests'); - disp('5 ... inputdlg tests'); - disp('6 ... TeX code tests'); - - answer = str2num(input ('Run which test? [0] > ','s')); - - disp(''); - - switch answer - case 1 - test_listdlg(); - case 2 - test_errordlg(); - case 3 - test_warndlg(); - case 4 - test_helpdlg(); - case 5 - test_inputdlg(); - case 6 - test_TeXCodes(); - end - end - - % d = javaObject('javax.swing.JDialog'); - % cp = d.getContentPane; - % b = javaObject('javax.swing.JButton','OK'); - % cp.add(b); - % d.pack; - % d.setVisible(true); - - - page_screen_output(1); - -end - -function test_listdlg - - %----------------------------------------------- - disp('- test listdlg with selectionmode single. No caption, no prompt.'); - itemlist = {'An item \\alpha', 'another', 'yet another'}; - s = listdlg ( 'ListString',itemlist, 'SelectionMode','Single' ); - imax = numel (s); - for i=1:1:imax - disp(['Selected: ',num2str(i),': ', itemlist{s(i)}]); - end - - %----------------------------------------------- - disp('- test listdlg with selectionmode and preselection. Has caption and two lines prompt.'); - s = listdlg ( 'ListString',itemlist, ... - 'SelectionMode','Multiple', ... - 'Name','Selection Dialog', ... - 'InitialValue',[1,2,3,4], - 'PromptString',{'Select an item...', '...or multiple items'} ); - imax = numel (s); - for i=1:1:imax - disp(['Selected: ',num2str(i),': ', itemlist{s(i)}]); - end - -end - -function test_errordlg - %----------------------------------------------- - disp('- test errordlg with prompt only.'); - errordlg('Oops, an expected error occured'); - %----------------------------------------------- - disp('- test errordlg with prompt and caption.'); - errordlg('Oops another error','This is a very long and informative caption'); -end - -function test_warndlg - %----------------------------------------------- - disp('- test warndlg with prompt only.'); - warndlg('Oh, a warning occured'); - %----------------------------------------------- - disp('- test warndlg with prompt and caption.'); - warndlg('Oh, No...','This is the last Warning'); -end - -function test_helpdlg - %----------------------------------------------- - disp('- test helpdlg with a help message only.'); - helpdlg("Below, you should see 3 lines:\nline #1\nline #2, and\nline #3."); - %----------------------------------------------- - disp('- test helpdlg with help message and caption.'); - helpdlg('You should see a single line.','A help dialog'); -end - -function test_inputdlg - %----------------------------------------------- - disp('- test inputdlg with prompt and caption only.'); - prompt = {'Width','Height','Depth'}; - dims = inputdlg ( prompt, 'Enter Box Dimensions' ); - if isempty(dims) - helpdlg('Canceled by user', 'Information'); - else - volume = str2num(dims{1}) * str2num(dims{2}) * str2num(dims{3}); - surface = 2 * (str2num(dims{1}) * str2num(dims{2}) + ... - str2num(dims{2}) * str2num(dims{3}) + ... - str2num(dims{1}) * str2num(dims{3})); - helpdlg(sprintf('Results:\nVolume = %.3f\nSurface = %.3f', volume, surface), 'Box Dimensions'); - end - - %----------------------------------------------- - disp('- test inputdlg with prescribed scalar (2 lines per text field) and defaults.'); - prompt = {'Width','Height','Depth'}; - default = {'1.1','2.2','3.3'}; - rc = 2; - dims = inputdlg ( prompt, 'Enter Box Dimensions',rc,default ); - if isempty(dims) - helpdlg('Canceled by user', 'Information'); - else - volume = str2num(dims{1}) * str2num(dims{2}) * str2num(dims{3}); - surface = 2 * (str2num(dims{1}) * str2num(dims{2}) + ... - str2num(dims{2}) * str2num(dims{3}) + ... - str2num(dims{1}) * str2num(dims{3})); - helpdlg(sprintf('Results:\nVolume = %.3f\nSurface = %.3f', volume, surface), 'Box Dimensions'); - end - %----------------------------------------------- - disp('- test inputdlg with prescribed vector [1,2,3] for # of lines per text field and defaults.'); - prompt = {'Width','Height','Depth'}; - default = {'1.10', '2.10', '3.10'}; - rc = [1,2,3]; % NOTE: must be an array - dims = inputdlg ( prompt, 'Enter Box Dimensions',rc,default ); - if isempty(dims) - helpdlg('Canceled by user', 'Information'); - else - volume = str2num(dims{1}) * str2num(dims{2}) * str2num(dims{3}); - surface = 2 * (str2num(dims{1}) * str2num(dims{2}) + ... - str2num(dims{2}) * str2num(dims{3}) + ... - str2num(dims{1}) * str2num(dims{3})); - helpdlg(sprintf('Results:\nVolume = %.3f\nSurface = %.3f', volume, surface), 'Box Dimensions'); - end - %----------------------------------------------- - disp('- test inputdlg with prescribed row by column sizes and defaults.'); - prompt = {'Width','Height','Depth'}; - default = {'1.10', '2.20', '3.30'}; - rc = [1,10; 2,20; 3,30]; % NOTE: must be an array - dims = inputdlg ( prompt, 'Enter Box Dimensions',rc,default ); - if isempty(dims) - helpdlg('Canceled by user', 'Information'); - else - volume = str2num(dims{1}) * str2num(dims{2}) * str2num(dims{3}); - surface = 2 * (str2num(dims{1}) * str2num(dims{2}) + ... - str2num(dims{2}) * str2num(dims{3}) + ... - str2num(dims{1}) * str2num(dims{3})); - helpdlg(sprintf('Results:\nVolume = %.3f\nSurface = %.3f', volume, surface), 'Box Dimensions'); - end -end - -%% show a table of TeX symbol codes and the resulting Unicode character -function test_TeXCodes - %----------------------------------------------- - disp('- test TeX code to Unicode translation.'); - - msgbox ( ['\\alpha = ''\alpha '' \\beta = ''\beta '' \\gamma = ''\gamma ''', 10, ... - '\\delta = ''\delta '' \\epsilon = ''\epsilon '' \\zeta = ''\zeta ''', 10, ... - '\\eta = ''\eta '' \\theta = ''\theta '' \\vartheta = ''\vartheta ''', 10, ... - '\\iota = ''\iota '' \\kappa = ''\kappa '' \\lambda = ''\lambda ''', 10, ... - '\\mu = ''\mu '' \\nu = ''\nu '' \\xi = ''\xi ''', 10, ... - '\\pi = ''\pi '' \\rho = ''\rho '' \\sigma = ''\sigma ''', 10, ... - '\\varsigma = ''\varsigma '' \\tau = ''\tau '' \\phi = ''\phi ''', 10, ... - '\\chi = ''\chi '' \\psi = ''\psi '' \\omega = ''\omega ''', 10, ... - '\\upsilon = ''\upsilon '' \\Gamma = ''\Gamma '' \\Delta = ''\Delta ''', 10, ... - '\\Theta = ''\Theta '' \\Lambda = ''\Lambda '' \\Pi = ''\Pi ''', 10, ... - '\\Xi = ''\Xi '' \\Sigma = ''\Sigma '' \\Upsilon = ''\Upsilon ''', 10, ... - '\\Phi = ''\Phi '' \\Psi = ''\Psi '' \\Omega = ''\Omega ''', 10, ... - '\\Im = ''\Im '' \\Re = ''\Re '' \\leq = ''\leq ''', 10, ... - '\\geq = ''\geq '' \\neq = ''\neq '' \\pm = ''\pm ''', 10, ... - '\\infty = ''\infty '' \\partial = ''\partial '' \\approx = ''\approx ''', 10, ... - '\\circ = ''\circ '' \\bullet = ''\bullet '' \\times = ''\times ''', 10, ... - '\\sim = ''\sim '' \\nabla = ''\nabla '' \\ldots = ''\ldots ''', 10, ... - '\\exists = ''\exists '' \\neg = ''\neg '' \\aleph = ''\aleph ''', 10, ... - '\\forall = ''\forall '' \\cong = ''\cong '' \\wp = ''\wp ''', 10, ... - '\\propto = ''\propto '' \\otimes = ''\otimes '' \\oplus = ''\oplus ''', 10, ... - '\\oslash = ''\oslash '' \\cap = ''\cap '' \\cup = ''\cup ''', 10, ... - '\\ni = ''\ni '' \\in = ''\in '' \\div = ''\div ''', 10, ... - '\\equiv = ''\equiv '' \\int = ''\int '' \\perp = ''\perp ''', 10, ... - '\\wedge = ''\wedge '' \\vee = ''\vee '' \\supseteq = ''\supseteq ''', 10, ... - '\\supset = ''\supset '' \\subseteq = ''\subseteq '' \\subset = ''\subset ''', 10, ... - '\\clubsuit = ''\clubsuit '' \\spadesuit = ''\spadesuit '' \\heartsuit = ''\heartsuit ''', 10, ... - '\\diamondsuit = ''\diamondsuit '' \\copyright = ''\copyright '' \\leftarrow = ''\leftarrow ''', 10, ... - '\\uparrow = ''\uparrow '' \\rightarrow = ''\rightarrow '' \\downarrow = ''\downarrow ''', 10, ... - '\\leftrightarrow = ''\leftrightarrow '' \\updownarrow = ''\updownarrow '''], ... - 'TeX symbol code table Test'); -end
--- a/scripts/java/module.mk +++ b/scripts/java/module.mk @@ -1,7 +1,6 @@ FCN_FILE_DIRS += java java_FCN_FILES = \ - java/dlgtest.m \ java/javaArray.m \ java/javaaddpath.m \ java/javaclasspath.m \
--- a/scripts/ui/errordlg.m +++ b/scripts/ui/errordlg.m @@ -40,3 +40,10 @@ endfunction +%!demo +%! disp('- test errordlg with prompt only.'); +%! errordlg('Oops, an expected error occured'); + +%!demo +%! disp('- test errordlg with prompt and caption.'); +%! errordlg('Oops another error','This is a very long and informative caption');
--- a/scripts/ui/helpdlg.m +++ b/scripts/ui/helpdlg.m @@ -40,3 +40,10 @@ endfunction +%!demo +%! disp('- test helpdlg with a help message only.'); +%! helpdlg("Below, you should see 3 lines:\nline #1\nline #2, and\nline #3."); + +%!demo +%! disp('- test helpdlg with help message and caption.'); +%! helpdlg('You should see a single line.','A help dialog');
--- a/scripts/ui/inputdlg.m +++ b/scripts/ui/inputdlg.m @@ -126,13 +126,90 @@ defs = cellfun (@num2str, defaults, "UniformOutput", false); rc = arrayfun (@num2str, rowscols, "UniformOutput", false); - user_inputs = javaMethod ("inputdlg", "org.octave.JDialogBox", - prompt, title, rc, defs); - - if (isempty (user_inputs)) - cstr = {}; - else - cstr = cellstr (user_inputs); - endif + cstr = __octave_link_input_dialog__ (prompt, title, rowscols, defs); + + if (iscell (cstr)) + return; + endif + + if (__have_feature__ ("JAVA")) + user_inputs = javaMethod ("inputdlg", "org.octave.JDialogBox", + prompt, title, rc, defs); + + if (isempty (user_inputs)) + cstr = {}; + else + cstr = cellstr (user_inputs); + endif + + return; + + endif + + ## FIXME -- provide terminal-based implementation here? + + error ("inputdlg is not available in this version of Octave"); endfunction + +%!demo +%! disp('- test inputdlg with prompt and caption only.'); +%! prompt = {'Width','Height','Depth'}; +%! dims = inputdlg ( prompt, 'Enter Box Dimensions' ); +%! if isempty(dims) +%! helpdlg('Canceled by user', 'Information'); +%! else +%! volume = str2num(dims{1}) * str2num(dims{2}) * str2num(dims{3}); +%! surface = 2 * (str2num(dims{1}) * str2num(dims{2}) + ... +%! str2num(dims{2}) * str2num(dims{3}) + ... +%! str2num(dims{1}) * str2num(dims{3})); +%! helpdlg(sprintf('Results:\nVolume = %.3f\nSurface = %.3f', volume, surface), 'Box Dimensions'); +%! end + +%!demo +%! disp('- test inputdlg with prescribed scalar (2 lines per text field) and defaults.'); +%! prompt = {'Width','Height','Depth'}; +%! default = {'1.1','2.2','3.3'}; +%! rc = 2; +%! dims = inputdlg ( prompt, 'Enter Box Dimensions',rc,default ); +%! if isempty(dims) +%! helpdlg('Canceled by user', 'Information'); +%! else +%! volume = str2num(dims{1}) * str2num(dims{2}) * str2num(dims{3}); +%! surface = 2 * (str2num(dims{1}) * str2num(dims{2}) + ... +%! str2num(dims{2}) * str2num(dims{3}) + ... +%! str2num(dims{1}) * str2num(dims{3})); +%! helpdlg(sprintf('Results:\nVolume = %.3f\nSurface = %.3f', volume, surface), 'Box Dimensions'); +%! end + +%!demo +%! disp('- test inputdlg with prescribed vector [1,2,3] for # of lines per text field and defaults.'); +%! prompt = {'Width','Height','Depth'}; +%! default = {'1.10', '2.10', '3.10'}; +%! rc = [1,2,3]; % NOTE: must be an array +%! dims = inputdlg ( prompt, 'Enter Box Dimensions',rc,default ); +%! if isempty(dims) +%! helpdlg('Canceled by user', 'Information'); +%! else +%! volume = str2num(dims{1}) * str2num(dims{2}) * str2num(dims{3}); +%! surface = 2 * (str2num(dims{1}) * str2num(dims{2}) + ... +%! str2num(dims{2}) * str2num(dims{3}) + ... +%! str2num(dims{1}) * str2num(dims{3})); +%! helpdlg(sprintf('Results:\nVolume = %.3f\nSurface = %.3f', volume, surface), 'Box Dimensions'); +%! end + +%!demo +%! disp('- test inputdlg with prescribed row by column sizes and defaults.'); +%! prompt = {'Width','Height','Depth'}; +%! default = {'1.10', '2.20', '3.30'}; +%! rc = [1,10; 2,20; 3,30]; % NOTE: must be an array +%! dims = inputdlg ( prompt, 'Enter Box Dimensions',rc,default ); +%! if isempty(dims) +%! helpdlg('Canceled by user', 'Information'); +%! else +%! volume = str2num(dims{1}) * str2num(dims{2}) * str2num(dims{3}); +%! surface = 2 * (str2num(dims{1}) * str2num(dims{2}) + ... +%! str2num(dims{2}) * str2num(dims{3}) + ... +%! str2num(dims{1}) * str2num(dims{3})); +%! helpdlg(sprintf('Results:\nVolume = %.3f\nSurface = %.3f', volume, surface), 'Box Dimensions'); +%! end
--- a/scripts/ui/listdlg.m +++ b/scripts/ui/listdlg.m @@ -77,7 +77,7 @@ ## @seealso{errordlg, helpdlg, inputdlg, msgbox, questdlg, warndlg} ## @end deftypefn -function varargout = listdlg (varargin) +function [sel, ok] = listdlg (varargin) if (nargin < 2) print_usage (); @@ -122,21 +122,60 @@ if (! iscell (listcell)) listcell = {listcell}; endif - - ## 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); + + [sel, ok] = __octave_link_list_dialog__ (listcell, selmode, listsize, + initialvalue, name, prompt, + okstring, cancelstring); + if (ok > 0) + return; + endif - if (numel (ret) > 0) - varargout = {ret, 1}; - else - varargout = {{}, 0}; + 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); + + if (numel (ret) > 0) + sel = ret; + ok = 1; + else + sel = {}; + ok = 0; + endif + + return; + endif + ## FIXME -- provide terminal-based implementation here? + + error ("listdlg is not available in this version of Octave"); + endfunction +%!demo +%! disp('- test listdlg with selectionmode single. No caption, no prompt.'); +%! itemlist = {'An item \\alpha', 'another', 'yet another'}; +%! s = listdlg ( 'ListString',itemlist, 'SelectionMode','Single' ); +%! imax = numel (s); +%! for i=1:1:imax +%! disp(['Selected: ',num2str(i),': ', itemlist{s(i)}]); +%! end + +%!demo +%! disp('- test listdlg with selectionmode and preselection. Has caption and two lines prompt.'); +%! itemlist = {'An item \\alpha', 'another', 'yet another'}; +%! s = listdlg ( 'ListString',itemlist, ... +%! 'SelectionMode','Multiple', ... +%! 'Name','Selection Dialog', ... +%! 'InitialValue',[1,2,3,4], +%! 'PromptString',{'Select an item...', '...or multiple items'} ); +%! imax = numel (s); +%! for i=1:1:imax +%! disp(['Selected: ',num2str(i),': ', itemlist{s(i)}]); +%! end
--- a/scripts/ui/msgbox.m +++ b/scripts/ui/msgbox.m @@ -45,3 +45,10 @@ endfunction +%!demo +%! disp('- test msgbox message only.'); +%! msgbox("Below, you should see 3 lines:\nline #1\nline #2, and\nline #3."); + +%!demo +%! disp('- test msgbox message and caption.'); +%! msgbox('You should see a single line.','A msgbox');
--- a/scripts/ui/private/message_dialog.m +++ b/scripts/ui/private/message_dialog.m @@ -52,16 +52,21 @@ endswitch endif + retval = __octave_link_message_dialog__ (dlg, msg, title); + if (retval > 0) + return; + endif + if (__have_feature__ ("JAVA")) retval = javaMethod (dlg, "org.octave.JDialogBox", msg, title); - if (retval) + if (retval > 0) return; endif endif ## FIXME -- provide terminal-based implementation here? - if (! retval) + if (retval <= 0) error ("%s is not available in this version of Octave", dlg); endif