Mercurial > hg > octave-jordi
changeset 18849:479d1d3cb5c3
maint: Periodic merge of gui-release to default.
author | John W. Eaton <jwe@octave.org> |
---|---|
date | Thu, 19 Jun 2014 18:08:00 -0400 |
parents | aa9ca67f09fb (current diff) b314efd58072 (diff) |
children | 47d4b680d0e0 |
files | doc/interpreter/plot.txi libgui/src/files-dock-widget.cc libgui/src/main-window.cc libgui/src/settings-dialog.cc libgui/src/shortcut-manager.cc libinterp/corefcn/graphics.in.h libinterp/corefcn/ls-mat5.cc libinterp/dldfcn/chol.cc liboctave/array/CMatrix.cc liboctave/array/dMatrix.cc liboctave/array/fCMatrix.cc liboctave/array/fMatrix.cc |
diffstat | 23 files changed, 550 insertions(+), 167 deletions(-) [+] |
line wrap: on
line diff
--- a/bootstrap.conf +++ b/bootstrap.conf @@ -50,6 +50,10 @@ isatty largefile link + log2 + log2-ieee + log2f + log2f-ieee lstat malloc-gnu mbrtowc
--- a/doc/interpreter/expr.txi +++ b/doc/interpreter/expr.txi @@ -1237,8 +1237,19 @@ @end example @noindent -where @var{op} can be either @code{+}, @code{-}, @code{*}, or @code{/}. -So, the expression +where @var{op} can be either @code{+}, @code{-}, @code{*}, or @code{/}, +as long as @var{expr2} is a simple expression with no side effects. If +@var{expr2} also contains an assignment operator, then this expression +is evaluated as + +@example +@var{temp} = @var{expr2} +@var{expr1} = (@var{expr1}) @var{op} @var{temp} +@end example + +@noindent +where @var{temp} is a placeholder temporary value storing the computed +result of evaluating @var{expr2}. So, the expression @example a *= b+1
--- a/doc/interpreter/plot.txi +++ b/doc/interpreter/plot.txi @@ -593,21 +593,21 @@ @node Use of the @code{interpreter} Property @subsection Use of the @code{interpreter} Property -All text objects, including titles, labels, legends, and text, include -the property @qcode{"interpreter"}, this property determines the manner in which -special control sequences in the text are rendered. If the interpreter -is set to @qcode{"none"}, then no rendering occurs. At this point the -@qcode{"latex"} option is not implemented and so the @qcode{"latex"} -interpreter also does not interpret the text. - -The @qcode{"tex"} option implements a subset of @TeX{} functionality in the -rendering of the text. This allows the insertion of special characters -such as Greek or mathematical symbols within the text. The special -characters are also inserted with a code starting with the backslash -(\) character, as in the table @ref{tab:extended}. +All text objects---such as titles, labels, legends, and text---include +the property @qcode{"interpreter"}, this property determines the manner in +which special control sequences in the text are rendered. If the interpreter +is set to @qcode{"none"}, then no rendering occurs. Currently the +@qcode{"latex"} interpreter is not implemented and is equivalent to +@qcode{"none"}. + +The @qcode{"tex"} option implements a subset of @TeX{} functionality when +rendering text. This allows the insertion of special glyphs such as Greek +characters or mathematical symbols. The special characters are inserted with +a code following a backslash (\) character, as in the table +@ref{tab:extended}. In addition, the formatting of the text can be changed within the string -with the codes +by using the codes @multitable @columnfractions .2 .2 .6 .2 @item @tab \bf @tab Bold font @tab @@ -616,7 +616,7 @@ @item @tab \rm @tab Normal font @tab @end multitable -These are be used in conjunction with the @{ and @} characters to limit +These may be used in conjunction with the @{ and @} characters to limit the change in the font to part of the string. For example, @example @@ -636,7 +636,7 @@ use @tab @end multitable -Finally, the superscript and subscripting can be controlled with the @qcode{'^'} +Finally, superscripting and subscripting can be controlled with the @qcode{'^'} and @qcode{'_'} characters. If the @qcode{'^'} or @qcode{'_'} is followed by a @{ character, then all of the block surrounded by the @{ @} pair is super- or sub-scripted. Without the @{ @} pair, only the character immediately following
--- a/libgui/qterminal-module.mk +++ b/libgui/qterminal-module.mk @@ -10,6 +10,7 @@ qterminal/libqterminal/unix/CharacterColor.h \ qterminal/libqterminal/unix/Emulation.h \ qterminal/libqterminal/unix/ExtendedDefaultTranslator.h \ + qterminal/libqterminal/unix/ExtendedDefaultTranslatorMac.h \ qterminal/libqterminal/unix/Filter.h \ qterminal/libqterminal/unix/History.h \ qterminal/libqterminal/unix/KeyboardTranslator.h \
--- a/libgui/src/files-dock-widget.cc +++ b/libgui/src/files-dock-widget.cc @@ -828,7 +828,7 @@ QString dir = QFileDialog::getExistingDirectory (this, tr ("Set directory of file browser"), _file_system_model->rootPath (), - QFileDialog::DontUseNativeDialog); + QFileDialog::ShowDirsOnly | QFileDialog::DontUseNativeDialog); set_current_directory (dir); }
--- a/libgui/src/m-editor/file-editor-tab.cc +++ b/libgui/src/m-editor/file-editor-tab.cc @@ -48,6 +48,7 @@ #include <QVBoxLayout> #include <QInputDialog> #include <QPrintDialog> +#include <QDateTime> #include "file-editor-tab.h" #include "file-editor.h" @@ -58,6 +59,7 @@ #include "octave-qt-link.h" #include "version.h" #include "utils.h" +#include "defaults.h" // Make parent null for the file editor tab so that warning // WindowModal messages don't affect grandparents. @@ -67,6 +69,7 @@ _lexer_apis = 0; _app_closing = false; _is_octave_file = true; + _modal_dialog = false; // Make sure there is a slash at the end of the directory name // for identification when saved later. @@ -330,17 +333,75 @@ } } + QSettings *settings = resource_manager::get_settings (); + + // build information for auto completion (APIs) _lexer_apis = new QsciAPIs(lexer); + if (_lexer_apis) { + bool update_apis_file = false; // flag, whether update of apis files + // get path to prepared api info QDesktopServices desktopServices; QString prep_apis_path = desktopServices.storageLocation (QDesktopServices::HomeLocation) + "/.config/octave/" + QString(OCTAVE_VERSION) + "/qsci/"; - _prep_apis_file = prep_apis_path + lexer->lexer () + ".pap"; + + // get settings which infos are used for octave + bool octave_builtins = settings->value ( + "editor/codeCompletion_octave_builtins", true).toBool (); + bool octave_functions = settings->value ( + "editor/codeCompletion_octave_functions", true).toBool (); + + if (_is_octave_file) + { + // octave file: keywords are always used + _prep_apis_file = prep_apis_path + lexer->lexer () + "_k"; + + if (octave_builtins) + _prep_apis_file = _prep_apis_file + "b"; // use builtins, too + + if (octave_functions) + _prep_apis_file = _prep_apis_file + "f"; // use keywords, too + + _prep_apis_file = _prep_apis_file + ".pap"; // final name of apis file + + // check whether the APIs info needs to be prepared and saved + QFileInfo apis_file = QFileInfo (_prep_apis_file); + update_apis_file = ! apis_file.exists (); // flag whether apis file needs update - if (!_lexer_apis->loadPrepared (_prep_apis_file)) + // function list depends on installed packages: check mod. date + if (! update_apis_file & octave_functions) + { + // check whether package file is newer than apis_file + QDateTime apis_date = apis_file.lastModified (); + + // compare to local package list + // FIXME: How to get user chosen location? + QFileInfo local_pkg_list = QFileInfo ( + desktopServices.storageLocation (QDesktopServices::HomeLocation) + + "/.octave_packages"); + if (local_pkg_list.exists () + & (apis_date < local_pkg_list.lastModified ()) ) + update_apis_file = true; + + // compare to global package list + // FIXME: How to get user chosen location? + QFileInfo global_pkg_list = QFileInfo ( + QString::fromStdString (Voctave_home) + + "/share/octave/octave_packages"); + if (global_pkg_list.exists () + & (apis_date < global_pkg_list.lastModified ()) ) + update_apis_file = true; + } + } + else // no octave file, just add extension + { + _prep_apis_file = prep_apis_path + lexer->lexer () + ".pap"; + } + + if (update_apis_file | !_lexer_apis->loadPrepared (_prep_apis_file)) { // no prepared info loaded, prepare and save if possible @@ -348,12 +409,34 @@ QString keyword; QStringList keyword_list; int i,j; - for (i=1; i<=3; i++) // test the first 5 keyword sets + + if (_is_octave_file) { - keyword = QString(lexer->keywords (i)); // get list - keyword_list = keyword.split (QRegExp ("\\s+")); // split - for (j = 0; j < keyword_list.size (); j++) // add to API - _lexer_apis->add (keyword_list.at (j)); + // octave: get keywords from internal informations depending on + // user preferences + + // keywords are always used + add_octave_apis (F__keywords__ ()); // add new entries + + if (octave_builtins) + add_octave_apis (F__builtins__ ()); // add new entries + + if (octave_functions) + add_octave_apis (F__list_functions__ ()); // add new entries + + } + else + { + + _prep_apis_file = prep_apis_path + lexer->lexer () + ".pap"; + + for (i=1; i<=3; i++) // test the first 5 keyword sets + { + keyword = QString(lexer->keywords (i)); // get list + keyword_list = keyword.split (QRegExp ("\\s+")); // split + for (j = 0; j < keyword_list.size (); j++) // add to API + _lexer_apis->add (keyword_list.at (j)); + } } // dsiconnect slot for saving prepared info if already connected @@ -369,9 +452,7 @@ } } - QSettings *settings = resource_manager::get_settings (); - if (settings) - lexer->readSettings (*settings); + lexer->readSettings (*settings); _edit_area->setLexer (lexer); @@ -383,6 +464,17 @@ } +// function for adding entries to the octave lexer's APIs +void +file_editor_tab::add_octave_apis (octave_value_list key_ovl) +{ + octave_value keys = key_ovl(0); + Cell key_list = keys.cell_value (); + + for (int idx = 0; idx < key_list.numel (); idx++) + _lexer_apis->add (QString (key_list.elem (idx).string_value ().data ())); +} + void file_editor_tab::save_apis_info () { @@ -481,8 +573,12 @@ if (ID != this) return; - if (_edit_area->isModified ()) - save_file (_file_name); + if (_edit_area->isModified () | ! valid_file_name ()) + { + _modal_dialog = true; // force modal dialog if the file is a new one + save_file (_file_name); // save file dialog + _modal_dialog = false; // back to non-modal dialogs + } QFileInfo info (_file_name); emit run_file_signal (info); @@ -986,12 +1082,12 @@ } // show_dialog: shows a modal or non modal dialog depeding on the closing -// of the app +// of the app and the flag _modal_dialog void file_editor_tab::show_dialog (QDialog *dlg) { dlg->setAttribute (Qt::WA_DeleteOnClose); - if (_app_closing) + if (_app_closing | _modal_dialog) dlg->exec (); else { @@ -1233,6 +1329,11 @@ // constructor argument. fileDialog->setDirectory (_file_name); } + + // propose a name corresponding to the function name + QString fname = get_function_name (); + if (! fname.isEmpty ()) + fileDialog->selectFile (fname + ".m"); } fileDialog->setNameFilter (tr ("Octave Files (*.m);;All Files (*)")); @@ -1648,4 +1749,26 @@ emit set_global_edit_shortcuts_signal (! focus); } +QString +file_editor_tab::get_function_name () +{ + QRegExp rxfun1 ("^([\t ]*)function([^=]+)=([^\\(]+)\\(([^\\)]*)\\)"); + QRegExp rxfun2 ("^([\t ]*)function([^\\(]+)\\(([^\\)]*)\\)"); + QRegExp rxfun3 ("^([\t ]*)function([\t ]*)([^\t ]+)"); + + QStringList lines = _edit_area->text ().split ("\n"); + + for (int i = 0; i < lines.count (); i++) + { + if (rxfun1.indexIn (lines.at (i)) != -1) + return rxfun1.cap (3).remove (QRegExp("[ \t]*")); + else if (rxfun2.indexIn (lines.at (i)) != -1) + return rxfun2.cap (2).remove (QRegExp("[ \t]*")); + else if (rxfun3.indexIn (lines.at (i)) != -1) + return rxfun3.cap (3).remove (QRegExp("[ \t]*")); + } + + return QString (); +} + #endif
--- a/libgui/src/m-editor/file-editor-tab.h +++ b/libgui/src/m-editor/file-editor-tab.h @@ -34,6 +34,7 @@ #include "find-dialog.h" #include "octave-qscintilla.h" +#include "builtin-defun-decls.h" class file_editor; @@ -206,6 +207,9 @@ void remove_all_breakpoints_callback (const bp_info& info); void center_current_line (); + void add_octave_apis (octave_value_list key_ovl); + QString get_function_name (); + octave_qscintilla *_edit_area; QStatusBar *_status_bar; @@ -219,6 +223,7 @@ bool _copy_available; bool _app_closing; bool _is_octave_file; + bool _modal_dialog; QFileSystemWatcher _file_system_watcher;
--- a/libgui/src/main-window.cc +++ b/libgui/src/main-window.cc @@ -369,14 +369,17 @@ release_notes_window->setWindowTitle (tr ("Octave Release Notes")); browser->document()->adjustSize (); - QSize doc_size = browser->document()->size().toSize (); - doc_size.rwidth () += 45; - int h = QApplication::desktop ()->height (); - if (h > 800) - h = 800; - doc_size.rheight () = h; - - release_notes_window->resize (doc_size); + + // center the window on the screen where octave is running + QDesktopWidget *m_desktop = QApplication::desktop (); + int screen = m_desktop->screenNumber (this); // screen of the main window + QRect screen_geo = m_desktop->availableGeometry (screen); + int win_x = screen_geo.width (); // width of the screen + int win_y = screen_geo.height (); // height of the screen + int reln_x = std::min (480, win_x-80); // desired width of release notes + int reln_y = std::min (640, win_y-80); // desired height of release notes + release_notes_window->resize (reln_x, reln_y); // set size + release_notes_window->move (20, 0); // move to the top left corner } if (! release_notes_window->isVisible ()) @@ -556,9 +559,16 @@ community_news_window->setLayout (vlayout); community_news_window->setWindowTitle (tr ("Octave Community News")); - community_news_window->resize (640, 480); - int win_x = QApplication::desktop ()->width (); - int win_y = QApplication::desktop ()->height (); + + // center the window on the screen where octave is running + QDesktopWidget *m_desktop = QApplication::desktop (); + int screen = m_desktop->screenNumber (this); // screen of the main window + QRect screen_geo = m_desktop->availableGeometry (screen); + int win_x = screen_geo.width (); // width of the screen + int win_y = screen_geo.height (); // height of the screen + int news_x = std::min (640, win_x-80); // desired width of news window + int news_y = std::min (480, win_y-80); // desired height of news window + community_news_window->resize (news_x, news_y); // set size and center community_news_window->move ((win_x - community_news_window->width ())/2, (win_y - community_news_window->height ())/2); } @@ -1014,11 +1024,6 @@ { foreach (octave_dock_widget *widget, dock_widget_list ()) widget->connect_visibility_changed (); - -#ifdef HAVE_QSCINTILLA - // Main window completely shown, determine whether to create an empty script - editor_window->empty_script (true, false); -#endif } void @@ -1323,6 +1328,14 @@ } set_current_working_directory (startup_dir.absolutePath ()); + +#ifdef HAVE_QSCINTILLA + // Octave ready, determine whether to create an empty script. + // This can not be done when the editor is created because all functions + // must be known for the lexer's auto completion informations + editor_window->empty_script (true, false); +#endif + } @@ -2082,7 +2095,7 @@ command_editor::redisplay (); // We are executing inside the command editor event loop. Force // the current line to be returned for processing. - command_editor::interrupt (); + command_editor::accept_line (); } if (repost) // queue not empty, so repost event for further processing
--- a/libgui/src/settings-dialog.cc +++ b/libgui/src/settings-dialog.cc @@ -58,8 +58,6 @@ { ui->setupUi (this); - shortcut_manager::fill_treewidget (ui->shortcuts_treewidget); - QSettings *settings = resource_manager::get_settings (); // restore last geometry @@ -168,6 +166,14 @@ settings->value ("editor/codeCompletion_threshold",2).toInt ()); ui->editor_checkbox_ac_keywords->setChecked ( settings->value ("editor/codeCompletion_keywords",true).toBool ()); + ui->editor_checkbox_ac_builtins->setEnabled ( + ui->editor_checkbox_ac_keywords->isChecked ()); + ui->editor_checkbox_ac_functions->setEnabled ( + ui->editor_checkbox_ac_keywords->isChecked ()); + ui->editor_checkbox_ac_builtins->setChecked ( + settings->value ("editor/codeCompletion_octave_builtins",true).toBool ()); + ui->editor_checkbox_ac_functions->setChecked ( + settings->value ("editor/codeCompletion_octave_functions",true).toBool ()); ui->editor_checkbox_ac_document->setChecked ( settings->value ("editor/codeCompletion_document",false).toBool ()); ui->editor_checkbox_ac_case->setChecked ( @@ -280,12 +286,27 @@ read_terminal_colors (settings); // shortcuts + ui->cb_prevent_readline_conflicts->setChecked ( settings->value ("shortcuts/prevent_readline_conflicts", true).toBool ()); int set = settings->value ("shortcuts/set",0).toInt (); ui->rb_sc_set1->setChecked (set == 0); ui->rb_sc_set2->setChecked (set == 1); + // initialize the tree view with all shortcut data + shortcut_manager::fill_treewidget (ui->shortcuts_treewidget); + + // connect the buttons for import/export of the shortcut sets + connect (ui->btn_import_shortcut_set1, SIGNAL (clicked ()), + this, SLOT (import_shortcut_set1 ())); + connect (ui->btn_export_shortcut_set1, SIGNAL (clicked ()), + this, SLOT (export_shortcut_set1 ())); + connect (ui->btn_import_shortcut_set2, SIGNAL (clicked ()), + this, SLOT (import_shortcut_set2 ())); + connect (ui->btn_export_shortcut_set2, SIGNAL (clicked ()), + this, SLOT (export_shortcut_set2 ())); + + #ifdef HAVE_QSCINTILLA // editor styles: create lexer, read settings, and create dialog elements QsciLexer *lexer; @@ -592,6 +613,10 @@ ui->editor_spinbox_ac_threshold->value ()); settings->setValue ("editor/codeCompletion_keywords", ui->editor_checkbox_ac_keywords->isChecked ()); + settings->setValue ("editor/codeCompletion_octave_builtins", + ui->editor_checkbox_ac_builtins->isChecked ()); + settings->setValue ("editor/codeCompletion_octave_functions", + ui->editor_checkbox_ac_functions->isChecked ()); settings->setValue ("editor/codeCompletion_document", ui->editor_checkbox_ac_document->isChecked ()); settings->setValue ("editor/codeCompletion_case", @@ -713,7 +738,7 @@ if (ui->rb_sc_set2->isChecked ()) set = 1; settings->setValue ("shortcuts/set",set); - shortcut_manager::write_shortcuts (); + shortcut_manager::write_shortcuts (0, settings); // 0: write both sets // settings dialog's geometry settings->setValue ("settings/last_tab",ui->tabWidget->currentIndex ()); @@ -882,3 +907,28 @@ ui->pb_file_browser_dir->setDisabled (disable); } } + +// slots for import/export of shortcut sets +void +settings_dialog::import_shortcut_set1 () +{ + shortcut_manager::import_export (true,1); +} + +void +settings_dialog::export_shortcut_set1 () +{ + shortcut_manager::import_export (false,1); +} + +void +settings_dialog::import_shortcut_set2 () +{ + shortcut_manager::import_export (true,2); +} + +void +settings_dialog::export_shortcut_set2 () +{ + shortcut_manager::import_export (false,2); +}
--- a/libgui/src/settings-dialog.h +++ b/libgui/src/settings-dialog.h @@ -52,6 +52,12 @@ void get_dir (QLineEdit*, const QString&); void set_disabled_pref_file_browser_dir (bool disable); + // slots for import/export-buttons of shortcut sets + void import_shortcut_set1 (); + void export_shortcut_set1 (); + void import_shortcut_set2 (); + void export_shortcut_set2 (); + private: Ui::settings_dialog * ui; #ifdef HAVE_QSCINTILLA
--- a/libgui/src/settings-dialog.ui +++ b/libgui/src/settings-dialog.ui @@ -404,9 +404,9 @@ <property name="geometry"> <rect> <x>0</x> - <y>0</y> + <y>-146</y> <width>662</width> - <height>524</height> + <height>553</height> </rect> </property> <layout class="QVBoxLayout" name="verticalLayout_16"> @@ -874,7 +874,7 @@ </property> </widget> </item> - <item row="1" column="0"> + <item row="2" column="0"> <widget class="QCheckBox" name="editor_checkbox_ac_case"> <property name="enabled"> <bool>true</bool> @@ -887,7 +887,17 @@ </property> </widget> </item> - <item row="1" column="2"> + <item row="1" column="0"> + <widget class="QCheckBox" name="editor_checkbox_ac_document"> + <property name="enabled"> + <bool>true</bool> + </property> + <property name="text"> + <string>Match words in document</string> + </property> + </widget> + </item> + <item row="2" column="2"> <widget class="QCheckBox" name="editor_checkbox_ac_replace"> <property name="enabled"> <bool>true</bool> @@ -910,17 +920,7 @@ </property> </spacer> </item> - <item row="0" column="2"> - <widget class="QCheckBox" name="editor_checkbox_ac_document"> - <property name="enabled"> - <bool>true</bool> - </property> - <property name="text"> - <string>Match words in document</string> - </property> - </widget> - </item> - <item row="1" column="3"> + <item row="2" column="3"> <spacer name="horizontalSpacer_19"> <property name="orientation"> <enum>Qt::Horizontal</enum> @@ -933,6 +933,30 @@ </property> </spacer> </item> + <item row="0" column="2"> + <layout class="QHBoxLayout" name="horizontalLayout_14"> + <item> + <widget class="QCheckBox" name="editor_checkbox_ac_builtins"> + <property name="enabled"> + <bool>false</bool> + </property> + <property name="text"> + <string>With Octave builtins</string> + </property> + </widget> + </item> + <item> + <widget class="QCheckBox" name="editor_checkbox_ac_functions"> + <property name="enabled"> + <bool>false</bool> + </property> + <property name="text"> + <string>With Octave functions</string> + </property> + </widget> + </item> + </layout> + </item> </layout> </item> <item row="3" column="1"> @@ -1738,33 +1762,57 @@ </widget> </item> <item> - <layout class="QHBoxLayout" name="horizontalLayout_14"> - <item> - <widget class="QLabel" name="label_22"> + <layout class="QGridLayout" name="gridLayout_12"> + <property name="topMargin"> + <number>10</number> + </property> + <item row="3" column="0"> + <layout class="QHBoxLayout" name="horizontalLayout_16"> + <property name="topMargin"> + <number>0</number> + </property> + </layout> + </item> + <item row="1" column="2"> + <widget class="QRadioButton" name="rb_sc_set2"> <property name="text"> - <string>Use Shortcut Set: </string> + <string>Use this set</string> </property> </widget> </item> - <item> + <item row="0" column="0"> + <widget class="QLabel" name="label_23"> + <property name="text"> + <string>Set 1:</string> + </property> + </widget> + </item> + <item row="1" column="4"> + <widget class="QPushButton" name="btn_export_shortcut_set2"> + <property name="text"> + <string>Export</string> + </property> + </widget> + </item> + <item row="1" column="3"> + <widget class="QPushButton" name="btn_import_shortcut_set2"> + <property name="text"> + <string>Import</string> + </property> + </widget> + </item> + <item row="0" column="2"> <widget class="QRadioButton" name="rb_sc_set1"> <property name="text"> - <string>Set 1</string> + <string>Use this set</string> </property> <property name="checked"> <bool>true</bool> </property> </widget> </item> - <item> - <widget class="QRadioButton" name="rb_sc_set2"> - <property name="text"> - <string>Set 2</string> - </property> - </widget> - </item> - <item> - <spacer name="horizontalSpacer_17"> + <item row="0" column="5"> + <spacer name="horizontalSpacer_26"> <property name="orientation"> <enum>Qt::Horizontal</enum> </property> @@ -1776,6 +1824,43 @@ </property> </spacer> </item> + <item row="0" column="4"> + <widget class="QPushButton" name="btn_export_shortcut_set1"> + <property name="text"> + <string>Export</string> + </property> + </widget> + </item> + <item row="0" column="3"> + <widget class="QPushButton" name="btn_import_shortcut_set1"> + <property name="text"> + <string>Import</string> + </property> + </widget> + </item> + <item row="1" column="0"> + <widget class="QLabel" name="label_24"> + <property name="text"> + <string>Set 2:</string> + </property> + </widget> + </item> + <item row="0" column="1"> + <spacer name="horizontalSpacer_33"> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + <property name="sizeType"> + <enum>QSizePolicy::Fixed</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>20</width> + <height>20</height> + </size> + </property> + </spacer> + </item> </layout> </item> <item> @@ -2539,5 +2624,37 @@ </hint> </hints> </connection> + <connection> + <sender>editor_checkbox_ac_keywords</sender> + <signal>toggled(bool)</signal> + <receiver>editor_checkbox_ac_builtins</receiver> + <slot>setEnabled(bool)</slot> + <hints> + <hint type="sourcelabel"> + <x>118</x> + <y>231</y> + </hint> + <hint type="destinationlabel"> + <x>296</x> + <y>231</y> + </hint> + </hints> + </connection> + <connection> + <sender>editor_checkbox_ac_keywords</sender> + <signal>toggled(bool)</signal> + <receiver>editor_checkbox_ac_functions</receiver> + <slot>setEnabled(bool)</slot> + <hints> + <hint type="sourcelabel"> + <x>118</x> + <y>231</y> + </hint> + <hint type="destinationlabel"> + <x>446</x> + <y>231</y> + </hint> + </hints> + </connection> </connections> </ui>
--- a/libgui/src/shortcut-manager.cc +++ b/libgui/src/shortcut-manager.cc @@ -34,6 +34,7 @@ #include <QCheckBox> #include <QHeaderView> #include <QAction> +#include <QFileDialog> #include "error.h" #include "resource-manager.h" @@ -332,7 +333,7 @@ QColor fg = QColor (tree_item->foreground (1).color ()); fg.setAlpha (128); tree_item->setForeground (1, QBrush (fg)); - tree_item->setForeground (3,QBrush (fg)); + tree_item->setForeground (3, QBrush (fg)); // write the shortcuts tree_item->setText (0, sc.description); @@ -347,18 +348,35 @@ } +// write one or all actual shortcut set(s) into a settings file void -shortcut_manager::do_write_shortcuts () +shortcut_manager::do_write_shortcuts (int set, QSettings* settings) { - for (int i = 0; i < _sc.count (); i++) + if (set) { - _settings->setValue("shortcuts/"+_sc.at (i).settings_key, _sc.at (i).actual_sc[0].toString ()); - _settings->setValue("shortcuts/"+_sc.at (i).settings_key+"_1", _sc.at (i).actual_sc[1].toString ()); + // set is not zero, only write the desired set (index = set-1) + // into the settings file that the user has selected for this export + for (int i = 0; i < _sc.count (); i++) // loop over all shortcuts + { + settings->setValue("shortcuts/"+_sc.at (i).settings_key, + _sc.at (i).actual_sc[set-1].toString ()); + } + } + else + { + // set is zero, write all sets into the normal octave settings file + // (this is only the case when called from the closing settings dialog) + for (int i = 0; i < _sc.count (); i++) // loop over all shortcuts + { + settings->setValue("shortcuts/"+_sc.at (i).settings_key, + _sc.at (i).actual_sc[0].toString ()); + settings->setValue("shortcuts/"+_sc.at (i).settings_key+"_1", + _sc.at (i).actual_sc[1].toString ()); + } + delete _dialog; // the dialog for key sequences can be removed now } - _settings->sync (); - - delete _dialog; + settings->sync (); // sync the settings file } void @@ -530,26 +548,85 @@ _edit_actual->setText (_label_default->text ()); } +// import a shortcut set from a given settings file and refresh the tree view +void +shortcut_manager::import_shortcuts (int set, QSettings *settings) +{ + for (int i = 0; i < _sc.count (); i++) + { + // update the list of all shortcuts + shortcut_t sc = _sc.at (i); // make a copy + sc.actual_sc[set-1] = QKeySequence ( // get new shortcut from settings + settings->value ("shortcuts/"+sc.settings_key,sc.actual_sc[set-1]). + toString ()); // and use the old one as default + _sc.replace (i,sc); // replace the old with the new one + + // update the tree view + QTreeWidgetItem* tree_item = _index_item_hash[i]; // get related tree item + tree_item->setText (2*set, sc.actual_sc [set-1]); // display new shortcut + } +} + +// import or export of shortcut sets, +// called from settings dialog when related buttons are clicked +void +shortcut_manager::do_import_export (bool import, int set) +{ + QString file; + + // get the file name to read or write the shortcuts, + // the default extension is .osc (octave shortcuts) + if (import) + { + file = QFileDialog::getOpenFileName (this, + tr ("Import shortcut set %1 from file ...").arg (set), QString (), + tr ("Octave Shortcut Files (*.osc);;All Files (*)")); + } + else + { + file = QFileDialog::getSaveFileName (this, + tr ("Export shortcut set %1 into file ...").arg (set), QString (), + tr ("Octave Shortcut Files (*.osc);;All Files (*)")); + } + + // create a settings object related to this file + QSettings *osc_settings = new QSettings (file, QSettings::IniFormat); + if (osc_settings) + { + // the settings object was successfully created: carry on + if (import) + import_shortcuts (set, osc_settings); // import (special action) + else + do_write_shortcuts (set, osc_settings); // export, like saving settings + } + else + qWarning () << tr ("Failed to open %1 as octave shortcut file"). arg (file); + +} +// enter_shortcut: +// class derived from QLineEdit for directly entering key sequences which enter_shortcut::enter_shortcut (QWidget *p) : QLineEdit (p) { - _direct_shortcut = true; + _direct_shortcut = true; // the shortcut is directly entered } enter_shortcut::~enter_shortcut () { } +// slot for checkbox whether the shortcut is directly entered or not void enter_shortcut::handle_direct_shortcut (int state) { if (state) - _direct_shortcut = true; + _direct_shortcut = true; // the shortcut is directly entered else - _direct_shortcut = false; + _direct_shortcut = false; // the shortcut has to be written as text } +// new keyPressEvent void enter_shortcut::keyPressEvent (QKeyEvent *e) { @@ -580,4 +657,3 @@ setText (QKeySequence(key)); } } -
--- a/libgui/src/shortcut-manager.h +++ b/libgui/src/shortcut-manager.h @@ -63,10 +63,10 @@ instance->do_init_data (); } - static void write_shortcuts () + static void write_shortcuts (int set, QSettings *settings) { if (instance_ok ()) - instance->do_write_shortcuts (); + instance->do_write_shortcuts (set, settings); } static void set_shortcut (QAction *action, const QString& key) @@ -81,6 +81,12 @@ instance->do_fill_treewidget (tree_view); } + static void import_export (bool import, int set) + { + if (instance_ok ()) + instance->do_import_export (import, set); + } + public slots: signals: @@ -107,10 +113,12 @@ void init (QString, QString, QKeySequence); void do_init_data (); - void do_write_shortcuts (); + void do_write_shortcuts (int set, QSettings *settings); void do_set_shortcut (QAction *action, const QString& key); void do_fill_treewidget (QTreeWidget *tree_view); + void do_import_export (bool import, int set); void shortcut_dialog (int); + void import_shortcuts (int set, QSettings *settings); struct shortcut_t {
--- a/libinterp/corefcn/graphics.in.h +++ b/libinterp/corefcn/graphics.in.h @@ -3762,7 +3762,7 @@ array_property plotboxaspectratio mu , Matrix (1, 3, 1.0) radio_property plotboxaspectratiomode u , "{auto}|manual" array_property position u , default_axes_position () - radio_property projection , "{orthographic}|perpective" + radio_property projection , "{orthographic}|perspective" radio_property tickdir mu , "{in}|out" radio_property tickdirmode u , "{auto}|manual" array_property ticklength u , default_axes_ticklength ()
--- a/libinterp/corefcn/ls-mat5.cc +++ b/libinterp/corefcn/ls-mat5.cc @@ -667,7 +667,15 @@ } int ndims = dim_len / 4; - dims.resize (ndims); + if (ndims == 1) + { + // R and Python can create a 1-D object which is really an Nx1 object + dims.resize (2); + dims(1) = 1; + } + else + dims.resize (ndims); + for (int i = 0; i < ndims; i++) { int32_t n;
--- a/libinterp/corefcn/xnorm.cc +++ b/libinterp/corefcn/xnorm.cc @@ -48,7 +48,9 @@ if (isfloat || x.is_double_type ()) { - if (isvector) + if (x.is_empty ()) + retval = octave_value (0); + else if (isvector) { if (isfloat & iscomplex) retval = xnorm (x.float_complex_column_vector_value (),
--- a/libinterp/dldfcn/chol.cc +++ b/libinterp/dldfcn/chol.cc @@ -212,7 +212,7 @@ if (nargout > 1 || info == 0) { - retval(1) = fact.P (); + retval(1) = info; if (LLt) retval(0) = fact.L (); else @@ -240,7 +240,7 @@ if (nargout > 1 || info == 0) { - retval(1) = fact.P (); + retval(1) = info; if (LLt) retval(0) = fact.L (); else @@ -375,6 +375,11 @@ /* %!assert (chol ([2, 1; 1, 1]), [sqrt(2), 1/sqrt(2); 0, 1/sqrt(2)], sqrt (eps)) %!assert (chol (single ([2, 1; 1, 1])), single ([sqrt(2), 1/sqrt(2); 0, 1/sqrt(2)]), sqrt (eps ("single"))) +%!test +%! ## Bug #42587 +%! A = sparse ([1 0 8;0 1 8;8 8 1]); +%! [Q, p] = chol (A); +%! assert (p != 0); %!error chol () %!error <matrix must be positive definite> chol ([1, 2; 3, 4])
--- a/liboctave/array/CMatrix.cc +++ b/liboctave/array/CMatrix.cc @@ -2683,11 +2683,8 @@ // call. double dminmn = static_cast<double> (minmn); double dsmlsizp1 = static_cast<double> (smlsiz+1); -#if defined (HAVE_LOG2) - double tmp = log2 (dminmn / dsmlsizp1); -#else - double tmp = log (dminmn / dsmlsizp1) / log (2.0); -#endif + double tmp = xlog2 (dminmn / dsmlsizp1); + octave_idx_type nlvl = static_cast<octave_idx_type> (tmp) + 1; if (nlvl < 0) nlvl = 0; @@ -2875,11 +2872,8 @@ // call. double dminmn = static_cast<double> (minmn); double dsmlsizp1 = static_cast<double> (smlsiz+1); -#if defined (HAVE_LOG2) - double tmp = log2 (dminmn / dsmlsizp1); -#else - double tmp = log (dminmn / dsmlsizp1) / log (2.0); -#endif + double tmp = xlog2 (dminmn / dsmlsizp1); + octave_idx_type nlvl = static_cast<octave_idx_type> (tmp) + 1; if (nlvl < 0) nlvl = 0;
--- a/liboctave/array/dMatrix.cc +++ b/liboctave/array/dMatrix.cc @@ -2320,11 +2320,8 @@ // of LAPACK does not return it on a query call. double dminmn = static_cast<double> (minmn); double dsmlsizp1 = static_cast<double> (smlsiz+1); -#if defined (HAVE_LOG2) - double tmp = log2 (dminmn / dsmlsizp1); -#else - double tmp = log (dminmn / dsmlsizp1) / log (2.0); -#endif + double tmp = xlog2 (dminmn / dsmlsizp1); + octave_idx_type nlvl = static_cast<octave_idx_type> (tmp) + 1; if (nlvl < 0) nlvl = 0; @@ -2511,11 +2508,8 @@ // of LAPACK does not return it on a query call. double dminmn = static_cast<double> (minmn); double dsmlsizp1 = static_cast<double> (smlsiz+1); -#if defined (HAVE_LOG2) - double tmp = log2 (dminmn / dsmlsizp1); -#else - double tmp = log (dminmn / dsmlsizp1) / log (2.0); -#endif + double tmp = xlog2 (dminmn / dsmlsizp1); + octave_idx_type nlvl = static_cast<octave_idx_type> (tmp) + 1; if (nlvl < 0) nlvl = 0;
--- a/liboctave/array/fCMatrix.cc +++ b/liboctave/array/fCMatrix.cc @@ -2699,11 +2699,8 @@ // call. float dminmn = static_cast<float> (minmn); float dsmlsizp1 = static_cast<float> (smlsiz+1); -#if defined (HAVE_LOG2) - float tmp = log2 (dminmn / dsmlsizp1); -#else - float tmp = log (dminmn / dsmlsizp1) / log (2.0); -#endif + float tmp = xlog2 (dminmn / dsmlsizp1); + octave_idx_type nlvl = static_cast<octave_idx_type> (tmp) + 1; if (nlvl < 0) nlvl = 0; @@ -2894,11 +2891,8 @@ // call. float dminmn = static_cast<float> (minmn); float dsmlsizp1 = static_cast<float> (smlsiz+1); -#if defined (HAVE_LOG2) - float tmp = log2 (dminmn / dsmlsizp1); -#else - float tmp = log (dminmn / dsmlsizp1) / log (2.0); -#endif + float tmp = xlog2 (dminmn / dsmlsizp1); + octave_idx_type nlvl = static_cast<octave_idx_type> (tmp) + 1; if (nlvl < 0) nlvl = 0;
--- a/liboctave/array/fMatrix.cc +++ b/liboctave/array/fMatrix.cc @@ -2340,11 +2340,8 @@ // of LAPACK does not return it on a query call. float dminmn = static_cast<float> (minmn); float dsmlsizp1 = static_cast<float> (smlsiz+1); -#if defined (HAVE_LOG2) - float tmp = log2 (dminmn / dsmlsizp1); -#else - float tmp = log (dminmn / dsmlsizp1) / log (2.0); -#endif + float tmp = xlog2 (dminmn / dsmlsizp1); + octave_idx_type nlvl = static_cast<octave_idx_type> (tmp) + 1; if (nlvl < 0) nlvl = 0; @@ -2531,11 +2528,8 @@ // of LAPACK does not return it on a query call. float dminmn = static_cast<float> (minmn); float dsmlsizp1 = static_cast<float> (smlsiz+1); -#if defined (HAVE_LOG2) - float tmp = log2 (dminmn / dsmlsizp1); -#else - float tmp = log (dminmn / dsmlsizp1) / log (2.0); -#endif + float tmp = xlog2 (dminmn / dsmlsizp1); + octave_idx_type nlvl = static_cast<octave_idx_type> (tmp) + 1; if (nlvl < 0) nlvl = 0;
--- a/liboctave/numeric/lo-mappers.cc +++ b/liboctave/numeric/lo-mappers.cc @@ -92,17 +92,7 @@ double xlog2 (double x) { -#if defined (HAVE_LOG2) - return log2 (x); -#else -#if defined (M_LN2) - static double ln2 = M_LN2; -#else - static double ln2 = log (2); -#endif - - return log (x) / ln2; -#endif + return gnulib::log2 (x); } Complex @@ -317,19 +307,7 @@ float xlog2 (float x) { -#if defined (HAVE_LOG2F) - return log2f (x); -#elif defined (HAVE_LOG2) - return log2 (x); -#else -#if defined (M_LN2) - static float ln2 = M_LN2; -#else - static float ln2 = log2 (2); -#endif - - return log (x) / ln2; -#endif + return gnulib::log2f (x); } FloatComplex
--- a/scripts/plot/util/private/__gnuplot_ginput__.m +++ b/scripts/plot/util/private/__gnuplot_ginput__.m @@ -101,7 +101,7 @@ fputs (ostream, "set print \"-\";\n"); fflush (ostream); fputs (ostream, "pause mouse any;\n\n"); - fputs (ostream, "\nif (exists(\"MOUSE_KEY\") && exists(\"MOUSE_X\")) print \"OCTAVE: \", MOUSE_X, MOUSE_Y, MOUSE_KEY; else print \"0 0 -1\"\n"); + fputs (ostream, "\nif (exists(\"MOUSE_KEY\") && exists(\"MOUSE_X\")) key = (MOUSE_KEY==1063 ? 1 : MOUSE_KEY); print \"OCTAVE: \", MOUSE_X, MOUSE_Y, key; else print \"0 0 -1\"\n"); ## Close output file, to force it to be flushed fputs (ostream, "set print;\n");