changeset 18867:6504a1932637 gui-release

auto completion offers builtins and file functions for octave (bug #41371) * file-editor-tab.cc (update_lexer): read settings whether builtin and file functions should also be considered in auto completion for octave files; when functions are also displayed, updating of the files with prepared auto completion informations depends on last modification date of package lists; (add_octave_apis): new function for adding strings to the lexer APIs from the internal octave functions * file-editor-tab.h (add_octave_apis): new function * main-window.cc (handle_octave_ready): call function for creating the empty tab in the editor here because all octave functions must be known for creating the auto completion information * settings-dialog.ui: new checkboxes for auto completion of octaves buitlin and file functions * settings-dialog.cc (constructor): read states for new checkboxes from the settings file; (write_changed_settings): write states of new checkboxes into the settings file
author Torsten <ttl@justmail.de>
date Mon, 16 Jun 2014 12:11:21 +0200
parents 4b98fc5c2eb1
children 0e6f7b5f6556
files libgui/src/m-editor/file-editor-tab.cc libgui/src/m-editor/file-editor-tab.h libgui/src/main-window.cc libgui/src/settings-dialog.cc libgui/src/settings-dialog.ui
diffstat 5 files changed, 196 insertions(+), 31 deletions(-) [+]
line wrap: on
line diff
--- a/libgui/src/m-editor/file-editor-tab.cc	Thu Jun 12 19:48:50 2014 +0200
+++ b/libgui/src/m-editor/file-editor-tab.cc	Mon Jun 16 12:11:21 2014 +0200
@@ -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.
@@ -330,17 +332,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 +408,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 +451,7 @@
         }
     }
 
-  QSettings *settings = resource_manager::get_settings ();
-  if (settings)
-    lexer->readSettings (*settings);
+  lexer->readSettings (*settings);
 
   _edit_area->setLexer (lexer);
 
@@ -383,6 +463,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 ()
 {
--- a/libgui/src/m-editor/file-editor-tab.h	Thu Jun 12 19:48:50 2014 +0200
+++ b/libgui/src/m-editor/file-editor-tab.h	Mon Jun 16 12:11:21 2014 +0200
@@ -34,6 +34,7 @@
 
 #include "find-dialog.h"
 #include "octave-qscintilla.h"
+#include "builtin-defun-decls.h"
 
 class file_editor;
 
@@ -206,6 +207,8 @@
   void remove_all_breakpoints_callback (const bp_info& info);
   void center_current_line ();
 
+  void add_octave_apis (octave_value_list key_ovl);
+
   octave_qscintilla *_edit_area;
 
   QStatusBar *_status_bar;
--- a/libgui/src/main-window.cc	Thu Jun 12 19:48:50 2014 +0200
+++ b/libgui/src/main-window.cc	Mon Jun 16 12:11:21 2014 +0200
@@ -1014,11 +1014,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 +1318,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
+
 }
 
 
--- a/libgui/src/settings-dialog.cc	Thu Jun 12 19:48:50 2014 +0200
+++ b/libgui/src/settings-dialog.cc	Mon Jun 16 12:11:21 2014 +0200
@@ -166,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 (
@@ -605,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",
--- a/libgui/src/settings-dialog.ui	Thu Jun 12 19:48:50 2014 +0200
+++ b/libgui/src/settings-dialog.ui	Mon Jun 16 12:11:21 2014 +0200
@@ -32,7 +32,7 @@
       </size>
      </property>
      <property name="currentIndex">
-      <number>6</number>
+      <number>1</number>
      </property>
      <widget class="QWidget" name="tab_general">
       <property name="enabled">
@@ -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">
@@ -2600,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>