r18912 - gnucash/trunk/src/gnc - Add event registration and handling from the qof_event_handlers.
Christian Stimming
cstim at code.gnucash.org
Mon Mar 15 14:38:26 EDT 2010
Author: cstim
Date: 2010-03-15 14:38:26 -0400 (Mon, 15 Mar 2010)
New Revision: 18912
Trac: http://svn.gnucash.org/trac/changeset/18912
Added:
gnucash/trunk/src/gnc/QofEventWrapper.cpp
gnucash/trunk/src/gnc/QofEventWrapper.hpp
Modified:
gnucash/trunk/src/gnc/CMakeLists.txt
gnucash/trunk/src/gnc/SplitListModel.cpp
gnucash/trunk/src/gnc/SplitListModel.hpp
gnucash/trunk/src/gnc/main.cpp
Log:
Add event registration and handling from the qof_event_handlers.
This way, the split view is updated correctly even on undo/redo.
Modified: gnucash/trunk/src/gnc/CMakeLists.txt
===================================================================
--- gnucash/trunk/src/gnc/CMakeLists.txt 2010-03-15 16:10:26 UTC (rev 18911)
+++ gnucash/trunk/src/gnc/CMakeLists.txt 2010-03-15 18:38:26 UTC (rev 18912)
@@ -14,6 +14,7 @@
Book.cpp
Cmd.cpp
Numeric.cpp
+ QofEventWrapper.cpp
RecentFileMenu.cpp
Session.cpp
Split.cpp
@@ -32,6 +33,7 @@
Account.hpp
Book.hpp
Cmd.hpp
+ QofEventWrapper.hpp
Session.hpp
Split.hpp
Transaction.hpp
Added: gnucash/trunk/src/gnc/QofEventWrapper.cpp
===================================================================
--- gnucash/trunk/src/gnc/QofEventWrapper.cpp (rev 0)
+++ gnucash/trunk/src/gnc/QofEventWrapper.cpp 2010-03-15 18:38:26 UTC (rev 18912)
@@ -0,0 +1,59 @@
+/*
+ * QofEventWrapper.cpp
+ * Copyright (C) 2010 Christian Stimming
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, contact:
+ *
+ * Free Software Foundation Voice: +1-617-542-5942
+ * 51 Franklin Street, Fifth Floor Fax: +1-617-542-2652
+ * Boston, MA 02110-1301, USA gnu at gnu.org
+ */
+
+#include "QofEventWrapper.hpp"
+#include "engine/gnc-event.h"
+
+#include "gnc/SplitListModel.hpp"
+#include "gnc/Transaction.hpp"
+
+namespace gnc
+{
+
+// Explicit instantiation to check for compiler errors
+template class QofEventWrapper<SplitListModel, ::Transaction*>;
+
+#define EVENT_TO_STR(result, input, evtype) \
+ if ((input) & (evtype)) result += QString(result.isEmpty() ? "" : ",") + #evtype
+
+QString qofEventToString(QofEventId event_type)
+{
+ if (event_type == QOF_EVENT_NONE)
+ return "NONE";
+ QString r;
+ EVENT_TO_STR(r, event_type, QOF_EVENT_CREATE);
+ EVENT_TO_STR(r, event_type, QOF_EVENT_MODIFY);
+ EVENT_TO_STR(r, event_type, QOF_EVENT_DESTROY);
+ EVENT_TO_STR(r, event_type, QOF_EVENT_ADD);
+ EVENT_TO_STR(r, event_type, QOF_EVENT_REMOVE);
+
+ EVENT_TO_STR(r, event_type, GNC_EVENT_ITEM_ADDED);
+ EVENT_TO_STR(r, event_type, GNC_EVENT_ITEM_REMOVED);
+ EVENT_TO_STR(r, event_type, GNC_EVENT_ITEM_CHANGED);
+
+ if (r.isEmpty())
+ r = QString::number(event_type);
+ return r;
+}
+
+
+} // END namespace gnc
Added: gnucash/trunk/src/gnc/QofEventWrapper.hpp
===================================================================
--- gnucash/trunk/src/gnc/QofEventWrapper.hpp (rev 0)
+++ gnucash/trunk/src/gnc/QofEventWrapper.hpp 2010-03-15 18:38:26 UTC (rev 18912)
@@ -0,0 +1,116 @@
+/*
+ * QofEventWrapper.hpp
+ * Copyright (C) 2010 Christian Stimming
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, contact:
+ *
+ * Free Software Foundation Voice: +1-617-542-5942
+ * 51 Franklin Street, Fifth Floor Fax: +1-617-542-2652
+ * Boston, MA 02110-1301, USA gnu at gnu.org
+ */
+
+#ifndef GNC_QOFEVENTWRAPPER_HPP
+#define GNC_QOFEVENTWRAPPER_HPP
+
+// gnucash includes
+#include "config.h" // required by qof/qofutil.h
+extern "C"
+{
+#include "qof.h"
+}
+
+#include <QString>
+#include <QDebug>
+
+namespace gnc
+{
+
+/** Conversion of the event_type to string (for debugging) */
+QString qofEventToString(QofEventId event_type);
+
+/** Retrieval of the Qof instance class name (for debugging) */
+inline const char* getQofType(QofInstance* obj)
+{
+ return obj->e_type;
+}
+
+/** Template wrapper class for objects which want to receive
+ * notifications from the qof_event system in any of their member
+ * functions.
+ *
+ * The receiver's class is the first template argument; the argument
+ * type of the to-be-called member function is the second template
+ * (usually a pointer type). */
+template<class ReceiverT, class ValuePtrT, typename SlotFunc = void (ReceiverT::*)(ValuePtrT)>
+class QofEventWrapper
+{
+public:
+ QofEventWrapper(ReceiverT& receiver,
+ SlotFunc recvSlot,
+ const char* qof_type,
+ QofEventId event_type)
+ : m_receiver(receiver)
+ , m_receiveFunc(recvSlot)
+ , m_qof_type(qof_type)
+ , m_event_type(event_type)
+ {
+ m_handler_id = qof_event_register_handler(QofEventWrapper::event_handler, this);
+ }
+
+ ~QofEventWrapper()
+ {
+ qof_event_unregister_handler(m_handler_id);
+ }
+
+ static void event_handler (QofInstance *entity, QofEventId event_type,
+ gpointer user_data, gpointer event_data)
+ {
+ QofEventWrapper* wrapper = static_cast<QofEventWrapper *>(user_data);
+ wrapper->private_event_handler(entity, event_type, event_data);
+ }
+
+private:
+ void private_event_handler (QofInstance *entity, QofEventId event_type,
+ gpointer event_data)
+ {
+// qDebug() << "private_event_handler, id=" << qofEventToString(event_type)
+// << "entity=" << getQofType(entity);
+
+ // Verify that we have the correct QofInstance type and also
+ // correct event type
+ if (!QOF_CHECK_TYPE(entity, m_qof_type))
+ return;
+ if ((event_type & m_event_type) == 0)
+ return;
+
+ qDebug() << "private_event_handler, id=" << qofEventToString(event_type)
+ << "entity=" << getQofType(entity);
+
+ ValuePtrT vptr = reinterpret_cast<ValuePtrT>(entity);
+
+ // Call the pointer-to-member function with that weird C++
+ // syntax
+ (m_receiver.*m_receiveFunc)(vptr);
+ }
+
+ ReceiverT& m_receiver;
+ SlotFunc m_receiveFunc;
+ const char* m_qof_type;
+ QofEventId m_event_type;
+ gint m_handler_id;
+};
+
+} // END namespace gnc
+
+#endif
Modified: gnucash/trunk/src/gnc/SplitListModel.cpp
===================================================================
--- gnucash/trunk/src/gnc/SplitListModel.cpp 2010-03-15 16:10:26 UTC (rev 18911)
+++ gnucash/trunk/src/gnc/SplitListModel.cpp 2010-03-15 18:38:26 UTC (rev 18912)
@@ -23,19 +23,33 @@
#include "SplitListModel.hpp"
#include "gnc/Transaction.hpp"
#include "gnc/Cmd.hpp"
+#include "gnc/Session.hpp"
#include <QDebug>
#include <QUndoStack>
namespace gnc
{
+
+
SplitListModel::SplitListModel(const SplitQList splits, QUndoStack* undoStack, QObject *parent)
: QAbstractItemModel(parent)
, m_list(splits)
, m_undoStack(undoStack)
+ , m_eventWrapper(*this, &SplitListModel::transactionModified,
+ GNC_ID_TRANS, QOF_EVENT_MODIFY)
{
+ // Cache the mapping of transactions to split in the m_hash
+ for (int k = 0; k < m_list.size(); ++k)
+ {
+ m_hash.insert(Split(m_list[k]).getParent().get(), k);
+ }
}
+SplitListModel::~SplitListModel()
+{
+}
+
QModelIndex SplitListModel::index(int row, int column,
const QModelIndex &parent) const
{
@@ -62,6 +76,29 @@
return 8; // Fixed number for now
}
+Qt::ItemFlags SplitListModel::flags(const QModelIndex &index) const
+{
+ //qDebug() << "flags()" << index;
+ if (!index.isValid())
+ return 0;
+
+ Qt::ItemFlags result = Qt::ItemIsEnabled | Qt::ItemIsSelectable;
+ switch (index.column())
+ {
+ case 0:
+ case 1:
+ case 2:
+ case 4:
+ //case 5:
+ //case 6:
+ // Allow write access as well
+ return result | Qt::ItemIsEditable;
+ default:
+ // Ensure read-only access only
+ return result;
+ }
+}
+
QVariant SplitListModel::data(const QModelIndex& index, int role) const
{
//qDebug() << "data(), " << index;
@@ -106,29 +143,6 @@
return QVariant();
}
-Qt::ItemFlags SplitListModel::flags(const QModelIndex &index) const
-{
- //qDebug() << "flags()" << index;
- if (!index.isValid())
- return 0;
-
- Qt::ItemFlags result = Qt::ItemIsEnabled | Qt::ItemIsSelectable;
- switch (index.column())
- {
- case 0:
- case 1:
- case 2:
- case 4:
- //case 5:
- //case 6:
- // Allow write access as well
- return result | Qt::ItemIsEditable;
- default:
- // Ensure read-only access only
- return result;
- }
-}
-
QVariant SplitListModel::headerData(int section, Qt::Orientation orientation, int role) const
{
//qDebug() << "headerData()" << section;
@@ -222,10 +236,21 @@
if (cmd)
{
m_undoStack->push(cmd);
- emit dataChanged(index, index);
+ // No dataChanged() signal here because it is emitted from the
+ // transactionChanged slot.
return true;
}
return false;
}
+void SplitListModel::transactionModified( ::Transaction* trans)
+{
+ if (m_hash.contains(trans))
+ {
+ int row = m_hash.value(trans);
+ emit dataChanged(index(row, 0), index(row, columnCount() - 1));
+ }
+
+}
+
} // END namespace gnc
Modified: gnucash/trunk/src/gnc/SplitListModel.hpp
===================================================================
--- gnucash/trunk/src/gnc/SplitListModel.hpp 2010-03-15 16:10:26 UTC (rev 18911)
+++ gnucash/trunk/src/gnc/SplitListModel.hpp 2010-03-15 18:38:26 UTC (rev 18912)
@@ -24,8 +24,15 @@
#define GNC_SPLITLISTMODEL_HPP
#include "gnc/Split.hpp"
+#include "gnc/QofEventWrapper.hpp"
+extern "C"
+{
+#include "engine/Transaction.h"
+}
+
#include <QAbstractItemModel>
+#include <QHash>
class QUndoStack;
namespace gnc
@@ -38,6 +45,7 @@
Q_OBJECT
public:
SplitListModel(const SplitQList splits, QUndoStack* undoStack, QObject *parent = 0);
+ ~SplitListModel();
QModelIndex parent(const QModelIndex &index) const { return QModelIndex(); }
int rowCount(const QModelIndex& parent = QModelIndex()) const { return m_list.size(); }
@@ -50,10 +58,17 @@
QVariant headerData(int section, Qt::Orientation orientation, int role) const;
bool setData(const QModelIndex &index, const QVariant &value, int role);
+public slots:
+ void transactionModified( ::Transaction* trans);
protected:
SplitQList m_list;
QUndoStack* m_undoStack;
+ typedef QHash< ::Transaction*, int> TransactionRowHash;
+ TransactionRowHash m_hash;
+
+ /** The wrapper for receiving events from gnc. */
+ QofEventWrapper<SplitListModel, ::Transaction*> m_eventWrapper;
};
} // END namespace gnc
Modified: gnucash/trunk/src/gnc/main.cpp
===================================================================
--- gnucash/trunk/src/gnc/main.cpp 2010-03-15 16:10:26 UTC (rev 18911)
+++ gnucash/trunk/src/gnc/main.cpp 2010-03-15 18:38:26 UTC (rev 18912)
@@ -186,15 +186,21 @@
gnc_module_init_business_core_xml_init();
gnc_ui_util_init();
- // From here on the new C++ code
- QApplication app(argc, argv);
- gnc::MainWindow mainWin;
- mainWin.show();
+ int r;
+ {
+ // From here on the new C++ code
+ QApplication app(argc, argv);
+ gnc::MainWindow mainWin;
+ mainWin.show();
- // Go into the main qt event loop
- int r = app.exec();
+ // Go into the main qt event loop
+ r = app.exec();
- // Shutdown
+ // Destruction of the MainWindow will trigger all the C++
+ // destructors
+ }
+
+ // Shutdown of the C side after all C++ was destructed already.
//gnc_module_finalize_backend_dbi();
qof_close();
return r;
More information about the gnucash-changes
mailing list