diff options
Diffstat (limited to 'kmymoney2/widgets/register.h')
-rw-r--r-- | kmymoney2/widgets/register.h | 605 |
1 files changed, 605 insertions, 0 deletions
diff --git a/kmymoney2/widgets/register.h b/kmymoney2/widgets/register.h new file mode 100644 index 0000000..d9d2627 --- /dev/null +++ b/kmymoney2/widgets/register.h @@ -0,0 +1,605 @@ +/*************************************************************************** + register.h + ---------- + begin : Fri Mar 10 2006 + copyright : (C) 2006 by Thomas Baumgart + email : Thomas Baumgart <ipwizard@users.sourceforge.net> + ***************************************************************************/ + +/*************************************************************************** + * * + * 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. * + * * + ***************************************************************************/ + +#ifndef REGISTER_H +#define REGISTER_H + +// Some STL headers in GCC4.3 contain operator new. Memory checker mangles these +#ifdef _CHECK_MEMORY + #undef new +#endif + +#include <algorithm> + +// ---------------------------------------------------------------------------- +// QT Includes + +#include <qtable.h> +#include <qvaluelist.h> +#include <qvaluevector.h> +#include <qwidgetlist.h> +#include <qmap.h> +#include <qpair.h> +#include <qevent.h> + +// ---------------------------------------------------------------------------- +// KDE Includes + +// ---------------------------------------------------------------------------- +// Project Includes +#ifdef _CHECK_MEMORY + #include <kmymoney/mymoneyutils.h> +#endif + +#include <kmymoney/mymoneyaccount.h> +#include <kmymoney/registeritem.h> +#include <kmymoney/transaction.h> +#include <kmymoney/transactioneditorcontainer.h> +#include <kmymoney/selectedtransaction.h> +#include <kmymoney/transactionsortoption.h> + +class RegisterToolTip; + +namespace KMyMoneyRegister { + +typedef enum { + UnknownSort = 0, //< unknown sort criteria + PostDateSort = 1, //< sort by post date + EntryDateSort, //< sort by entry date + PayeeSort, //< sort by payee name + ValueSort, //< sort by value + NoSort, //< sort by number field + EntryOrderSort, //< sort by entry order + TypeSort, //< sort by CashFlowDirection + CategorySort, //< sort by Category + ReconcileStateSort, //< sort by reconciliation state + SecuritySort, //< sort by security (only useful for investment accounts) + // insert new values in front of this line + MaxSortFields +} TransactionSortField; + +typedef enum { + Ascending = 0, //< sort in ascending order + Descending //< sort in descending order +} SortDirection; + +class Register; +class RegisterItem; +class ItemPtrVector; + +const QString sortOrderToText(TransactionSortField idx); +TransactionSortField textToSortOrder(const QString& text); + + +class QWidgetContainer : public QMap<QString, QWidget*> +{ +public: + QWidgetContainer() {} + + QWidget* haveWidget(const QString& name) const { + QWidgetContainer::const_iterator it_w; + it_w = find(name); + if(it_w != end()) + return *it_w; + return 0; + } + + void removeOrphans(void) { + QWidgetContainer::iterator it_w; + for(it_w = begin(); it_w != end(); ) { + if((*it_w) && (*it_w)->parent()) + ++it_w; + else { + delete (*it_w); + remove(it_w); + it_w = begin(); + } + } + } + +}; + +class GroupMarker : public RegisterItem +{ +public: + GroupMarker(Register* parent, const QString& txt = QString()); + ~GroupMarker(); + void setText(const QString& txt) { m_txt = txt; } + const QString& text(void) const { return m_txt; } + bool isSelectable(void) const { return false; } + bool canHaveFocus(void) const { return false; } + int numRows(void) const { return 1; } + + virtual const char* className(void) { return "GroupMarker"; } + + bool isErronous(void) const { return false; } + + void paintRegisterCell(QPainter* painter, int row, int col, const QRect& r, bool selected, const QColorGroup& cg); + void paintFormCell(QPainter* /* painter */, int /* row */, int /* col */, const QRect& /* r */, bool /* selected */, const QColorGroup& /* cg */) {} + + int rowHeightHint(void) const; + + bool matches(const QString&) const { return true; } + virtual int sortSamePostDate(void) const { return 0; } + +protected: + void setupColors(QColorGroup& cg); + +protected: + QString m_txt; + unsigned int m_drawCounter; + bool m_showDate; + + static QPixmap* m_bg; + static int m_bgRefCnt; +}; + + +class FancyDateGroupMarker : public GroupMarker +{ +public: + FancyDateGroupMarker(Register* parent, const QDate& date, const QString& txt); + + virtual const QDate& sortPostDate(void) const { return m_date; } + virtual const QDate& sortEntryDate(void) const { return m_date; } + virtual const char* className(void) { return "FancyDateGroupMarker"; } +private: + QDate m_date; +}; + +class StatementGroupMarker : public FancyDateGroupMarker +{ +public: + StatementGroupMarker(Register* parent, CashFlowDirection dir, const QDate& date, const QString& txt ); + CashFlowDirection sortType(void) const { return m_dir; } + virtual int sortSamePostDate(void) const { return 3; } +private: + CashFlowDirection m_dir; +}; + +class SimpleDateGroupMarker : public FancyDateGroupMarker +{ +public: + SimpleDateGroupMarker(Register* parent, const QDate& date, const QString& txt); + void paintRegisterCell(QPainter* painter, int row, int col, const QRect& r, bool selected, const QColorGroup& cg); + int rowHeightHint(void) const; + virtual const char* className(void) { return "SimpleDateGroupMarker"; } +}; + +class TypeGroupMarker : public GroupMarker +{ +public: + TypeGroupMarker(Register* parent, CashFlowDirection dir, MyMoneyAccount::accountTypeE accType); + CashFlowDirection sortType(void) const { return m_dir; } +private: + CashFlowDirection m_dir; +}; + +class FiscalYearGroupMarker : public FancyDateGroupMarker +{ +public: + FiscalYearGroupMarker(Register* parent, const QDate& date, const QString& txt); + virtual const char* className(void) { return "FiscalYearGroupMarker"; } + virtual int sortSamePostDate(void) const { return 1; } + +protected: + void setupColors(QColorGroup& cg); +}; + +class PayeeGroupMarker : public GroupMarker +{ +public: + PayeeGroupMarker(Register* parent, const QString& name); + const QString& sortPayee(void) const { return m_txt; } +}; + +class CategoryGroupMarker : public GroupMarker +{ +public: + CategoryGroupMarker(Register* parent, const QString& category); + const QString& sortCategory(void) const { return m_txt; } + const QString& sortSecurity(void) const { return m_txt; } + + virtual const char* className(void) { return "CategoryGroupMarker"; } +}; + +class ReconcileGroupMarker : public GroupMarker +{ +public: + ReconcileGroupMarker(Register* parent, MyMoneySplit::reconcileFlagE state); + virtual MyMoneySplit::reconcileFlagE sortReconcileState(void) const { return m_state; } +private: + MyMoneySplit::reconcileFlagE m_state; +}; + + +class ItemPtrVector : public QValueVector<RegisterItem *> +{ +public: + ItemPtrVector() {} + + void sort(void); + +protected: + /** + * sorter's compare routine. Returns true if i1 < i2 + */ + static bool item_cmp(RegisterItem* i1, RegisterItem* i2); +}; + + +class Register : public TransactionEditorContainer +{ + Q_OBJECT + + // friend class QHeader; + // friend class QTableHeader; + // friend class RegisterItem; + friend class Transaction; + friend class StdTransaction; + friend class InvestTransaction; + +public: + Register(QWidget *parent = 0, const char *name = 0); + virtual ~Register(); + + /** + * add the item @a p to the register + */ + void addItem(RegisterItem* p); + + /** + * insert the item @a p into the register after item @a q + */ + void insertItemAfter(RegisterItem* p, RegisterItem* q); + + /** + * remove the item @p from the register + */ + void removeItem(RegisterItem* p); + + /** + * This method returns a list of pointers to all selected items + * in the register + * + * @retval QValueList<RegisterItem*> + */ + QValueList<RegisterItem*> selectedItems(void) const; + + /** + * Construct a list of all currently selected transactions in the register. + * If the current item carrying the focus (see focusItem() ) is selected + * it will be the first one contained in the list. + * + * @param list reference to QValueList receiving the SelectedTransaction()'s + */ + void selectedTransactions(SelectedTransactions& list) const; + + QString text(int row, int col) const; + QWidget* createEditor(int row, int col, bool initFromCell) const; + void setCellContentFromEditor(int row, int col); + QWidget* cellWidget(int row, int col) const; + void endEdit(int row, int col, bool accept, bool replace); + void paintCell(QPainter* painter, int row, int col, const QRect& r, bool selected, const QColorGroup& cg); + + void resizeData(int) {} + QTableItem* item(int, int) { return 0; } + void setItem(int, int, QTableItem*) {} + void clearCell(int, int) {} + void clearCellWidget(int, int); + + /** + * Override the QTable member function to avoid display of focus + */ + void paintFocus(QPainter*, const QRect& ) {} + + /** + * Override the QTable member function to avoid functionality + */ + void updateCell(int /* row */, int /* col */) {} + + RegisterItem* focusItem(void) const { return m_focusItem; } + RegisterItem* anchorItem(void) const { return m_selectAnchor; } + + /** + * set focus to specific item. + * @return true if the item got focus + */ + bool setFocusItem(RegisterItem* focusItem); + + void setAnchorItem(RegisterItem* anchorItem); + + /** + * Set focus to the first focussable item + * @return true if a focussable item was found + */ + bool setFocusToTop(void); + + /** + * Select @a item and unselect all others if @a dontChangeSelections + * is @a false. If m_buttonState differs from Qt::NoButton (method is + * called as a result of a mouse button press), then the setting of + * @a dontChangeSelections has no effect. + */ + void selectItem(RegisterItem* item, bool dontChangeSelections = false); + + /** + * Clears all items in the register. All objects + * added to the register will be deleted. + */ + void clear(void); + + void updateRegister(bool forceUpdateRowHeight = false); + + /** + * Assign all visible items an alternate background color + */ + void updateAlternate(void) const; + + /** + * make sure, we only show a single marker in a row + * through hiding unused ones + */ + void suppressAdjacentMarkers(void); + + /** + * Adjusts column @a col so that all data fits in width. + */ + void adjustColumn(int col); + + /** + * Convenience method to setup the register to show the columns + * based on the account type of @a account. If @a showAccountColumn + * is @a true then the account column is shown independant of the + * account type. If @a account does not have an @a id, all columns + * will be hidden. + */ + void setupRegister(const MyMoneyAccount& account, bool showAccountColumn = false); + + /** + * Show the columns contained in @a cols for @a account. @a account + * can be left empty ( MyMoneyAccount() ) e.g. for the search dialog. + */ + void setupRegister(const MyMoneyAccount& account, const QValueList<Column>& cols); + + void setSortOrder(const QString& order); + const QValueList<TransactionSortField>& sortOrder(void) const { return m_sortOrder; } + TransactionSortField primarySortKey(void) const; + void sortItems(void); + + /** + * This member returns the last visible column that is used by the register + * after it has been setup using setupRegister(). + * + * @return last actively used column (base 0) + */ + Column lastCol(void) const { return m_lastCol; } + + RegisterItem* firstItem(void) const; + RegisterItem* firstVisibleItem(void) const; + RegisterItem* nextItem(RegisterItem*) const; + RegisterItem* lastItem(void) const; + RegisterItem* lastVisibleItem(void) const; + RegisterItem* prevItem(RegisterItem*) const; + RegisterItem* itemAtRow(int row) const; + + void resize(int col); + + void forceUpdateLists(void) { m_listsDirty = true; } + + void ensureItemVisible(RegisterItem* item); + + void arrangeEditWidgets(QMap<QString, QWidget*>& editWidgets, Transaction* t); + void removeEditWidgets(QMap<QString, QWidget*>& editWidgets); + void tabOrder(QWidgetList& tabOrderWidgets, KMyMoneyRegister::Transaction* t) const; + + int rowHeightHint(void) const; + + void clearSelection(void); + + bool markErronousTransactions(void) const { return (m_markErronousTransactions & 0x01) != 0; } + + /** + * This method creates a specifc transaction according to the + * transaction passed in @a transaction. + * + * @param parent pointer to register where the created object should be added + * @param transaction the transaction which should be used to create the object + * @param split the split of the transaction which should be used to create the object + * @param uniqueId an int that will be used to construct the id of the item + * + * @return pointer to created object (0 upon failure) + */ + static Transaction* transactionFactory(Register *parent, const MyMoneyTransaction& transaction, const MyMoneySplit& split, int uniqueId); + + const MyMoneyAccount& account(void) const { return m_account; } + + void repaintItems(RegisterItem* first = 0, RegisterItem* last = 0); + + unsigned int drawCounter(void) const { return m_drawCounter; } + + /** + * This method creates group marker items and adds them to the register + */ + void addGroupMarkers(void); + + /** + * This method removes all trailing group markers and in a second + * run reduces all adjacent group markers to show only one. In that + * case the last one will remain. + */ + void removeUnwantedGroupMarkers(void); + + void setLedgerLensForced(bool forced=true) { m_ledgerLensForced = forced; } + + /** + * Sets the selection mode to @a mode. Supported modes are QTable::Single and + * QTable::Multi. QTable::Multi is the default when the object is created. + */ + void setSelectionMode(SelectionMode mode) { m_selectionMode = mode; } + +protected: + + void drawContents(QPainter *p, int cx, int cy, int cw, int ch); + + void contentsMouseReleaseEvent( QMouseEvent *e ); + + void unselectItems(int from = -1, int to = -1) { doSelectItems(from, to, false); } + void selectItems(int from, int to) { doSelectItems(from, to, true); } + void doSelectItems(int from, int to, bool selected); + int selectedItemsCount(void) const; + + void focusOutEvent(QFocusEvent*); + void focusInEvent(QFocusEvent*); + void keyPressEvent(QKeyEvent*); + + int rowToIndex(int row) const; + void setupItemIndex(int rowCount); + + /** + * This method determines the register item that is one page + * further down or up in the ledger from the previous focus item. + * The height to scroll is determined by visibleHeight() + * + * @param key Qt::Page_Up or Qt::Page_Down depending on the direction to scroll + * @param state state of Qt::ShiftButton, Qt::ControlButton, Qt::AltButton and + * Qt::MetaButton. + */ + void scrollPage(int key, ButtonState state); + + /** + * This method determines the pointer to a RegisterItem + * based on the item's @a id. If @a id is empty, this method + * returns @a m_lastItem. + * + * @param id id of the item to be searched + * @return pointer to RegisterItem or 0 if not found + */ + RegisterItem* itemById(const QString& id) const; + + void insertWidget(int row, int col, QWidget* w); + + /** + * Override logic and use standard QFrame behaviour + */ + bool focusNextPrevChild(bool next); + + bool eventFilter(QObject* o, QEvent* e); + + void handleItemChange(RegisterItem* old, bool shift, bool control); + + void selectRange(RegisterItem* from, RegisterItem* to, bool invert, bool includeFirst, bool clearSel); + + // DND + void dragMoveEvent(QDragMoveEvent* event); + void dropEvent(QDropEvent* event); + Transaction* dropTransaction(QPoint cPos) const; + +protected slots: + void resize(void); + + void selectItem(int row, int col, int button, const QPoint & mousePos ); + void slotEnsureItemVisible(void); + void slotDoubleClicked(int, int, int, const QPoint&); + + void slotToggleErronousTransactions(void); + void slotAutoColumnSizing(int section); + +signals: + void selectionChanged(void); + void selectionChanged(const KMyMoneyRegister::SelectedTransactions& list); + /** + * This signal is emitted when the focus and selection changes to @p item. + * + * @param item pointer to transaction that received the focus and was selected + */ + void focusChanged(KMyMoneyRegister::Transaction* item); + + /** + * This signal is emitted when the focus changes but the selection remains + * the same. This usually happens when the focus is changed using the keyboard. + */ + void focusChanged(void); + + /** + * This signal is emitted when an @p item is about to be selected. The boolean + * @p okToSelect is preset to @c true. If the @p item should not be selected + * for whatever reason, the boolean @p okToSelect should be reset to @c false + * by the connected slot. + */ + void aboutToSelectItem(KMyMoneyRegister::RegisterItem* item, bool& okToSelect); + + void editTransaction(void); + void headerClicked(void); + + /** + * This signal is sent out when the user clicks on the ReconcileStateColumn and + * only a single transaction is selected. + */ + void reconcileStateColumnClicked(KMyMoneyRegister::Transaction* item); + + /** + * This signal is sent out, if an item without a transaction id has been selected. + */ + void emptyItemSelected(void); + + /** + * This signal is sent out, if the user selects an item with the right mouse button + */ + void openContextMenu(void); + + /** + * This signal is sent out when a new item has been added to the register + */ + void itemAdded(RegisterItem* item); + +protected: + ItemPtrVector m_items; + QValueVector<RegisterItem*> m_itemIndex; + RegisterItem* m_selectAnchor; + RegisterItem* m_focusItem; + RegisterItem* m_ensureVisibleItem; + RegisterItem* m_firstItem; + RegisterItem* m_lastItem; + RegisterItem* m_firstErronous; + RegisterItem* m_lastErronous; + + int m_markErronousTransactions; + int m_rowHeightHint; + + MyMoneyAccount m_account; + + bool m_ledgerLensForced; + SelectionMode m_selectionMode; + +private: + bool m_listsDirty; + bool m_ignoreNextButtonRelease; + bool m_needInitialColumnResize; + Qt::ButtonState m_buttonState; + Column m_lastCol; + QValueList<TransactionSortField> m_sortOrder; + QMap<QPair<int, int>, QWidget*> m_cellWidgets; + RegisterToolTip* m_tooltip; + QRect m_lastRepaintRect; + unsigned int m_drawCounter; +}; + +} // namespace + +#endif +// vim:cin:si:ai:et:ts=2:sw=2: |