[rkward/work/optionset_experiments] rkward: Accordion control is starting to look usable (but still unfinished and with many quirks).
Thomas Friedrichsmeier
thomas.friedrichsmeier at ruhr-uni-bochum.de
Mon Oct 26 19:14:18 UTC 2015
Git commit 41eaaa05b9c48292528d01170eddad5f5b41c5ca by Thomas Friedrichsmeier.
Committed on 26/10/2015 at 19:13.
Pushed by tfry into branch 'work/optionset_experiments'.
Accordion control is starting to look usable (but still unfinished and with many quirks).
M +84 -20 rkward/misc/rkaccordiontable.cpp
M +10 -1 rkward/misc/rkaccordiontable.h
M +12 -3 rkward/plugin/rkoptionset.cpp
M +1 -0 rkward/plugin/rkoptionset.h
http://commits.kde.org/rkward/41eaaa05b9c48292528d01170eddad5f5b41c5ca
diff --git a/rkward/misc/rkaccordiontable.cpp b/rkward/misc/rkaccordiontable.cpp
index daa8f73..3506fb4 100644
--- a/rkward/misc/rkaccordiontable.cpp
+++ b/rkward/misc/rkaccordiontable.cpp
@@ -20,7 +20,14 @@
#include <QPointer>
#include <QVBoxLayout>
#include <QAbstractProxyModel>
+#include <QToolButton>
+#include <QHBoxLayout>
+
#include <kvbox.h>
+#include <klocale.h>
+
+#include "rkcommonfunctions.h"
+#include "rkstandardicons.h"
#include "../debug.h"
@@ -86,9 +93,10 @@ public:
void setSourceModel (QAbstractItemModel* source_model) {
/* More than these would be needed for a proper proxy of any model, but in our case, we only have to support the RKOptionsetDisplayModel */
- connect (source_model, SIGNAL (rowsInserted(const QModelIndex&,int,int)), this, SLOT (rowsInserted(QModelIndex,int,int)));
- connect (source_model, SIGNAL (rowsRemoved(const QModelIndex&,int,int)), this, SLOT (rowsRemoved(QModelIndex,int,int)));
- connect (source_model, SIGNAL (layoutChanged()), this, SLOT (relayLayoutChange()));
+ connect (source_model, SIGNAL (rowsInserted(const QModelIndex&,int,int)), this, SLOT (r_rowsInserted(QModelIndex,int,int)));
+ connect (source_model, SIGNAL (rowsRemoved(const QModelIndex&,int,int)), this, SLOT (r_rowsRemoved(QModelIndex,int,int)));
+ connect (source_model, SIGNAL (dataChanged(QModelIndex,QModelIndex)), this, SLOT (r_dataChanged(QModelIndex,QModelIndex)));
+ connect (source_model, SIGNAL (layoutChanged()), this, SLOT (r_layoutChanged()));
QAbstractProxyModel::setSourceModel (source_model);
}
@@ -98,27 +106,29 @@ public:
static const quint32 real_item_id = 0xFFFFFFFF;
public slots:
- void rowsInserted (const QModelIndex& parent, int start, int end) {
+ void r_rowsInserted (const QModelIndex& parent, int start, int end) {
RK_TRACE (MISC);
RK_ASSERT (!parent.isValid ());
beginInsertRows (mapFromSource (parent), start, end);
endInsertRows ();
}
- void rowsRemoved (const QModelIndex& parent, int start, int end) {
+ void r_rowsRemoved (const QModelIndex& parent, int start, int end) {
RK_TRACE (MISC);
RK_ASSERT (!parent.isValid ());
beginRemoveRows (mapFromSource (parent), start, end);
endRemoveRows ();
}
- void relayLayoutChange () {
+ void r_dataChanged (const QModelIndex& from, const QModelIndex& to) {
+ emit (dataChanged (mapFromSource (from), mapFromSource (to)));
+ }
+ void r_layoutChanged () {
RK_DEBUG (MISC, DL_ERROR, "reset");
emit (layoutChanged());
}
};
-
/** Protects the given child widget from deletion */
class RKWidgetGuard : public QWidget {
public:
@@ -145,16 +155,21 @@ private:
QWidget *fallback_parent;
};
-#include <QLabel>
+#include <QScrollBar>
+#include <QHeaderView>
RKAccordionTable::RKAccordionTable (QWidget* parent) : QTreeView (parent) {
RK_TRACE (MISC);
+ show_add_remove_buttons = false;
default_widget = new KVBox;
- new QLabel ("This is the content\nExcept it's just a dummy!!!!!!!!!!!!!!!", default_widget);
- setSelectionBehavior (SelectRows);
- setSelectionMode (SingleSelection);
+ setSelectionMode (NoSelection);
+ setIndentation (0);
+ setExpandsOnDoubleClick (false); // we expand on single click, instead
+ setSizePolicy (QSizePolicy::MinimumExpanding, QSizePolicy::MinimumExpanding);
+ setViewportMargins (20, 0, 0, 0);
pmodel = new RKAccordionDummyModel (this);
connect (this, SIGNAL (expanded(QModelIndex)), this, SLOT (rowExpanded(QModelIndex)));
+ connect (this, SIGNAL (clicked(QModelIndex)), this, SLOT (rowClicked(QModelIndex)));
}
RKAccordionTable::~RKAccordionTable () {
@@ -163,14 +178,21 @@ RKAccordionTable::~RKAccordionTable () {
delete default_widget;
}
-void RKAccordionTable::currentChanged (const QModelIndex& current, const QModelIndex& previous) {
+QSize RKAccordionTable::minimumSizeHint () const {
+ RK_TRACE (MISC);
+
+ QSize min = default_widget->minimumSize ();
+ min.setHeight (min.height () + horizontalScrollBar ()->minimumSizeHint ().height () + sizeHintForRow (0) * 4);
+ min.setWidth (qMax (min.width (), QTreeView::minimumSizeHint ().width ()));
+ return min;
+}
+
+void RKAccordionTable::rowClicked (QModelIndex row) {
RK_TRACE (MISC);
- RK_ASSERT (current.isValid ());
- Q_UNUSED (previous);
-// TODO: needed?
- return;
- if (!isExpanded (current)) {
- expand (current);
+
+ row = model ()->index (row.row (), 0, row.parent ()); // Fix up index to point to column 0, or isExpanded() will always return false
+ if (!row.parent ().isValid ()) {
+ setExpanded (row, !isExpanded (row));
}
}
@@ -178,10 +200,46 @@ void RKAccordionTable::rowExpanded (QModelIndex row) {
RK_TRACE (MISC);
for (int i = 0; i < model ()->rowCount (); ++i) {
- if (i != row.row ()) setExpanded (model ()->index (i, 0), false);
+ if (i != row.row ()) {
+ setIndexWidget (model ()->index (0, 0, model ()->index (i, 0)), 0);
+ setExpanded (model ()->index (i, 0), false);
+ }
}
setFirstColumnSpanned (0, row, true);
setIndexWidget (model ()->index (0, 0, row), new RKWidgetGuard (0, default_widget, this));
+ setCurrentIndex (row);
+ emit (activated (row.row ()));
+}
+
+void RKAccordionTable::updateWidget () {
+ RK_TRACE (MISC);
+
+ bool seen_expanded = false;
+ for (int i = 0; i < model ()->rowCount (); ++i) {
+ QModelIndex row = model ()->index (i, 0);
+ if (isExpanded (row) && !seen_expanded) {
+ rowExpanded (row);
+ seen_expanded = true;
+ }
+
+ if (show_add_remove_buttons && (indexWidget (row) == 0)) {
+ QWidget *display_buttons = new QWidget;
+ QHBoxLayout *layout = new QHBoxLayout (display_buttons);
+ layout->setContentsMargins (0, 0, 0, 0);
+ layout->setSpacing (0);
+ QToolButton *add_button = new QToolButton (display_buttons);
+ add_button->setIcon (RKStandardIcons::getIcon (RKStandardIcons::ActionInsertRow));
+ RKCommonFunctions::setTips (i18n ("Add a row / element"), add_button);
+ QToolButton *remove_button = new QToolButton (display_buttons);
+ remove_button->setIcon (RKStandardIcons::getIcon (RKStandardIcons::ActionDeleteRow));
+ RKCommonFunctions::setTips (i18n ("Remove a row / element"), remove_button);
+ layout->addWidget (add_button);
+ layout->addWidget (remove_button);
+ setIndexWidget (row, display_buttons);
+ }
+ }
+
+ if (show_add_remove_buttons) header ()->setResizeMode (0, QHeaderView::ResizeToContents);
}
void RKAccordionTable::setModel (QAbstractItemModel* model) {
@@ -189,6 +247,9 @@ void RKAccordionTable::setModel (QAbstractItemModel* model) {
pmodel->setSourceModel (model);
QTreeView::setModel (pmodel);
+ connect (pmodel, SIGNAL (layoutChanged()), this, SLOT (updateWidget()));
+ connect (pmodel, SIGNAL (rowsInserted(const QModelIndex&,int,int)), this, SLOT (updateWidget()));
+ connect (pmodel, SIGNAL (rowsRemoved(const QModelIndex&,int,int)), this, SLOT (updateWidget()));
if (pmodel->rowCount () > 0) expand (pmodel->index (0, 0));
}
@@ -199,8 +260,11 @@ void RKAccordionTable::resizeEvent (QResizeEvent* event) {
}
// TODO
-// - add buttons to each row
+// - add buttons to each row (in correct size)
// - handle resize
+// - fix initial size
+// - margins
+// - handle row insertions / removals correctly
// KF5 TODO: remove:
#include "rkaccordiontable.moc"
#include "rkaccordiontablemodel_moc.cpp"
diff --git a/rkward/misc/rkaccordiontable.h b/rkward/misc/rkaccordiontable.h
index 7fc5530..5e68f54 100644
--- a/rkward/misc/rkaccordiontable.h
+++ b/rkward/misc/rkaccordiontable.h
@@ -33,12 +33,21 @@ public:
QWidget *defaultWidget () const { return default_widget; };
void setModel (QAbstractItemModel *model);
+ void setShowAddRemoveButtons (bool show) {
+ show_add_remove_buttons = show;
+ }
+
+ QSize minimumSizeHint () const; // reimplemented to assure a proper size for the content
public slots:
void rowExpanded (QModelIndex row);
+ void rowClicked (QModelIndex row);
+ void updateWidget ();
+signals:
+ void activated (int row);
protected:
- void currentChanged (const QModelIndex& current, const QModelIndex& previous); // reimplemented to adjust selection / activate correct row
void resizeEvent (QResizeEvent* event); // reimplemented to make the current content widget stretch / shrink
private:
+ bool show_add_remove_buttons;
QWidget *default_widget;
QAbstractProxyModel *pmodel;
};
diff --git a/rkward/plugin/rkoptionset.cpp b/rkward/plugin/rkoptionset.cpp
index 6b12b95..13d4737 100644
--- a/rkward/plugin/rkoptionset.cpp
+++ b/rkward/plugin/rkoptionset.cpp
@@ -56,7 +56,10 @@ RKOptionSet::RKOptionSet (const QDomElement &element, RKComponent *parent_compon
if (exp_mode != Detached) layout->addWidget (switcher);
user_area = new KVBox (this);
switcher->addWidget (user_area);
- if (exp_mode == Accordion) accordion = new RKAccordionTable (user_area);
+ if (exp_mode == Accordion) {
+ accordion = new RKAccordionTable (user_area);
+ connect (accordion, SIGNAL(activated(int)), this, SLOT(currentRowChanged(int)));
+ }
updating_notice = new QLabel (i18n ("Updating status, please wait"), this);
switcher->addWidget (updating_notice);
update_timer.setInterval (0);
@@ -188,6 +191,7 @@ RKOptionSet::RKOptionSet (const QDomElement &element, RKComponent *parent_compon
connect (remove_button, SIGNAL (clicked()), this, SLOT (removeRow()));
}
}
+ if (!keycolumn && (exp_mode == Accordion)) accordion->setShowAddRemoveButtons (true);
}
RKOptionSet::~RKOptionSet () {
@@ -759,8 +763,13 @@ void RKOptionSet::currentRowChanged () {
RK_TRACE (PLUGIN);
RK_ASSERT (display);
- int r = getCurrentRowFromDisplay (display);
- if (active_row != r) current_row->setIntValue (r);
+ currentRowChanged (getCurrentRowFromDisplay (display));
+}
+
+void RKOptionSet::currentRowChanged (int row) {
+ RK_TRACE (PLUGIN);
+
+ if (active_row != row) current_row->setIntValue (row);
// --> currentRowPropertyChanged ()
}
diff --git a/rkward/plugin/rkoptionset.h b/rkward/plugin/rkoptionset.h
index aa2e949..095190f 100644
--- a/rkward/plugin/rkoptionset.h
+++ b/rkward/plugin/rkoptionset.h
@@ -55,6 +55,7 @@ private slots:
void addRow ();
void removeRow ();
void currentRowChanged ();
+ void currentRowChanged (int row);
void fetchDefaults ();
void slotUpdateUnfinishedRows ();
/** When keys in the key column change, all other columns have to be updated, accordingly. */
More information about the rkward-tracker
mailing list