[rkward/work/generalized_preview] rkward: Don't discard preview window when toggling docked preview; implement docked previews for wizards.

Thomas Friedrichsmeier thomas.friedrichsmeier at ruhr-uni-bochum.de
Thu Jan 7 19:20:10 UTC 2016


Git commit 905e97b00f0fff9dfd59f6194d996d0d248c8d5f by Thomas Friedrichsmeier.
Committed on 07/01/2016 at 19:19.
Pushed by tfry into branch 'work/generalized_preview'.

Don't discard preview window when toggling docked preview; implement docked previews for wizards.

M  +14   -6    rkward/plugin/rkpreviewbox.cpp
M  +1    -1    rkward/plugin/rkpreviewbox.h
M  +1    -1    rkward/plugin/rkstandardcomponent.cpp
M  +41   -21   rkward/plugin/rkstandardcomponentgui.cpp
M  +5    -2    rkward/plugin/rkstandardcomponentgui.h
M  +7    -0    rkward/plugins/testing/preview.xml

http://commits.kde.org/rkward/905e97b00f0fff9dfd59f6194d996d0d248c8d5f

diff --git a/rkward/plugin/rkpreviewbox.cpp b/rkward/plugin/rkpreviewbox.cpp
index 34f3ea2..f86e456 100644
--- a/rkward/plugin/rkpreviewbox.cpp
+++ b/rkward/plugin/rkpreviewbox.cpp
@@ -82,6 +82,12 @@ RKPreviewBox::RKPreviewBox (const QDomElement &element, RKComponent *parent_comp
 			// create an empty data.frame as dummy. This is only really appropriate for data-previews, but even for other docked previews it has the effect of initializing the preview area
 			// with _something_.
 			RKGlobals::rInterface ()->issueCommand ("local ({\nrk.assign.preview.data(" + idprop + ", data.frame ())\n})\n" + placement_command + "rk.edit(rkward::.rk.variables$.rk.preview.data[[" + idprop + "]])" + placement_end, RCommand::Plugin | RCommand::Sync);
+
+			// A bit of a hack: For now, in wizards, docked previews are always active, and control boxes are meaningless.
+			if (uicomp->isWizardish ()) {
+				hide ();
+				toggle_preview_box->setChecked (true);
+			}
 		}
 	}
 
