[rkward/work/generalized_preview] rkward: Support using different style for preview windows (not perfect, yet).

Thomas Friedrichsmeier thomas.friedrichsmeier at ruhr-uni-bochum.de
Wed Jan 6 20:25:26 UTC 2016


Git commit a062521588abebe01cb1ea283f6b9fe101856942 by Thomas Friedrichsmeier.
Committed on 06/01/2016 at 20:24.
Pushed by tfry into branch 'work/generalized_preview'.

Support using different style for preview windows (not perfect, yet).

Minor refactoring on the way.

M  +14   -3    rkward/dataeditor/twintable.cpp
M  +5    -1    rkward/dataeditor/twintable.h
M  +9    -6    rkward/plugin/rkpreviewbox.cpp
M  +1    -1    rkward/rbackend/rinterface.cpp
M  +1    -1    rkward/rbackend/rpackages/rkward/NAMESPACE
M  +19   -14   rkward/rbackend/rpackages/rkward/R/rk.workspace-functions.R
D  +0    -45   rkward/rbackend/rpackages/rkward/man/rk.with.placement.hint.Rd
A  +52   -0    rkward/rbackend/rpackages/rkward/man/rk.with.window.hints.Rd
M  +8    -1    rkward/windows/rkmdiwindow.cpp
M  +3    -0    rkward/windows/rkmdiwindow.h
M  +1    -1    rkward/windows/rkwindowcatcher.cpp
M  +1    -2    rkward/windows/rkwindowcatcher.h
M  +59   -49   rkward/windows/rkworkplace.cpp
M  +5    -4    rkward/windows/rkworkplace.h

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

diff --git a/rkward/dataeditor/twintable.cpp b/rkward/dataeditor/twintable.cpp
index 595e620..7a80975 100644
--- a/rkward/dataeditor/twintable.cpp
+++ b/rkward/dataeditor/twintable.cpp
@@ -2,7 +2,7 @@
                           twintable.cpp  -  description
                              -------------------
     begin                : Tue Oct 29 2002
-    copyright            : (C) 2002, 2006, 2007, 2010, 2015 by Thomas Friedrichsmeier
+    copyright            : (C) 2002-2016 by Thomas Friedrichsmeier
     email                : thomas.friedrichsmeier at kdemail.net
  ***************************************************************************/
 
