[rkward/work/new_completion_to_console] rkward: Move code completion settings into a separate class, in preparation for adding console settings.

Thomas Friedrichsmeier null at kde.org
Wed Apr 15 15:08:37 BST 2020


Git commit 39fa7b8bacc702c1822871d823e81589cfa187b3 by Thomas Friedrichsmeier.
Committed on 15/04/2020 at 14:07.
Pushed by tfry into branch 'work/new_completion_to_console'.

Move code completion settings into a separate class, in preparation for adding console settings.

M  +14   -0    rkward/settings/rksettingsmodule.h
M  +141  -110  rkward/settings/rksettingsmodulecommandeditor.cpp
M  +41   -40   rkward/settings/rksettingsmodulecommandeditor.h
M  +13   -13   rkward/windows/rkcodecompletion.cpp
M  +1    -1    rkward/windows/rkcommandeditorwindow.cpp

https://commits.kde.org/rkward/39fa7b8bacc702c1822871d823e81589cfa187b3

diff --git a/rkward/settings/rksettingsmodule.h b/rkward/settings/rksettingsmodule.h
index c9d35d48..91ed7df5 100644
--- a/rkward/settings/rksettingsmodule.h
+++ b/rkward/settings/rksettingsmodule.h
@@ -20,6 +20,7 @@
 #include <qstring.h>
 #include <qwidget.h>
 #include <QUrl>
+#include <KConfigGroup>
 
 class KConfig;
 class RKSettings;
@@ -46,6 +47,7 @@ be inserted into this chain. It's safe to use this unconditionally, as if there
 
 	virtual QUrl helpURL () { return QUrl (); };
 protected:
+friend class RKSettingsModuleWidget;
 	void change ();
 
 	bool changed;
@@ -55,6 +57,18 @@ friend class RKSettings;
 	static RCommandChain *chain;
 };
 
+/** Base class for UI widgets operating on an RKSettingsModule. For now this is used, only where similar settings are shared across modules (e.g. code completion). Eventually, this could be used to disentangle RKSettingsModule from QWidget. */
+class RKSettingsModuleWidget : public QWidget {
+public:
+	RKSettingsModuleWidget(QWidget *parent, RKSettingsModule *_module) : QWidget(parent), module(_module) {};
+	~RKSettingsModuleWidget() {};
+	virtual void applyChanges() = 0;
+protected:
+	void change() { module->change(); }
+private:
+	RKSettingsModule *module;
+};
+
 #include <functional>
 /** Simple helper class to formalize the API of widgets used for the interactive validation of settings.
  *  (For quering about settings that may need adjusting on startup. Possibly to be expanded to a "first-run-wizard", in the future). */
diff --git a/rkward/settings/rksettingsmodulecommandeditor.cpp b/rkward/settings/rksettingsmodulecommandeditor.cpp
index f1a940b0..1d03eab4 100644
--- a/rkward/settings/rksettingsmodulecommandeditor.cpp
+++ b/rkward/settings/rksettingsmodulecommandeditor.cpp
@@ -36,19 +36,129 @@
 #include "../debug.h"
 
 // static members
-int RKSettingsModuleCommandEditor::auto_completion_min_chars;
-int RKSettingsModuleCommandEditor::auto_completion_timeout;
-bool RKSettingsModuleCommandEditor::auto_completion_enabled;
-bool RKSettingsModuleCommandEditor::auto_completion_cursor_activated;
-bool RKSettingsModuleCommandEditor::completion_type_enabled[RKSettingsModuleCommandEditor::N_COMPLETION_CATEGORIES];
-int RKSettingsModuleCommandEditor::completion_options;
-bool RKSettingsModuleCommandEditor::cursor_navigates_completions;
+RKCodeCompletionSettings RKSettingsModuleCommandEditor::completion_settings;
 bool RKSettingsModuleCommandEditor::autosave_enabled;
 bool RKSettingsModuleCommandEditor::autosave_keep;
 int RKSettingsModuleCommandEditor::autosave_interval;
 int RKSettingsModuleCommandEditor::num_recent_files;
 QString RKSettingsModuleCommandEditor::script_file_filter;
 