@@ -107,7 +113,7 @@ RKPreviewBox::RKPreviewBox (const QDomElement &element, RKComponent *parent_comp
 RKPreviewBox::~RKPreviewBox () {
 	RK_TRACE (PLUGIN);
 
-	killPreview ();
+	killPreview (true);
 }
 
 QVariant RKPreviewBox::value(const QString& modifier) {
@@ -197,16 +203,18 @@ void RKPreviewBox::setStatusMessage(const QString& status) {
 	window->setStatusMessage (status);
 }
 
-void RKPreviewBox::killPreview () {
+void RKPreviewBox::killPreview (bool force) {
 	RK_TRACE (PLUGIN);
 
 	if (!preview_active) return;
 	preview_active = false;
 
-	QString command;
-	if (preview_mode == PlotPreview) command = ".rk.killPreviewDevice (" + idprop + ')';
-	else command = "rk.discard.preview.data (" + idprop + ')';
-	RKGlobals::rInterface ()->issueCommand (command, RCommand::Plugin | RCommand::Sync);
+	if (force || placement != DockedPreview) {
+		QString command;
+		if (preview_mode == PlotPreview) command = ".rk.killPreviewDevice (" + idprop + ')';
+		else command = "rk.discard.preview.data (" + idprop + ')';
+		RKGlobals::rInterface ()->issueCommand (command, RCommand::Plugin | RCommand::Sync);
+	}
 
 	prior_preview_done = true;
 	new_preview_pending = false;
diff --git a/rkward/plugin/rkpreviewbox.h b/rkward/plugin/rkpreviewbox.h
index 400ba40..547446d 100644
--- a/rkward/plugin/rkpreviewbox.h
+++ b/rkward/plugin/rkpreviewbox.h
@@ -55,7 +55,7 @@ private:
 	bool prior_preview_done;
 	bool new_preview_pending;
 	void tryPreview ();
-	void killPreview ();
+	void killPreview (bool force = false);
 	void updateStatusLabel ();
 	void setStatusMessage (const QString& status);
 	enum PreviewMode {
diff --git a/rkward/plugin/rkstandardcomponent.cpp b/rkward/plugin/rkstandardcomponent.cpp
index 369ff94..e1b8a0a 100644
--- a/rkward/plugin/rkstandardcomponent.cpp
+++ b/rkward/plugin/rkstandardcomponent.cpp
@@ -274,12 +274,12 @@ bool RKStandardComponent::createTopLevel (const QDomElement &doc_element, int fo
 		static_cast<RKStandardComponentWizard *> (gui)->createWizard (!dialog_element.isNull ());
 		wizard = static_cast<RKStandardComponentWizard *> (gui)->getStack ();
 		buildAndInitialize (doc_element, wizard_element, gui->mainWidget (), true, enslaved);
-		static_cast<RKStandardComponentWizard *> (gui)->addLastPage ();
 	} else {
 		gui = new RKStandardComponentGUI (this, code, enslaved);
 		gui->createDialog (!wizard_element.isNull ());
 		buildAndInitialize (doc_element, dialog_element, gui->mainWidget (), false, enslaved);
 	}
+	gui->finalize ();
 
 	return true;
 }
diff --git a/rkward/plugin/rkstandardcomponentgui.cpp b/rkward/plugin/rkstandardcomponentgui.cpp
index d7ff245..2c09048 100644
--- a/rkward/plugin/rkstandardcomponentgui.cpp
+++ b/rkward/plugin/rkstandardcomponentgui.cpp
@@ -51,6 +51,7 @@ RKStandardComponentGUI::RKStandardComponentGUI (RKStandardComponent *component,
 
 	toggle_code_box = 0;
 	splitter = 0;
+	code_display = 0;
 
 	RKStandardComponentGUI::component = component;
 	RKStandardComponentGUI::code_property = code_property;
@@ -65,6 +66,11 @@ RKStandardComponentGUI::RKStandardComponentGUI (RKStandardComponent *component,
 	connect (code_update_timer, SIGNAL (timeout()), this, SLOT (updateCodeNow()));
 
 	if (!enslaved) {
+		// code display
+		code_display = new RKCommandEditorWindow (0, true, false);
+		code_display->setReadOnly (true);
+		addDockedPreview (code_display, &code_display_visibility, i18n ("Code Preview"), RKSettingsModulePlugins::defaultCodeHeight ());
+
 		KActionCollection *action_collection = new KActionCollection (this);
 		action_collection->addAction (KStandardAction::Copy, this, SLOT (copyCode()));
 	}
@@ -132,39 +138,43 @@ void RKStandardComponentGUI::createDialog (bool switchable) {
 	connect (toggle_code_box, SIGNAL (clicked()), this, SLOT (toggleCode()));
 	vbox->addWidget (toggle_code_box);
 	if (enslaved) toggle_code_box->hide ();
-	
-	// code display
-	code_display = new RKCommandEditorWindow (0, true, false);
-	code_display->setReadOnly (true);
 
 	splitter->addWidget (upper_widget);
 	splitter->setStretchFactor (0, 0);          // When resizing the dialog, *and* any preview is visible, effectively resize the preview. Dialog area can be resized via splitter.
 	splitter->setChildrenCollapsible (false);   // It's just too difficult to make this consistent, esp. for shrinking the dialog would _also_ be expected to collapse widgets. Besides, this makes it
 	                                            // easier to keep track of which expansions are currently visible.
-	addDockedPreview (code_display, &code_display_visibility, i18n ("Code Preview"), RKSettingsModulePlugins::defaultCodeHeight ());
 
 	if (!enslaved && RKSettingsModulePlugins::showCodeByDefault ()) {
 		toggle_code_box->setChecked (true);	// will trigger showing the code along with the dialog
 	}
 }
 
+void RKStandardComponentGUI::finalize () {
+	RK_TRACE (PLUGIN);
+
+	for (int i = 0; i < previews.size (); ++i) {
+		KVBox *dummy = new KVBox ();
+		QLabel *lab = new QLabel (i18n ("<b>%1</b>", previews[i].label), dummy);
+		lab->setStyleSheet ("background-color: rgb(100, 100, 255);");
+		previews[i].area->show ();
+		previews[i].area->setParent (dummy);
+		previews[i].area = dummy;
+		if (!(previews[i].controller->boolValue ())) dummy->hide ();
+		splitter->insertWidget (i+1, previews[i].area);
+		splitter->setStretchFactor (i+1, 1);
+	}
+}
+
 void RKStandardComponentGUI::addDockedPreview (QWidget *area, RKComponentPropertyBool *controller, const QString& label, int sizehint) {
 	RK_TRACE (PLUGIN);
 
 	PreviewArea parea;
-	KVBox *dummy = new KVBox ();
-	QLabel *lab = new QLabel (i18n ("<b>%1</b>", label), dummy);
-	lab->setStyleSheet ("background-color: rgb(100, 100, 255);");
-	area->setParent (dummy);
-	dummy->hide ();
-	parea.area = dummy;
+	parea.area = area;
 	parea.controller = controller;
 	parea.sizehint = sizehint;
+	parea.label = label;
 	previews.insert (0, parea);
 
-	splitter->insertWidget (1, dummy);
-	splitter->setStretchFactor (1, 1);
-
 	connect (controller, SIGNAL (valueChanged(RKComponentPropertyBase*)), this, SLOT (previewVisibilityChanged(RKComponentPropertyBase*)));
 };
 
@@ -388,7 +398,7 @@ void RKStandardComponentWizard::createWizard (bool switchable) {
 	auto_close_box->hide ();
 }
 
-void RKStandardComponentWizard::addLastPage () {
+void RKStandardComponentWizard::finalize () {
 	RK_TRACE (PLUGIN);
 
 	if (!enslaved) {
@@ -396,12 +406,22 @@ void RKStandardComponentWizard::addLastPage () {
 		RKComponent *last_page = stack->addPage (component);
 		QVBoxLayout *vbox = new QVBoxLayout (last_page);
 		vbox->setContentsMargins (0, 0, 0, 0);
-		QLabel *label = new QLabel (i18n ("Below you can see the command(s) corresponding to the settings you made. Click 'Submit' to run the command(s)."), last_page);
-		label->setWordWrap (true);
-		code_display = new RKCommandEditorWindow (last_page, true, false);
-		code_display->setReadOnly (true);
-		vbox->addWidget (label);
-		vbox->addWidget (code_display);
+		if (previews.size () < 2) {
+			RK_ASSERT (previews.size () == 1);
+			QLabel *label = new QLabel (i18n ("Below you can preview the R commands corresponding to the settings you made. Click 'Submit' to run the commands."), last_page);
+			label->setWordWrap (true);
+			vbox->addWidget (label);
+			vbox->addWidget (code_display);
+		} else {
+			QLabel *label = new QLabel (i18n ("Below you can preview the result of your settings, and the R commands to be run. Click 'Submit' to run the commands."), last_page);
+			label->setWordWrap (true);
+			vbox->addWidget (label);
+			QTabWidget *previews_widget = new QTabWidget (last_page);
+			vbox->addWidget (previews_widget);
+			for (int i = 0; i < previews.size (); ++i) {
+				previews_widget->addTab (previews[i].area, previews[i].label);
+			}
+		}
 	}
 
 	stack->goToFirstPage ();
diff --git a/rkward/plugin/rkstandardcomponentgui.h b/rkward/plugin/rkstandardcomponentgui.h
index 9f76428..cea337b 100644
--- a/rkward/plugin/rkstandardcomponentgui.h
+++ b/rkward/plugin/rkstandardcomponentgui.h
@@ -84,6 +84,8 @@ public:
 /** reimplemented from QWidget to take care of showing the code display if needed */
 	void showEvent (QShowEvent *e);
 	void addDockedPreview (QWidget *area, RKComponentPropertyBool *controller, const QString& label, int sizehint = -1);
+/** Do anything needed after the dialog is created and its contents have been built. Base class adds the preview regions to the splitter */
+	virtual void finalize ();
 public slots:
 	void ok ();
 	void cancel ();
@@ -120,6 +122,7 @@ protected:
 	struct PreviewArea {
 		QWidget *area;
 		RKComponentPropertyBool *controller;
+		QString label;
 		int sizehint;
 	};
 	QList<PreviewArea> previews;
@@ -137,8 +140,8 @@ public:
 	void enableSubmit (bool enable);
 	void updateCode ();
 	void createWizard (bool switchable);
-/** Add a standard last page in the wizard. To confuse everybody, this also initializes the view to the first page */
-	void addLastPage ();
+/** Adds a standard last page in the wizard, and initializes the view to the first page */
+	void finalize () override;
 
 	void updateState ();
 
diff --git a/rkward/plugins/testing/preview.xml b/rkward/plugins/testing/preview.xml
index 0088fad..8632925 100644
--- a/rkward/plugins/testing/preview.xml
+++ b/rkward/plugins/testing/preview.xml
@@ -8,4 +8,11 @@
 		<spinbox id="value" type="real" min="0" label="Value" initial="1.23"/>
 		<preview mode="data" label="Preview data"/>
 	</dialog>
+	<wizard label="Testing various preview features">
+		<page>
+			<spinbox id="size" type="integer" min="0" label="Size" initial="3"/>
+			<spinbox id="value" type="real" min="0" label="Value" initial="1.23"/>
+			<preview mode="data" label="Preview data"/>
+		</page>
+	</wizard>
 </document> 



More information about the rkward-tracker mailing list