@@ -47,8 +47,8 @@ TwinTable::TwinTable (QWidget *parent) : RKEditor (parent), RObjectListener (ROb
 	QVBoxLayout *layout = new QVBoxLayout(this);
 	layout->setContentsMargins (0, 0, 0, 0);
 	
-	QSplitter *splitter = new QSplitter(this);
-	splitter->setOrientation(Qt::Vertical);
+	splitter = new QSplitter (this);
+	splitter->setOrientation (Qt::Vertical);
 
 	metaview = new TwinTableMember (splitter);
 	splitter->setStretchFactor (splitter->indexOf (metaview), 0);
@@ -193,6 +193,17 @@ void TwinTable::initTable (RKVarEditModel* model, RObject* object) {
 	connect (model, SIGNAL (hasDuplicates(QStringList)), this, SLOT (containsDuplicates(QStringList)));
 }
 
+void TwinTable::setWindowStyleHint (const QString& hint) {
+	RK_TRACE (EDITOR);
+	if (hint == "preview") { // preview skin: Squeeze header as much as possible
+		metaview->horizontalHeader ()->hide ();
+		metaview->setMinimumHeight (metaview->rowHeight (0));
+		splitter->setStretchFactor (0, 0);
+		splitter->setStretchFactor (1, 1);
+	}
+	RKMDIWindow::setWindowStyleHint (hint);
+}
+
 void TwinTable::containsDuplicates (const QStringList& dupes) {
 	RK_TRACE (EDITOR);
 
diff --git a/rkward/dataeditor/twintable.h b/rkward/dataeditor/twintable.h
index fab8671..a43f566 100644
--- a/rkward/dataeditor/twintable.h
+++ b/rkward/dataeditor/twintable.h
@@ -2,7 +2,7 @@
                           twintable.h  -  description
                              -------------------
     begin                : Tue Oct 29 2002
-    copyright            : (C) 2002, 2006, 2007, 2010, 2015 by Thomas Friedrichsmeier
+    copyright            : (C) 2002-2016 by Thomas Friedrichsmeier
     email                : thomas.friedrichsmeier at kdemail.net
  ***************************************************************************/
 
@@ -31,6 +31,7 @@ class TwinTableMember;
 class RKVarEditModel;
 class QActionGroup;
 class KAction;
+class QSplitter;
 
 /**
   *@author Thomas Friedrichsmeier
@@ -54,6 +55,7 @@ public:
 	RKVarEditModel* datamodel;
 
 	QActionGroup* editActions () const { return edit_actions; };
+	void setWindowStyleHint (const QString& hint) override;
 public slots:
 	void metaHeaderPressed (int section);
 	void metaHeaderEntered (int section);
@@ -85,6 +87,8 @@ private:
 	int context_menu_row;
 /** Only valid, if context_menu_table != 0. Column of current context menu event. -1 for header column. -2 for no cell. */
 	int context_menu_column;
+
+	QSplitter *splitter;
 protected:	
 /** Returns the active Table (of the two members), 0 if no table active */
 	TwinTableMember *activeTable ();
diff --git a/rkward/plugin/rkpreviewbox.cpp b/rkward/plugin/rkpreviewbox.cpp
index 3b4aa16..b3a9393 100644
--- a/rkward/plugin/rkpreviewbox.cpp
+++ b/rkward/plugin/rkpreviewbox.cpp
@@ -162,15 +162,18 @@ void RKPreviewBox::tryPreviewNow () {
 
 	preview_active = true;
 
-	QString placement_command;
-	if (placement == AttachedPreview) placement_command = "attached";
-	else if (placement == DetachedPreview) placement_command = "detached";
-	placement_command = ".rk.with.placement.hint (" + RObject::rQuote (placement_command + ':' + idprop) + ", {\n";
-	QString placement_end = "\n})";
+	QString placement_command = ".rk.with.window.hints ({";
+	QString placement_end = "\n}, ";
+	if (placement == AttachedPreview) placement_end.append ("\"attached\"");
+	else if (placement == DetachedPreview) placement_end.append ("\"detached\"");
+	else placement_end.append ("\"\"");
+	placement_end.append (", " + RObject::rQuote (idprop) + ", style=\"preview\")");
 
 	setStatusMessage (i18n ("Preview updating"));
 	if (preview_mode == PlotPreview) {
-		RKGlobals::rInterface ()->issueCommand (placement_command + ".rk.startPreviewDevice (" + idprop + ')' + placement_end + "\nlocal({\n" + code_property->preview () + "})\n", RCommand::Plugin | RCommand::Sync, QString (), this, DO_PREVIEW);
+		RKGlobals::rInterface ()->issueCommand (placement_command + ".rk.startPreviewDevice (" + idprop + ')' + placement_end, RCommand::Plugin | RCommand::Sync, QString ());
+		// creating window generates warnings, sometimes. Don't make those part of the warnings shown for the preview -> separate command for the actual plot.
+		RKGlobals::rInterface ()->issueCommand ("local({\n" + code_property->preview () + "})\n", RCommand::Plugin | RCommand::Sync, QString (), this, DO_PREVIEW);
 	} else if (preview_mode == DataPreview) {
 		RKGlobals::rInterface ()->issueCommand ("local({\n" + code_property->preview () + "\nrk.assign.preview.data(" + idprop + ", preview_data)\n" + placement_command + "rk.edit(rkward::.rk.variables$.rk.preview.data[[" + idprop + "]])" + placement_end + "\n})\n", RCommand::Plugin | RCommand::Sync, QString (), this, DO_PREVIEW);
 	} else {
diff --git a/rkward/rbackend/rinterface.cpp b/rkward/rbackend/rinterface.cpp
index 7e88e31..ef4d19e 100644
--- a/rkward/rbackend/rinterface.cpp
+++ b/rkward/rbackend/rinterface.cpp
@@ -626,7 +626,7 @@ QStringList RInterface::processPlainGenericRequest (const QStringList &calllist)
 			return (RKWorkplace::mainWorkplace ()->makeWorkplaceDescription ());
 		}
 	} else if (call == "set.window.placement.hint") {
-		RKWorkplace::mainWorkplace ()->setWindowPlacementOverride (calllist.value (1));
+		RKWorkplace::mainWorkplace ()->setWindowPlacementOverrides (calllist.value (1), calllist.value (2), calllist.value (3));
 	} else if (call == "getSessionInfo") {
 		// Non-translatable on purpose. This is meant for posting to the bug tracker, mostly.
 		QStringList lines ("-- Frontend --");
diff --git a/rkward/rbackend/rpackages/rkward/NAMESPACE b/rkward/rbackend/rpackages/rkward/NAMESPACE
index 1c8eea7..811ab90 100644
--- a/rkward/rbackend/rpackages/rkward/NAMESPACE
+++ b/rkward/rbackend/rpackages/rkward/NAMESPACE
@@ -44,7 +44,7 @@ export(.rk.variables)
 export(.rk.watch.globalenv)
 export(.rk.watch.symbol)
 export(.rk.watched.symbols)
-export(.rk.with.placement.hint)
+export(.rk.with.window.hints)
 export(RK)
 export(Sys.setlocale)
 export(X11)
diff --git a/rkward/rbackend/rpackages/rkward/R/rk.workspace-functions.R b/rkward/rbackend/rpackages/rkward/R/rk.workspace-functions.R
index c08a74d..31f4278 100644
--- a/rkward/rbackend/rpackages/rkward/R/rk.workspace-functions.R
+++ b/rkward/rbackend/rpackages/rkward/R/rk.workspace-functions.R
@@ -70,39 +70,44 @@
 	invisible (NULL)
 }
 
-#' Control window placement
+#' Control window placement and style
 #' 
-#' \code{.rk.with.placement.hint} can be used to make windows appear in a specific
+#' \code{.rk.with.window.hints} can be used to make windows appear in a specific
 #' location: attached, detached, or in a named position where a previous window is
-#' found. (The latter used for preview windows, importantly).
+#' found. (The latter used for preview windows, importantly). It can also be used to pass
+#' "style" hints, importantly indicating that the window is a preview window. All specifications
+#' affect newly created windows, only, not existing ones.
 #' 
 #' NOTE: This function is still somewhat experimental, and it is not guaranteed that
 #' it will remain in place, with compatible parameters.
 #' 
-#' @aliases .rk.with.placement.hint rk.with.placement.hint
-#' @param hint a character string specifying the placement in the form "[attached|detached][:name]"
-#'        If a name is given, and this position is not yet known, the attached/detached hint will
-#'        be followed (or, if ommitted, default placement will be used). If later a second window is
-#'        created with the same given name, it will replace the first window.
+#' @aliases .rk.with.window.hints rk.with.window.hints
 #' @param expr Expression to evaluate, unsually an expression that is expected to create exactly one
 #'        new window.
+#' @param placement a character string specifying either "attached" or "detached" placement, or
+#'        (if left empty) the default placement for the type of window created.
+#' @param name character string specifing a named position. If a name is given, and this position is
+#'        not yet known, the placement hint (see above) will be followed. If later a second window is
+#'        created with the same given name, it will replace the first window.
+#' @param style character string specifing a style hint. Currently, this can either be "preview" or
+#'        "" (default), with most types of window not implementing any special behavior for "preview".
 #' @return \code{NULL}, invisibly.
 #' @author Thomas Friedrichsmeier \email{rkward-devel@@kde.org}
 #' @keywords utilities
-#' @rdname rk.with.placement.hint
+#' @rdname rk.with.window.hints
 #' @examples
 #' 
 #' ## Not run
-#' .rk.with.placement.hint ("attached", {
+#' .rk.with.window.hints ({
 #'    RK ()
 #'    plot (1, 1)
-#' })
+#' }, "attached")
 #' ## End not run
 #' 
 #' @export
-".rk.with.placement.hint" <- function (hint, expr) {
-	.rk.do.plain.call ("set.window.placement.hint", as.character (hint), FALSE)
-	on.exit (.rk.do.plain.call ("set.window.placement.hint", "", FALSE))
+".rk.with.window.hints" <- function (expr, placement="", name="", style="") {
+	.rk.do.plain.call ("set.window.placement.hint", as.character (c (placement, name, style)), FALSE)
+	on.exit (.rk.do.plain.call ("set.window.placement.hint", c ("", "", ""), FALSE))
 	eval.parent (substitute (eval (quote (expr), parent.frame ())))
 	invisible (NULL)
 }
diff --git a/rkward/rbackend/rpackages/rkward/man/rk.with.placement.hint.Rd b/rkward/rbackend/rpackages/rkward/man/rk.with.placement.hint.Rd
deleted file mode 100644
index 2916f4d..0000000
--- a/rkward/rbackend/rpackages/rkward/man/rk.with.placement.hint.Rd
+++ /dev/null
@@ -1,45 +0,0 @@
-% Generated by roxygen2: do not edit by hand
-% Please edit documentation in R/rk.workspace-functions.R
-\name{.rk.with.placement.hint}
-\alias{.rk.with.placement.hint}
-\alias{rk.with.placement.hint}
-\title{Control window placement}
-\usage{
-.rk.with.placement.hint(hint, expr)
-}
-\arguments{
-\item{hint}{a character string specifying the placement in the form "[attached|detached][:name]"
-If a name is given, and this position is not yet known, the attached/detached hint will
-be followed (or, if ommitted, default placement will be used). If later a second window is
-created with the same given name, it will replace the first window.}
-
-\item{expr}{Expression to evaluate, unsually an expression that is expected to create exactly one
-new window.}
-}
-\value{
-\code{NULL}, invisibly.
-}
-\description{
-\code{.rk.with.placement.hint} can be used to make windows appear in a specific
-location: attached, detached, or in a named position where a previous window is
-found. (The latter used for preview windows, importantly).
-}
-\details{
-NOTE: This function is still somewhat experimental, and it is not guaranteed that
-it will remain in place, with compatible parameters.
-}
-\examples{
-
-## Not run
-.rk.with.placement.hint ("attached", {
-   RK ()
-   plot (1, 1)
-})
-## End not run
-
-}
-\author{
-Thomas Friedrichsmeier \email{rkward-devel at kde.org}
-}
-\keyword{utilities}
-
diff --git a/rkward/rbackend/rpackages/rkward/man/rk.with.window.hints.Rd b/rkward/rbackend/rpackages/rkward/man/rk.with.window.hints.Rd
new file mode 100644
index 0000000..8b45eb5
--- /dev/null
+++ b/rkward/rbackend/rpackages/rkward/man/rk.with.window.hints.Rd
@@ -0,0 +1,52 @@
+% Generated by roxygen2: do not edit by hand
+% Please edit documentation in R/rk.workspace-functions.R
+\name{.rk.with.window.hints}
+\alias{.rk.with.window.hints}
+\alias{rk.with.window.hints}
+\title{Control window placement and style}
+\usage{
+.rk.with.window.hints(expr, placement = "", name = "", style = "")
+}
+\arguments{
+\item{expr}{Expression to evaluate, unsually an expression that is expected to create exactly one
+new window.}
+
+\item{placement}{a character string specifying either "attached" or "detached" placement, or
+(if left empty) the default placement for the type of window created.}
+
+\item{name}{character string specifing a named position. If a name is given, and this position is
+not yet known, the placement hint (see above) will be followed. If later a second window is
+created with the same given name, it will replace the first window.}
+
+\item{style}{character string specifing a style hint. Currently, this can either be "preview" or
+"" (default), with most types of window not implementing any special behavior for "preview".}
+}
+\value{
+\code{NULL}, invisibly.
+}
+\description{
+\code{.rk.with.window.hints} can be used to make windows appear in a specific
+location: attached, detached, or in a named position where a previous window is
+found. (The latter used for preview windows, importantly). It can also be used to pass
+"style" hints, importantly indicating that the window is a preview window. All specifications
+affect newly created windows, only, not existing ones.
+}
+\details{
+NOTE: This function is still somewhat experimental, and it is not guaranteed that
+it will remain in place, with compatible parameters.
+}
+\examples{
+
+## Not run
+.rk.with.window.hints ({
+   RK ()
+   plot (1, 1)
+}, "attached")
+## End not run
+
+}
+\author{
+Thomas Friedrichsmeier \email{rkward-devel at kde.org}
+}
+\keyword{utilities}
+
diff --git a/rkward/windows/rkmdiwindow.cpp b/rkward/windows/rkmdiwindow.cpp
index 05bdf17..e9e415c 100644
--- a/rkward/windows/rkmdiwindow.cpp
+++ b/rkward/windows/rkmdiwindow.cpp
@@ -67,6 +67,7 @@ RKMDIWindow::RKMDIWindow (QWidget *parent, int type, bool tool_window, const cha
 	tool_window_bar = 0;
 	part = 0;
 	active = false;
+	no_border_when_active = false;
 	standard_client = 0;
 	status_popup = 0;
 
@@ -248,7 +249,7 @@ void RKMDIWindow::paintEvent (QPaintEvent *e) {
 
 	QFrame::paintEvent (e);
 
-	if (isActive ()) {
+	if (isActive () && !no_border_when_active) {
 		QPainter paint (this);
 		paint.setPen (QColor (255, 0, 0));
 		paint.drawLine (0, 0, 0, height ()-1);
@@ -313,6 +314,12 @@ void RKMDIWindow::clearStatusMessage () {
 	setStatusMessage (QString ());
 }
 
+void RKMDIWindow::setWindowStyleHint (const QString& hint) {
+	RK_TRACE (APP);
+
+	if (hint == "preview") no_border_when_active = true;
+}
+
 void RKMDIWindow::setMetaInfo (const QString& _generic_window_name, const QString& _help_url, RKSettings::SettingsPage _settings_page) {
 	RK_TRACE (APP);
 
diff --git a/rkward/windows/rkmdiwindow.h b/rkward/windows/rkmdiwindow.h
index bdbb1e9..c69ad7b 100644
--- a/rkward/windows/rkmdiwindow.h
+++ b/rkward/windows/rkmdiwindow.h
@@ -107,6 +107,8 @@ public:
 This should be used, when the information shown is currently out-of-date (e.g. when refreshing a preview / loading a plot from history), _not_ when the window
 is simply busy (e.g. when saving the current plot to history). */
 	void setStatusMessage (const QString& message, RCommand* command=0);
+/** Set a style hint for the window. So far the only interpreted style hint is "preview", and not all windows implement it. Base implements hiding of "active" indicator border for "preview"s. */
+	virtual void setWindowStyleHint (const QString& hint);
 
 	bool eventFilter (QObject *watched, QEvent *e);
 	bool acceptsEventsFor (QObject *object);
@@ -149,6 +151,7 @@ friend class RKToolWindowBar;
 	State state;
 	RKToolWindowBar *tool_window_bar;
 	bool active;
+	bool no_border_when_active;
 	RKMDIStandardActionClient *standard_client;
 /** @see globalContextProperty() */
 	QMap<QString, QString> global_context_properties;
diff --git a/rkward/windows/rkwindowcatcher.cpp b/rkward/windows/rkwindowcatcher.cpp
index 8f45e19..dfbb613 100644
--- a/rkward/windows/rkwindowcatcher.cpp
+++ b/rkward/windows/rkwindowcatcher.cpp
@@ -140,7 +140,7 @@ void RKWindowCatcher::killDevice (int device_number) {
 // static
 QHash<int, RKCaughtX11Window*> RKCaughtX11Window::device_windows;
 
-RKCaughtX11Window::RKCaughtX11Window (WId window_to_embed, int device_number) : RKMDIWindow (0, X11Window), RCommandReceiver () {
+RKCaughtX11Window::RKCaughtX11Window (WId window_to_embed, int device_number) : RKMDIWindow (0, X11Window) {
 	RK_TRACE (MISC);
 
 	commonInit (device_number);
diff --git a/rkward/windows/rkwindowcatcher.h b/rkward/windows/rkwindowcatcher.h
index e244263..632148d 100644
--- a/rkward/windows/rkwindowcatcher.h
+++ b/rkward/windows/rkwindowcatcher.h
@@ -80,7 +80,6 @@ private:
 
 
 #include "rkmdiwindow.h"
-#include "../rbackend/rcommandreceiver.h"
 
 #include <QHash>
 
@@ -98,7 +97,7 @@ class RKGraphicsDevice;
 
 /** An R onscreen graphics device window managed by rkward. Currently, this can be X11 devices (on X11), Windows devices (on Windows), and
  RK devices (anywhere). */
-class RKCaughtX11Window : public RKMDIWindow, public RCommandReceiver {
+class RKCaughtX11Window : public RKMDIWindow {
 	Q_OBJECT
 public:
 /** ctor
diff --git a/rkward/windows/rkworkplace.cpp b/rkward/windows/rkworkplace.cpp
index b8bf426..f16f8a0 100644
--- a/rkward/windows/rkworkplace.cpp
+++ b/rkward/windows/rkworkplace.cpp
@@ -65,6 +65,7 @@ RKWorkplace::RKWorkplace (QWidget *parent) : QWidget (parent) {
 
 	main_workplace = this;
 	_workspace_config = 0;
+	window_placement_override = RKMDIWindow::AnyWindowState;
 
 	/* Splitter setup contains heavy copying from Kate's katemdi! */
 	KVBox *vbox = new KVBox (this);
@@ -211,58 +212,54 @@ void RKWorkplace::detachWindow (RKMDIWindow *window, bool was_attached) {
 void RKWorkplace::addWindow (RKMDIWindow *window, bool attached) {
 	RK_TRACE (APP);
 
-	// 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);
-
-		if (hint == "attached") {
-			if (!attached) window->state = RKMDIWindow::Detached;   // Ok, yeah. BAD style. But windows that would go to detached by default would not prepareToBeAttached(), without this.
-			                                                        // TODO: Create third state: NotManaged
-			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;
-			}
+	// first handle placement overrides
+	if (window_placement_override == RKMDIWindow::Attached) {
+		if (!attached) window->state = RKMDIWindow::Detached;   // Ok, yeah. BAD style. But windows that would go to detached by default would not prepareToBeAttached(), without this.
+		                                                        // TODO: Create third state: NotManaged
+		attached = true;
+	} else if (window_placement_override == RKMDIWindow::Detached) {
+		attached = false;
+	}
 
-			NamedWindow &nw = named_windows[pos];
-			if (nw.window != window) {
-				if (nw.window) {  // kill existing window (going to be replaced)
-					// TODO: this is not really elegant, yet, as it will change tab-placement (for attached windows), and discard / recreate container (for detached windows)
-					disconnect (nw.window, SIGNAL (destroyed(QObject*)), this, SLOT (namedWindowDestroyed(QObject*)));
-					nw.window->deleteLater ();
-				}
-				nw.window = window;
-				connect (nw.window, SIGNAL (destroyed(QObject*)), this, SLOT (namedWindowDestroyed(QObject*)));
+	// style override. Windows may or may not handle this
+	if (!window_style_override.isEmpty ()) window->setWindowStyleHint (window_style_override);
+
+	// next handle name overrides, if any
+	if (!window_name_override.isEmpty ()) {
+		int pos = -1;
+		for (int i = 0; i < named_windows.size (); ++i) {
+			if (named_windows[i].id == window_name_override) {
+				pos = i;
+				break;
 			}
-			named_windows[pos] = nw;
-
-			// 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 this is somewhat inconsistent. But such windows are not attached to the main workplace view, which makes them rather behave detached.
-				window->state = RKMDIWindow::Detached;
-				// NOTE: The window is _not_ added to the window list/window history in this case.
-				return;
+		}
+		if (pos < 0) {   // not yet known: implicit registration -> create corresponing named_window_spec on the fly.
+			registerNamedWindow (window_name_override, 0, attached ? RKWardMainWindow::getMain () : 0);
+			pos = named_windows.size () - 1;
+		}
+
+		NamedWindow &nw = named_windows[pos];
+		if (nw.window != window) {
+			if (nw.window) {  // kill existing window (going to be replaced)
+				// TODO: this is not really elegant, yet, as it will change tab-placement (for attached windows), and discard / recreate container (for detached windows)
+				disconnect (nw.window, SIGNAL (destroyed(QObject*)), this, SLOT (namedWindowDestroyed(QObject*)));
+				nw.window->deleteLater ();
 			}
+			nw.window = window;
+			connect (nw.window, SIGNAL (destroyed(QObject*)), this, SLOT (namedWindowDestroyed(QObject*)));
+		}
+		named_windows[pos] = nw;
+
+		// 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 this is somewhat inconsistent. But such windows are not attached to the main workplace view, which makes them rather behave detached.
+			window->state = RKMDIWindow::Detached;
+			// NOTE: The window is _not_ added to the window list/window history in this case.
+			return;
 		}
 	}
 
@@ -303,6 +300,19 @@ void RKWorkplace::placeInToolWindowBar (RKMDIWindow *window, int position) {
 	else if (needs_registration) attachWindow (window);
 }
 
+void RKWorkplace::setWindowPlacementOverrides(const QString& placement, const QString& name, const QString& style) {
+	RK_TRACE (APP);
+
+	if (placement == "attached") window_placement_override = RKMDIWindow::Attached;
+	else if (placement == "detached") window_placement_override = RKMDIWindow::Attached;
+	else {
+		RK_ASSERT (placement.isEmpty ());
+		window_placement_override = RKMDIWindow::AnyWindowState;
+	}
+	window_name_override = name;
+	window_style_override = style;
+}
+
 void RKWorkplace::registerNamedWindow (const QString& id, QObject* owner, QWidget* parent, RKMDIWindow* window) {
 	RK_TRACE (APP);
 
diff --git a/rkward/windows/rkworkplace.h b/rkward/windows/rkworkplace.h
index 1062329..afd8258 100644
--- a/rkward/windows/rkworkplace.h
+++ b/rkward/windows/rkworkplace.h
@@ -167,9 +167,8 @@ Has no effect, if RKSettingsModuleGeneral::workplaceSaveMode () != RKSettingsMod
 /** 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; };
+ *  @note It is the caller's responsibility to clear the override (by calling setWindowPlacementOverride ()) after the window in question has been created. */
+	void setWindowPlacementOverrides (const QString& placement=QString (), const QString& name=QString (), const QString& style=QString ());
 signals:
 /** emitted when the workspace Url has changed */
 	void workspaceUrlChanged (const KUrl& url);
@@ -216,7 +215,9 @@ friend class RKToolWindowBar;
 		QString id;
 	};
 	QList<NamedWindow> named_windows;
-	QString placement_override_spec;
+	RKMDIWindow::State window_placement_override;
+	QString window_name_override;
+	QString window_style_override;
 };
 
 #endif



More information about the rkward-tracker mailing list