[rkward/work/generalized_preview] rkward/windows: Work in progress: Add support for showing new windows in specified position (frontend side).

Thomas Friedrichsmeier thomas.friedrichsmeier at ruhr-uni-bochum.de
Mon Jan 4 21:28:09 UTC 2016


Git commit b574c4835288e53fe7f048ea9c902c2350e7cd00 by Thomas Friedrichsmeier.
Committed on 04/01/2016 at 21:27.
Pushed by tfry into branch 'work/generalized_preview'.

Work in progress: Add support for showing new windows in specified position (frontend side).

M  +105  -1    rkward/windows/rkworkplace.cpp
M  +26   -1    rkward/windows/rkworkplace.h

http://commits.kde.org/rkward/b574c4835288e53fe7f048ea9c902c2350e7cd00

diff --git a/rkward/windows/rkworkplace.cpp b/rkward/windows/rkworkplace.cpp
index 38ee0ae..5aaf8fc 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-2013 by Thomas Friedrichsmeier
+    copyright            : (C) 2006-2016 by Thomas Friedrichsmeier
     email                : thomas.friedrichsmeier at kdemail.net
  ***************************************************************************/
 
@@ -215,6 +215,53 @@ void RKWorkplace::addWindow (RKMDIWindow *window, bool attached) {
 	connect (window, SIGNAL (destroyed(QObject*)), this, SLOT (removeWindow(QObject*)));
 	connect (window, SIGNAL (windowActivated(RKMDIWindow*)), history, SLOT (windowActivated(RKMDIWindow*)));
 	if (window->isToolWindow () && !window->tool_window_bar) return;
+
+	// a placment override / named window exists
+	if (!placement_override_spec.isEmpty ()) {
+		QString hint = placement_override_spec.section (':', 0, 0);
+		QString name = placement_override_spec.section (':', 1, 1);
+
+		if (hint == "attached") {
+			attached = true;
+		} else if (hint == "detached") {
+			attached = false;
+		} else {
+			RK_ASSERT (hint.isEmpty ());
+		}
+		QWidget *parent_hint = attached ? RKWardMainWindow::getMain () : 0;
+
+		if (!name.isEmpty ()) {
+			int pos = -1;
+			for (int i = 0; i < named_windows.size (); ++i) {
+				if (named_windows[i].id == name) {
+					pos = i;
+					break;
+				}
+			}
+			if (pos < 0) {   // not yet known: implicit registration -> create corresponing named_window_spec on the fly.
+				registerNamedWindow (name, 0, parent_hint);
+				pos = named_windows.size () - 1;
+			}
+
+			NamedWindow &nw = named_windows[pos];
+			if (nw.window && nw.window != window) {   // kill existing window (going to be replaced)
+				disconnect (nw.window, SIGNAL (destroyed(QObject*)), this, SLOT (namedWindowDestroyed(QObject*)));
+				nw.window->deleteLater ();
+				nw.window = window;
+			}
+
+			// add window in the correct area
+			if (nw.parent == RKWardMainWindow::getMain ()) attached = true;
+			else if (nw.parent == 0) attached = false;
+			else { // custom parent
+				window->prepareToBeAttached ();
+				window->setParent (nw.parent);
+				// TODO: do we have to set window state to attached?
+				return;
+			}
+		}
+	}
+
 	if (attached) attachWindow (window);
 	else detachWindow (window, false);
 }
@@ -247,6 +294,63 @@ void RKWorkplace::placeInToolWindowBar (RKMDIWindow *window, int position) {
 	else if (needs_registration) attachWindow (window);
 }
 
