[rkward/work/kateintegration] rkward/windows: More work on implementening the interfaces for plugin integration.

Thomas Friedrichsmeier null at kde.org
Tue Jan 7 12:04:28 GMT 2020


Git commit 0d372fd927657422ad823d39749a1a61723ce466 by Thomas Friedrichsmeier.
Committed on 07/01/2020 at 12:03.
Pushed by tfry into branch 'work/kateintegration'.

More work on implementening the interfaces for plugin integration.

It's starting to look usable, but a lot of work still left to be done.

M  +122  -13   rkward/windows/katepluginintegration.cpp
M  +5    -0    rkward/windows/katepluginintegration.h
M  +10   -7    rkward/windows/rkworkplace.cpp
M  +8    -5    rkward/windows/rkworkplace.h

https://commits.kde.org/rkward/0d372fd927657422ad823d39749a1a61723ce466

diff --git a/rkward/windows/katepluginintegration.cpp b/rkward/windows/katepluginintegration.cpp
index 9a0661f4..cf6060f0 100644
--- a/rkward/windows/katepluginintegration.cpp
+++ b/rkward/windows/katepluginintegration.cpp
@@ -30,7 +30,9 @@
 
 #include "../rkward.h"
 #include "rkworkplace.h"
+#include "rkworkplaceview.h"
 #include "rkcommandeditorwindow.h"
+#include "../misc/rkdummypart.h"
 
 #include "../debug.h"
 
@@ -55,15 +57,56 @@ KatePluginIntegration::KatePluginIntegration (QObject *parent) : QObject (parent
 	// TODO
 }
 
+/** 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
+ *  to do that. Where did the good old KVBox go? */
+class KatePluginWrapperWidget : public QWidget {
+	Q_OBJECT
+public:
+	KatePluginWrapperWidget(QWidget *parent) : QWidget(parent) {
+		QVBoxLayout *layout = new QVBoxLayout(this);
+		setLayout(layout);
+		setFocusPolicy (Qt::StrongFocus);
+	}
+	void childEvent(QChildEvent *ev) override {
+		if ((ev->type() == QEvent::ChildAdded) && qobject_cast<QWidget *>(ev->child())) {
+			QWidget *widget = qobject_cast<QWidget *>(ev->child());
+			setFocusProxy(widget);
+			layout()->addWidget(widget);
+		}
+		QWidget::childEvent(ev);
+	}
+};
+
+class KatePluginToolWindow : public RKMDIWindow {
+	Q_OBJECT
+public:
+	KatePluginToolWindow(QWidget *parent, RKMDIWindow::Type type) : RKMDIWindow(parent, type, true) {
+		RK_TRACE (APP);
+
+		QVBoxLayout *layout = new QVBoxLayout(this);
+		layout->setContentsMargins(0, 0, 0, 0);
+		wrapper = new KatePluginWrapperWidget(this);
+		layout->addWidget (wrapper);
+		setPart(new RKDummyPart(this, wrapper));
+	}
+	~KatePluginToolWindow() {
+		RK_TRACE (APP);
+	}
+	QWidget* wrapper;
+};
+
 QWidget * KatePluginIntegration::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");
 
