[rkward-cvs] SF.net SVN: rkward: [2194] branches/KDE4_port/rkward/dataeditor

tfry at users.sourceforge.net tfry at users.sourceforge.net
Fri Nov 9 18:47:04 UTC 2007


Revision: 2194
          http://rkward.svn.sourceforge.net/rkward/?rev=2194&view=rev
Author:   tfry
Date:     2007-11-09 10:47:04 -0800 (Fri, 09 Nov 2007)

Log Message:
-----------
Piecing back together the parts: CellEditor mostly working

Modified Paths:
--------------
    branches/KDE4_port/rkward/dataeditor/celleditor.cpp
    branches/KDE4_port/rkward/dataeditor/celleditor.h
    branches/KDE4_port/rkward/dataeditor/rkvareditmodel.cpp
    branches/KDE4_port/rkward/dataeditor/rkvareditmodel.h
    branches/KDE4_port/rkward/dataeditor/twintable.cpp
    branches/KDE4_port/rkward/dataeditor/twintablemember.cpp
    branches/KDE4_port/rkward/dataeditor/twintablemember.h

Modified: branches/KDE4_port/rkward/dataeditor/celleditor.cpp
===================================================================
--- branches/KDE4_port/rkward/dataeditor/celleditor.cpp	2007-11-09 15:25:13 UTC (rev 2193)
+++ branches/KDE4_port/rkward/dataeditor/celleditor.cpp	2007-11-09 18:47:04 UTC (rev 2194)
@@ -2,7 +2,7 @@
                           celleditor  -  description
                              -------------------
     begin                : Mon Sep 13 2004
-    copyright            : (C) 2004 by Thomas Friedrichsmeier
+    copyright            : (C) 2004, 2007 by Thomas Friedrichsmeier
     email                : tfry at users.sourceforge.net
  ***************************************************************************/
 
@@ -17,105 +17,105 @@
 #include "celleditor.h"
 
 #include <qapplication.h>
-#include <q3popupmenu.h>
-#include <qstyle.h>
+#include <QMenu>
+#include <QTimer>
+
 //Added by qt3to4:
 #include <QEvent>
-#include <Q3Frame>
 #include <QTimerEvent>
 #include <QKeyEvent>
 
-#include "twintablemember.h"
 #include "../debug.h"
 