+void RKWorkplace::registerNamedWindow (const QString& id, QObject* owner, QWidget* parent, RKMDIWindow* window) {
+	RK_TRACE (APP);
+
+	NamedWindow nw;
+	nw.id = id;
+	nw.owner = owner;
+	nw.parent = parent;
+	nw.window = window;
+
+	for (int i = 0; i < named_windows.size (); ++i) {
+		RK_ASSERT (named_windows[i].id != id);
+	}
+
+	named_windows.append (nw);
+	if (owner) connect (owner, SIGNAL (destroyed(QObject*)), this, SLOT (namedWindowOwnerDestroyed(QObject*)));
+	if (window) connect (window, SIGNAL (destroyed(QObject*)), this, SLOT (namedWindowDestroyed(QObject*)));
+}
+
+RKMDIWindow* RKWorkplace::getNamedWindow (const QString& id) {
+	RK_TRACE (APP);
+
+	for (int i = 0; i < named_windows.size (); ++i) {
+		if (named_windows[i].id == id) {
+			return named_windows[i].window;
+		}
+	}
+
+	return 0;
+}
+
+void RKWorkplace::namedWindowDestroyed (QObject* window) {
+	RK_TRACE (APP);
+
+	for (int i = 0; i < named_windows.size (); ++i) {
+		if (named_windows[i].window == window) {
+			if (!named_windows[i].owner) {
+				named_windows.removeAt (i);
+				return;
+			}
+		}
+	}
+}
+
+void RKWorkplace::namedWindowOwnerDestroyed (QObject* owner) {
+	RK_TRACE (APP);
+
+	for (int i = 0; i < named_windows.size (); ++i) {
+		if (named_windows[i].owner == owner) {
+			if (named_windows[i].window) {
+				named_windows[i].window->deleteLater ();
+			}
+			named_windows.removeAt (i);
+			return;
+		}
+	}
+}
+
 bool RKWorkplace::openAnyUrl (const KUrl &url, const QString &known_mimetype, bool force_external) {
 	RK_TRACE (APP);
 
diff --git a/rkward/windows/rkworkplace.h b/rkward/windows/rkworkplace.h
index c784274..5a2d4ec 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-2013 by Thomas Friedrichsmeier
+    copyright            : (C) 2006-2016 by Thomas Friedrichsmeier
     email                : thomas.friedrichsmeier at kdemail.net
  ***************************************************************************/
 
@@ -162,6 +162,14 @@ Has no effect, if RKSettingsModuleGeneral::workplaceSaveMode () != RKSettingsMod
 	KUrl workspaceURL () const { return current_url; };
 	KConfigBase *workspaceConfig ();
 	QString portableUrl (const KUrl &url);
+/** Register a named area where to place MDI windows. For directing preview windows to a specific location. */
+	void registerNamedWindow (const QString& id, QObject *owner, QWidget* parent, RKMDIWindow *window=0);
+/** Return the window in the specified named area (can be 0). */
+	RKMDIWindow *getNamedWindow (const QString& id);
+/** Make the next window to be created appear in a specific location (can be a named window). 
+ *  @note It is the caller's responsibility to clear the override (by calling setWindowPlacementOverride ()) after the window in question has been created.
+ *  @param spec can be "[attached|detached][:name]". */
+	void setWindowPlacementOverride (const QString& spec=QString ()) { placement_override_spec = spec; };
 signals:
 /** emitted when the workspace Url has changed */
 	void workspaceUrlChanged (const KUrl& url);
@@ -169,6 +177,9 @@ public slots:
 /** When windows are attached to the workplace, their QObject::destroyed () signal is connected to this slot. Thereby deleted objects are removed from the workplace automatically */
 	void removeWindow (QObject *window);
 	void saveSettings ();
+private slots:
+	void namedWindowDestroyed (QObject *);
+	void namedWindowOwnerDestroyed (QObject *);
 private:
 	KUrl current_url;
 	KConfig *_workspace_config;
@@ -192,6 +203,20 @@ private:
 	RKToolWindowBar* tool_window_bars[TOOL_WINDOW_BAR_COUNT];
 friend class RKToolWindowBar;
 	void placeInToolWindowBar (RKMDIWindow *window, int position);
+
+	/** Control placement of windows from R */
+	struct NamedWindow {
+		/** "Owner" of this named window. If non-0, and the owner gets destroyed, the named window record gets closed, too. */
+		QObject *owner;
+		/** Where to place window, if it does not exist, yet. Can be one of 0: detached, RKWardMainWindow::getMain(): attached, any other: docked in a special region */
+		QPointer<QWidget> parent;
+		/** Pointer to window, if it exists, already */
+		QPointer<RKMDIWindow> window;
+		/** Identifier string */
+		QString id;
+	};
+	QList<NamedWindow> named_windows;
+	QString placement_override_spec;
 };
 
 #endif



More information about the rkward-tracker mailing list