-	QWidget *dummy = new QWidget();
-	dummy->setLayout (new QVBoxLayout ());
-//	dummy->show();
-	return dummy;
-	// TODO
+	// TODO: Save reference
+	// TODO: Set proper RKMDIWindow:type
+	KatePluginToolWindow *window = new KatePluginToolWindow(RKWorkplace::mainWorkplace()->view(), RKMDIWindow::ConsoleWindow);
+	window->setCaption(text);
+	window->setWindowIcon(icon);
+	RKWorkplace::mainWorkplace()->placeInToolWindowBar(window, pos);
+
+	return window->wrapper;
 }
 
 bool KatePluginIntegration::showToolView (QWidget *widget) {
@@ -130,17 +173,51 @@ QList<KTextEditor::View *> KatePluginIntegration::views() {
 KTextEditor::View *KatePluginIntegration::activeView() {
 	RK_TRACE (APP);
 
-	RKMDIWindow *w = RKWorkplace::mainWorkplace()->activeWindow (RKMDIWindow::AnyWindowState);
+	RKMDIWindow *w = RKWorkplace::mainWorkplace()->activeWindow(RKMDIWindow::AnyWindowState);
 	if (w && w->isType (RKMDIWindow::CommandEditorWindow)) {
 		return static_cast<RKCommandEditorWindow*>(w)->getView();
 	}
 	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;
+}
+
+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) {
 	RK_TRACE (APP);
+
+	RKCommandEditorWindow* w = findWindowForDocument(document);
+	if (w) {
+		w->activate();
+		return w->getView();
+	}
 	return 0;
-	// TODO
 }
 
 KTextEditor::View *KatePluginIntegration::openUrl(const QUrl &url, const QString &encoding) {
@@ -174,8 +251,10 @@ bool KatePluginIntegration::closeSplitView(KTextEditor::View* view) {
 
 bool KatePluginIntegration::closeView(KTextEditor::View* view) {
 	RK_TRACE (APP);
+
+	RKMDIWindow *w = findWindowForView(view);
+	if (w) return RKWorkplace::mainWorkplace()->closeWindow(w);
 	return false;
-	// TODO
 }
 
 void KatePluginIntegration::deleteViewBar(KTextEditor::View* view) {
@@ -254,26 +333,54 @@ QList<KTextEditor::Document *> KatePluginIntegration2::documents() {
 
 KTextEditor::Document *KatePluginIntegration2::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;
-	// TODO
 }
 
 KTextEditor::Document *KatePluginIntegration2::openUrl(const QUrl &url, const QString &encoding) {
 	RK_TRACE (APP);
+
+	KTextEditor::View *v = buddy->openUrl(url, encoding);
+	if (v) return v->document();
 	return 0;
-	// TODO
 }
 
 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;
-	// TODO
 }
 
 bool KatePluginIntegration2::closeDocuments(const QList<KTextEditor::Document *> &documents) {
 	RK_TRACE (APP);
-	return false;
-	// TODO
+
+	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) {
@@ -281,3 +388,5 @@ KTextEditor::Plugin *KatePluginIntegration2::plugin(const QString &name) {
 	return 0;
 	// TODO
 }
+
+#include "katepluginintegration.moc"
diff --git a/rkward/windows/katepluginintegration.h b/rkward/windows/katepluginintegration.h
index f08738a2..cd0fbbae 100644
--- a/rkward/windows/katepluginintegration.h
+++ b/rkward/windows/katepluginintegration.h
@@ -57,6 +57,11 @@ private slots:
 private:
 friend class KatePluginIntegration2;
 	KTextEditor::MainWindow *main;
+/*
+	struct ActivePlugin {
+		QWidget *inner;
+		RKMDIWindow *outer;
+	}; */
 	QMap<QString, KPluginMetaData> known_plugins;
 	QString idForPlugin(const KPluginMetaData &plugin) const;
 };
diff --git a/rkward/windows/rkworkplace.cpp b/rkward/windows/rkworkplace.cpp
index 94b33788..03565519 100644
--- a/rkward/windows/rkworkplace.cpp
+++ b/rkward/windows/rkworkplace.cpp
@@ -2,7 +2,7 @@
                           rkworkplace  -  description
                              -------------------
     begin                : Thu Sep 21 2006
-    copyright            : (C) 2006-2019 by Thomas Friedrichsmeier
+    copyright            : (C) 2006-2020 by Thomas Friedrichsmeier
     email                : thomas.friedrichsmeier at kdemail.net
  ***************************************************************************/
 
@@ -627,14 +627,15 @@ void RKWorkplace::flushAllData () {
 	}
 }
 
-void RKWorkplace::closeWindow (RKMDIWindow *window) {
+bool RKWorkplace::closeWindow (RKMDIWindow *window) {
 	RK_TRACE (APP);
 	RK_ASSERT (windows.contains (window));
 
 	bool tool_window = window->isToolWindow ();
-	window->close (true);		// all the rest should happen in removeWindow ()
-	
-	if (tool_window) windowRemoved ();	// for regular windows, this happens in removeWindow(), already
+	bool closed = window->close (true);		// all the rest should happen in removeWindow ()
+
+	if (closed && tool_window) windowRemoved ();	// for regular windows, this happens in removeWindow(), already
+	return closed;
 }
 
 void RKWorkplace::closeActiveWindow () {
@@ -662,14 +663,16 @@ void RKWorkplace::closeAll (int type, int state) {
 	closeWindows (getObjectList (type, state));
 }
 
-void RKWorkplace::closeWindows (QList<RKMDIWindow*> windows) {
+bool RKWorkplace::closeWindows (QList<RKMDIWindow*> windows) {
 	RK_TRACE (APP);
 
+	bool allclosed = true;
 	RKWardMainWindow::getMain ()->lockGUIRebuild (true);
 	for (int i = windows.size () - 1; i >= 0; --i) {
-		closeWindow (windows[i]);
+		if (!closeWindow (windows[i])) allclosed = false;
 	}
 	RKWardMainWindow::getMain ()->lockGUIRebuild (false);
+	return allclosed;
 }
 
 void RKWorkplace::removeWindow (QObject *object) {
diff --git a/rkward/windows/rkworkplace.h b/rkward/windows/rkworkplace.h
index 6f7be732..1945633c 100644
--- a/rkward/windows/rkworkplace.h
+++ b/rkward/windows/rkworkplace.h
@@ -2,7 +2,7 @@
                           rkworkplace  -  description
                              -------------------
     begin                : Thu Sep 21 2006
-    copyright            : (C) 2006-2016 by Thomas Friedrichsmeier
+    copyright            : (C) 2006-2020 by Thomas Friedrichsmeier
     email                : thomas.friedrichsmeier at kdemail.net
  ***************************************************************************/
 
@@ -136,11 +136,13 @@ public:
 /** Close the active (attached) window. Safe to call even if there is no current active window (no effect in that case) */
 	void closeActiveWindow ();
 /** Close the given window, whether it is attached or detached.
- at param window window to close */
-	void closeWindow (RKMDIWindow *window);
+ at param window window to close
+ at returns true, if the window was actually closed (not cancelled) */
+	bool closeWindow (RKMDIWindow *window);
 /** Close the given windows, whether they are attached or detached. TODO: Be smart about asking what to save.
- at param windows list windows to close */
-	void closeWindows (QList<RKMDIWindow*> windows);
+ at param windows list windows to close
+ at returns true, if _all_ windows were actually closed. */
+	bool closeWindows (QList<RKMDIWindow*> windows);
 /** Closes all windows of the given type(s). Default call (no arguments) closes all windows
 @param type: A bitwise OR of RKWorkplaceObjectType
 @param state: A bitwise OR of RKWorkplaceObjectState */
@@ -219,6 +221,7 @@ private:
 
 	RKToolWindowBar* tool_window_bars[TOOL_WINDOW_BAR_COUNT];
 friend class RKToolWindowBar;
+friend class KatePluginIntegration;
 	void placeInToolWindowBar (RKMDIWindow *window, int position);
 
 	/** Control placement of windows from R */



More information about the rkward-tracker mailing list