GNU Octave  4.2.1
A high-level interpreted language, primarily intended for numerical computations, mostly compatible with Matlab
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Pages
octave-qt-link.cc
Go to the documentation of this file.
1 /*
2 
3 Copyright (C) 2013-2017 John W. Eaton
4 Copyright (C) 2011-2016 Jacob Dawid
5 Copyright (C) 2011-2016 John P. Swensen
6 
7 This file is part of Octave.
8 
9 Octave is free software; you can redistribute it and/or modify it
10 under the terms of the GNU General Public License as published by the
11 Free Software Foundation; either version 3 of the License, or (at your
12 option) any later version.
13 
14 Octave is distributed in the hope that it will be useful, but WITHOUT
15 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
16 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
17 for more details.
18 
19 You should have received a copy of the GNU General Public License
20 along with Octave; see the file COPYING. If not, see
21 <http://www.gnu.org/licenses/>.
22 
23 */
24 
25 #if defined (HAVE_CONFIG_H)
26 # include "config.h"
27 #endif
28 
29 #include <QStringList>
30 #include <QDialog>
31 #include <QDir>
32 #include <QPushButton>
33 
34 #include "oct-env.h"
35 #include "str-vec.h"
36 
37 #include "builtin-defun-decls.h"
38 #include "dialog.h"
39 #include "error.h"
40 #include "load-path.h"
41 #include "utils.h"
42 
43 #include "octave-gui.h"
44 #include "octave-qt-link.h"
45 #include "resource-manager.h"
46 #include "workspace-element.h"
47 
49  octave::gui_application *app_context)
50  : octave_link (), main_thread (new QThread ()),
51  m_app_context (app_context),
52  command_interpreter (new octave_interpreter (app_context))
53 {
54  _current_directory = "";
55  _new_dir = true;
56 
57  connect (this, SIGNAL (execute_interpreter_signal (void)),
58  command_interpreter, SLOT (execute (void)));
59 
60  connect (command_interpreter, SIGNAL (octave_ready_signal ()),
61  p, SLOT (handle_octave_ready ()));
62 
63  command_interpreter->moveToThread (main_thread);
64 
65  main_thread->start ();
66 }
67 
69 {
70  delete command_interpreter;
71  delete main_thread;
72 }
73 
74 void
76 {
78 }
79 
80 bool
82 {
83  // Lock the mutex before emitting signal.
84  mutex.lock ();
85 
87 
88  // Wait while the GUI shuts down.
89  waitcondition.wait (&mutex);
90 
91  // The GUI has sent a signal and the thread has been awakened.
92 
93  mutex.unlock ();
94 
96 }
97 
98 bool
100 {
101  emit exit_app_signal (status);
102 
103  // Could wait for a while and then timeout, but for now just
104  // assume the GUI application exit will be without problems.
105  return true;
106 }
107 
108 bool
110 {
112 
113  return true;
114 }
115 
116 bool
118 {
120 
121  return true;
122 }
123 
124 bool
126 {
127  QSettings *settings = resource_manager::get_settings ();
128 
129  if (! settings || settings->value ("editor/create_new_file",false).toBool ())
130  return true;
131 
132  QFileInfo file_info (QString::fromStdString (file));
133  QStringList btn;
134  QStringList role;
135  role << "YesRole" << "RejectRole";
136  btn << tr ("Create") << tr ("Cancel");
137 
138  // Lock mutex before signaling.
139  uiwidget_creator.mutex.lock ();
140 
142  tr ("File\n%1\ndoes not exist. Do you want to create it?").
143  arg (QDir::currentPath () + QDir::separator ()
144  + QString::fromStdString (file)),
145  tr ("Octave Editor"), "quest", btn, tr ("Create"), role);
146 
147  // Wait while the user is responding to message box.
149 
150  // The GUI has sent a signal and the thread has been awakened.
151 
152  QString answer = uiwidget_creator.get_dialog_button ();
153 
154  uiwidget_creator.mutex.unlock ();
155 
156  return (answer == tr ("Create"));
157 }
158 
159 int
161  const std::string& msg,
162  const std::string& title)
163 {
164  // Lock mutex before signaling.
165  uiwidget_creator.mutex.lock ();
166 
168  QString::fromStdString (title),
170  QStringList (), QString (),
171  QStringList ());
172 
173  // Wait while the user is responding to message box.
175 
176  // The GUI has sent a signal and the thread has been awakened.
177 
178  int answer = uiwidget_creator.get_dialog_result ();
179 
180  uiwidget_creator.mutex.unlock ();
181 
182  return answer;
183 }
184 
187  const std::string& title,
188  const std::string& btn1,
189  const std::string& btn2,
190  const std::string& btn3,
191  const std::string& btndef)
192 {
193  QStringList btn;
194  QStringList role;
195  role << "AcceptRole" << "AcceptRole" << "AcceptRole";
196  btn << QString::fromStdString (btn1);
197  if (btn2 == "")
198  role.removeAt (0);
199  else
200  btn << QString::fromStdString (btn2);
201  btn << QString::fromStdString (btn3);
202 
203  // Lock mutex before signaling.
204  uiwidget_creator.mutex.lock ();
205 
206  uiwidget_creator.signal_dialog (QString::fromStdString (msg),
207  QString::fromStdString (title),
208  "quest",
209  btn,
210  QString::fromStdString (btndef),
211  role);
212 
213  // Wait while the user is responding to message box.
215 
216  // The GUI has sent a signal and the thread has been awakened.
217 
218  std::string answer = uiwidget_creator.get_dialog_button ().toStdString ();
219 
220  uiwidget_creator.mutex.unlock ();
221 
222  return answer;
223 }
224 
225 static QStringList
226 make_qstring_list (const std::list<std::string>& lst)
227 {
228  QStringList retval;
229 
230  for (std::list<std::string>::const_iterator it = lst.begin ();
231  it != lst.end (); it++)
232  {
233  retval.append (QString::fromStdString (*it));
234  }
235 
236  return retval;
237 }
238 
239 static QStringList
241 {
242  QStringList retval;
243 
244  // We have pairs of data, first being the list of extensions
245  // exta;exb;extc etc second the name to use as filter name
246  // (optional). Qt wants a list of filters in the format of
247  // 'FilterName (space separated exts)'.
248 
249  for (octave_link::filter_list::const_iterator it = lst.begin ();
250  it != lst.end (); it++)
251  {
252  QString ext = QString::fromStdString (it->first);
253  QString name = QString::fromStdString (it->second);
254 
255  // Strip out extensions from name and replace ';' with spaces in
256  // list.
257 
258  name.replace (QRegExp ("\\(.*\\)"), "");
259  ext.replace (";", " ");
260 
261  if (name.isEmpty ())
262  {
263  // No name field. Build one from the extensions.
264  name = ext.toUpper () + " Files";
265  }
266 
267  retval.append (name + " (" + ext + ")");
268  }
269 
270  return retval;
271 }
272 
273 std::pair<std::list<int>, int>
274 octave_qt_link::do_list_dialog (const std::list<std::string>& list,
275  const std::string& mode,
276  int width, int height,
277  const std::list<int>& initial,
278  const std::string& name,
279  const std::list<std::string>& prompt,
280  const std::string& ok_string,
281  const std::string& cancel_string)
282 {
283  // Lock mutex before signaling.
284  uiwidget_creator.mutex.lock ();
285 
287  QString::fromStdString (mode),
288  width, height,
289  QList<int>::fromStdList (initial),
290  QString::fromStdString (name),
291  make_qstring_list (prompt),
292  QString::fromStdString (ok_string),
293  QString::fromStdString (cancel_string));
294 
295  // Wait while the user is responding to message box.
297 
298  // The GUI has sent a signal and the thread has been awakened.
299 
300  const QIntList *selected = uiwidget_creator.get_list_index ();
302 
303  uiwidget_creator.mutex.unlock ();
304 
305  return std::pair<std::list<int>, int> (selected->toStdList (), ok);
306 }
307 
308 std::list<std::string>
309 octave_qt_link::do_input_dialog (const std::list<std::string>& prompt,
310  const std::string& title,
311  const std::list<float>& nr,
312  const std::list<float>& nc,
313  const std::list<std::string>& defaults)
314 {
315  std::list<std::string> retval;
316 
317  // Lock mutex before signaling.
318  uiwidget_creator.mutex.lock ();
319 
321  QString::fromStdString (title),
322  QFloatList::fromStdList (nr),
323  QFloatList::fromStdList (nc),
324  make_qstring_list (defaults));
325 
326  // Wait while the user is responding to message box.
328 
329  // The GUI has sent a signal and the thread has been awakened.
330 
331  const QStringList *inputLine = uiwidget_creator.get_string_list ();
332 
333  uiwidget_creator.mutex.unlock ();
334 
335  for (QStringList::const_iterator it = inputLine->begin ();
336  it != inputLine->end (); it++)
337  {
338  retval.push_back (it->toStdString ());
339  }
340 
341  return retval;
342 }
343 
344 std::list<std::string>
346  const std::string& title,
347  const std::string& filename,
348  const std::string& dirname,
349  const std::string& multimode)
350 {
351  std::list<std::string> retval;
352 
353  // Lock mutex before signaling.
354  uiwidget_creator.mutex.lock ();
355 
357  QString::fromStdString (title),
358  QString::fromStdString (filename),
359  QString::fromStdString (dirname),
360  QString::fromStdString (multimode));
361 
362  // Wait while the user is responding to dialog.
364 
365  // The GUI has sent a signal and the thread has been awakened.
366 
367  // Add all the file dialog results to a string list.
368  const QStringList *inputLine = uiwidget_creator.get_string_list ();
369 
370  for (QStringList::const_iterator it = inputLine->begin ();
371  it != inputLine->end (); it++)
372  retval.push_back (it->toStdString ());
373 
374  retval.push_back (uiwidget_creator.get_dialog_path ()->toStdString ());
375  retval.push_back ((QString ("%1").arg (
376  uiwidget_creator.get_dialog_result ())).toStdString ());
377 
378  uiwidget_creator.mutex.unlock ();
379 
380  return retval;
381 }
382 
383 // Prompt to allow file to be run by setting cwd (or if addpath_option==true,
384 // alternatively setting the path).
385 // This uses a QMessageBox unlike other functions in this file,
386 // because uiwidget_creator.waitcondition.wait hangs when called from
387 // file_editor_tab::handle_context_menu_break_condition(). (FIXME: why hang?)
388 int
390  const std::string& dir,
391  bool addpath_option)
392 {
393  int retval = -1;
394 
395  QString qdir = QString::fromStdString (dir);
396  QString qfile = QString::fromStdString (file);
397  QString msg
398  = (addpath_option
399  ? tr ("The file %1 does not exist in the load path. To run or debug the function you are editing, you must either change to the directory %2 or add that directory to the load path.").arg (qfile).arg (qdir)
400  : tr ("The file %1 is shadowed by a file with the same name in the load path. To run or debug the function you are editing, change to the directory %2.").arg (qfile).arg (qdir));
401 
402  QString title = tr ("Change Directory or Add Directory to Load Path");
403 
404  QString cd_txt = tr ("Change Directory");
405  QString addpath_txt = tr ("Add Directory to Load Path");
406  QString cancel_txt = tr ("Cancel");
407 
408  QStringList btn;
409  QStringList role;
410  btn << cd_txt;
411  role << "YesRole";
412  if (addpath_option)
413  {
414  btn << addpath_txt;
415  role << "AcceptRole";
416  }
417  btn << cancel_txt;
418  role << "RejectRole";
419 
420  // Lock mutex before signaling.
421  uiwidget_creator.mutex.lock ();
422 
423  uiwidget_creator.signal_dialog (msg, title, "quest", btn, cancel_txt, role);
424 
425  // Wait while the user is responding to message box.
427 
428  // The GUI has sent a signal and the thread has been awakened.
429 
431 
432  uiwidget_creator.mutex.unlock ();
433 
434  if (result == cd_txt)
435  retval = 1;
436  else if (result == addpath_txt)
437  retval = 2;
438 
439  return retval;
440 }
441 
442 void
444 {
446  _new_dir = true;
447 }
448 
449 void
451 {
453  _new_dir = false;
454 }
455 
456 void
458 {
460 }
461 
462 void
464  const std::list<workspace_element>& ws)
465 {
466  if (! top_level && ! debug)
467  return;
468 
469  if (_new_dir)
470  update_directory ();
471 
472  QString scopes;
473  QStringList symbols;
474  QStringList class_names;
475  QStringList dimensions;
476  QStringList values;
477  QIntList complex_flags;
478 
479  for (std::list<workspace_element>::const_iterator it = ws.begin ();
480  it != ws.end (); it++)
481  {
482  scopes.append (it->scope ());
483  symbols.append (QString::fromStdString (it->symbol ()));
484  class_names.append (QString::fromStdString (it->class_name ()));
485  dimensions.append (QString::fromStdString (it->dimension ()));
486  values.append (QString::fromStdString (it->value ()));
487  complex_flags.append (it->complex_flag ());
488  }
489 
490  emit set_workspace_signal (top_level, debug, scopes, symbols, class_names,
491  dimensions, values, complex_flags);
492 }
493 
494 void
496 {
497  emit clear_workspace_signal ();
498 }
499 
500 void
502 {
503  QStringList qt_hist;
504 
505  for (octave_idx_type i = 0; i < hist.numel (); i++)
506  qt_hist.append (QString::fromStdString (hist[i]));
507 
508  emit set_history_signal (qt_hist);
509 }
510 
511 void
513 {
514  emit append_history_signal (QString::fromStdString (hist_entry));
515 }
516 
517 void
519 {
520  emit clear_history_signal ();
521 }
522 
523 void
525 { }
526 
527 void
529 { }
530 
531 void
533 {
534  do_insert_debugger_pointer (file, line);
535 
536  emit enter_debugger_signal ();
537 }
538 
539 void
541 {
542  do_delete_debugger_pointer (file, line);
543 }
544 
545 void
547 {
548  emit exit_debugger_signal ();
549 }
550 
551 // Display (if @insert true) or remove the appropriate symbol for a breakpoint
552 // in @file at @line with condition @cond.
553 void
555  const std::string& file, int line,
556  const std::string& cond)
557 {
559  line, QString::fromStdString (cond));
560 }
561 
562 void
564  std::string& ps4)
565 {
566  if (m_app_context->start_gui_p ())
567  {
568  ps1 = ">> ";
569  ps2 = "";
570  ps4 = "";
571  }
572 }
573 
574 void
576 {
578 }
579 
580 void
582 {
584 }
585 
586 bool
587 octave_qt_link::file_in_path (const std::string& file, const std::string& dir)
588 {
589 
590  bool ok = false;
591  bool addpath_option = true;
592 
594 
595  if (same_file (curr_dir, dir))
596  ok = true;
597  else
598  {
599  bool dir_in_load_path = load_path::contains_canonical (dir);
600 
601  // get base name, allowing "@class/method.m" (bug #41514)
602  std::string base_file = (file.length () > dir.length ())
603  ? file.substr (dir.length () + 1)
605 
606  std::string lp_file = load_path::find_file (base_file);
607 
608  if (dir_in_load_path)
609  {
610  if (same_file (lp_file, file))
611  ok = true;
612  }
613  else
614  {
615  // File directory is not in path. Is the file in the path in
616  // the current directory? If so, then changing the current
617  // directory will be needed. Adding directory to path is
618  // not enough because the file in the current directory would
619  // still be found.
620 
621  if (same_file (lp_file, base_file))
622  {
623  if (same_file (curr_dir, dir))
624  ok = true;
625  else
626  addpath_option = false;
627  }
628  }
629  }
630 
631  if (! ok)
632  {
633  int action = debug_cd_or_addpath_error (file, dir, addpath_option);
634  switch (action)
635  {
636  case 1:
637  Fcd (ovl (dir));
638  ok = true;
639  break;
640 
641  case 2:
642  load_path::prepend (dir);
643  ok = true;
644  break;
645 
646  default:
647  break;
648  }
649  }
650 
651  return ok;
652 }
653 
654 void
656 {
657  emit show_preferences_signal ();
658 }
659 
660 void
662 {
664 }
665 
666 void
668 {
670 }
void signal_dialog(const QString &message, const QString &title, const QString &icon, const QStringList &button, const QString &defbutton, const QStringList &role)
Definition: dialog.h:56
static std::string get_current_directory(void)
Definition: oct-env.cc:136
For example cd octave end example noindent changes the current working directory to file
Definition: dirfns.cc:120
bool same_file(const std::string &f, const std::string &g)
Definition: utils.cc:130
bool signal_filedialog(const QStringList &filters, const QString &title, const QString &filename, const QString &dirname, const QString &multimode)
Definition: dialog.h:107
int get_dialog_result(void)
Definition: dialog.h:73
The value of lines which begin with a space character are not saved in the history list A value of all commands are saved on the history list
Definition: oct-hist.cc:728
static void prepend(const std::string &dir, bool warn=false)
Definition: load-path.h:77
OCTAVE_EXPORT octave_value_list isa nd deftypefn *return ovl(args(0).is_integer_type())
octave_idx_type numel(void) const
Number of elements in the array.
Definition: Array.h:363
Return the CPU time used by your Octave session The first output is the total time spent executing your process and is equal to the sum of second and third which are the number of CPU seconds spent executing in user mode and the number of CPU seconds spent executing in system mode
Definition: data.cc:6386
static std::string find_file(const std::string &file)
Definition: load-path.h:200
QString fromStdString(const std::string &s)
const QIntList * get_list_index(void)
Definition: dialog.h:91
std::string filename
Definition: urlwrite.cc:340
to define functions rather than attempting to enter them directly on the command line The block of commands is executed as soon as you exit the editor To avoid executing any simply delete all the lines from the buffer before leaving the editor When invoked with no edit the previously executed command
Definition: oct-hist.cc:587
QMutex mutex
Definition: dialog.h:120
octave_value arg
Definition: pr-output.cc:3440
cell array If invoked with two or more scalar integer or a vector of integer values
Definition: ov-cell.cc:1205
QUIWidgetCreator uiwidget_creator
Definition: dialog.cc:45
OCTAVE_EXPORT octave_value_list any number nd example oindent prints the prompt xample Pick a any number!nd example oindent and waits for the user to enter a value The string entered by the user is evaluated as an so it may be a literal a variable name
Definition: input.cc:871
const QStringList * get_string_list(void)
Definition: dialog.h:105
bool signal_listview(const QStringList &list, const QString &mode, int wd, int ht, const QList< int > &initial, const QString &name, const QStringList &prompt, const QString &ok_string, const QString &cancel_string)
Definition: dialog.h:77
octave_value retval
Definition: data.cc:6294
bool start_gui_p(void) const
Definition: octave-gui.cc:74
MArray< T > filter(MArray< T > &b, MArray< T > &a, MArray< T > &x, MArray< T > &si, int dim=0)
Definition: filter.cc:43
static std::string base_pathname(const std::string &s)
Definition: oct-env.cc:122
static bool contains_canonical(const std::string &dir_name)
Definition: load-path.h:94
static QSettings * get_settings(void)
QWaitCondition waitcondition
Definition: dialog.h:121
With real return the complex result
Definition: data.cc:3375
static bool debug
Definition: mkoctfile.cc:239
=val(i)}if ode{val(i)}occurs in table i
Definition: lookup.cc:239
p
Definition: lu.cc:138
bool signal_inputlayout(const QStringList &prompt, const QString &title, const QFloatList &nr, const QFloatList &nc, const QStringList &defaults)
Definition: dialog.h:93
const QString * get_dialog_path(void)
Definition: dialog.h:115
QList< int > QIntList
Definition: dialog.h:38
QString get_dialog_button(void)
Definition: dialog.h:75
If this string is the system will ring the terminal sometimes it is useful to be able to print the original representation of the string
Definition: utils.cc:854
OCTINTERP_API octave_value_list Fcd(const octave_value_list &=octave_value_list(), int=0)
Definition: dirfns.cc:120