[rkward/work/kateintegration] rkward: Some renaming / slight restructuring, and a few more implementation bits.

Thomas Friedrichsmeier null at kde.org
Wed Jan 8 11:18:52 GMT 2020


Git commit 94e316f0bf4f7cd6b47ea49b73ad25fff71d3b46 by Thomas Friedrichsmeier.
Committed on 08/01/2020 at 11:18.
Pushed by tfry into branch 'work/kateintegration'.

Some renaming / slight restructuring, and a few more implementation bits.

M  +3    -3    rkward/rkward.cpp
M  +3    -3    rkward/rkward.h
M  +224  -203  rkward/windows/katepluginintegration.cpp
M  +53   -41   rkward/windows/katepluginintegration.h
M  +1    -1    rkward/windows/rkcommandeditorwindow.cpp
M  +1    -1    rkward/windows/rkworkplace.h

https://commits.kde.org/rkward/94e316f0bf4f7cd6b47ea49b73ad25fff71d3b46

diff --git a/rkward/rkward.cpp b/rkward/rkward.cpp
index 34bc8dcc..c0326fd0 100644
--- a/rkward/rkward.cpp
+++ b/rkward/rkward.cpp
@@ -154,7 +154,7 @@ RKWardMainWindow::RKWardMainWindow () : KParts::MainWindow ((QWidget *)0, (Qt::W
 	setHelpMenuEnabled (false);
 	setXMLFile ("rkwardui.rc");
 	insertChildClient (toplevel_actions = new RKTopLevelWindowGUI (this));
-	insertChildClient (katePluginIntegration ());
+	insertChildClient (katePluginIntegration ()->mainWindow ());
 	createShellGUI (true);
 	katePluginIntegration ()->loadPlugin ("katesearchplugin");
 	RKXMLGUISyncer::self ()->watchXMLGUIClientUIrc (this);
@@ -187,11 +187,11 @@ RKWardMainWindow::~RKWardMainWindow() {
 	delete RKComponentMap::getMap ();
 }
 
-KatePluginIntegration* RKWardMainWindow::katePluginIntegration () {
+KatePluginIntegrationApp* RKWardMainWindow::katePluginIntegration () {
 	RK_TRACE (APP);
 
 	if (!katepluginintegration) {
-		katepluginintegration = new KatePluginIntegration (this);
+		katepluginintegration = new KatePluginIntegrationApp (this);
 	}
 	return katepluginintegration;
 }
diff --git a/rkward/rkward.h b/rkward/rkward.h
index f50828ad..f1d0bf81 100644
--- a/rkward/rkward.h
+++ b/rkward/rkward.h
@@ -29,7 +29,7 @@ class RKTopLevelWindowGUI;
 class KRecentFilesAction;
 class KSqueezedTextLabel;
 class QAction;
-class KatePluginIntegration;
+class KatePluginIntegrationApp;
 
 /**
 The main class of rkward. This is where all strings are tied together, controls the initialization, and there are some of the most important slots for user actions. All real work is done elsewhere.
@@ -60,7 +60,7 @@ public:
 /** Merge files to be loaded, instead of closing windows / clearing workspace */
 	void setMergeLoads (bool merge) { merge_loads = merge; };
 
-	KatePluginIntegration *katePluginIntegration ();
+	KatePluginIntegrationApp *katePluginIntegration ();
 protected:
 	/** save Options/Settings. Includes general Options like all bar positions and status as well as the geometry and the recent file list */
 	void saveOptions();
@@ -203,7 +203,7 @@ private:
 	bool workspace_modified;
 	bool merge_loads;
 
-	KatePluginIntegration *katepluginintegration;
+	KatePluginIntegrationApp *katepluginintegration;
 };
 
 #endif // RKWARD_H
diff --git a/rkward/windows/katepluginintegration.cpp b/rkward/windows/katepluginintegration.cpp
index cf6060f0..f640f30c 100644
--- a/rkward/windows/katepluginintegration.cpp
+++ b/rkward/windows/katepluginintegration.cpp
@@ -33,28 +33,186 @@
 #include "rkworkplaceview.h"
 #include "rkcommandeditorwindow.h"
 #include "../misc/rkdummypart.h"
+#include "../settings/rksettingsmodulecommandeditor.h"
 
 #include "../debug.h"
 
-KatePluginIntegration::KatePluginIntegration (QObject *parent) : QObject (parent), KXMLGUIClient () {
+///  BEGIN  KTextEditor::Application interface
+
+KatePluginIntegrationApp::KatePluginIntegrationApp(QObject *parent) : QObject (parent) {
 	RK_TRACE (APP);
 
-	// This one is passed to each created plugin
-	main = new KTextEditor::MainWindow(this);
-	// While this one may be accessed from plugins via KTextEditor::Editor::instance()->application()
-	KatePluginIntegration2 *buddy = new KatePluginIntegration2(this);
-	KTextEditor::Editor::instance()->setApplication (buddy->app);
+	window = new KatePluginIntegrationWindow(this);
+	app = new KTextEditor::Application(this);
+	KTextEditor::Editor::instance()->setApplication(app);
 
 	// enumerate all available kate plugins
-	QVector<KPluginMetaData> plugins = KPluginLoader::findPlugins (QStringLiteral ("ktexteditor"), [](const KPluginMetaData &md) { return md.serviceTypes().contains(QLatin1String("KTextEditor/Plugin")); });
+	QVector<KPluginMetaData> plugins = KPluginLoader::findPlugins(QStringLiteral ("ktexteditor"), [](const KPluginMetaData &md) { return md.serviceTypes().contains(QLatin1String("KTextEditor/Plugin")); });
     for (int i = plugins.size() -1; i >= 0; --i) {
-		KPluginMetaData &plugin = plugins[i];
-		// Note: creates a lookup-table *and* eliminates potential dupes later in the search path 
-		known_plugins.insert (idForPlugin (plugin), plugin);
+		PluginInfo info;
+		info.plugin = 0;
+		info.data = plugins[i];
+		// Note: creates a lookup-table *and* eliminates potential dupes later in the search path
+		known_plugins.insert(idForPlugin(info.data), info);
+
+		// TODO: remove me
+		qDebug ("%s", qPrintable(info.data.fileName()));
+	}
+}
+
+KatePluginIntegrationApp::~KatePluginIntegrationApp() {
+	RK_TRACE (APP);
+}
+
+QString KatePluginIntegrationApp::idForPlugin(const KPluginMetaData &plugin) const {
+	return QFileInfo(plugin.fileName()).baseName();
+}
+
+QObject* KatePluginIntegrationApp::loadPlugin (const QString& identifier) {
+	RK_TRACE (APP);
+
+	if (!known_plugins.contains (identifier)) {
+		RK_DEBUG (APP, DL_WARNING, "Plugin %s is not known", qPrintable (identifier));
+		return 0;
+	}
 
-		qDebug ("%s", qPrintable(plugin.fileName()));
+	KPluginFactory *factory = KPluginLoader(known_plugins[identifier].data.fileName ()).factory ();
+	if (factory) {
+		KTextEditor::Plugin *plugin = factory->create<KTextEditor::Plugin>(this, QVariantList () << identifier);
+		if (plugin) {
+			known_plugins[identifier].plugin = plugin;
+			emit KTextEditor::Editor::instance()->application()->pluginCreated(identifier, plugin);
+			mainWindow()->createPluginView(plugin);
+			return plugin;
+		}
 	}
-	// TODO
+
+    return 0;
+	// TODO load config, create gui?
+}
+
+QList<KTextEditor::MainWindow *> KatePluginIntegrationApp::mainWindows() {
+	RK_TRACE (APP);
+	QList<KTextEditor::MainWindow *> ret;
+	ret.append (window->main);
+	return ret;
+}
+
+KTextEditor::MainWindow *KatePluginIntegrationApp::activeMainWindow() {
+	RK_TRACE (APP);
+	return window->main;
+}
+
+RKCommandEditorWindow* findWindowForView(KTextEditor::View *view) {
+	RK_TRACE (APP);
+
+	QList<RKMDIWindow*> w = RKWorkplace::mainWorkplace()->getObjectList(RKMDIWindow::CommandEditorWindow);
+	for (int i = 0; i < w.size(); ++i) {
+		KTextEditor::View *v = static_cast<RKCommandEditorWindow*>(w[i])->getView();
+		if (v && (v == view)) {
+			return static_cast<RKCommandEditorWindow*>(w[i]);
+		}
+	}
+	return 0;
+}
+
+RKCommandEditorWindow* findWindowForDocument(KTextEditor::Document *document) {
+	RK_TRACE (APP);
+
+	QList<RKMDIWindow*> w = RKWorkplace::mainWorkplace()->getObjectList(RKMDIWindow::CommandEditorWindow);
+	for (int i = 0; i < w.size(); ++i) {
+		KTextEditor::View *v = static_cast<RKCommandEditorWindow*>(w[i])->getView();
+		if (v && (v->document() == document)) {
+			return static_cast<RKCommandEditorWindow*>(w[i]);
+		}
+	}
+	return 0;
+}
+
+QList<KTextEditor::Document *> KatePluginIntegrationApp::documents() {
+	RK_TRACE (APP);
+
+	QList<RKMDIWindow*> w = RKWorkplace::mainWorkplace()->getObjectList(RKMDIWindow::CommandEditorWindow);
+	QList<KTextEditor::Document*> ret;
+	for (int i = 0; i < w.size (); ++i) {
+		KTextEditor::View *v = static_cast<RKCommandEditorWindow*>(w[i])->getView();
+		if (v) ret.append (v->document());
+	}
+	return ret;
+}
+
+KTextEditor::Document *KatePluginIntegrationApp::findUrl(const QUrl &url) {
+	RK_TRACE (APP);
+
+	QUrl _url = url.adjusted(QUrl::NormalizePathSegments);  // Needed?
+	QList<RKMDIWindow*> w = RKWorkplace::mainWorkplace()->getObjectList(RKMDIWindow::CommandEditorWindow);
+	for (int i = 0; i < w.size (); ++i) {
+		if (_url == static_cast<RKCommandEditorWindow*>(w[i])->url().adjusted(QUrl::NormalizePathSegments)) {
+			KTextEditor::View *v = static_cast<RKCommandEditorWindow*>(w[i])->getView();
+			if (v) return v->document();
+		}
+	}
+	return 0;
+}
+
+KTextEditor::Document *KatePluginIntegrationApp::openUrl(const QUrl &url, const QString &encoding) {
+	RK_TRACE (APP);
+
+	KTextEditor::View *v = window->openUrl(url, encoding);
+	if (v) return v->document();
+	return 0;
+}
+
+bool KatePluginIntegrationApp::closeDocument(KTextEditor::Document *document) {
+	RK_TRACE (APP);
+
+	RKMDIWindow *w = findWindowForDocument(document);
+	if (w) return RKWorkplace::mainWorkplace()->closeWindow(w); // NOTE: Closes only a single view of the document
+	return false;
+}
+
+bool KatePluginIntegrationApp::closeDocuments(const QList<KTextEditor::Document *> &documents) {
+	RK_TRACE (APP);
+
+	bool allfound = true;
+	QList<RKMDIWindow*> w = RKWorkplace::mainWorkplace()->getObjectList(RKMDIWindow::CommandEditorWindow);
+	QList<RKMDIWindow*> toclose;
+	for (int i = 0; i < documents.size(); ++i) {
+		bool found = false;
+		for (int j = 0; j < w.size(); ++j) {
+			KTextEditor::View *v = static_cast<RKCommandEditorWindow*>(w[j])->getView();
+			if (v && v->document() == documents[i]) {
+				toclose.append(w[i]);
+				found = true;
+				break;
+			}
+		}
+		if (!found) allfound = false;
+	}
+
+	return RKWorkplace::mainWorkplace()->closeWindows(toclose) && allfound;
+}
+
+KTextEditor::Plugin *KatePluginIntegrationApp::plugin(const QString &name) {
+	RK_TRACE (APP);
+
+	if (known_plugins.contains(name)) {
+		return known_plugins[name].plugin;
+	}
+	return 0;
+}
+
+///  END  KTextEditor::Application interface
+///  BEGIN  KTextEditor::MainWindow interface
+
+
+KatePluginIntegrationWindow::KatePluginIntegrationWindow (KatePluginIntegrationApp *parent) : QObject (parent), KXMLGUIClient () {
+	RK_TRACE (APP);
+
+	// This one is passed to each created plugin
+	main = new KTextEditor::MainWindow(this);
+	// While this one may be accessed from plugins via KTextEditor::Editor::instance()->application()
+	app = parent;
 }
 
 /** This is a bit lame, but the plugin does not add itself to the parent widget's layout by itself. So we need this class
@@ -95,11 +253,9 @@ public:
 	QWidget* wrapper;
 };
 
-QWidget * KatePluginIntegration::createToolView (KTextEditor::Plugin *plugin, const QString &identifier, KTextEditor::MainWindow::ToolViewPosition pos, const QIcon &icon, const QString &text) {
+QWidget * KatePluginIntegrationWindow::createToolView (KTextEditor::Plugin *plugin, const QString &identifier, KTextEditor::MainWindow::ToolViewPosition pos, const QIcon &icon, const QString &text) {
 	RK_TRACE (APP);
-	RKDebug (APP, DL_ERROR, "createToolView");
 
-	// TODO: Save reference
 	// TODO: Set proper RKMDIWindow:type
 	KatePluginToolWindow *window = new KatePluginToolWindow(RKWorkplace::mainWorkplace()->view(), RKMDIWindow::ConsoleWindow);
 	window->setCaption(text);
@@ -109,41 +265,18 @@ QWidget * KatePluginIntegration::createToolView (KTextEditor::Plugin *plugin, co
 	return window->wrapper;
 }
 
-bool KatePluginIntegration::showToolView (QWidget *widget) {
+bool KatePluginIntegrationWindow::showToolView (QWidget *widget) {
 	RK_TRACE (APP);
-	RKDebug (APP, DL_ERROR, "showToolView");
-	widget->show ();
-	return true;
-	// TODO
-}
-
-QString KatePluginIntegration::idForPlugin(const KPluginMetaData &plugin) const {
-	return QFileInfo(plugin.fileName()).baseName();
-}
-
-QObject* KatePluginIntegration::loadPlugin (const QString& identifier) {
-	RK_TRACE (APP);
-
-	if (!known_plugins.contains (identifier)) {
-		RK_DEBUG (APP, DL_WARNING, "Plugin %s is not known", qPrintable (identifier));
-		return 0;
-	}
-
-	KPluginFactory *factory = KPluginLoader (known_plugins[identifier].fileName ()).factory ();
-	if (factory) {
-		KTextEditor::Plugin *plugin = factory->create<KTextEditor::Plugin> (this, QVariantList () << identifier);
-		if (plugin) {
-			emit KTextEditor::Editor::instance ()->application ()->pluginCreated (identifier, plugin);
-			plugin->createView (main);
-			return plugin;
-		}
+	RKMDIWindow *w = qobject_cast<RKMDIWindow*>(widget);
+	if (w) w->activate();
+	else {
+		RK_ASSERT(w);
+		widget->show();
 	}
-
-    return 0;
-	// TODO
+	return true;
 }
 
-KXMLGUIFactory *KatePluginIntegration::guiFactory () {
+KXMLGUIFactory *KatePluginIntegrationWindow::guiFactory () {
 	RK_TRACE (APP);
 
 	// We'd rather like to add the plugin to our own RKMDIWindows, rather than
@@ -153,13 +286,13 @@ KXMLGUIFactory *KatePluginIntegration::guiFactory () {
 	// TODO
 }
 
-QWidget *KatePluginIntegration::window() {
+QWidget *KatePluginIntegrationWindow::window() {
 	RK_TRACE (APP);
-	return 0;
-	// TODO
+
+	return RKWorkplace::mainWorkplace()->view()->window();
 }
 
-QList<KTextEditor::View *> KatePluginIntegration::views() {
+QList<KTextEditor::View *> KatePluginIntegrationWindow::views() {
 	RK_TRACE (APP);
 
 	QList<RKMDIWindow*> w = RKWorkplace::mainWorkplace()->getObjectList(RKMDIWindow::CommandEditorWindow);
@@ -170,7 +303,7 @@ QList<KTextEditor::View *> KatePluginIntegration::views() {
 	return ret;
 }
 
-KTextEditor::View *KatePluginIntegration::activeView() {
+KTextEditor::View *KatePluginIntegrationWindow::activeView() {
 	RK_TRACE (APP);
 
 	RKMDIWindow *w = RKWorkplace::mainWorkplace()->activeWindow(RKMDIWindow::AnyWindowState);
@@ -180,36 +313,10 @@ KTextEditor::View *KatePluginIntegration::activeView() {
 	return 0;
 	// TODO: This probably isn't right: As far as RKWard is concerned, the active window will most likely be the tool window
 	//       at this point, while the intention will be to get an active window that the tool should operate on.
-	// TODO: Further, it looks like some plugins assume this cannot return 0, so maybe wee need to create a new window on the fly, if needed.
-}
-
-RKCommandEditorWindow* findWindowForView(KTextEditor::View *view) {
-	RK_TRACE (APP);
-
-	QList<RKMDIWindow*> w = RKWorkplace::mainWorkplace()->getObjectList(RKMDIWindow::CommandEditorWindow);
-	for (int i = 0; i < w.size(); ++i) {
-		KTextEditor::View *v = static_cast<RKCommandEditorWindow*>(w[i])->getView();
-		if (v && (v == view)) {
-			return static_cast<RKCommandEditorWindow*>(w[i]);
-		}
-	}
-	return 0;
+	// TODO: Further, it looks like some plugins assume this cannot return 0, so maybe wee need to create a new window on the fly, if needed. It's a bug in those plugins, but one that seems likely enough, as kate always has an active view.
 }
 
-RKCommandEditorWindow* findWindowForDocument(KTextEditor::Document *document) {
-	RK_TRACE (APP);
-
-	QList<RKMDIWindow*> w = RKWorkplace::mainWorkplace()->getObjectList(RKMDIWindow::CommandEditorWindow);
-	for (int i = 0; i < w.size(); ++i) {
-		KTextEditor::View *v = static_cast<RKCommandEditorWindow*>(w[i])->getView();
-		if (v && (v->document() == document)) {
-			return static_cast<RKCommandEditorWindow*>(w[i]);
-		}
-	}
-	return 0;
-}
-
-KTextEditor::View *KatePluginIntegration::activateView(KTextEditor::Document *document) {
+KTextEditor::View *KatePluginIntegrationWindow::activateView(KTextEditor::Document *document) {
 	RK_TRACE (APP);
 
 	RKCommandEditorWindow* w = findWindowForDocument(document);
@@ -220,36 +327,28 @@ KTextEditor::View *KatePluginIntegration::activateView(KTextEditor::Document *do
 	return 0;
 }
 
-KTextEditor::View *KatePluginIntegration::openUrl(const QUrl &url, const QString &encoding) {
+KTextEditor::View *KatePluginIntegrationWindow::openUrl(const QUrl &url, const QString &encoding) {
 	RK_TRACE (APP);
-	return 0;
-	// TODO
-}
+	RKMDIWindow *w = RKWorkplace::mainWorkplace()->openScriptEditor(url, encoding, RKSettingsModuleCommandEditor::matchesScriptFileFilter(url.fileName()));
+	if (w) return static_cast<RKCommandEditorWindow*>(w)->getView();
 
-QWidget *KatePluginIntegration::createViewBar(KTextEditor::View *view) {
-	RK_TRACE (APP);
+	RK_ASSERT(w);  // should not happen
 	return 0;
-	// TODO
 }
 
-QObject *KatePluginIntegration::pluginView(const QString &name) {
+QObject *KatePluginIntegrationWindow::pluginView(const QString &name) {
 	RK_TRACE (APP);
-	return 0;
-	// TODO
-}
 
-void KatePluginIntegration::addWidgetToViewBar(KTextEditor::View* view, QWidget* bar) {
-	RK_TRACE (APP);
-	// TODO
+	return plugin_views.value(app->plugin(name));
 }
 
-bool KatePluginIntegration::closeSplitView(KTextEditor::View* view) {
+bool KatePluginIntegrationWindow::closeSplitView(KTextEditor::View* view) {
 	RK_TRACE (APP);
 	return false;
 	// TODO
 }
 
-bool KatePluginIntegration::closeView(KTextEditor::View* view) {
+bool KatePluginIntegrationWindow::closeView(KTextEditor::View* view) {
 	RK_TRACE (APP);
 
 	RKMDIWindow *w = findWindowForView(view);
@@ -257,136 +356,58 @@ bool KatePluginIntegration::closeView(KTextEditor::View* view) {
 	return false;
 }
 
-void KatePluginIntegration::deleteViewBar(KTextEditor::View* view) {
-	RK_TRACE (APP);
-	// TODO
-}
 
-bool KatePluginIntegration::hideToolView(QWidget* widget) {
+bool KatePluginIntegrationWindow::hideToolView(QWidget* widget) {
 	RK_TRACE (APP);
-	return false;
-	// TODO
-}
 
-void KatePluginIntegration::hideViewBar(KTextEditor::View* view) {
-	RK_TRACE (APP);
-	// TODO
+	RKMDIWindow *w = qobject_cast<RKMDIWindow*>(widget);
+	if (w) w->close(false);
+	else {
+		RK_ASSERT(w);
+		widget->hide();
+	}
+	return true;
 }
 
-bool KatePluginIntegration::moveToolView(QWidget* widget, KTextEditor::MainWindow::ToolViewPosition pos) {
-	RK_TRACE (APP);
-	// TODO
-	return false;
-}
+/* These appear to be truly optional, so let's disable them for now.
+void KatePluginIntegrationWindow::hideViewBar(KTextEditor::View* view) {}
+void KatePluginIntegrationWindow::showViewBar(KTextEditor::View* view) {}
+void KatePluginIntegrationWindow::deleteViewBar(KTextEditor::View* view) {}
+void KatePluginIntegrationWindow::addWidgetToViewBar(KTextEditor::View* view, QWidget* bar) {}
+QWidget *KatePluginIntegrationWindow::createViewBar(KTextEditor::View *view) {} */
 
-void KatePluginIntegration::showViewBar(KTextEditor::View* view) {
+bool KatePluginIntegrationWindow::moveToolView(QWidget* widget, KTextEditor::MainWindow::ToolViewPosition pos) {
 	RK_TRACE (APP);
-	// TODO
+
+	RKMDIWindow *w = qobject_cast<RKMDIWindow*>(widget);
+	if (w) {
+		RKWorkplace::mainWorkplace ()->placeInToolWindowBar (w, pos);
+		return true;
+	}
+	return false;
 }
 
-void KatePluginIntegration::splitView(Qt::Orientation orientation) {
+void KatePluginIntegrationWindow::splitView(Qt::Orientation orientation) {
 	RK_TRACE (APP);
 	// TODO
 }
 
-bool KatePluginIntegration::viewsInSameSplitView(KTextEditor::View* view1, KTextEditor::View* view2) {
+bool KatePluginIntegrationWindow::viewsInSameSplitView(KTextEditor::View* view1, KTextEditor::View* view2) {
 	RK_TRACE (APP);
 	// TODO
 	return false;
 }
 
-///  BEGIN  KTextEditor::Application interface
-
-KatePluginIntegration2::KatePluginIntegration2(KatePluginIntegration *_buddy) : QObject (_buddy) {
-	RK_TRACE (APP);
-	buddy = _buddy;
-	app = new KTextEditor::Application (this);
-}
-
-KatePluginIntegration2::~KatePluginIntegration2() {
-	RK_TRACE (APP);
-}
-
-QList<KTextEditor::MainWindow *> KatePluginIntegration2::mainWindows() {
-	RK_TRACE (APP);
-	QList<KTextEditor::MainWindow *> ret;
-	ret.append (buddy->main);
-	return ret;
-}
-
-KTextEditor::MainWindow *KatePluginIntegration2::activeMainWindow() {
-	RK_TRACE (APP);
-	return buddy->main;
-}
-
-QList<KTextEditor::Document *> KatePluginIntegration2::documents() {
-	RK_TRACE (APP);
-
-	QList<RKMDIWindow*> w = RKWorkplace::mainWorkplace()->getObjectList(RKMDIWindow::CommandEditorWindow);
-	QList<KTextEditor::Document*> ret;
-	for (int i = 0; i < w.size (); ++i) {
-		KTextEditor::View *v = static_cast<RKCommandEditorWindow*>(w[i])->getView(); 
-		if (v) ret.append (v->document());
-	}
-	return ret;
-}
-
-KTextEditor::Document *KatePluginIntegration2::findUrl(const QUrl &url) {
+void KatePluginIntegrationWindow::createPluginView(KTextEditor::Plugin* plugin) {
 	RK_TRACE (APP);
 
-	QUrl _url = url.adjusted(QUrl::NormalizePathSegments);  // Needed?
-	QList<RKMDIWindow*> w = RKWorkplace::mainWorkplace()->getObjectList(RKMDIWindow::CommandEditorWindow);
-	for (int i = 0; i < w.size (); ++i) {
-		if (_url == static_cast<RKCommandEditorWindow*>(w[i])->url().adjusted(QUrl::NormalizePathSegments)) {
-			KTextEditor::View *v = static_cast<RKCommandEditorWindow*>(w[i])->getView(); 
-			if (v) return v->document();
-		}
-	}
-	return 0;
+	QObject *view = plugin->createView(main);
+	plugin_views.insert(plugin, view);
+	connect(plugin, &QObject::destroyed, [&]() { plugin_views.remove(plugin); });
 }
 
-KTextEditor::Document *KatePluginIntegration2::openUrl(const QUrl &url, const QString &encoding) {
-	RK_TRACE (APP);
+// TODO: Don't forget to make sure to emit all the signals!
 
-	KTextEditor::View *v = buddy->openUrl(url, encoding);
-	if (v) return v->document();
-	return 0;
-}
-
-bool KatePluginIntegration2::closeDocument(KTextEditor::Document *document) {
-	RK_TRACE (APP);
-
-	RKMDIWindow *w = findWindowForDocument(document);
-	if (w) return RKWorkplace::mainWorkplace()->closeWindow(w); // NOTE: Closes only a single view of the document
-	return false;
-}
-
-bool KatePluginIntegration2::closeDocuments(const QList<KTextEditor::Document *> &documents) {
-	RK_TRACE (APP);
-
-	bool allfound = true;
-	QList<RKMDIWindow*> w = RKWorkplace::mainWorkplace()->getObjectList(RKMDIWindow::CommandEditorWindow);
-	QList<RKMDIWindow*> toclose;
-	for (int i = 0; i < documents.size(); ++i) {
-		bool found = false;
-		for (int j = 0; j < w.size(); ++j) {
-			KTextEditor::View *v = static_cast<RKCommandEditorWindow*>(w[j])->getView();
-			if (v && v->document() == documents[i]) {
-				toclose.append(w[i]);
-				found = true;
-				break;
-			}
-		}
-		if (!found) allfound = false;
-	}
-
-	return RKWorkplace::mainWorkplace()->closeWindows(toclose) && allfound;
-}
-
-KTextEditor::Plugin *KatePluginIntegration2::plugin(const QString &name) {
-	RK_TRACE (APP);
-	return 0;
-	// TODO
-}
+///  END  KTextEditor::MainWindow interface
 
 #include "katepluginintegration.moc"
diff --git a/rkward/windows/katepluginintegration.h b/rkward/windows/katepluginintegration.h
index cd0fbbae..3eb6d282 100644
--- a/rkward/windows/katepluginintegration.h
+++ b/rkward/windows/katepluginintegration.h
@@ -25,15 +25,52 @@
 
 #include <QMap>
 
-class KatePluginIntegration : public QObject, public KXMLGUIClient {
-Q_OBJECT
+class KatePluginIntegrationWindow;
+
+/** This class provides implementations for the KTextEditor::Application interface.
+ *  Note that there is a separate interface KatePluginIntegrationWindow / KTextEditor::MainWindow that serves
+ *  as an abstraction of main windows. Even though - for now - we will be creating (detachable) plugins only in
+ *  one "main" window, we follow this separation to be on the safe side for future extensions (and also there is
+ *  a name-clash in on of the slots (openUrl()), otherwise. */
+class KatePluginIntegrationApp : public QObject {
+	Q_OBJECT
 public:
-	KatePluginIntegration(QObject *parent);
-	KTextEditor::MainWindow *mainWindow() const { return main; };
+	KatePluginIntegrationApp(QObject *parent);
+	~KatePluginIntegrationApp();
 	QObject* loadPlugin(const QString& identifier);
+	KatePluginIntegrationWindow *mainWindow() const { return window; };
+private slots:
+friend class KatePluginIntegrationWindow;
+	// These are the implementations of the KTextEditor::Application interface.
+	// NOTE that they are not technically overrides, but get invoked via QMetaObject::invokeMethod()
+	QList<KTextEditor::MainWindow *> mainWindows();
+	KTextEditor::MainWindow *activeMainWindow();
+	QList<KTextEditor::Document *> documents();
+	KTextEditor::Document *findUrl(const QUrl &url);
+	KTextEditor::Document *openUrl(const QUrl &url, const QString &encoding = QString());
+	bool closeDocument(KTextEditor::Document *document);
+	bool closeDocuments(const QList<KTextEditor::Document *> &documents);
+	KTextEditor::Plugin *plugin(const QString &name);
+private:
+	KatePluginIntegrationWindow *window;  // For now, only one main window
+	KTextEditor::Application *app;
+
+	struct PluginInfo {
+		KPluginMetaData data;
+		KTextEditor::Plugin *plugin;
+	};
+	QMap<QString, PluginInfo> known_plugins;
+	QString idForPlugin(const KPluginMetaData &plugin) const;
+};
+
+class KatePluginIntegrationWindow : public QObject, public KXMLGUIClient {
+	Q_OBJECT
+public:
+	KatePluginIntegrationWindow(KatePluginIntegrationApp *parent);
+	KTextEditor::MainWindow *mainWindow() const { return main; };
 private slots:
 	// These are the implementations of the KTextEditor::MainWindow interface.
-	// NOTE that they  are not technically overrides, but get invoked via QMetaObject::invokeMethod()
+	// NOTE that they are not technically overrides, but get invoked via QMetaObject::invokeMethod()
 	QWidget *createToolView(KTextEditor::Plugin *plugin, const QString &identifier, KTextEditor::MainWindow::ToolViewPosition pos, const QIcon &icon, const QString &text);
 	KXMLGUIFactory *guiFactory();
 	QWidget *window();
@@ -45,49 +82,24 @@ private slots:
 	void splitView(Qt::Orientation orientation);
 	bool closeSplitView(KTextEditor::View *view);
 	bool viewsInSameSplitView(KTextEditor::View *view1, KTextEditor::View *view2);
-	QWidget *createViewBar(KTextEditor::View *view);
-	void deleteViewBar(KTextEditor::View *view);
-	void addWidgetToViewBar(KTextEditor::View *view, QWidget *bar);
-	void showViewBar(KTextEditor::View *view);
-	void hideViewBar(KTextEditor::View *view);
 	bool moveToolView(QWidget *widget, KTextEditor::MainWindow::ToolViewPosition pos);
 	bool showToolView(QWidget *widget);
 	bool hideToolView(QWidget *widget);
 	QObject *pluginView(const QString &name);
+
+/* Apparently, these are truely optional, so let's disable them for the time being
+	QWidget *createViewBar(KTextEditor::View *view);
+	void deleteViewBar(KTextEditor::View *view);
+	void showViewBar(KTextEditor::View *view);
+	void hideViewBar(KTextEditor::View *view);
+	void addWidgetToViewBar(KTextEditor::View *view, QWidget *bar); */
 private:
-friend class KatePluginIntegration2;
+friend class KatePluginIntegrationApp;
 	KTextEditor::MainWindow *main;
-/*
-	struct ActivePlugin {
-		QWidget *inner;
-		RKMDIWindow *outer;
-	}; */
-	QMap<QString, KPluginMetaData> known_plugins;
-	QString idForPlugin(const KPluginMetaData &plugin) const;
-};
+	void createPluginView(KTextEditor::Plugin* plugin);
+	QHash<KTextEditor::Plugin*, QObject*> plugin_views;
 
-/** This class provides implementations for the KTextEditor::Application interface. I'd love to merge it into
- *  KatePluginIntegration, but this is not possible due to a name clash in one of the slots (openUrl()). */
-class KatePluginIntegration2 : public QObject {
-	Q_OBJECT
-public:
-	KatePluginIntegration2(KatePluginIntegration *_buddy);
-	~KatePluginIntegration2();
-private slots:
-	// And these are the implementations of the KTextEditor::Application interface.
-	// NOTE that they are not technically overrides, but get invoked via QMetaObject::invokeMethod()
-	QList<KTextEditor::MainWindow *> mainWindows();
-	KTextEditor::MainWindow *activeMainWindow();
-	QList<KTextEditor::Document *> documents();
-	KTextEditor::Document *findUrl(const QUrl &url);
-	KTextEditor::Document *openUrl(const QUrl &url, const QString &encoding = QString());
-	bool closeDocument(KTextEditor::Document *document);
-	bool closeDocuments(const QList<KTextEditor::Document *> &documents);
-	KTextEditor::Plugin *plugin(const QString &name);
-private:
-friend class KatePluginIntegration;
-	KatePluginIntegration *buddy;
-	KTextEditor::Application *app;
+	KatePluginIntegrationApp *app;
 };
 
 #endif
diff --git a/rkward/windows/rkcommandeditorwindow.cpp b/rkward/windows/rkcommandeditorwindow.cpp
index 7ea52269..bfadd885 100644
--- a/rkward/windows/rkcommandeditorwindow.cpp
+++ b/rkward/windows/rkcommandeditorwindow.cpp
@@ -179,7 +179,7 @@ RKCommandEditorWindow::RKCommandEditorWindow (QWidget *parent, const QUrl _url,
 	KTextEditor::ModificationInterface* em_iface = qobject_cast<KTextEditor::ModificationInterface*> (m_doc);
 	if (em_iface) em_iface->setModifiedOnDiskWarning (true);
 	else RK_ASSERT (false);
-	m_view = m_doc->createView (this, RKWardMainWindow::getMain ()->katePluginIntegration ()->mainWindow ());
+	m_view = m_doc->createView (this, RKWardMainWindow::getMain ()->katePluginIntegration ()->mainWindow ()->mainWindow());
 	preview = new RKXMLGUIPreviewArea (QString(), this);
 	preview_manager = new RKPreviewManager (this);
 	connect (preview_manager, &RKPreviewManager::statusChanged, [this]() { preview_timer.start (500); });
diff --git a/rkward/windows/rkworkplace.h b/rkward/windows/rkworkplace.h
index 1945633c..bb73c773 100644
--- a/rkward/windows/rkworkplace.h
+++ b/rkward/windows/rkworkplace.h
@@ -221,7 +221,7 @@ private:
 
 	RKToolWindowBar* tool_window_bars[TOOL_WINDOW_BAR_COUNT];
 friend class RKToolWindowBar;
-friend class KatePluginIntegration;
+friend class KatePluginIntegrationWindow;
 	void placeInToolWindowBar (RKMDIWindow *window, int position);
 
 	/** Control placement of windows from R */



More information about the rkward-tracker mailing list