You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
607 lines
19 KiB
607 lines
19 KiB
/***************************************************************************
|
|
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 <tqtable.h>
|
|
#include <tqvaluelist.h>
|
|
#include <tqvaluevector.h>
|
|
#include <tqwidgetlist.h>
|
|
#include <tqmap.h>
|
|
#include <tqpair.h>
|
|
#include <tqevent.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 TQString sortOrderToText(TransactionSortField idx);
|
|
TransactionSortField textToSortOrder(const TQString& text);
|
|
|
|
|
|
class TQWidgetContainer : public TQMap<TQString, TQWidget*>
|
|
{
|
|
public:
|
|
TQWidgetContainer() {}
|
|
|
|
TQWidget* haveWidget(const TQString& name) const {
|
|
TQWidgetContainer::const_iterator it_w;
|
|
it_w = tqfind(name);
|
|
if(it_w != end())
|
|
return *it_w;
|
|
return 0;
|
|
}
|
|
|
|
void removeOrphans(void) {
|
|
TQWidgetContainer::iterator it_w;
|
|
for(it_w = begin(); it_w != end(); ) {
|
|
if((*it_w) && (*it_w)->tqparent())
|
|
++it_w;
|
|
else {
|
|
delete (*it_w);
|
|
remove(it_w);
|
|
it_w = begin();
|
|
}
|
|
}
|
|
}
|
|
|
|
};
|
|
|
|
class GroupMarker : public RegisterItem
|
|
{
|
|
public:
|
|
GroupMarker(Register* tqparent, const TQString& txt = TQString());
|
|
~GroupMarker();
|
|
void setText(const TQString& txt) { m_txt = txt; }
|
|
const TQString& 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(TQPainter* painter, int row, int col, const TQRect& r, bool selected, const TQColorGroup& cg);
|
|
void paintFormCell(TQPainter* /* painter */, int /* row */, int /* col */, const TQRect& /* r */, bool /* selected */, const TQColorGroup& /* cg */) {}
|
|
|
|
int rowHeightHint(void) const;
|
|
|
|
bool matches(const TQString&) const { return true; }
|
|
virtual int sortSamePostDate(void) const { return 0; }
|
|
|
|
protected:
|
|
void setupColors(TQColorGroup& cg);
|
|
|
|
protected:
|
|
TQString m_txt;
|
|
unsigned int m_drawCounter;
|
|
bool m_showDate;
|
|
|
|
static TQPixmap* m_bg;
|
|
static int m_bgRefCnt;
|
|
};
|
|
|
|
|
|
class FancyDateGroupMarker : public GroupMarker
|
|
{
|
|
public:
|
|
FancyDateGroupMarker(Register* tqparent, const TQDate& date, const TQString& txt);
|
|
|
|
virtual const TQDate& sortPostDate(void) const { return m_date; }
|
|
virtual const TQDate& sortEntryDate(void) const { return m_date; }
|
|
virtual const char* className(void) { return "FancyDateGroupMarker"; }
|
|
private:
|
|
TQDate m_date;
|
|
};
|
|
|
|
class StatementGroupMarker : public FancyDateGroupMarker
|
|
{
|
|
public:
|
|
StatementGroupMarker(Register* tqparent, CashFlowDirection dir, const TQDate& date, const TQString& 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* tqparent, const TQDate& date, const TQString& txt);
|
|
void paintRegisterCell(TQPainter* painter, int row, int col, const TQRect& r, bool selected, const TQColorGroup& cg);
|
|
int rowHeightHint(void) const;
|
|
virtual const char* className(void) { return "SimpleDateGroupMarker"; }
|
|
};
|
|
|
|
class TypeGroupMarker : public GroupMarker
|
|
{
|
|
public:
|
|
TypeGroupMarker(Register* tqparent, CashFlowDirection dir, MyMoneyAccount::accountTypeE accType);
|
|
CashFlowDirection sortType(void) const { return m_dir; }
|
|
private:
|
|
CashFlowDirection m_dir;
|
|
};
|
|
|
|
class FiscalYearGroupMarker : public FancyDateGroupMarker
|
|
{
|
|
public:
|
|
FiscalYearGroupMarker(Register* tqparent, const TQDate& date, const TQString& txt);
|
|
virtual const char* className(void) { return "FiscalYearGroupMarker"; }
|
|
virtual int sortSamePostDate(void) const { return 1; }
|
|
|
|
protected:
|
|
void setupColors(TQColorGroup& cg);
|
|
};
|
|
|
|
class PayeeGroupMarker : public GroupMarker
|
|
{
|
|
public:
|
|
PayeeGroupMarker(Register* tqparent, const TQString& name);
|
|
const TQString& sortPayee(void) const { return m_txt; }
|
|
};
|
|
|
|
class CategoryGroupMarker : public GroupMarker
|
|
{
|
|
public:
|
|
CategoryGroupMarker(Register* tqparent, const TQString& category);
|
|
const TQString& sortCategory(void) const { return m_txt; }
|
|
const TQString& sortSecurity(void) const { return m_txt; }
|
|
|
|
virtual const char* className(void) { return "CategoryGroupMarker"; }
|
|
};
|
|
|
|
class ReconcileGroupMarker : public GroupMarker
|
|
{
|
|
public:
|
|
ReconcileGroupMarker(Register* tqparent, MyMoneySplit::reconcileFlagE state);
|
|
virtual MyMoneySplit::reconcileFlagE sortReconcileState(void) const { return m_state; }
|
|
private:
|
|
MyMoneySplit::reconcileFlagE m_state;
|
|
};
|
|
|
|
|
|
class ItemPtrVector : public TQValueVector<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
|
|
TQ_OBJECT
|
|
|
|
// friend class TQHeader;
|
|
// friend class TQTableHeader;
|
|
// friend class RegisterItem;
|
|
friend class Transaction;
|
|
friend class StdTransaction;
|
|
friend class InvestTransaction;
|
|
|
|
public:
|
|
Register(TQWidget *tqparent = 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 TQValueList<RegisterItem*>
|
|
*/
|
|
TQValueList<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 TQValueList receiving the SelectedTransaction()'s
|
|
*/
|
|
void selectedTransactions(SelectedTransactions& list) const;
|
|
|
|
TQString text(int row, int col) const;
|
|
TQWidget* createEditor(int row, int col, bool initFromCell) const;
|
|
void setCellContentFromEditor(int row, int col);
|
|
TQWidget* cellWidget(int row, int col) const;
|
|
void endEdit(int row, int col, bool accept, bool tqreplace);
|
|
void paintCell(TQPainter* painter, int row, int col, const TQRect& r, bool selected, const TQColorGroup& cg);
|
|
|
|
void resizeData(int) {}
|
|
TQTableItem* item(int, int) { return 0; }
|
|
void setItem(int, int, TQTableItem*) {}
|
|
void clearCell(int, int) {}
|
|
void clearCellWidget(int, int);
|
|
|
|
/**
|
|
* Override the TQTable member function to avoid display of focus
|
|
*/
|
|
void paintFocus(TQPainter*, const TQRect& ) {}
|
|
|
|
/**
|
|
* Override the TQTable 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 TQValueList<Column>& cols);
|
|
|
|
void setSortOrder(const TQString& order);
|
|
const TQValueList<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(TQMap<TQString, TQWidget*>& editWidgets, Transaction* t);
|
|
void removeEditWidgets(TQMap<TQString, TQWidget*>& editWidgets);
|
|
void tabOrder(TQWidgetList& 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 tqparent 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 *tqparent, 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 TQTable::Single and
|
|
* TQTable::Multi. TQTable::Multi is the default when the object is created.
|
|
*/
|
|
void setSelectionMode(SelectionMode mode) { m_selectionMode = mode; }
|
|
|
|
protected:
|
|
|
|
void drawContents(TQPainter *p, int cx, int cy, int cw, int ch);
|
|
|
|
void contentsMouseReleaseEvent( TQMouseEvent *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(TQFocusEvent*);
|
|
void focusInEvent(TQFocusEvent*);
|
|
void keyPressEvent(TQKeyEvent*);
|
|
|
|
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 TQt::Page_Up or TQt::Page_Down depending on the direction to scroll
|
|
* @param state state of TQt::ShiftButton, TQt::ControlButton, TQt::AltButton and
|
|
* TQt::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 TQString& id) const;
|
|
|
|
void insertWidget(int row, int col, TQWidget* w);
|
|
|
|
/**
|
|
* Override logic and use standard TQFrame behaviour
|
|
*/
|
|
bool focusNextPrevChild(bool next);
|
|
|
|
bool eventFilter(TQObject* o, TQEvent* e);
|
|
|
|
void handleItemChange(RegisterItem* old, bool shift, bool control);
|
|
|
|
void selectRange(RegisterItem* from, RegisterItem* to, bool invert, bool includeFirst, bool clearSel);
|
|
|
|
// DND
|
|
void dragMoveEvent(TQDragMoveEvent* event);
|
|
void dropEvent(TQDropEvent* event);
|
|
Transaction* dropTransaction(TQPoint cPos) const;
|
|
|
|
protected slots:
|
|
void resize(void);
|
|
|
|
void selectItem(int row, int col, int button, const TQPoint & mousePos );
|
|
void slotEnsureItemVisible(void);
|
|
void slotDoubleClicked(int, int, int, const TQPoint&);
|
|
|
|
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;
|
|
TQValueVector<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;
|
|
TQt::ButtonState m_buttonState;
|
|
Column m_lastCol;
|
|
TQValueList<TransactionSortField> m_sortOrder;
|
|
TQMap<TQPair<int, int>, TQWidget*> m_cellWidgets;
|
|
RegisterToolTip* m_tooltip;
|
|
TQRect m_lastRepaintRect;
|
|
unsigned int m_drawCounter;
|
|
};
|
|
|
|
} // namespace
|
|
|
|
#endif
|
|
// vim:cin:si:ai:et:ts=2:sw=2:
|