GNU Octave 7.1.0
A high-level interpreted language, primarily intended for numerical computations, mostly compatible with Matlab
resource-manager.cc
Go to the documentation of this file.
1////////////////////////////////////////////////////////////////////////
2//
3// Copyright (C) 2011-2022 The Octave Project Developers
4//
5// See the file COPYRIGHT.md in the top-level directory of this
6// distribution or <https://octave.org/copyright/>.
7//
8// This file is part of Octave.
9//
10// Octave is free software: you can redistribute it and/or modify it
11// under the terms of the GNU General Public License as published by
12// the Free Software Foundation, either version 3 of the License, or
13// (at your option) any later version.
14//
15// Octave is distributed in the hope that it will be useful, but
16// WITHOUT ANY WARRANTY; without even the implied warranty of
17// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18// GNU General Public License for more details.
19//
20// You should have received a copy of the GNU General Public License
21// along with Octave; see the file COPYING. If not, see
22// <https://www.gnu.org/licenses/>.
23//
24////////////////////////////////////////////////////////////////////////
25
26#if defined (HAVE_CONFIG_H)
27# include "config.h"
28#endif
29
30#include <algorithm>
31#include <array>
32#include <string>
33
34#include <QDir>
35#include <QFile>
36#include <QFontComboBox>
37#include <QFontDatabase>
38#include <QLibraryInfo>
39#include <QMessageBox>
40#include <QNetworkProxy>
41#if defined (HAVE_QSTANDARDPATHS)
42# include <QStandardPaths>
43#else
44# include <QDesktopServices>
45#endif
46
47#include <QTextCodec>
48
49#include "QTerminal.h"
50#include "gui-preferences-cs.h"
51#include "gui-preferences-ed.h"
53#include "octave-qobject.h"
54#include "resource-manager.h"
55#include "variable-editor.h"
56#include "workspace-model.h"
57
58#include "file-ops.h"
60#include "oct-env.h"
61
62#include "defaults.h"
63#include "error.h"
64#include "help.h"
65
66namespace octave
67{
69 : m_settings_directory (), m_settings_file (), m_settings (nullptr),
70 m_default_settings (nullptr), m_temporary_files ()
71 {
72 // Let gui_settings decide where to put the ini file with gui preferences
74 = new gui_settings (QSettings::IniFormat, QSettings::UserScope,
75 "octave", "octave-gui");
76
78
79 QFileInfo sfile (m_settings_file);
80 m_settings_directory = sfile.absolutePath ();
81
82 QString xdg_config_home
83 = QString::fromLocal8Bit (qgetenv ("XDG_CONFIG_HOME"));
84
85 if ((! sfile.exists ()) && xdg_config_home.isEmpty ())
86 {
87 // File does not exist yet: Look for a settings file at the old
88 // location ($HOME/.config/octave/qt-settings) for impoting all
89 // available keys into the new settings file.
90 // Do not look for an old settings file if XDG_CONFIG_HOME is set,
91 // since then a nonexistent new settings file does not necessarily
92 // indicate a first run of octave with new config file locations.
93#if defined (HAVE_QSTANDARDPATHS)
94 QString home_path
95 = QStandardPaths::writableLocation (QStandardPaths::HomeLocation);
96#else
97 QString home_path
98 = QDesktopServices::storageLocation (QDesktopServices::HomeLocation);
99#endif
100
101 QString old_settings_directory = home_path + "/.config/octave";
102 QString old_settings_file = old_settings_directory + "/qt-settings";
103
104 QFile ofile (old_settings_file);
105
106 if (ofile.exists ())
107 {
108 // Old settings file exists; create a gui_settings object related
109 // to it and copy all available keys to the new settings
110 gui_settings old_settings (old_settings_file, QSettings::IniFormat);
111
112 QStringList keys = old_settings.allKeys ();
113 for (int i = 0; i < keys.count(); i++)
114 m_default_settings->setValue (keys.at(i),
115 old_settings.value(keys.at(i)));
116
117 m_default_settings->sync (); // Done, make sure keys are written
118 }
119 }
120 }
121
123 {
124 delete m_settings;
125 delete m_default_settings;
126
127 for (int i = m_temporary_files.count () - 1; i >=0; i--)
129 }
130
132 {
133 // get environment variable for the locale dir (e.g. from run-octave)
134 std::string dldir = sys::env::getenv ("OCTAVE_LOCALE_DIR");
135 if (dldir.empty ())
136 dldir = config::oct_locale_dir (); // env-var empty, load the default location
137 return QString::fromStdString (dldir);
138 }
139
140 void resource_manager::config_translators (QTranslator *qt_tr,
141 QTranslator *qsci_tr,
142 QTranslator *gui_tr)
143 {
144 bool loaded;
145
146 QString qt_trans_dir
147 = QLibraryInfo::location (QLibraryInfo::TranslationsPath);
148
149 QString language = "SYSTEM"; // take system language per default
150
151 // FIXME: can we somehow ensure that the settings object will always
152 // be initialize and valid?
153
154 if (m_settings)
155 {
156 // get the locale from the settings if already available
157 language = m_settings->value (global_language.key,
158 global_language.def).toString ();
159 }
160
161 // load the translations depending on the settings
162 if (language == "SYSTEM")
163 {
164 // get the system locale and pass it to the translators for loading
165 // the suitable translation files
166 QLocale sys_locale = QLocale::system ();
167
168 qt_tr->load (sys_locale, "qt", "_", qt_trans_dir);
169 qsci_tr->load (sys_locale, "qscintilla", "_", qt_trans_dir);
170 gui_tr->load (sys_locale, "", "", get_gui_translation_dir ());
171 }
172 else
173 {
174 // load the translation files depending on the given locale name
175 loaded = qt_tr->load ("qt_" + language, qt_trans_dir);
176 if (! loaded) // try lower case
177 qt_tr->load ("qt_" + language.toLower (), qt_trans_dir);
178
179 loaded = qsci_tr->load ("qscintilla_" + language, qt_trans_dir);
180 if (! loaded) // try lower case
181 qsci_tr->load ("qscintilla_" + language.toLower (), qt_trans_dir);
182
183 gui_tr->load (language, get_gui_translation_dir ());
184 }
185
186 }
187
189 {
190 return m_settings;
191 }
192
194 {
195 return m_default_settings;
196 }
197
199 {
201 }
202
204 {
205 return m_settings_file;
206 }
207
209 {
210 QString default_family;
211
212 // Get all available fixed width fonts via a font combobox
213 QFontComboBox font_combo_box;
214 font_combo_box.setFontFilters (QFontComboBox::MonospacedFonts);
215 QStringList fonts;
216
217 for (int index = 0; index < font_combo_box.count(); index++)
218 fonts << font_combo_box.itemText(index);
219
220#if defined (Q_OS_MAC)
221 // Use hard coded default on macOS, since selection of fixed width
222 // default font is unreliable (see bug #59128).
223 // Test for macOS default fixed width font
224 if (fonts.contains (global_mono_font.def.toString ()))
225 default_family = global_mono_font.def.toString ();
226#endif
227
228 // If default font is still empty (on all other platforms or
229 // if macOS default font is not available): use QFontDatabase
230 if (default_family.isEmpty ())
231 {
232 // Get the system's default monospaced font
233 QFont fixed_font = QFontDatabase::systemFont (QFontDatabase::FixedFont);
234 default_family = fixed_font.defaultFamily ();
235
236 // Since this might be unreliable, test all available fixed width fonts
237 if (! fonts.contains (default_family))
238 {
239 // Font returned by QFontDatabase is not in fixed fonts list.
240 // Fallback: take first from this list
241 default_family = fonts[0];
242 }
243 }
244
245 // Test env variable which has preference
246 std::string env_default_family = sys::env::getenv ("OCTAVE_DEFAULT_FONT");
247 if (! env_default_family.empty ())
248 default_family = QString::fromStdString (env_default_family);
249
250 return default_family;
251 }
252
254 {
255 QString default_family = get_default_font_family ();
256
257 // determine the fefault font size of the system
258 // FIXME: QApplication::font () does not return the monospace font,
259 // but the size should be probably near to the monospace font
260 QFont font = QApplication::font ();
261
262 int font_size = font.pointSize ();
263 if (font_size == -1)
264 font_size = static_cast <int> (std::floor(font.pointSizeF ()));
265
266 // check for valid font size, otherwise take default 10
267 QString default_font_size = "10";
268 if (font_size > 0)
269 default_font_size = QString::number (font_size);
270
271 std::string env_default_font_size
272 = sys::env::getenv ("OCTAVE_DEFAULT_FONT_SIZE");
273
274 if (! env_default_font_size.empty ())
275 default_font_size = QString::fromStdString (env_default_font_size);
276
277 QStringList result;
278 result << default_family;
279 result << default_font_size;
280 return result;
281 }
282
284 {
285 // Declare some empty options, which may be set at first startup for
286 // writing them into the newly created settings file
287 QString custom_editor;
288 QStringList def_font;
289
290 // Check whether the settings file does not yet exist
291 if (! QFile::exists (m_settings_file))
292 {
293 // Get the default font (for terminal)
294 def_font = get_default_font ();
295
296 // Get a custom editor defined as env variable
297 std::string env_default_editor
298 = sys::env::getenv ("OCTAVE_DEFAULT_EDITOR");
299
300 if (! env_default_editor.empty ())
301 custom_editor = QString::fromStdString (env_default_editor);
302 }
303
305
306 // Write some settings that were dynamically determined at first startup
307 if (m_settings)
308 {
309 // Custom editor
310 if (! custom_editor.isEmpty ())
311 m_settings->setValue (global_custom_editor.key, custom_editor);
312
313 // Default monospace font for the terminal
314 if (def_font.count () > 1)
315 {
316 m_settings->setValue (cs_font.key, def_font[0]);
317 m_settings->setValue (cs_font_size.key, def_font[1].toInt ());
318 }
319
320 // Write the default monospace font into the settings for later use by
321 // console and editor as fallbacks of their font preferences.
323 }
324 }
325
326#if defined (HAVE_QSCINTILLA)
328 {
329 int max_style = 0;
330 int actual_style = 0;
331 while (actual_style < ed_max_style_number && max_style < ed_max_lexer_styles)
332 {
333 if ((lexer->description (actual_style)) != "") // valid style
334 styles[max_style++] = actual_style;
335 actual_style++;
336 }
337 return max_style;
338 }
339#endif
340
342 const QFont& base) const
343 {
344 QFont dest (base);
345
346 dest.setBold (attr.bold ());
347 dest.setItalic (attr.italic ());
348 dest.setUnderline (attr.underline ());
349
350 return dest;
351 }
352
353#if defined (HAVE_QSCINTILLA)
356 int mode, int def)
357 {
358 // Test whether the settings for lexer is already contained in the
359 // given gui settings file. If yes, load them, if not copy them from the
360 // default settings file.
361 // This is useful when a new language support is implemented and the
362 // existing settings file is used (which is of course the common case).
363 int m = mode;
364 if (m > 1)
365 m = 1;
366
367 QString group ("Scintilla" + settings_color_modes_ext[m]);
368
369 settings->beginGroup (group);
370 settings->beginGroup (lexer->language ());
371
372 QStringList lexer_keys = settings->allKeys ();
373
374 settings->endGroup ();
375 settings->endGroup ();
376
377 if (def == settings_reload_default_colors_flag || lexer_keys.count () == 0)
378 {
379 // We have to reload the default values or no Lexer keys found:
380 // If mode == 0, take all settings except font from default lexer
381 // If Mode == 1, take all settings except font from default lexer
382 // and convert the color by inverting the lightness
383
384 // Get the default font
385 QStringList def_font = get_default_font ();
386 QFont df (def_font[0], def_font[1].toInt ());
387 QFont dfa = copy_font_attributes (lexer->defaultFont (), df);
388 lexer->setDefaultFont (dfa);
389
390 QColor c, p;
391
392 int styles[ed_max_lexer_styles]; // array for saving valid styles
393 int max_style = get_valid_lexer_styles (lexer, styles);
394
395 for (int i = 0; i < max_style; i++)
396 {
397 c = settings->get_color_value (QVariant (lexer->color (styles[i])), m);
398 lexer->setColor (c, styles[i]);
399 p = settings->get_color_value (QVariant (lexer->paper (styles[i])), m);
400 lexer->setPaper (p, styles[i]);
401 dfa = copy_font_attributes (lexer->font (styles[i]), df);
402 lexer->setFont (dfa, styles[i]);
403 }
404 // Set defaults last for not changing the defaults of the styles
405 lexer->setDefaultColor (lexer->color (styles[0]));
406 lexer->setDefaultPaper (lexer->paper (styles[0]));
407
408 // Write settings if not just reload the default values
410 {
411 const std::string group_str = group.toStdString ();
412 lexer->writeSettings (*settings, group_str.c_str ());
413 settings->sync ();
414 }
415 }
416 else
417 {
418 // Found lexer keys, read the settings
419 const std::string group_str = group.toStdString ();
420 lexer->readSettings (*settings, group_str.c_str ());
421 }
422 }
423#endif
424
425 void resource_manager::set_settings (const QString& file)
426 {
427 delete m_settings;
428 m_settings = new gui_settings (file, QSettings::IniFormat);
429
430 if (m_settings->status () == QSettings::NoError)
431 {
432 // Test usability (force file to be really created)
433 m_settings->setValue ("dummy", 0);
434 m_settings->sync ();
435 }
436
437 if (! (QFile::exists (m_settings->fileName ())
438 && m_settings->isWritable ()
439 && m_settings->status () == QSettings::NoError))
440 {
441 QString msg
442 = QString (QT_TR_NOOP ("The settings file\n%1\n"
443 "does not exist and can not be created.\n"
444 "Make sure you have read and write permissions to\n%2\n\n"
445 "Octave GUI must be closed now."));
446
447 QMessageBox::critical (nullptr,
448 QString (QT_TR_NOOP ("Octave Critical Error")),
449 msg.arg (get_settings_file ()).arg (get_settings_directory ()));
450
451 exit (1);
452 }
453 else
454 m_settings->remove ("dummy"); // Remove test entry
455 }
456
457 bool resource_manager::update_settings_key (const QString& old_key,
458 const QString& new_key)
459 {
460 if (m_settings->contains (old_key))
461 {
462 QVariant preference = m_settings->value (old_key);
463 m_settings->setValue (new_key, preference);
464 m_settings->remove (old_key);
465 return true;
466 }
467
468 return false;
469 }
470
472 {
473 return ! QFile::exists (m_settings_file);
474 }
475
477 {
478 if (! m_settings)
479 return;
480
481 QNetworkProxy proxy;
482
483 // Assume no proxy and empty proxy data
484 QNetworkProxy::ProxyType proxy_type = QNetworkProxy::NoProxy;
485 QString scheme;
486 QString host;
487 int port = 0;
488 QString user;
489 QString pass;
490 QUrl proxy_url = QUrl ();
491
493 {
494 // Use a proxy, collect all required information
495 QString proxy_type_string
497
498 // The proxy type for the Qt proxy settings
499 if (proxy_type_string == "Socks5Proxy")
500 proxy_type = QNetworkProxy::Socks5Proxy;
501 else if (proxy_type_string == "HttpProxy")
502 proxy_type = QNetworkProxy::HttpProxy;
503
504 // The proxy data from the settings
505 if (proxy_type_string == "HttpProxy"
506 || proxy_type_string == "Socks5Proxy")
507 {
509 global_proxy_host.def).toString ();
511 global_proxy_port.def).toInt ();
513 global_proxy_user.def).toString ();
515 global_proxy_pass.def).toString ();
516 if (proxy_type_string == "HttpProxy")
517 scheme = "http";
518 else if (proxy_type_string == "Socks5Proxy")
519 scheme = "socks5";
520
521 QUrl env_var_url = QUrl ();
522 proxy_url.setScheme (scheme);
523 proxy_url.setHost (host);
524 proxy_url.setPort (port);
525 if (! user.isEmpty ())
526 proxy_url.setUserName (user);
527 if (! pass.isEmpty ())
528 proxy_url.setPassword (pass);
529 }
530
531 // The proxy data from environment variables
532 if (proxy_type_string == global_proxy_all_types.at (2))
533 {
534 const std::array<std::string, 6> env_vars =
535 {
536 "ALL_PROXY", "all_proxy",
537 "HTTP_PROXY", "http_proxy",
538 "HTTPS_PROXY", "https_proxy"
539 };
540
541 unsigned int count = 0;
542 while (! proxy_url.isValid () && count < env_vars.size ())
543 {
544 proxy_url = QUrl (QString::fromStdString
545 (sys::env::getenv (env_vars[count])));
546 count++;
547 }
548
549 if (proxy_url.isValid ())
550 {
551 // Found an entry, get the data from the string
552 scheme = proxy_url.scheme ();
553
554 if (scheme.contains ("socks", Qt::CaseInsensitive))
555 proxy_type = QNetworkProxy::Socks5Proxy;
556 else
557 proxy_type = QNetworkProxy::HttpProxy;
558
559 host = proxy_url.host ();
560 port = proxy_url.port ();
561 user = proxy_url.userName ();
562 pass = proxy_url.password ();
563 }
564 }
565 }
566
567 // Set proxy for Qt framework
568 proxy.setType (proxy_type);
569 proxy.setHostName (host);
570 proxy.setPort (port);
571 proxy.setUser (user);
572 proxy.setPassword (pass);
573
574 QNetworkProxy::setApplicationProxy (proxy);
575
576 // Set proxy for curl library if not based on environment variables
577 std::string proxy_url_str = proxy_url.toString().toStdString ();
578 sys::env::putenv ("http_proxy", proxy_url_str);
579 sys::env::putenv ("HTTP_PROXY", proxy_url_str);
580 sys::env::putenv ("https_proxy", proxy_url_str);
581 sys::env::putenv ("HTTPS_PROXY", proxy_url_str);
582 }
583
584 QIcon resource_manager::icon (const QString& icon_name, bool fallback)
585 {
586 // If system icon theme is not desired, take own icon files
587 if (! m_settings->value (global_icon_theme).toBool ())
588 return QIcon (":/actions/icons/" + icon_name + ".png");
589
590 // Use system icon theme with own files as fallback except when the
591 // fallback is explicitly disabled (fallback=false)
592 if (fallback)
593 return QIcon::fromTheme (icon_name,
594 QIcon (":/actions/icons/" + icon_name + ".png"));
595 else
596 return QIcon::fromTheme (icon_name);
597 }
598
599 // get a list of all available encodings
600 void resource_manager::get_codecs (QStringList *codecs)
601 {
602 // get the codec name for each mib
603 QList<int> all_mibs = QTextCodec::availableMibs ();
604 for (auto mib : all_mibs)
605 {
606 QTextCodec *c = QTextCodec::codecForMib (mib);
607 codecs->append (c->name ().toUpper ());
608 }
609
610 // Append SYSTEM
611 codecs->append (QString ("SYSTEM (") +
612 QString (octave_locale_charset_wrapper ()).toUpper () +
613 QString (")"));
614
615 // Clean up and sort list of codecs
616 codecs->removeDuplicates ();
617 std::sort (codecs->begin (), codecs->end ());
618 }
619
620 // initialize a given combo box with available text encodings
621 void resource_manager::combo_encoding (QComboBox *combo,
622 const QString& current)
623 {
624 QStringList all_codecs;
625 get_codecs (&all_codecs);
626
627 // get the value from the settings file if no current encoding is given
628 QString enc = current;
629
630 // Check for valid codec for the default. If this fails, "SYSTEM" (i.e.
631 // locale_charset) will be chosen.
632 // FIXME: The default is "SYSTEM" on all platforms. So can this fallback
633 // logic be removed completely?
634 bool default_exists = false;
635 bool show_system = false;
636 if (ed_default_enc.def.toString ().startsWith ("SYSTEM"))
637 show_system = true;
638 else if (QTextCodec::codecForName (ed_default_enc.def.toString ().toLatin1 ()))
639 default_exists = true;
640
641 QString default_enc =
642 QString ("SYSTEM (") +
643 QString (octave_locale_charset_wrapper ()).toUpper () + QString (")");
644
645 if (enc.isEmpty ())
646 {
647 enc = m_settings->value (ed_default_enc).toString ();
648
649 if (enc.isEmpty ()) // still empty?
650 {
651 if (default_exists)
652 enc = ed_default_enc.def.toString ();
653 else
654 enc = default_enc;
655 }
656 }
657
658 // fill the combo box
659 for (const auto& c : all_codecs)
660 combo->addItem (c);
661
662 // prepend the default item
663 combo->insertSeparator (0);
664 if (show_system || ! default_exists)
665 combo->insertItem (0, default_enc);
666 else
667 combo->insertItem (0, ed_default_enc.def.toString ());
668
669 // select the default or the current one
670 int idx = combo->findText (enc, Qt::MatchExactly);
671 if (idx >= 0)
672 combo->setCurrentIndex (idx);
673 else
674 combo->setCurrentIndex (0);
675
676 combo->setMaxVisibleItems (12);
677 }
678
679 QPointer<QTemporaryFile>
680 resource_manager::create_tmp_file (const QString& extension,
681 const QString& contents)
682 {
683 QString ext = extension;
684 if ((! ext.isEmpty ()) && (! ext.startsWith ('.')))
685 ext = QString (".") + ext;
686
687 // Create octave dir within temp. dir
688 QString tmp_dir = QDir::tempPath () + QDir::separator() + "octave";
689 QDir::temp ().mkdir ("octave");
690
691 // Create temp. file
692 QPointer<QTemporaryFile> tmp_file
693 = new QTemporaryFile (tmp_dir + QDir::separator() +
694 "octave_XXXXXX" + ext, this);
695
696 if (tmp_file->open ())
697 {
698 tmp_file->write (contents.toUtf8 ());
699 tmp_file->close ();
700
701 m_temporary_files << tmp_file;
702 }
703
704 return tmp_file;
705 }
706
707 void resource_manager::remove_tmp_file (QPointer<QTemporaryFile> tmp_file)
708 {
709 if (tmp_file)
710 {
711 if (tmp_file->exists ())
712 tmp_file->remove ();
713
714 m_temporary_files.removeAll (tmp_file);
715 }
716 }
717}
QVariant value(const gui_pref &pref) const
Definition: gui-settings.h:63
QString get_default_font_family(void)
void combo_encoding(QComboBox *combo, const QString &current=QString())
gui_settings * get_settings(void) const
QStringList get_default_font(void)
gui_settings * get_default_settings(void) const
void read_lexer_settings(QsciLexer *lexer, gui_settings *settings, int mode=0, int def=0)
void get_codecs(QStringList *codecs)
QFont copy_font_attributes(const QFont &attr, const QFont &base) const
gui_settings * m_default_settings
int get_valid_lexer_styles(QsciLexer *lexer, int *styles)
QString get_gui_translation_dir(void)
bool is_first_run(void) const
QList< QTemporaryFile * > m_temporary_files
QPointer< QTemporaryFile > create_tmp_file(const QString &extension=QString(), const QString &contents=QString())
QIcon icon(const QString &icon_name, bool fallback=true)
void remove_tmp_file(QPointer< QTemporaryFile > tmp_file)
bool update_settings_key(const QString &new_key, const QString &old_key)
QString get_settings_directory(void)
void set_settings(const QString &file)
void config_translators(QTranslator *qt_tr, QTranslator *qsci_tr, QTranslator *gui_tr)
static std::string getenv(const std::string &name)
Definition: oct-env.cc:294
static void putenv(const std::string &name, const std::string &value)
Definition: oct-env.cc:301
const gui_pref cs_font_size("terminal/fontSize", QVariant(10))
const gui_pref cs_font("terminal/fontName", QVariant())
const int ed_max_lexer_styles
const gui_pref ed_default_enc("editor/default_encoding", QVariant("UTF-8"))
const int ed_max_style_number
const gui_pref global_use_proxy("useProxyServer", QVariant(false))
const gui_pref global_mono_font("monospace_font", global_font_family)
const gui_pref global_proxy_pass("proxyPassword", QVariant(QString()))
const QStringList global_proxy_all_types(QStringList()<< "HttpProxy"<< "Socks5Proxy"<< QT_TRANSLATE_NOOP("octave::settings_dialog", "Environment Variables"))
const gui_pref global_proxy_host("proxyHostName", QVariant(QString()))
const gui_pref global_proxy_type("proxyType", QVariant(QString()))
const gui_pref global_proxy_user("proxyUserName", QVariant(QString()))
const gui_pref global_icon_theme("use_system_icon_theme", QVariant(true))
const gui_pref global_custom_editor("customFileEditor", QVariant("emacs +%l %f"))
const gui_pref global_proxy_port("proxyPort", QVariant(80))
const gui_pref global_language("language", QVariant("SYSTEM"))
const QStringList settings_color_modes_ext(QStringList()<< ""<< "_2")
const int settings_reload_default_colors_flag
Definition: gui-settings.h:156
const char * octave_locale_charset_wrapper(void)
std::string oct_locale_dir(void)
Definition: defaults.cc:371
QString fromStdString(const std::string &s)
std::complex< T > floor(const std::complex< T > &x)
Definition: lo-mappers.h:130
int system(const std::string &cmd_str)
Definition: lo-sysdep.cc:59
const QString key
const QVariant def