[rkward/work/split_views] /: Fix saving and restoring split layout, including relative sizes.
Thomas Friedrichsmeier
null at kde.org
Wed Jun 21 13:36:03 UTC 2017
Git commit 613fadc78af272d3ddd8b52a8910b632e45874eb by Thomas Friedrichsmeier.
Committed on 21/06/2017 at 13:35.
Pushed by tfry into branch 'work/split_views'.
Fix saving and restoring split layout, including relative sizes.
M +1 -0 ChangeLog
M +59 -19 rkward/windows/rkworkplaceview.cpp
M +2 -2 rkward/windows/rkworkplaceview.h
https://commits.kde.org/rkward/613fadc78af272d3ddd8b52a8910b632e45874eb
diff --git a/ChangeLog b/ChangeLog
index 1cdb1835..d5b3ee01 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,6 @@
TODO: Workplace save as does not as for overwrite confirmation
+- Implement "split view" feature, allowing to partion the main window, and to hvae several views of the same files / data side-by-side
- 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/rkworkplaceview.cpp b/rkward/windows/rkworkplaceview.cpp
index 0ac5218b..04d76728 100644
--- a/rkward/windows/rkworkplaceview.cpp
+++ b/rkward/windows/rkworkplaceview.cpp
@@ -201,10 +201,11 @@ QSplitter *createSplitter (Qt::Orientation orientation) {
return ret;
}
-RKWorkplaceViewPane* RKWorkplaceView::createPane () {
+RKWorkplaceViewPane* RKWorkplaceView::createPane (bool init_actions) {
RK_TRACE (APP);
newpane = new RKWorkplaceViewPane (this);
QObject::connect (newpane, &RKWorkplaceViewPane::becameEmpty, this, &RKWorkplaceView::purgePane);
+ if (init_actions) newpane->initActions ();
return newpane;
}
@@ -212,7 +213,7 @@ RKWorkplaceView::RKWorkplaceView (QWidget *parent) : QSplitter (parent) {
RK_TRACE (APP);
newpane = 0;
- RKWorkplaceViewPane *pane = createPane ();
+ RKWorkplaceViewPane *pane = createPane (false);
addWidget (pane);
panes.append (pane);
setChildrenCollapsible (false);
@@ -266,9 +267,7 @@ void RKWorkplaceView::initActions (KActionCollection *ac) {
connect (action_split_horiz, &QAction::triggered, this, &RKWorkplaceView::splitViewHoriz);
action_split_horiz->setWhatsThis (i18n ("Split the currently active view into two views, horizontally."));
- for (int i = 0; i < panes.size (); ++i) {
- panes[i]->initActions ();
- }
+ panes.first ()->initActions ();
updateActions ();
}
@@ -363,7 +362,6 @@ void RKWorkplaceView::splitView (Qt::Orientation orientation, const QString &des
newpane = createPane ();
panes.insert (lindex + 1, newpane);
- newpane->initActions ();
// If there is only one child (left) in the current splitter, we can just set the orientation as needed.
if (splitter->count () == 1) {
@@ -502,39 +500,75 @@ void RKWorkplaceView::setCaption (const QString &caption) {
void RKWorkplaceView::restoreLayout(const QString& desc) {
RK_TRACE (APP);
+ bool old_updates_enabled = updatesEnabled ();
+ setUpdatesEnabled (false);
+
+ QList<RKMDIWindow*> windows_to_readd;
+ // It is probably not a good idea to restore the layout while merging workplaces, i.e. without closing existing windows, first.
+ // However, we'll do our best to cope... For this, we clear out all splitters, first.
+ for (int i = 0; i < panes.count (); ++i) {
+ while (panes[i]->count ()) {
+ RKMDIWindow *win = static_cast<RKMDIWindow*> (panes[i]->widget (0));
+ panes[i]->removeTab (0);
+ windows_to_readd.append (win);
+ win->hide ();
+ win->setParent (0);
+ }
+ }
+ while (count ()) {
+ delete (widget (0));
+ }
+ panes.clear ();
+
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) {
+ for (int i = 1; i < dl.size (); ++i) {
+ if (parents.isEmpty ()) {
+ RK_DEBUG (APP, DL_ERROR, "Bad specification while restoring workplace view layout");
+ break;
+ }
if (dl[i] == QStringLiteral ("p")) {
RKWorkplaceViewPane *pane = createPane ();
+ pane = createPane ();
panes.append (pane);
- parents.last ()->insertWidget (-1, pane);
+ parents.last ()->addWidget (pane);
} else if (dl[i] == QStringLiteral ("row")) {
QSplitter* newsplit = createSplitter (Qt::Horizontal);
- parents.last ()->insertWidget (-1, newsplit);
+ parents.last ()->addWidget (newsplit);
parents.append (newsplit);
} else if (dl[i] == QStringLiteral ("col")) {
QSplitter* newsplit = createSplitter (Qt::Vertical);
- parents.last ()->insertWidget (-1, newsplit);
+ parents.last ()->addWidget (newsplit);
parents.append (newsplit);
} else {
- RK_ASSERT (dl[i] == QStringLiteral ("end"));
- if (parents.isEmpty ()) {
- RK_ASSERT (!parents.isEmpty ());
- } else {
- parents.pop_back ();
+ RK_ASSERT (dl[i].startsWith (QStringLiteral ("end")));
+ const QStringList s = dl[i].mid (4).split (',');
+ QList<int> sizes = parents.last ()->sizes (); // simply to have an initialized list of the correct length
+ for (int i = 0; i < sizes.count (); ++i) {
+ int size = qMax (50, s.value (i).toInt ()); // avoid collapsed views in case of errors
+ sizes[i] = size;
}
- }
- if (parents.isEmpty ()) {
- RK_DEBUG (APP, DL_ERROR, "Bad specification while restoring workplace view layout");
+ parents.last ()->setSizes (sizes);
+ parents.pop_back ();
}
}
+ if (panes.isEmpty ()) {
+ panes.append (createPane ());
+ addWidget (panes[0]);
+ }
+
newpane = panes.value (0);
+
+ for (int i = 0; i < windows_to_readd.count (); ++i) {
+ addWindow (windows_to_readd[i]);
+ }
+
+ setUpdatesEnabled (old_updates_enabled);
}
void RKWorkplaceView::nextPane () {
@@ -575,7 +609,13 @@ QString listLayout (const QSplitter *parent) {
}
}
- return ret + QStringLiteral ("-end");
+ ret.append (QStringLiteral ("-end"));
+ const QList<int> sizes = parent->sizes ();
+ for (int i = 0; i < sizes.count (); ++i) {
+ ret.append (',' + QString::number (sizes[i]));
+ }
+
+ return ret;
}
void listContents (const QSplitter *parent, QStringList *ret) {
diff --git a/rkward/windows/rkworkplaceview.h b/rkward/windows/rkworkplaceview.h
index 0345d1e9..2d0ab0e0 100644
--- a/rkward/windows/rkworkplaceview.h
+++ b/rkward/windows/rkworkplaceview.h
@@ -72,7 +72,7 @@ public:
/** add the given window to the view */
void addWindow (RKMDIWindow *widget);
-/** remove the given window to the view
+/** remove the given window from the view
@param destroyed if the window is already destroyed, set this to true */
void removeWindow (RKMDIWindow *widget, bool destroyed=false);
/** does this window exist in the view? */
@@ -121,7 +121,7 @@ private slots:
void splitViewHoriz ();
private:
void updateActions ();
- RKWorkplaceViewPane *createPane ();
+ RKWorkplaceViewPane *createPane (bool init_actions = true);
RKWorkplaceViewPane *findWindow (RKMDIWindow *window) const;
void splitView (Qt::Orientation orientation, const QString &description=QString (), const QString &base=QString ());
More information about the rkward-tracker
mailing list