-CellEditor::CellEditor (TwinTableMember *parent, const QString &text, int mode, const RObject::ValueLabels *named_values) : QLineEdit (parent->viewport ()) {
+CellEditor::CellEditor (QWidget* parent) : QLineEdit (parent) {
 	RK_TRACE (EDITOR);
-	
-	table = parent;
-	
-	setText (text);
+
 	setFrame (false);
-	selectAll ();
-	
-	timer_id = 0;
-	if (named_values) {
-		value_list = new Q3PopupMenu ();
-		value_list->setFont (font ());
-		value_list->setPalette (palette ());
-		value_list->setFrameStyle (Q3Frame::Box | Q3Frame::Plain);
-		value_list->setLineWidth (1);
-		value_list->setFocusProxy (this);
-		
-		connect(value_list, SIGNAL (activated (int)), SLOT (selectedFromList (int)));
-		
-		int i=0;
-		for (RObject::ValueLabels::const_iterator it = named_values->constBegin (); it != named_values->constEnd (); ++it) {
-			popup_values.insert (value_list->insertItem (it.key () + ": " + it.data (), i), &(it.key ()));
-			i++;
-		}
-		
-		timer_id = startTimer (200);
-	} else {
-		value_list = 0;
-	}
+
+	value_list = 0;
 }
 
 CellEditor::~CellEditor () {
 	RK_TRACE (EDITOR);
-	if (value_list) {
-		value_list->setFocusProxy (0);
-		delete value_list;
+}
+
+void CellEditor::setValueLabels (const RObject::ValueLabels *labels) {
+	RK_TRACE (EDITOR);
+	RK_ASSERT (labels);
+
+// NOTE: not using a QComboBox, as we do not want it to pop up immediately
+	value_list = new QMenu (this);
+	value_list->setFont (font ());
+	value_list->setPalette (palette ());
+//	value_list->setFrameStyle (Q3Frame::Box | Q3Frame::Plain);
+//	value_list->setLineWidth (1);
+	value_list->setFocusProxy (this);
+	value_list->installEventFilter (this);
+
+	for (RObject::ValueLabels::const_iterator it = labels->constBegin (); it != labels->constEnd (); ++it) {
+		value_list->addAction (it.key () + ": " + it.data ())->setData (it.key ());
 	}
+	connect (value_list, SIGNAL (triggered(QAction*)), SLOT (selectedFromList(QAction*)));
+
+	QTimer::singleShot (200, this, SLOT (showValueLabels ()));
 }
 
-void CellEditor::selectedFromList (int id) {
+void CellEditor::selectedFromList (QAction* action) {
 	RK_TRACE (EDITOR);
-	setText (*popup_values[id]);
+	RK_ASSERT (action);
+
+	setText (action->data ().toString ());	// which is an int, really
 }
 
-void CellEditor::timerEvent (QTimerEvent *e) {
-	if (e->timerId () != timer_id) {
-		QLineEdit::timerEvent (e);
-		return;
-	}
+void CellEditor::setText (const QString& text) {
 	RK_TRACE (EDITOR);
-	
+
+	QLineEdit::setText (text);
+	selectAll ();
+}
+
+void CellEditor::showValueLabels () {
+	RK_TRACE (EDITOR);
 	RK_ASSERT (value_list);
-	
+
 	QPoint pos = mapToGlobal (QPoint (5, height ()+5));
-
 	value_list->popup (QPoint (pos));
-	
-	killTimer (timer_id);
-	timer_id = 0;
 }
 
-bool CellEditor::event (QEvent *e) {
-	if (e->type () == QEvent::KeyPress) {
-		QKeyEvent *kev = static_cast<QKeyEvent *> (e);
-		if ((kev->key () == Qt::Key_Tab) || (kev->key () == Qt::Key_BackTab)) {
-			table->keyPressEvent (kev);
-			return true;
-		}
-	}
-	return QLineEdit::event (e);
-}
-
 void CellEditor::keyPressEvent (QKeyEvent *e) {
 	if (!e->state ()) {
 		if (e->key () == Qt::Key_Left) {
 			if (cursorPosition () < 1) {
-				table->keyPressEvent (e);
+				emit (done (this, RKItemDelegate::EditorExitLeft));
 				return;
 			}
-		} else if (e->key () == Qt::Key_Right) {
+		}
+		if (e->key () == Qt::Key_Right) {
 			if (cursorPosition () >= (int) text ().length ()) {
-				table->keyPressEvent (e);
+				emit (done (this, RKItemDelegate::EditorExitRight));
 				return;
 			}
 		}
+		if (e->key () == Qt::Key_Up) {
+			emit (done (this, RKItemDelegate::EditorExitUp));
+			return;
+		}
+		if (e->key () == Qt::Key_Down) {
+			emit (done (this, RKItemDelegate::EditorExitDown));
+			return;
+		}
 	}
 	QLineEdit::keyPressEvent (e);
 }
 
+bool CellEditor::eventFilter (QObject* object, QEvent* e) {
+	if (object && (object == value_list)) {
+		if (e->type() == QEvent::KeyPress) {
+			RK_TRACE (EDITOR);
+			return event (e);
+		}
+	}
+	return false;
+}
+
 #include "celleditor.moc"

Modified: branches/KDE4_port/rkward/dataeditor/celleditor.h
===================================================================
--- branches/KDE4_port/rkward/dataeditor/celleditor.h	2007-11-09 15:25:13 UTC (rev 2193)
+++ branches/KDE4_port/rkward/dataeditor/celleditor.h	2007-11-09 18:47:04 UTC (rev 2194)
@@ -2,7 +2,7 @@
                           celleditor  -  description
                              -------------------
     begin                : Mon Sep 13 2004
-    copyright            : (C) 2004 by Thomas Friedrichsmeier
+    copyright            : (C) 2004, 2007 by Thomas Friedrichsmeier
     email                : tfry at users.sourceforge.net
  ***************************************************************************/
 
@@ -18,18 +18,16 @@
 #define CELLEDITOR_H
 
 #include <qlineedit.h>
-#include <q3intdict.h>
+#include <QList>
 //Added by qt3to4:
 #include <QKeyEvent>
 #include <QEvent>
-#include <QTimerEvent>
-#include <Q3PopupMenu>
 
 #include "../core/robject.h"
+#include "twintablemember.h"
 
 class QStringList;
-class Q3PopupMenu;
-class TwinTableMember;
+class QMenu;
 
 /**
 This is the main editor used in the TwinTableMembers
@@ -42,22 +40,23 @@
 class CellEditor : public QLineEdit {
 Q_OBJECT
 public:
-	CellEditor (TwinTableMember* parent, const QString &text, int mode, const RObject::ValueLabels *named_values=0);
+	CellEditor (QWidget* parent);
+	~CellEditor ();
 
-	~CellEditor();
+	void setValueLabels (const RObject::ValueLabels *labels);
+
+	void setText (const QString& text);
+signals:
+	void done (QWidget* widget, RKItemDelegate::EditorDoneReason reason);
 public slots:
-	void selectedFromList (int id);
+	void selectedFromList (QAction* action);
+	void showValueLabels ();
 protected:
-/// for showing/hiding list of name_values
-	void timerEvent (QTimerEvent *e);
 /// reimplemented to ignore arrow left/right if at the beginning/end
 	void keyPressEvent (QKeyEvent *e);
-/// needed to catch Tab-keypresses (not usually sent to keyPressEvent) and relay those to the parent
-	bool event (QEvent *e);
+	bool eventFilter (QObject* object, QEvent* event);
 private:
-	Q3PopupMenu *value_list;
-	int timer_id;
-	Q3IntDict<QString> popup_values;
+	QMenu *value_list;
 	TwinTableMember *table;
 };
 

Modified: branches/KDE4_port/rkward/dataeditor/rkvareditmodel.cpp
===================================================================
--- branches/KDE4_port/rkward/dataeditor/rkvareditmodel.cpp	2007-11-09 15:25:13 UTC (rev 2193)
+++ branches/KDE4_port/rkward/dataeditor/rkvareditmodel.cpp	2007-11-09 18:47:04 UTC (rev 2194)
@@ -44,6 +44,16 @@
 	for (int i = objects.size () - 1; i >= 0; --i) stopListenForObject (objects[i]);
 }
 
+RKVariable* RKVarEditModel::getObject (int index) const {
+	RK_TRACE (EDITOR);
+
+	if (index >= trueCols ()) {
+		RK_ASSERT (false);
+		return 0;
+	}
+	return objects[index];
+}
+
 void RKVarEditModel::addObject (int index, RKVariable* object) {
 	RK_TRACE (EDITOR);
 	RK_ASSERT (object);

Modified: branches/KDE4_port/rkward/dataeditor/rkvareditmodel.h
===================================================================
--- branches/KDE4_port/rkward/dataeditor/rkvareditmodel.h	2007-11-09 15:25:13 UTC (rev 2193)
+++ branches/KDE4_port/rkward/dataeditor/rkvareditmodel.h	2007-11-09 18:47:04 UTC (rev 2194)
@@ -85,14 +85,16 @@
 
 	void objectMetaChanged (RObject* changed);
 	void objectDataChanged (RObject* object, const RObject::ChangeSet *changes);
+
+	RKVariable* getObject (int index) const;
 protected:
 friend class RKVarEditMetaModel;
 	QList<RKVariable*> objects;
 
 	/** very simple convenience function to return the number of true cols + trailing cols */
-	int apparentCols () const { return objects.size () + trailing_cols; };
+	int apparentCols () const { return (trueCols () + trailing_cols); };
 	/** very simple convenience function to return the number of true rows + trailing rows */
-	int apparentRows () const { return (trailing_rows + (objects.isEmpty () ? 0 : objects[0]->getLength ())); };
+	int apparentRows () const { return (trueRows () + trailing_rows); };
 
 	/** Receives notifications of object removals. Takes care of removing the object from the list. */
 	void objectRemoved (RObject* object);
@@ -139,6 +141,8 @@
 
 	int trueCols () const { return data_model->trueCols (); };
 	int trueRows () const { return RowCount; };
+
+	RKVariable* getObject (int index) const { return data_model->getObject (index); };
 protected:
 friend class RKVarEditModel;
 	RKVarEditMetaModel (RKVarEditModel* data_model);

Modified: branches/KDE4_port/rkward/dataeditor/twintable.cpp
===================================================================
--- branches/KDE4_port/rkward/dataeditor/twintable.cpp	2007-11-09 15:25:13 UTC (rev 2193)
+++ branches/KDE4_port/rkward/dataeditor/twintable.cpp	2007-11-09 18:47:04 UTC (rev 2194)
@@ -91,8 +91,9 @@
 	RK_TRACE (EDITOR);
 
 	datamodel = model;
-	dataview->setModel (model);
-	metaview->setModel (model->getMetaModel ());
+	dataview->setRKModel (model);
+	metaview->setRKModel (model->getMetaModel ());
+	dataview->seRKItemDelegate (new RKItemDelegate (this, datamodel));
 
 	metaview->setMinimumHeight (metaview->horizontalHeader ()->height ());
 	metaview->setMaximumHeight (metaview->rowHeight (0) * 5 + metaview->horizontalHeader ()->height () + 5);

Modified: branches/KDE4_port/rkward/dataeditor/twintablemember.cpp
===================================================================
--- branches/KDE4_port/rkward/dataeditor/twintablemember.cpp	2007-11-09 15:25:13 UTC (rev 2193)
+++ branches/KDE4_port/rkward/dataeditor/twintablemember.cpp	2007-11-09 18:47:04 UTC (rev 2194)
@@ -59,8 +59,15 @@
 	RK_TRACE (EDITOR);
 	mymodel = model;
 	setModel (model);
-};
+}
 
+void TwinTableMember::seRKItemDelegate (RKItemDelegate* delegate) {
+	RK_TRACE (EDITOR);
+
+	setItemDelegate (delegate);
+	connect (delegate, SIGNAL (doCloseEditor(QWidget*,RKItemDelegate::EditorDoneReason)), this, SLOT (editorDone(QWidget*,RKItemDelegate::EditorDoneReason)));
+}
+
 void TwinTableMember::setTwin (TwinTableMember * new_twin) {
 	RK_TRACE (EDITOR);
 	twin = new_twin;
@@ -76,6 +83,24 @@
 	if (!selected.isEmpty ()) twin->clearSelection ();
 }
 
+void TwinTableMember::editorDone (QWidget* editor, RKItemDelegate::EditorDoneReason reason) {
+	RK_TRACE (EDITOR);
+
+	int row = currentIndex ().row ();
+	int col = currentIndex ().column ();
+
+	closeEditor (editor, QAbstractItemDelegate::NoHint);
+
+	if (reason == RKItemDelegate::EditorExitRight) ++col;
+	else if (reason == RKItemDelegate::EditorExitLeft) --col;
+	else if (reason == RKItemDelegate::EditorExitUp) --row;
+	else if (reason == RKItemDelegate::EditorExitDown) ++row;
+
+	if ((row < mymodel->rowCount ()) && (col < mymodel->columnCount ())) {
+		setCurrentIndex (mymodel->index (row, col));
+	}
+}
+
 void TwinTableMember::editorLostFocus () {
 	RK_TRACE (EDITOR);
 	stopEditing ();
@@ -211,10 +236,20 @@
 
 /////////////////// RKItemDelegate /////////////////////
 
-RKItemDelegate::RKItemDelegate (QObject *parent) : QItemDelegate (parent) {
+RKItemDelegate::RKItemDelegate (QObject *parent, RKVarEditModel* datamodel) : QItemDelegate (parent) {
 	RK_TRACE (EDITOR);
+
+	RKItemDelegate::datamodel = datamodel;
+	metamodel = 0;
 }
 
+RKItemDelegate::RKItemDelegate (QObject *parent, RKVarEditMetaModel* metamodel) : QItemDelegate (parent) {
+	RK_TRACE (EDITOR);
+
+	RKItemDelegate::metamodel = metamodel;
+	datamodel = 0;
+}
+
 RKItemDelegate::~RKItemDelegate () {
 	RK_TRACE (EDITOR);
 }
@@ -222,7 +257,17 @@
 QWidget* RKItemDelegate::createEditor (QWidget* parent, const QStyleOptionViewItem& option, const QModelIndex& index) const {
 	RK_TRACE (EDITOR);
 
-	#warning implement
+	if (datamodel) {
+		CellEditor* ced = new CellEditor (parent);
+		ced->setFont (option.font);
+		connect (ced, SIGNAL (done(QWidget*,RKItemDelegate::EditorDoneReason)), this, SLOT (editorDone(QWidget*,RKItemDelegate::EditorDoneReason)));
+		return ced;
+	} else if (metamodel) {
+#warning implement
+	}
+
+	RK_ASSERT (false);
+	return 0;
 }
 
 void RKItemDelegate::setEditorData (QWidget* editor, const QModelIndex& index) const {
@@ -230,20 +275,63 @@
 
 	if (!index.isValid ()) return;
 
-//	CellEditor* ed = new CellEditor ();
-	#warning implement
+	if (datamodel) {
+		CellEditor* ced = static_cast<CellEditor*> (editor);
+		ced->setText (datamodel->data (index, Qt::EditRole).toString ());
+
+		RObject::ValueLabels* labels = 0;
+		if (index.column () < datamodel->trueCols ()) {
+			labels = datamodel->getObject (index.column ())->getValueLabels ();
+		}
+		if (labels) ced->setValueLabels (labels);
+
+	} else if (metamodel) {
+#warning implement
+	} else {
+		RK_ASSERT (false);
+	}
 }
 
 void RKItemDelegate::setModelData (QWidget* editor, QAbstractItemModel* model, const QModelIndex& index) const {
 	RK_TRACE (EDITOR);
 
-	#warning implement
+	if (!index.isValid ()) return;
+
+	if (datamodel) {
+		RK_ASSERT (model == datamodel);
+
+		CellEditor* ced = static_cast<CellEditor*> (editor);
+		model->setData (index, ced->text (), Qt::EditRole);
+	} else if (metamodel) {
+#warning implement
+	} else {
+		RK_ASSERT (false);
+	}
 }
 
-void RKItemDelegate::editorDone (QWidget* editor, EditorDoneReason) {
+bool RKItemDelegate::eventFilter (QObject* object, QEvent* event) {
 	RK_TRACE (EDITOR);
 
-	#warning implement
+	QWidget *editor = qobject_cast<QWidget*> (object);
+	if (!editor) return false;
+
+	if (event->type() == QEvent::KeyPress) {
+		QKeyEvent* ke = static_cast<QKeyEvent *> (event);
+		if (ke->key () == Qt::Key_Tab) editorDone (editor, EditorExitRight);
+		else if (ke->key () == Qt::Key_Tab) editorDone (editor, EditorExitRight);
+		else if (ke->key () == Qt::Key_Enter) editorDone (editor, EditorExitDown);
+		else if (ke->key () == Qt::Key_Return) editorDone (editor, EditorExitDown);
+		else return QItemDelegate::eventFilter (editor, event);
+		return true;
+	}
+	return QItemDelegate::eventFilter (editor, event);
 }
 
+void RKItemDelegate::editorDone (QWidget* editor, RKItemDelegate::EditorDoneReason reason) {
+	RK_TRACE (EDITOR);
+
+	emit (commitData (editor));
+	emit (doCloseEditor (editor, reason));
+}
+
 #include "twintablemember.moc"

Modified: branches/KDE4_port/rkward/dataeditor/twintablemember.h
===================================================================
--- branches/KDE4_port/rkward/dataeditor/twintablemember.h	2007-11-09 15:25:13 UTC (rev 2193)
+++ branches/KDE4_port/rkward/dataeditor/twintablemember.h	2007-11-09 18:47:04 UTC (rev 2194)
@@ -34,6 +34,41 @@
 
 #include "rkeditor.h"
 
+class RKVarEditMetaModel;
+class RKVarEditModel;
+
+/** Item delegate for TwinTableMembers.
+ at author Thomas Friedrichsmeier */
+class RKItemDelegate : public QItemDelegate {
+	Q_OBJECT
+public:
+	RKItemDelegate (QObject *parent, RKVarEditModel* datamodel);
+	RKItemDelegate (QObject *parent, RKVarEditMetaModel* metamodel);
+	~RKItemDelegate ();
+
+	QWidget* createEditor (QWidget* parent, const QStyleOptionViewItem& option, const QModelIndex& index) const;
+	void setEditorData (QWidget* editor, const QModelIndex& index) const;
+	void setModelData (QWidget* editor, QAbstractItemModel* model, const QModelIndex& index) const;
+	bool eventFilter (QObject* editor, QEvent* event);
+
+	enum EditorDoneReason {
+		EditorExitLeft,
+		EditorExitRight,
+		EditorExitUp,
+		EditorExitDown,
+		EditorExit
+	};
+signals:
+	// much like QAbstractItemDelegate::closeEditor(), but with our own flexible EndEditHint
+	void doCloseEditor (QWidget* editor, RKItemDelegate::EditorDoneReason);
+public slots:
+	void editorDone (QWidget* editor, RKItemDelegate::EditorDoneReason reason);
+private:
+	RKVarEditModel* datamodel;
+	RKVarEditMetaModel* metamodel;
+};
+
+
 /** One of the tables used in a TwinTable.
 @author Thomas Friedrichsmeier
 */
@@ -60,6 +95,7 @@
 	QItemSelectionRange getSelectionBoundaries ();
 
 	void setRKModel (RKVarEditModelBase* model);
+	void seRKItemDelegate (RKItemDelegate* delegate);
 signals:
 	void contextMenuRequest (int row, int col, const QPoint& pos);
 protected:
@@ -75,6 +111,8 @@
 friend class TwinTable;
 	void setTwin (TwinTableMember *new_twin);
 public slots:
+	void editorDone (QWidget* editor, RKItemDelegate::EditorDoneReason);
+
 	void editorLostFocus ();
 /** called when the current cell is changed. If no selection is in place, will (does not do it yet) pop up the value-list */
 //	void currentCellChanged (int row, int col);
@@ -84,29 +122,4 @@
 	void tableSelectionChanged (const QItemSelection& selected, const QItemSelection& deselected);
 };
 
-
-/** Item delegate for TwinTableMembers.
- at author Thomas Friedrichsmeier */
-class RKItemDelegate : QItemDelegate {
-	Q_OBJECT
-public:
-	RKItemDelegate (QObject *parent);
-	~RKItemDelegate ();
-
-	QWidget* createEditor (QWidget* parent, const QStyleOptionViewItem& option, const QModelIndex& index) const;
-	void setEditorData (QWidget* editor, const QModelIndex& index) const;
-	void setModelData (QWidget* editor, QAbstractItemModel* model, const QModelIndex& index) const;
-
-	enum EditorDoneReason {
-		Left,
-		Right,
-		Up,
-		Down,
-		No
-	};
-
-public slots:
-	void editorDone (QWidget* editor, EditorDoneReason);
-};
-
 #endif


This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.




More information about the rkward-tracker mailing list