# HG changeset patch # User John W. Eaton # Date 1403215680 14400 # Node ID 479d1d3cb5c33fb8713b35e497d141bb97a5f134 # Parent aa9ca67f09fb95d401ef17b62c317a93d9cdc465# Parent b314efd58072a1eaef205f625ab336f4708b9634 maint: Periodic merge of gui-release to default. diff -r aa9ca67f09fb -r 479d1d3cb5c3 bootstrap.conf --- a/bootstrap.conf Wed Jun 18 19:38:40 2014 -0600 +++ b/bootstrap.conf Thu Jun 19 18:08:00 2014 -0400 @@ -50,6 +50,10 @@ isatty largefile link + log2 + log2-ieee + log2f + log2f-ieee lstat malloc-gnu mbrtowc diff -r aa9ca67f09fb -r 479d1d3cb5c3 doc/interpreter/expr.txi --- a/doc/interpreter/expr.txi Wed Jun 18 19:38:40 2014 -0600 +++ b/doc/interpreter/expr.txi Thu Jun 19 18:08:00 2014 -0400 @@ -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 diff -r aa9ca67f09fb -r 479d1d3cb5c3 doc/interpreter/plot.txi --- a/doc/interpreter/plot.txi Wed Jun 18 19:38:40 2014 -0600 +++ b/doc/interpreter/plot.txi Thu Jun 19 18:08:00 2014 -0400 @@ -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 diff -r aa9ca67f09fb -r 479d1d3cb5c3 libgui/qterminal-module.mk --- a/libgui/qterminal-module.mk Wed Jun 18 19:38:40 2014 -0600 +++ b/libgui/qterminal-module.mk Thu Jun 19 18:08:00 2014 -0400 @@ -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 \ diff -r aa9ca67f09fb -r 479d1d3cb5c3 libgui/src/files-dock-widget.cc --- a/libgui/src/files-dock-widget.cc Wed Jun 18 19:38:40 2014 -0600 +++ b/libgui/src/files-dock-widget.cc Thu Jun 19 18:08:00 2014 -0400 @@ -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); } diff -r aa9ca67f09fb -r 479d1d3cb5c3 libgui/src/m-editor/file-editor-tab.cc --- a/libgui/src/m-editor/file-editor-tab.cc Wed Jun 18 19:38:40 2014 -0600 +++ b/libgui/src/m-editor/file-editor-tab.cc Thu Jun 19 18:08:00 2014 -0400 @@ -48,6 +48,7 @@ #include #include #include +#include #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 diff -r aa9ca67f09fb -r 479d1d3cb5c3 libgui/src/m-editor/file-editor-tab.h --- a/libgui/src/m-editor/file-editor-tab.h Wed Jun 18 19:38:40 2014 -0600 +++ b/libgui/src/m-editor/file-editor-tab.h Thu Jun 19 18:08:00 2014 -0400 @@ -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; diff -r aa9ca67f09fb -r 479d1d3cb5c3 libgui/src/main-window.cc --- a/libgui/src/main-window.cc Wed Jun 18 19:38:40 2014 -0600 +++ b/libgui/src/main-window.cc Thu Jun 19 18:08:00 2014 -0400 @@ -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 diff -r aa9ca67f09fb -r 479d1d3cb5c3 libgui/src/settings-dialog.cc --- a/libgui/src/settings-dialog.cc Wed Jun 18 19:38:40 2014 -0600 +++ b/libgui/src/settings-dialog.cc Thu Jun 19 18:08:00 2014 -0400 @@ -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); +} diff -r aa9ca67f09fb -r 479d1d3cb5c3 libgui/src/settings-dialog.h --- a/libgui/src/settings-dialog.h Wed Jun 18 19:38:40 2014 -0600 +++ b/libgui/src/settings-dialog.h Thu Jun 19 18:08:00 2014 -0400 @@ -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 diff -r aa9ca67f09fb -r 479d1d3cb5c3 libgui/src/settings-dialog.ui --- a/libgui/src/settings-dialog.ui Wed Jun 18 19:38:40 2014 -0600 +++ b/libgui/src/settings-dialog.ui Thu Jun 19 18:08:00 2014 -0400 @@ -404,9 +404,9 @@ 0 - 0 + -146 662 - 524 + 553 @@ -874,7 +874,7 @@ - + true @@ -887,7 +887,17 @@ - + + + + true + + + Match words in document + + + + true @@ -910,17 +920,7 @@ - - - - true - - - Match words in document - - - - + Qt::Horizontal @@ -933,6 +933,30 @@ + + + + + + false + + + With Octave builtins + + + + + + + false + + + With Octave functions + + + + + @@ -1738,33 +1762,57 @@ - - - + + + 10 + + + + + 0 + + + + + - Use Shortcut Set: + Use this set - + + + + Set 1: + + + + + + + Export + + + + + + + Import + + + + - Set 1 + Use this set true - - - - Set 2 - - - - - + + Qt::Horizontal @@ -1776,6 +1824,43 @@ + + + + Export + + + + + + + Import + + + + + + + Set 2: + + + + + + + Qt::Horizontal + + + QSizePolicy::Fixed + + + + 20 + 20 + + + + @@ -2539,5 +2624,37 @@ + + editor_checkbox_ac_keywords + toggled(bool) + editor_checkbox_ac_builtins + setEnabled(bool) + + + 118 + 231 + + + 296 + 231 + + + + + editor_checkbox_ac_keywords + toggled(bool) + editor_checkbox_ac_functions + setEnabled(bool) + + + 118 + 231 + + + 446 + 231 + + + diff -r aa9ca67f09fb -r 479d1d3cb5c3 libgui/src/shortcut-manager.cc --- a/libgui/src/shortcut-manager.cc Wed Jun 18 19:38:40 2014 -0600 +++ b/libgui/src/shortcut-manager.cc Thu Jun 19 18:08:00 2014 -0400 @@ -34,6 +34,7 @@ #include #include #include +#include #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)); } } - diff -r aa9ca67f09fb -r 479d1d3cb5c3 libgui/src/shortcut-manager.h --- a/libgui/src/shortcut-manager.h Wed Jun 18 19:38:40 2014 -0600 +++ b/libgui/src/shortcut-manager.h Thu Jun 19 18:08:00 2014 -0400 @@ -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 { diff -r aa9ca67f09fb -r 479d1d3cb5c3 libinterp/corefcn/graphics.in.h --- a/libinterp/corefcn/graphics.in.h Wed Jun 18 19:38:40 2014 -0600 +++ b/libinterp/corefcn/graphics.in.h Thu Jun 19 18:08:00 2014 -0400 @@ -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 () diff -r aa9ca67f09fb -r 479d1d3cb5c3 libinterp/corefcn/ls-mat5.cc --- a/libinterp/corefcn/ls-mat5.cc Wed Jun 18 19:38:40 2014 -0600 +++ b/libinterp/corefcn/ls-mat5.cc Thu Jun 19 18:08:00 2014 -0400 @@ -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; diff -r aa9ca67f09fb -r 479d1d3cb5c3 libinterp/corefcn/xnorm.cc --- a/libinterp/corefcn/xnorm.cc Wed Jun 18 19:38:40 2014 -0600 +++ b/libinterp/corefcn/xnorm.cc Thu Jun 19 18:08:00 2014 -0400 @@ -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 (), diff -r aa9ca67f09fb -r 479d1d3cb5c3 libinterp/dldfcn/chol.cc --- a/libinterp/dldfcn/chol.cc Wed Jun 18 19:38:40 2014 -0600 +++ b/libinterp/dldfcn/chol.cc Thu Jun 19 18:08:00 2014 -0400 @@ -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 chol ([1, 2; 3, 4]) diff -r aa9ca67f09fb -r 479d1d3cb5c3 liboctave/array/CMatrix.cc --- a/liboctave/array/CMatrix.cc Wed Jun 18 19:38:40 2014 -0600 +++ b/liboctave/array/CMatrix.cc Thu Jun 19 18:08:00 2014 -0400 @@ -2683,11 +2683,8 @@ // call. double dminmn = static_cast (minmn); double dsmlsizp1 = static_cast (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 (tmp) + 1; if (nlvl < 0) nlvl = 0; @@ -2875,11 +2872,8 @@ // call. double dminmn = static_cast (minmn); double dsmlsizp1 = static_cast (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 (tmp) + 1; if (nlvl < 0) nlvl = 0; diff -r aa9ca67f09fb -r 479d1d3cb5c3 liboctave/array/dMatrix.cc --- a/liboctave/array/dMatrix.cc Wed Jun 18 19:38:40 2014 -0600 +++ b/liboctave/array/dMatrix.cc Thu Jun 19 18:08:00 2014 -0400 @@ -2320,11 +2320,8 @@ // of LAPACK does not return it on a query call. double dminmn = static_cast (minmn); double dsmlsizp1 = static_cast (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 (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 (minmn); double dsmlsizp1 = static_cast (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 (tmp) + 1; if (nlvl < 0) nlvl = 0; diff -r aa9ca67f09fb -r 479d1d3cb5c3 liboctave/array/fCMatrix.cc --- a/liboctave/array/fCMatrix.cc Wed Jun 18 19:38:40 2014 -0600 +++ b/liboctave/array/fCMatrix.cc Thu Jun 19 18:08:00 2014 -0400 @@ -2699,11 +2699,8 @@ // call. float dminmn = static_cast (minmn); float dsmlsizp1 = static_cast (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 (tmp) + 1; if (nlvl < 0) nlvl = 0; @@ -2894,11 +2891,8 @@ // call. float dminmn = static_cast (minmn); float dsmlsizp1 = static_cast (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 (tmp) + 1; if (nlvl < 0) nlvl = 0; diff -r aa9ca67f09fb -r 479d1d3cb5c3 liboctave/array/fMatrix.cc --- a/liboctave/array/fMatrix.cc Wed Jun 18 19:38:40 2014 -0600 +++ b/liboctave/array/fMatrix.cc Thu Jun 19 18:08:00 2014 -0400 @@ -2340,11 +2340,8 @@ // of LAPACK does not return it on a query call. float dminmn = static_cast (minmn); float dsmlsizp1 = static_cast (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 (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 (minmn); float dsmlsizp1 = static_cast (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 (tmp) + 1; if (nlvl < 0) nlvl = 0; diff -r aa9ca67f09fb -r 479d1d3cb5c3 liboctave/numeric/lo-mappers.cc --- a/liboctave/numeric/lo-mappers.cc Wed Jun 18 19:38:40 2014 -0600 +++ b/liboctave/numeric/lo-mappers.cc Thu Jun 19 18:08:00 2014 -0400 @@ -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 diff -r aa9ca67f09fb -r 479d1d3cb5c3 scripts/plot/util/private/__gnuplot_ginput__.m --- a/scripts/plot/util/private/__gnuplot_ginput__.m Wed Jun 18 19:38:40 2014 -0600 +++ b/scripts/plot/util/private/__gnuplot_ginput__.m Thu Jun 19 18:08:00 2014 -0400 @@ -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");