changeset 18884: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	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
--- 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
--- 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
--- 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 \
--- 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);
 }
 
--- 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 <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	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;
 
--- 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
--- 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);
+}
--- 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
--- 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 @@
           <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	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 <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	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
   {
--- 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 ()
--- 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;
--- 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 (),
--- 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 <matrix must be positive definite> chol ([1, 2; 3, 4])
--- 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<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	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<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	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<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	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<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	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
--- 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");