+class RKCodeCompletionSettingsWidget : public RKSettingsModuleWidget {
+public:
+	RKCodeCompletionSettingsWidget(QWidget *parent, RKSettingsModule *module, RKCodeCompletionSettings *settings) : RKSettingsModuleWidget(parent, module), settings(settings) {
+		RK_TRACE (SETTINGS);
+		QVBoxLayout* main_vbox = new QVBoxLayout (this);
+		main_vbox->setContentsMargins(0,0,0,0);
+
+		QGroupBox* group = new QGroupBox (i18n ("Code Completion / Code Hints"), this);
+		QVBoxLayout* box_layout = new QVBoxLayout (group);
+
+		QGridLayout *g_layout = new QGridLayout ();
+		box_layout->addLayout (g_layout);
+		makeCompletionTypeBoxes (QStringList () << i18n ("Function call tip") << i18n ("Function argument completion") << i18n ("Object name completion") << i18n ("Filename completion") << i18n ("Auto word completion"), g_layout);
+
+		auto_completion_enabled_box = new QGroupBox (i18n ("Start code completions/hints, automatically"), group);
+		auto_completion_enabled_box->setCheckable (true);
+		auto_completion_enabled_box->setChecked (settings->auto_completion_enabled);
+		connect (auto_completion_enabled_box, &QGroupBox::toggled, this, &RKCodeCompletionSettingsWidget::change);
+		box_layout->addWidget (auto_completion_enabled_box);
+
+		QFormLayout* form_layout = new QFormLayout (auto_completion_enabled_box);
+		auto_completion_min_chars_box = new RKSpinBox (auto_completion_enabled_box);
+		auto_completion_min_chars_box->setIntMode (1, INT_MAX, settings->auto_completion_min_chars);
+		connect (auto_completion_min_chars_box, static_cast<void (QSpinBox::*)(int)>(&QSpinBox::valueChanged), this, &RKCodeCompletionSettingsWidget::change);
+		form_layout->addRow ("Minimum number of characters", auto_completion_min_chars_box);
+
+		auto_completion_timeout_box = new RKSpinBox (auto_completion_enabled_box);
+		auto_completion_timeout_box->setIntMode (0, INT_MAX, settings->auto_completion_timeout);
+		connect (auto_completion_timeout_box, static_cast<void (QSpinBox::*)(int)>(&QSpinBox::valueChanged), this, &RKCodeCompletionSettingsWidget::change);
+		form_layout->addRow (i18n ("Timeout (milliseconds)"), auto_completion_timeout_box);
+
+		auto_completion_cursor_activated_box = new QCheckBox (auto_completion_enabled_box);
+		auto_completion_cursor_activated_box->setChecked (settings->auto_completion_cursor_activated);
+		connect (auto_completion_cursor_activated_box, &QCheckBox::stateChanged, this, &RKCodeCompletionSettingsWidget::change);
+		form_layout->addRow (i18n ("(Attempt to) start completion whenever the cursor position changes"), auto_completion_cursor_activated_box);
+
+		form_layout = new QFormLayout ();
+		box_layout->addLayout (form_layout);
+
+		cursor_navigates_completions_box = new QCheckBox (i18n ("Up/down cursor keys navigate completion items"));
+		cursor_navigates_completions_box->setChecked (settings->cursor_navigates_completions);
+		RKCommonFunctions::setTips (i18n ("Should the up / down cursor keys be used to navigate among the completion items, while code completion is active? If this option is unchecked, Alt+up/down will navigate completion items, while up / down will behave as if no completion was active."), cursor_navigates_completions_box);
+		connect (cursor_navigates_completions_box, &QCheckBox::stateChanged, this, &RKCodeCompletionSettingsWidget::change);
+		form_layout->addRow (cursor_navigates_completions_box);
+
+		completion_list_member_operator_box = new QComboBox (group);
+		completion_list_member_operator_box->addItem (i18n ("'$'-operator (list$member)"));
+		completion_list_member_operator_box->addItem (i18n ("'[['-operator (list[[\"member\"]])"));
+		completion_list_member_operator_box->setCurrentIndex ((settings->completion_options & RObject::DollarExpansion) ? 0 : 1);
+		connect (completion_list_member_operator_box, static_cast<void (QComboBox::*)(int)>(&QComboBox::currentIndexChanged), this, &RKCodeCompletionSettingsWidget::change);
+		form_layout->addRow (i18nc ("Note: list() and data.frame() are programming terms in R, and should not be translated, here", "Operator for access to members of list() and data.frame() objects"), completion_list_member_operator_box);
+
+		completion_slot_operator_box = new QComboBox (group);
+		completion_slot_operator_box->addItem (i18n ("'@'-operator (object at smember)"));
+		completion_slot_operator_box->addItem (i18n ("'slot()'-function (slot(object, member))"));
+		completion_slot_operator_box->setCurrentIndex ((settings->completion_options & RObject::ExplicitSlotsExpansion) ? 1 : 0);
+		connect (completion_slot_operator_box, static_cast<void (QComboBox::*)(int)>(&QComboBox::currentIndexChanged), this, &RKCodeCompletionSettingsWidget::change);
+		form_layout->addRow (i18nc ("Note: S4-slot() is a programming term in R, and should not be translated, here", "Operator for access to S4-slot()s"), completion_slot_operator_box);
+
+		completion_object_qualification_box = new QComboBox (group);
+		completion_object_qualification_box->addItem (i18n ("For masked objects, only"));
+		completion_object_qualification_box->addItem (i18n ("For objects outside of <i>.GlobalEnv</i>, only"));
+		completion_object_qualification_box->addItem (i18n ("Always"));
+		if (settings->completion_options & (RObject::IncludeEnvirIfNotGlobalEnv)) {
+			if (settings->completion_options & (RObject::IncludeEnvirIfNotGlobalEnv)) completion_object_qualification_box->setCurrentIndex (2);
+			else completion_object_qualification_box->setCurrentIndex (1);
+		}
+		connect (completion_object_qualification_box, static_cast<void (QComboBox::*)(int)>(&QComboBox::currentIndexChanged), this, &RKCodeCompletionSettingsWidget::change);
+		form_layout->addRow (i18n ("Include environment for objects on the search path:"), completion_object_qualification_box);
+
+		main_vbox->addWidget(group);
+	}
+
+	~RKCodeCompletionSettingsWidget() {};
+	void applyChanges() override {
+		settings->auto_completion_enabled = auto_completion_enabled_box->isChecked ();
+		settings->auto_completion_min_chars = auto_completion_min_chars_box->intValue ();
+		settings->auto_completion_timeout = auto_completion_timeout_box->intValue ();
+		settings->auto_completion_cursor_activated = auto_completion_cursor_activated_box->isChecked ();
+		for (int i = 0; i < RKCodeCompletionSettings::N_COMPLETION_CATEGORIES; ++i) {
+			settings->completion_type_enabled[i] = completion_type_enabled_box[i]->isChecked ();
+		}
+		settings->cursor_navigates_completions = cursor_navigates_completions_box->isChecked ();
+
+		settings->completion_options = 0;
+		if (completion_list_member_operator_box->currentIndex () == 0) settings->completion_options += RObject::DollarExpansion;
+		if (completion_slot_operator_box->currentIndex () == 1) settings->completion_options += RObject::ExplicitSlotsExpansion;
+		if (completion_object_qualification_box->currentIndex () == 2) settings->completion_options += RObject::IncludeEnvirForGlobalEnv | RObject::IncludeEnvirIfNotGlobalEnv;
+		else if (completion_object_qualification_box->currentIndex () == 1) settings->completion_options += RObject::IncludeEnvirIfNotGlobalEnv;
+		else settings->completion_options += RObject::IncludeEnvirIfMasked;
+	}
+private:
+	RKSpinBox* auto_completion_min_chars_box;
+	RKSpinBox* auto_completion_timeout_box;
+	QGroupBox* auto_completion_enabled_box;
+	QCheckBox* auto_completion_cursor_activated_box;
+	QCheckBox* completion_type_enabled_box[RKCodeCompletionSettings::N_COMPLETION_CATEGORIES];
+	QCheckBox* cursor_navigates_completions_box;
+	QComboBox* completion_list_member_operator_box;
+	QComboBox* completion_slot_operator_box;
+	QComboBox* completion_object_qualification_box;
+
+	RKCodeCompletionSettings *settings;
+
+	void makeCompletionTypeBoxes (const QStringList& labels, QGridLayout* layout) {
+		RK_ASSERT (labels.count () == RKCodeCompletionSettings::N_COMPLETION_CATEGORIES);
+		for (int i = 0; i < RKCodeCompletionSettings::N_COMPLETION_CATEGORIES; ++i) {
+			QCheckBox *box = new QCheckBox(labels[i]);
+			box->setChecked (settings->completion_type_enabled[i]);
+			completion_type_enabled_box[i] = box;
+			layout->addWidget (completion_type_enabled_box[i], i / 2, i % 2);
+			connect (box, &QCheckBox::stateChanged, this, &RKCodeCompletionSettingsWidget::change);
+		}
+	}
+};
+
 RKSettingsModuleCommandEditor::RKSettingsModuleCommandEditor (RKSettings *gui, QWidget *parent) : RKSettingsModule (gui, parent) {
 	RK_TRACE (SETTINGS);
 
@@ -56,78 +166,15 @@ RKSettingsModuleCommandEditor::RKSettingsModuleCommandEditor (RKSettings *gui, Q
 	main_vbox->addWidget (RKCommonFunctions::wordWrappedLabel (i18n ("Settings marked with (*) do not take effect until you restart RKWard")));
 	main_vbox->addSpacing (2 * RKGlobals::spacingHint ());
 
-	QGroupBox* group = new QGroupBox (i18n ("Code Completion / Code Hints"), this);
-	QVBoxLayout* box_layout = new QVBoxLayout (group);
-
-	QGridLayout *g_layout = new QGridLayout ();
-	box_layout->addLayout (g_layout);
-	makeCompletionTypeBoxes (QStringList () << i18n ("Function call tip") << i18n ("Function argument completion") << i18n ("Object name completion") << i18n ("Filename completion") << i18n ("Auto word completion"), g_layout);
-
-	auto_completion_enabled_box = new QGroupBox (i18n ("Start code completions/hints, automatically"), group);
-	auto_completion_enabled_box->setCheckable (true);
-	auto_completion_enabled_box->setChecked (auto_completion_enabled);
-	connect (auto_completion_enabled_box, &QGroupBox::toggled, this, &RKSettingsModuleCommandEditor::settingChanged);
-	box_layout->addWidget (auto_completion_enabled_box);
-
-	QFormLayout* form_layout = new QFormLayout (auto_completion_enabled_box);
-	auto_completion_min_chars_box = new RKSpinBox (auto_completion_enabled_box);
-	auto_completion_min_chars_box->setIntMode (1, INT_MAX, auto_completion_min_chars);
-	connect (auto_completion_min_chars_box, static_cast<void (QSpinBox::*)(int)>(&QSpinBox::valueChanged), this, &RKSettingsModuleCommandEditor::settingChanged);
-	form_layout->addRow ("Minimum number of characters", auto_completion_min_chars_box);
-
-	auto_completion_timeout_box = new RKSpinBox (auto_completion_enabled_box);
-	auto_completion_timeout_box->setIntMode (0, INT_MAX, auto_completion_timeout);
-	connect (auto_completion_timeout_box, static_cast<void (QSpinBox::*)(int)>(&QSpinBox::valueChanged), this, &RKSettingsModuleCommandEditor::settingChanged);
-	form_layout->addRow (i18n ("Timeout (milliseconds)"), auto_completion_timeout_box);
-
-	auto_completion_cursor_activated_box = new QCheckBox (auto_completion_enabled_box);
-	auto_completion_cursor_activated_box->setChecked (auto_completion_cursor_activated);
-	connect (auto_completion_cursor_activated_box, &QCheckBox::stateChanged, this, &RKSettingsModuleCommandEditor::settingChanged);
-	form_layout->addRow (i18n ("(Attempt to) start completion whenever the cursor position changes"), auto_completion_cursor_activated_box);
-
-	form_layout = new QFormLayout ();
-	box_layout->addLayout (form_layout);
-
-	cursor_navigates_completions_box = new QCheckBox (i18n ("Up/down cursor keys navigate completion items"));
-	cursor_navigates_completions_box->setChecked (cursor_navigates_completions);
-	RKCommonFunctions::setTips (i18n ("Should the up / down cursor keys be used to navigate among the completion items, while code completion is active? If this option is unchecked, Alt+up/down will navigate completion items, while up / down will behave as if no completion was active."), cursor_navigates_completions_box);
-	connect (cursor_navigates_completions_box, &QCheckBox::stateChanged, this, &RKSettingsModuleCommandEditor::settingChanged);
-	form_layout->addRow (cursor_navigates_completions_box);
-
-	completion_list_member_operator_box = new QComboBox (group);
-	completion_list_member_operator_box->addItem (i18n ("'$'-operator (list$member)"));
-	completion_list_member_operator_box->addItem (i18n ("'[['-operator (list[[\"member\"]])"));
-	completion_list_member_operator_box->setCurrentIndex ((completion_options & RObject::DollarExpansion) ? 0 : 1);
-	connect (completion_list_member_operator_box, static_cast<void (QComboBox::*)(int)>(&QComboBox::currentIndexChanged), this, &RKSettingsModuleCommandEditor::settingChanged);
-	form_layout->addRow (i18nc ("Note: list() and data.frame() are programming terms in R, and should not be translated, here", "Operator for access to members of list() and data.frame() objects"), completion_list_member_operator_box);
-
-	completion_slot_operator_box = new QComboBox (group);
-	completion_slot_operator_box->addItem (i18n ("'@'-operator (object at smember)"));
-	completion_slot_operator_box->addItem (i18n ("'slot()'-function (slot(object, member))"));
-	completion_slot_operator_box->setCurrentIndex ((completion_options & RObject::ExplicitSlotsExpansion) ? 1 : 0);
-	connect (completion_slot_operator_box, static_cast<void (QComboBox::*)(int)>(&QComboBox::currentIndexChanged), this, &RKSettingsModuleCommandEditor::settingChanged);
-	form_layout->addRow (i18nc ("Note: S4-slot() is a programming term in R, and should not be translated, here", "Operator for access to S4-slot()s"), completion_slot_operator_box);
-
-	completion_object_qualification_box = new QComboBox (group);
-	completion_object_qualification_box->addItem (i18n ("For masked objects, only"));
-	completion_object_qualification_box->addItem (i18n ("For objects outside of <i>.GlobalEnv</i>, only"));
-	completion_object_qualification_box->addItem (i18n ("Always"));
-	if (completion_options & (RObject::IncludeEnvirIfNotGlobalEnv)) {
-		if (completion_options & (RObject::IncludeEnvirIfNotGlobalEnv)) completion_object_qualification_box->setCurrentIndex (2);
-		else completion_object_qualification_box->setCurrentIndex (1);
-	}
-	connect (completion_object_qualification_box, static_cast<void (QComboBox::*)(int)>(&QComboBox::currentIndexChanged), this, &RKSettingsModuleCommandEditor::settingChanged);
-	form_layout->addRow (i18n ("Include environment for objects on the search path:"), completion_object_qualification_box);
-
-	main_vbox->addWidget (group);
+	main_vbox->addWidget (new RKCodeCompletionSettingsWidget (this, this, &completion_settings));
 
 	main_vbox->addSpacing (2 * RKGlobals::spacingHint ());
 
-	group = autosave_enabled_box = new QGroupBox (i18n ("Autosaves"), this);
+	QGroupBox *group = autosave_enabled_box = new QGroupBox (i18n ("Autosaves"), this);
 	autosave_enabled_box->setCheckable (true);
 	autosave_enabled_box->setChecked (autosave_enabled);
 	connect (autosave_enabled_box, &QGroupBox::toggled, this, &RKSettingsModuleCommandEditor::settingChanged);
-	form_layout = new QFormLayout (group);
+	QFormLayout *form_layout = new QFormLayout (group);
 
 	autosave_interval_box = new RKSpinBox (group);
 	autosave_interval_box->setIntMode (1, INT_MAX, autosave_interval);
@@ -166,17 +213,6 @@ RKSettingsModuleCommandEditor::~RKSettingsModuleCommandEditor () {
 	RK_TRACE (SETTINGS);
 }
 
-void RKSettingsModuleCommandEditor::makeCompletionTypeBoxes (const QStringList& labels, QGridLayout* layout) {
-	RK_ASSERT (labels.count () == N_COMPLETION_CATEGORIES);
-	for (int i = 0; i < N_COMPLETION_CATEGORIES; ++i) {
-		QCheckBox *box = new QCheckBox(labels[i]);
-		box->setChecked (completion_type_enabled[i]);
-		completion_type_enabled_box[i] = box;
-		layout->addWidget (completion_type_enabled_box[i], i / 2, i % 2);
-		connect (box, &QCheckBox::stateChanged, this, &RKSettingsModuleCommandEditor::settingChanged);
-	}
-}
-
 void RKSettingsModuleCommandEditor::settingChanged () {
 	RK_TRACE (SETTINGS);
 	change ();
@@ -190,22 +226,6 @@ QString RKSettingsModuleCommandEditor::caption () {
 void RKSettingsModuleCommandEditor::applyChanges () {
 	RK_TRACE (SETTINGS);
 
-	auto_completion_enabled = auto_completion_enabled_box->isChecked ();
-	auto_completion_min_chars = auto_completion_min_chars_box->intValue ();
-	auto_completion_timeout = auto_completion_timeout_box->intValue ();
-	auto_completion_cursor_activated = auto_completion_cursor_activated_box->isChecked ();
-	for (int i = 0; i < N_COMPLETION_CATEGORIES; ++i) {
-		completion_type_enabled[i] = completion_type_enabled_box[i]->isChecked ();
-	}
-	cursor_navigates_completions = cursor_navigates_completions_box->isChecked ();
-
-	completion_options = 0;
-	if (completion_list_member_operator_box->currentIndex () == 0) completion_options += RObject::DollarExpansion;
-	if (completion_slot_operator_box->currentIndex () == 1) completion_options += RObject::ExplicitSlotsExpansion;
-	if (completion_object_qualification_box->currentIndex () == 2) completion_options += RObject::IncludeEnvirForGlobalEnv | RObject::IncludeEnvirIfNotGlobalEnv;
-	else if (completion_object_qualification_box->currentIndex () == 1) completion_options += RObject::IncludeEnvirIfNotGlobalEnv;
-	else completion_options += RObject::IncludeEnvirIfMasked;
-
 	autosave_enabled = autosave_enabled_box->isChecked ();
 	autosave_keep = autosave_keep_box->isChecked ();
 	autosave_interval = autosave_interval_box->intValue ();
@@ -220,19 +240,17 @@ void RKSettingsModuleCommandEditor::save (KConfig *config) {
 }
 
 QString completionTypeToConfigKey (int cat) {
-	if (cat == RKSettingsModuleCommandEditor::Calltip) return "Calltips";
-	if (cat == RKSettingsModuleCommandEditor::Arghint) return "Argument completion";
-	if (cat == RKSettingsModuleCommandEditor::Object) return "Object completion";
-	if (cat == RKSettingsModuleCommandEditor::Filename) return "Filename completion";
-	if (cat == RKSettingsModuleCommandEditor::AutoWord) return "Auto word completion";
+	if (cat == RKCodeCompletionSettings::Calltip) return "Calltips";
+	if (cat == RKCodeCompletionSettings::Arghint) return "Argument completion";
+	if (cat == RKCodeCompletionSettings::Object) return "Object completion";
+	if (cat == RKCodeCompletionSettings::Filename) return "Filename completion";
+	if (cat == RKCodeCompletionSettings::AutoWord) return "Auto word completion";
 	RK_ASSERT(false);
 	return QString ();
 }
 
-void RKSettingsModuleCommandEditor::saveSettings (KConfig *config) {
+void RKCodeCompletionSettings::saveSettings(KConfigGroup& cg) {
 	RK_TRACE (SETTINGS);
-
-	KConfigGroup cg = config->group ("Command Editor Windows");
 	cg.writeEntry ("Completion enabled", auto_completion_enabled);
 	cg.writeEntry ("Completion min chars", auto_completion_min_chars);
 	cg.writeEntry ("Completion timeout", auto_completion_timeout);
@@ -242,6 +260,13 @@ void RKSettingsModuleCommandEditor::saveSettings (KConfig *config) {
 	for (int i = 0; i < N_COMPLETION_CATEGORIES; ++i) {
 		cg.writeEntry (completionTypeToConfigKey (i), completion_type_enabled[i]);
 	}
+}
+
+void RKSettingsModuleCommandEditor::saveSettings (KConfig *config) {
+	RK_TRACE (SETTINGS);
+
+	KConfigGroup cg = config->group ("Command Editor Windows");
+	completion_settings.saveSettings(cg);
 
 	cg.writeEntry ("Autosave enabled", autosave_enabled);
 	cg.writeEntry ("Autosave keep saves", autosave_keep);
@@ -251,10 +276,9 @@ void RKSettingsModuleCommandEditor::saveSettings (KConfig *config) {
 	cg.writeEntry ("Script file filter", script_file_filter);
 }
 
-void RKSettingsModuleCommandEditor::loadSettings (KConfig *config) {
+void RKCodeCompletionSettings::loadSettings(KConfigGroup& cg) {
 	RK_TRACE (SETTINGS);
 
-	KConfigGroup cg = config->group ("Command Editor Windows");
 	auto_completion_enabled = cg.readEntry ("Completion enabled", true);
 	auto_completion_min_chars = cg.readEntry ("Completion min chars", 2);
 	auto_completion_timeout = cg.readEntry ("Completion timeout", 250);
@@ -264,6 +288,13 @@ void RKSettingsModuleCommandEditor::loadSettings (KConfig *config) {
 	for (int i = 0; i < N_COMPLETION_CATEGORIES; ++i) {
 		completion_type_enabled[i] = cg.readEntry (completionTypeToConfigKey (i), true);
 	}
+}
+
+void RKSettingsModuleCommandEditor::loadSettings (KConfig *config) {
+	RK_TRACE (SETTINGS);
+
+	KConfigGroup cg = config->group ("Command Editor Windows");
+	completion_settings.loadSettings(cg);
 
 	autosave_enabled = cg.readEntry ("Autosave enabled", true);
 	autosave_keep = cg.readEntry ("Autosave keep saves", false);
diff --git a/rkward/settings/rksettingsmodulecommandeditor.h b/rkward/settings/rksettingsmodulecommandeditor.h
index 78a53930..57f7148a 100644
--- a/rkward/settings/rksettingsmodulecommandeditor.h
+++ b/rkward/settings/rksettingsmodulecommandeditor.h
@@ -26,6 +26,44 @@ class QGroupBox;
 class QComboBox;
 class QGridLayout;
 
+class RKCodeCompletionSettingsWidget;
+class RKCodeCompletionSettings {
+public:
+	RKCodeCompletionSettings() {};
+	~RKCodeCompletionSettings() {};
+
+	void loadSettings(KConfigGroup &config);
+	void saveSettings(KConfigGroup &config);
+
+	enum CompletionCategories {
+		Calltip = 0,
+		Arghint,
+		Object,
+		Filename,
+		AutoWord,
+		N_COMPLETION_CATEGORIES
+	};
+
+/// min number of character to try code completion
+	int autoMinChars () const { return auto_completion_min_chars; };
+	int autoTimeout () const { return auto_completion_timeout; };
+	bool autoEnabled () const { return auto_completion_enabled; };
+	bool autoCursorActivated () const { return (auto_completion_enabled && auto_completion_cursor_activated); };
+	bool argHintingEnabled () const { return isEnabled (Arghint); };  // TODO: remove me
+	int options () const { return completion_options; };
+	bool isEnabled (CompletionCategories cat) const { return completion_type_enabled[cat]; };
+	bool cursorNavigatesCompletions () const { return cursor_navigates_completions; };
+private:
+friend class RKCodeCompletionSettingsWidget;
+	int auto_completion_min_chars;
+	int auto_completion_timeout;
+	bool auto_completion_enabled;
+	bool auto_completion_cursor_activated;
+	bool completion_type_enabled[N_COMPLETION_CATEGORIES];
+	bool cursor_navigates_completions;
+	int completion_options;
+};
+
 /**
 configuration for the Command Editor windows
 
@@ -46,24 +84,7 @@ public:
 
 	QString caption () override;
 
-	enum CompletionCategories {
-		Calltip = 0,
-		Arghint,
-		Object,
-		Filename,
-		AutoWord,
-		N_COMPLETION_CATEGORIES
-	};
-
-/// min number of character to try code completion
-	static int autoCompletionMinChars () { return auto_completion_min_chars; };
-	static int autoCompletionTimeout () { return auto_completion_timeout; };
-	static bool autoCompletionEnabled () { return auto_completion_enabled; };
-	static bool autoCompletionCursorActivated () { return (auto_completion_enabled && auto_completion_cursor_activated); };
-	static bool argHintingEnabled () { return isCompletionEnabled (Arghint); };  // TODO: remove me
-	static int completionOptions () { return completion_options; };
-	static bool isCompletionEnabled (CompletionCategories cat) { return completion_type_enabled[cat]; };
-	static bool cursorNavigatesCompletions () { return cursor_navigates_completions; };
+	static const RKCodeCompletionSettings* completionSettings() { return &completion_settings; };
 
 	static bool autosaveEnabled () { return autosave_enabled; };
 	static bool autosaveKeep () { return autosave_keep; };
@@ -76,32 +97,12 @@ public:
 public slots:
 	void settingChanged ();
 private:
-	void makeCompletionTypeBoxes (const QStringList& label, QGridLayout* layout);
-
-	static int auto_completion_min_chars;
-	static int auto_completion_timeout;
-	static bool auto_completion_enabled;
-	static bool auto_completion_cursor_activated;
-	static bool completion_type_enabled[N_COMPLETION_CATEGORIES];
-	static bool cursor_navigates_completions;
-
-	RKSpinBox* auto_completion_min_chars_box;
-	RKSpinBox* auto_completion_timeout_box;
-	QGroupBox* auto_completion_enabled_box;
-	QCheckBox* auto_completion_cursor_activated_box;
-	QCheckBox* completion_type_enabled_box[N_COMPLETION_CATEGORIES];
-	QCheckBox* cursor_navigates_completions_box;
-
-	static int completion_options;
-
-	QComboBox* completion_list_member_operator_box;
-	QComboBox* completion_slot_operator_box;
-	QComboBox* completion_object_qualification_box;
-
+	static RKCodeCompletionSettings completion_settings;
 	static bool autosave_enabled;
 	static bool autosave_keep;
 	static int autosave_interval;
 
+	RKCodeCompletionSettingsWidget *completion_settings_widget;
 	QGroupBox* autosave_enabled_box;
 	QCheckBox* autosave_keep_box;
 	RKSpinBox* autosave_interval_box;
diff --git a/rkward/windows/rkcodecompletion.cpp b/rkward/windows/rkcodecompletion.cpp
index 6db3aa4f..efc31fdd 100644
--- a/rkward/windows/rkcodecompletion.cpp
+++ b/rkward/windows/rkcodecompletion.cpp
@@ -108,8 +108,8 @@ void RKCompletionManager::tryCompletionProxy () {
 	if (cc_iface->isCompletionActive () || keep_active) {
 		// Handle this in the next event cycle, as more than one event may trigger
 		completion_timer->start (0);
-	} else if (RKSettingsModuleCommandEditor::autoCompletionEnabled ()) {
-		completion_timer->start (RKSettingsModuleCommandEditor::autoCompletionTimeout ());
+	} else if (RKSettingsModuleCommandEditor::completionSettings()->autoEnabled ()) {
+		completion_timer->start (RKSettingsModuleCommandEditor::completionSettings()->autoTimeout ());
 	}
 }
 
@@ -161,7 +161,7 @@ void RKCompletionManager::tryCompletion () {
 	}
 
 	QString word = currentCompletionWord ();
-	if (user_triggered || (word.length () >= RKSettingsModuleCommandEditor::autoCompletionMinChars ())) {
+	if (user_triggered || (word.length () >= RKSettingsModuleCommandEditor::completionSettings()->autoMinChars ())) {
 		QString filename;
 		// as a very simple heuristic: If the current symbol starts with a quote, we should probably attempt file name completion, instead of symbol name completion
 		if (word.startsWith ('\"') || word.startsWith ('\'') || word.startsWith ('`')) {
@@ -286,17 +286,17 @@ void RKCompletionManager::updateVisibility () {
 		active_models.clear ();
 	}
 
-	bool min_len = (currentCompletionWord ().length () >= RKSettingsModuleCommandEditor::autoCompletionMinChars ()) || user_triggered;
-	startModel (cc_iface, completion_model, min_len && RKSettingsModuleCommandEditor::isCompletionEnabled (RKSettingsModuleCommandEditor::Object), symbol_range, &active_models);
-	startModel (cc_iface, file_completion_model, min_len && RKSettingsModuleCommandEditor::isCompletionEnabled (RKSettingsModuleCommandEditor::Filename), symbol_range, &active_models);
-	if (kate_keyword_completion_model && RKSettingsModuleCommandEditor::isCompletionEnabled (RKSettingsModuleCommandEditor::AutoWord)) {
+	bool min_len = (currentCompletionWord ().length () >= RKSettingsModuleCommandEditor::completionSettings()->autoMinChars ()) || user_triggered;
+	startModel (cc_iface, completion_model, min_len && RKSettingsModuleCommandEditor::completionSettings()->isEnabled (RKCodeCompletionSettings::Object), symbol_range, &active_models);
+	startModel (cc_iface, file_completion_model, min_len && RKSettingsModuleCommandEditor::completionSettings()->isEnabled (RKCodeCompletionSettings::Filename), symbol_range, &active_models);
+	if (kate_keyword_completion_model && RKSettingsModuleCommandEditor::completionSettings()->isEnabled (RKCodeCompletionSettings::AutoWord)) {
 		// Model needs to update, first, as we have not handled it in tryCompletion:
 		if (min_len) kate_keyword_completion_model->completionInvoked (view (), symbol_range, KTextEditor::CodeCompletionModel::ManualInvocation);
 		startModel (cc_iface, kate_keyword_completion_model, min_len, symbol_range, &active_models);
 	}
 // NOTE: Freaky bug in KF 5.44.0: Call hint will not show for the first time, if logically above the primary screen. TODO: provide patch for kateargumenthinttree.cpp:166pp
-	startModel (cc_iface, callhint_model, true && RKSettingsModuleCommandEditor::isCompletionEnabled (RKSettingsModuleCommandEditor::Calltip), currentCallRange (), &active_models);
-	startModel (cc_iface, arghint_model, min_len && RKSettingsModuleCommandEditor::isCompletionEnabled (RKSettingsModuleCommandEditor::Arghint), argname_range, &active_models);
+	startModel (cc_iface, callhint_model, true && RKSettingsModuleCommandEditor::completionSettings()->isEnabled (RKCodeCompletionSettings::Calltip), currentCallRange (), &active_models);
+	startModel (cc_iface, arghint_model, min_len && RKSettingsModuleCommandEditor::completionSettings()->isEnabled (RKCodeCompletionSettings::Arghint), argname_range, &active_models);
 
 	if (active_models.isEmpty ()) {
 		cc_iface->abortCompletion ();
@@ -337,7 +337,7 @@ void RKCompletionManager::cursorPositionChanged (KTextEditor::View* view, const
 			if (text.contains (QChar ('(')) || text.contains (QChar (')'))) update_call = true;
 		}
 		tryCompletionProxy ();
-	} else if (RKSettingsModuleCommandEditor::autoCompletionCursorActivated ()) {
+	} else if (RKSettingsModuleCommandEditor::completionSettings()->autoCursorActivated ()) {
 		tryCompletionProxy ();
 	}
 }
@@ -391,7 +391,7 @@ bool RKCompletionManager::eventFilter (QObject*, QEvent* event) {
 					// Ouch, how messy. We want to make sure completion stops, and is not re-triggered by the insertion, itself
 					active_models.clear ();
 					cc_iface->abortCompletion ();
-					if (RKSettingsModuleCommandEditor::autoCompletionEnabled ()) ignore_next_trigger = true;
+					if (RKSettingsModuleCommandEditor::completionSettings()->autoEnabled ()) ignore_next_trigger = true;
 				}
 				else if (comp.isEmpty ()) {
 					QApplication::beep (); // TODO: unfortunately, we catch *two* tab events, so this is not good, yet
@@ -399,7 +399,7 @@ bool RKCompletionManager::eventFilter (QObject*, QEvent* event) {
 				return true;
 			}
 		} else if ((k->key () == Qt::Key_Up || k->key () == Qt::Key_Down) && cc_iface->isCompletionActive ()) {
-			if (RKSettingsModuleCommandEditor::cursorNavigatesCompletions ()) return false;
+			if (RKSettingsModuleCommandEditor::completionSettings()->cursorNavigatesCompletions ()) return false;
 
 			// Make up / down-keys (without alt) navigate in the document (aborting the completion)
 			// Meke alt+up / alt+down naviate in the completion list
@@ -489,7 +489,7 @@ void RKCodeCompletionModel::updateCompletionList (const QString& symbol) {
 	n_completions = matches.size ();
 	icons.clear ();
 	icons.reserve (n_completions);
-	names = RObject::getFullNames (matches, RKSettingsModuleCommandEditor::completionOptions());
+	names = RObject::getFullNames (matches, RKSettingsModuleCommandEditor::completionSettings()->options());
 	for (int i = 0; i < n_completions; ++i) {
 		icons.append (RKStandardIcons::iconForObject (matches[i]));
 	}
diff --git a/rkward/windows/rkcommandeditorwindow.cpp b/rkward/windows/rkcommandeditorwindow.cpp
index b0b21a49..9ccba1b1 100644
--- a/rkward/windows/rkcommandeditorwindow.cpp
+++ b/rkward/windows/rkcommandeditorwindow.cpp
@@ -1094,7 +1094,7 @@ RKFunctionArgHinter::~RKFunctionArgHinter () {
 void RKFunctionArgHinter::tryArgHint () {
 	RK_TRACE (COMMANDEDITOR);
 
-	if (!RKSettingsModuleCommandEditor::argHintingEnabled ()) return;
+	if (!RKSettingsModuleCommandEditor::completionSettings()->argHintingEnabled ()) return;
 
 	// do this in the next event cycle to make sure any inserted characters have truly been inserted
 	QTimer::singleShot (0, this, SLOT (tryArgHintNow()));



More information about the rkward-tracker mailing list