[rkward/work/split_views] /: Restoring split views works in principle (with heavy issues, including geometry and orientation)
Thomas Friedrichsmeier
null at kde.org
Tue Jun 20 21:51:56 UTC 2017
Git commit 01464f05e7039c3299d89b62448bec832d5040d7 by Thomas Friedrichsmeier.
Committed on 20/06/2017 at 21:51.
Pushed by tfry into branch 'work/split_views'.
Restoring split views works in principle (with heavy issues, including geometry and orientation)
M +2 -0 ChangeLog
M +7 -17 rkward/windows/rkworkplace.cpp
M +104 -20 rkward/windows/rkworkplaceview.cpp
M +11 -4 rkward/windows/rkworkplaceview.h
https://commits.kde.org/rkward/01464f05e7039c3299d89b62448bec832d5040d7
diff --git a/ChangeLog b/ChangeLog
index e2900b48..1cdb1835 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,5 @@
+TODO: Workplace save as does not as for overwrite confirmation
+
- Fixed: Creating trellis on-screen plots, while package lattice is not on the search path would produce errors in plot history mechanism
- Limit the number of debug log-files to keep (at most three, each, for frontend and backend)
- Remove Windows-only UI for setInternet2()-option (no longer available in R, with setInternet2(TRUE) the default since R 3.2.2)
diff --git a/rkward/windows/rkworkplace.cpp b/rkward/windows/rkworkplace.cpp
index ec46de60..59092da4 100644
--- a/rkward/windows/rkworkplace.cpp
+++ b/rkward/windows/rkworkplace.cpp
@@ -874,16 +874,8 @@ QStringList RKWorkplace::makeWorkplaceDescription () {
if (!desc.isEmpty ()) workplace_description.append (desc);
}
- QVariantList attached_list = wview->listContents ();
- for (int i=0; i < attached_list.count (); ++i) {
- if (attached_list[i].canConvert<QObject*>()) {
- RKMDIWindow *win = static_cast<RKMDIWindow*> (attached_list[i].value<QObject*>());
- QString desc = makeItemDescription (win);
- if (!desc.isEmpty ()) workplace_description.append (desc);
- } else {
- workplace_description.append (attached_list[i].toString ());
- }
- }
+ workplace_description.append (QStringLiteral ("layout::::") + wview->listLayout ());
+ workplace_description.append (wview->listContents ());
list = getObjectList (RKMDIWindow::ToolWindow, RKMDIWindow::AnyWindowState);
foreach (RKMDIWindow *win, list) {
@@ -917,11 +909,6 @@ void RKWorkplace::restoreWorkplace (const QStringList &description) {
RKWardMainWindow::getMain ()->lockGUIRebuild (true);
QString base;
for (int i = 0; i < description.size (); ++i) {
-/* if (split_next) {
- split_next = false;
- view ()->restoreSplitView (split_orientation, description[i], base);
- } */
-
ItemSpecification spec = parseItemDescription (description[i]);
RKMDIWindow *win = 0;
if (spec.type == "base") {
@@ -929,8 +916,10 @@ void RKWorkplace::restoreWorkplace (const QStringList &description) {
base = spec.specification;
} else if (restoreDocumentWindowInternal (this, spec, base)) {
// it was restored. nothing else to do
- } else if (spec.type == "split") {
-#warning implement
+ } else if (spec.type == "layout") {
+ view ()->restoreLayout (spec.specification);
+ } else if (spec.type == "pane_end") {
+ view ()->nextPane ();
} else {
win = RKToolWindowList::findToolWindowById (spec.type);
RK_ASSERT (win);
@@ -952,6 +941,7 @@ void RKWorkplace::restoreWorkplace (const QStringList &description) {
}
}
}
+ view ()->purgeEmptyPanes ();
RKWardMainWindow::getMain ()->lockGUIRebuild (false);
}
diff --git a/rkward/windows/rkworkplaceview.cpp b/rkward/windows/rkworkplaceview.cpp
index afcd6942..0ac5218b 100644
--- a/rkward/windows/rkworkplaceview.cpp
+++ b/rkward/windows/rkworkplaceview.cpp
@@ -178,7 +178,7 @@ void RKWorkplaceViewPane::contextMenuDetachWindow () {
RKWorkplace::mainWorkplace ()->detachWindow (static_cast<RKMDIWindow*> (widget (tab)));
}
-void RKWorkplaceViewPane::currentPageChanged (int page) {
+void RKWorkplaceViewPane::currentPageChanged (int) {
RK_TRACE (APP);
RKMDIWindow *w = static_cast<RKMDIWindow*> (currentWidget ());
@@ -192,6 +192,14 @@ void RKWorkplaceViewPane::currentPageChanged (int page) {
}
+// Create new splitter with default setup
+QSplitter *createSplitter (Qt::Orientation orientation) {
+ RK_TRACE (APP);
+
+ QSplitter* ret = new QSplitter (orientation);
+ ret->setChildrenCollapsible (false);
+ return ret;
+}
RKWorkplaceViewPane* RKWorkplaceView::createPane () {
RK_TRACE (APP);
@@ -314,19 +322,19 @@ void RKWorkplaceView::pageRight () {
void RKWorkplaceView::splitViewHoriz () {
RK_TRACE (APP);
- splitView (Qt::Vertical, activePane ());
+ splitView (Qt::Vertical);
}
void RKWorkplaceView::splitViewVert () {
RK_TRACE (APP);
- splitView (Qt::Horizontal, activePane ());
+ splitView (Qt::Horizontal);
}
// NOTE: Some of this function taken from kate's kateviewmanager.cpp
-RKWorkplaceViewPane* RKWorkplaceView::splitView (Qt::Orientation orientation, RKWorkplaceViewPane *pane, const QString &description, const QString &base) {
+void RKWorkplaceView::splitView (Qt::Orientation orientation, const QString &description, const QString &base) {
RK_TRACE (APP);
- if (!pane) pane = activePane ();
+ RKWorkplaceViewPane* pane = activePane ();
QString _description = description;
if (_description.isEmpty ()) {
@@ -343,7 +351,7 @@ RKWorkplaceViewPane* RKWorkplaceView::splitView (Qt::Orientation orientation, RK
QSplitter *splitter = qobject_cast<QSplitter *> (pane->parentWidget ());
if (!splitter) {
RK_ASSERT (splitter);
- return 0;
+ return;
}
setUpdatesEnabled (false);
@@ -371,8 +379,7 @@ RKWorkplaceViewPane* RKWorkplaceView::splitView (Qt::Orientation orientation, RK
splitter->insertWidget (index + 1, newpane);
} else {
- QSplitter *newsplitter = new QSplitter (orientation);
- newsplitter->setChildrenCollapsible (false);
+ QSplitter *newsplitter = createSplitter (orientation);
newsplitter->addWidget (pane);
newsplitter->addWidget (newpane);
splitter->insertWidget (index, newsplitter);
@@ -386,13 +393,10 @@ RKWorkplaceViewPane* RKWorkplaceView::splitView (Qt::Orientation orientation, RK
if (!RKWorkplace::mainWorkplace ()->restoreDocumentWindow (_description, base)) {
RKWorkplace::mainWorkplace ()->openHelpWindow (QUrl ("rkward://page/rkward_split_views"));
}
- RKWorkplaceViewPane *ret = newpane;
newpane = 0;
splitter->setSizes (sizes);
setUpdatesEnabled (true);
-
- return ret;
}
void RKWorkplaceView::addWindow (RKMDIWindow *widget) {
@@ -495,7 +499,86 @@ void RKWorkplaceView::setCaption (const QString &caption) {
emit (captionChanged (caption));
}
-void listContents (const QSplitter *parent, QVariantList *ret) {
+void RKWorkplaceView::restoreLayout(const QString& desc) {
+ RK_TRACE (APP);
+
+ QList<QSplitter*> parents;
+ parents.append (this);
+ QStringList dl = desc.split ('-');
+ if (dl.value (0) == QStringLiteral ("col")) setOrientation (Qt::Vertical);
+ else setOrientation (Qt::Horizontal);
+
+ for (int i = 1; i < dl.size () - 1; ++i) {
+ if (dl[i] == QStringLiteral ("p")) {
+ RKWorkplaceViewPane *pane = createPane ();
+ panes.append (pane);
+ parents.last ()->insertWidget (-1, pane);
+ } else if (dl[i] == QStringLiteral ("row")) {
+ QSplitter* newsplit = createSplitter (Qt::Horizontal);
+ parents.last ()->insertWidget (-1, newsplit);
+ parents.append (newsplit);
+ } else if (dl[i] == QStringLiteral ("col")) {
+ QSplitter* newsplit = createSplitter (Qt::Vertical);
+ parents.last ()->insertWidget (-1, newsplit);
+ parents.append (newsplit);
+ } else {
+ RK_ASSERT (dl[i] == QStringLiteral ("end"));
+ if (parents.isEmpty ()) {
+ RK_ASSERT (!parents.isEmpty ());
+ } else {
+ parents.pop_back ();
+ }
+ }
+ if (parents.isEmpty ()) {
+ RK_DEBUG (APP, DL_ERROR, "Bad specification while restoring workplace view layout");
+ }
+ }
+
+ newpane = panes.value (0);
+}
+
+void RKWorkplaceView::nextPane () {
+ RK_TRACE (APP);
+
+ RKWorkplaceViewPane *pane = activePane ();
+ int index = panes.indexOf (pane);
+ newpane = panes.value (index + 1);
+
+ RK_DEBUG (APP, DL_DEBUG, "Activating pane %p after pane %p (index %d / %d)", newpane, pane, index + 1, index);
+}
+
+void RKWorkplaceView::purgeEmptyPanes () {
+ RK_TRACE (APP);
+
+ newpane = 0; // just in case of broken specifications during workplace restoration
+ for (int i = 0; i < panes.count (); ++i) {
+ if (panes[i]->count () < 1) {
+ purgePane (panes[i]);
+ --i;
+ }
+ }
+}
+
+QString listLayout (const QSplitter *parent) {
+ RK_TRACE (APP);
+
+ QString ret = (parent->orientation () == Qt::Horizontal ? QStringLiteral ("row") : QStringLiteral ("col"));
+
+ for (int i = 0; i < parent->count (); ++i) {
+ QWidget* w = parent->widget (i);
+ RKWorkplaceViewPane *pane = qobject_cast<RKWorkplaceViewPane*> (w);
+ if (pane) {
+ ret.append (QStringLiteral ("-p"));
+ } else {
+ QSplitter* sub = qobject_cast<QSplitter*> (w);
+ ret.append ('-' + listLayout (sub));
+ }
+ }
+
+ return ret + QStringLiteral ("-end");
+}
+
+void listContents (const QSplitter *parent, QStringList *ret) {
RK_TRACE (APP);
for (int i = 0; i < parent->count (); ++i) {
@@ -503,24 +586,25 @@ void listContents (const QSplitter *parent, QVariantList *ret) {
RKWorkplaceViewPane *pane = qobject_cast<RKWorkplaceViewPane*> (w);
if (pane) {
for (int j = 0; j < pane->count (); ++j) {
- ret->append (QVariant::fromValue<QObject*> (pane->widget (j)));
+ QString desc = RKWorkplace::mainWorkplace ()->makeItemDescription (static_cast<RKMDIWindow*> (pane->widget (j)));
+ if (!desc.isEmpty ()) ret->append (desc);
}
+ ret->append (QStringLiteral ("pane_end::::"));
} else {
QSplitter* sub = qobject_cast<QSplitter*> (w);
listContents (sub, ret);
}
- if (i < parent->count () - 1) {
- if (parent->orientation () == Qt::Vertical) ret->append (QStringLiteral ("split::::vert"));
- else ret->append (QStringLiteral ("split::::horiz"));
- }
}
- ret->append (QStringLiteral ("split::::end"));
}
-QVariantList RKWorkplaceView::listContents () const {
+QString RKWorkplaceView::listLayout () const {
+ return (::listLayout (this));
+}
+
+QStringList RKWorkplaceView::listContents () const {
RK_TRACE (APP);
- QVariantList ret;
+ QStringList ret;
::listContents (this, &ret);
return ret;
}
diff --git a/rkward/windows/rkworkplaceview.h b/rkward/windows/rkworkplaceview.h
index 12be7455..0345d1e9 100644
--- a/rkward/windows/rkworkplaceview.h
+++ b/rkward/windows/rkworkplaceview.h
@@ -89,10 +89,16 @@ public:
/** initialize the window left/right actions */
void initActions (KActionCollection *ac);
-/** List the contents of the view, recursively. Windows are returned as pointers in the list, Splits are returned as strings "split::::horiz", "split::::vert", or "split::::end" (for end of current splitter) */
- QVariantList listContents () const;
-/** Public for use by RKWorkplace while restoring a workplace, only. @return the newly created pane */
- RKWorkplaceViewPane* splitView (Qt::Orientation orientation, RKWorkplaceViewPane *pane, const QString &description=QString (), const QString &base=QString ());
+/** List the contents of the view, recursively. @see RKWorkplace::makeItemDescription() */
+ QStringList listContents () const;
+/** List the layout of the view, recursively. @see RKWorkplace::makeItemDescription() */
+ QString listLayout () const;
+/** For use during workplace restoration, only: Make the next pane the active one, so it can be filled with content. @see restoreLayout */
+ void nextPane ();
+/** For use during workplace restoration, only: Set up splitters and panes according to the given description (generated by listContents()) */
+ void restoreLayout (const QString& desc);
+/** For use right after workplace restoration: Purge any panes set up by restoreLayout(), but left empty */
+ void purgeEmptyPanes ();
signals:
/** a new page / window was activated
@param widget the newly activated window */
@@ -117,6 +123,7 @@ private:
void updateActions ();
RKWorkplaceViewPane *createPane ();
RKWorkplaceViewPane *findWindow (RKMDIWindow *window) const;
+ void splitView (Qt::Orientation orientation, const QString &description=QString (), const QString &base=QString ());
QAction *action_page_left;
QAction *action_page_right;
More information about the rkward-tracker
mailing list