mirror of
https://github.com/Gnucash/gnucash.git
synced 2025-02-25 18:55:30 -06:00
Cutecash: Implement entering new transactions in the register.
Only the account selection is still missing. git-svn-id: svn+ssh://svn.gnucash.org/repo/gnucash/trunk@18935 57a11ea4-9604-0410-9ed3-97b8803252fd
This commit is contained in:
parent
8e5379f352
commit
ad0ddae5e6
@ -19,6 +19,7 @@ SET (gnc_SOURCES
|
||||
Session.cpp
|
||||
Split.cpp
|
||||
SplitListModel.cpp
|
||||
SplitListView.cpp
|
||||
Transaction.cpp
|
||||
main.cpp
|
||||
mainwindow.cpp
|
||||
@ -29,6 +30,7 @@ SET (gnc_QOBJECT_HEADERS
|
||||
AccountItemModel.hpp
|
||||
RecentFileMenu.hpp
|
||||
SplitListModel.hpp
|
||||
SplitListView.hpp
|
||||
mainwindow.hpp
|
||||
)
|
||||
SET (gnc_HEADERS ${gnc_QOBJECT_HEADERS}
|
||||
|
219
src/gnc/Cmd.cpp
219
src/gnc/Cmd.cpp
@ -41,14 +41,14 @@ QUndoCommand* setSplitMemo(Split& t, const QString& newValue)
|
||||
{
|
||||
return new Cmd<Split, QString>(QObject::tr("Edit Split Memo"),
|
||||
t, &Split::setMemo,
|
||||
&Split::getMemo, newValue);
|
||||
t.getMemo(), newValue);
|
||||
}
|
||||
|
||||
QUndoCommand* setSplitAction(Split& t, const QString& newValue)
|
||||
{
|
||||
return new Cmd<Split, QString>(QObject::tr("Edit Split Action"),
|
||||
t, &Split::setAction,
|
||||
&Split::getAction, newValue);
|
||||
t.getAction(), newValue);
|
||||
}
|
||||
|
||||
QUndoCommand* setSplitReconcile(Split& t, char newValue)
|
||||
@ -58,21 +58,21 @@ QUndoCommand* setSplitReconcile(Split& t, char newValue)
|
||||
// must be given explicitly.
|
||||
return new Cmd<Split, char, void (Split::*)(char)>(QObject::tr("Edit Split Reconcile"),
|
||||
t, &Split::setReconcile,
|
||||
&Split::getReconcile, newValue);
|
||||
t.getReconcile(), newValue);
|
||||
}
|
||||
|
||||
QUndoCommand* setSplitAmount(Split& t, const Numeric& newValue)
|
||||
{
|
||||
return new Cmd<Split, Numeric>(QObject::tr("Edit Split Amount"),
|
||||
t, &Split::setAmount,
|
||||
&Split::getAmount, newValue);
|
||||
t.getAmount(), newValue);
|
||||
}
|
||||
|
||||
QUndoCommand* setSplitValue(Split& t, const Numeric& newValue)
|
||||
{
|
||||
return new Cmd<Split, Numeric>(QObject::tr("Edit Split Value"),
|
||||
t, &Split::setValue,
|
||||
&Split::getValue, newValue);
|
||||
t.getValue(), newValue);
|
||||
}
|
||||
|
||||
// ////////////////////////////////////////////////////////////
|
||||
@ -100,17 +100,8 @@ public:
|
||||
Q_ASSERT(m_target);
|
||||
}
|
||||
|
||||
virtual void redo()
|
||||
{
|
||||
set(m_newValue);
|
||||
}
|
||||
|
||||
virtual void undo()
|
||||
{
|
||||
set(m_previousValue);
|
||||
}
|
||||
|
||||
|
||||
virtual void redo() { set(m_newValue); }
|
||||
virtual void undo() { set(m_previousValue); }
|
||||
private:
|
||||
void set(const value_type& value)
|
||||
{
|
||||
@ -226,28 +217,214 @@ QUndoCommand* destroyTransaction(Transaction& t)
|
||||
t);
|
||||
}
|
||||
|
||||
// ////////////////////////////////////////////////////////////
|
||||
|
||||
/** This is another templated implementation of a QUndoCommand
|
||||
* class, this time with keeping a direct reference to the target object.
|
||||
*
|
||||
* This implements the Command pattern: Any instance of this
|
||||
* class represents the change of one member variable (of type ValueT)
|
||||
* in an instance of a TargetT object.
|
||||
*
|
||||
* As we need to keep a reference to the original object, it is
|
||||
* relevant who owns the life cycle of that original object. For
|
||||
* simplicity, we constrain this current implementation only to
|
||||
* classes which are implementations of a WeakPointer<...> which by
|
||||
* definition keeps a C pointer to the original object, and we hope
|
||||
* that one lives longer than we do.
|
||||
*/
|
||||
template<class TargetT, class ValueT, typename SetterFunc = void (TargetT::*)(const ValueT&)>
|
||||
class CmdRef : public QUndoCommand
|
||||
{
|
||||
public:
|
||||
/// The base class
|
||||
typedef QUndoCommand base_class;
|
||||
|
||||
/// Type of the target object on which this command is applied
|
||||
typedef TargetT target_type;
|
||||
|
||||
/// Type of the value that is set by this command
|
||||
typedef ValueT value_type;
|
||||
|
||||
/// Type of the setter function to set the value in the target object
|
||||
typedef SetterFunc setter_func;
|
||||
|
||||
/** Constructor with the previous value given directly.
|
||||
*
|
||||
* @param text The QUndoCommand's text which will be displayed in the Undo action.
|
||||
* @param targetRef Reference to the target object on which this command is applied.
|
||||
* @param setter Pointer to function which sets the value in the target object
|
||||
* @param previousValue The previous value, in case this command needs to be undone
|
||||
* @param newValue The new value to be set
|
||||
* @param parent The parent QUndoCommand instance, or NULL.
|
||||
*/
|
||||
CmdRef(const QString& text,
|
||||
TargetT& targetRef,
|
||||
setter_func setter,
|
||||
const value_type& previousValue,
|
||||
const value_type& newValue,
|
||||
QUndoCommand *parent = 0)
|
||||
: base_class(text, parent)
|
||||
, m_target(targetRef)
|
||||
, m_setter(setter)
|
||||
, m_previousValue(previousValue)
|
||||
, m_newValue(newValue)
|
||||
{
|
||||
Q_ASSERT(m_setter);
|
||||
}
|
||||
|
||||
virtual void redo() { set(m_newValue); }
|
||||
virtual void undo() { set(m_previousValue); }
|
||||
|
||||
private:
|
||||
void set(const value_type& value)
|
||||
{
|
||||
// Call the pointer-to-member which is stored in m_setter.
|
||||
(m_target.*m_setter)(value);
|
||||
}
|
||||
|
||||
protected:
|
||||
target_type& m_target;
|
||||
setter_func m_setter;
|
||||
value_type m_previousValue;
|
||||
value_type m_newValue;
|
||||
};
|
||||
|
||||
|
||||
QUndoCommand* setSplitReconcile(TmpSplit& t, char newValue)
|
||||
{
|
||||
return 0;
|
||||
// Special third argument: The setter function takes a value
|
||||
// directly, instead of a const-reference, so the template type
|
||||
// must be given explicitly.
|
||||
return new CmdRef<TmpSplit, char, void (TmpSplit::*)(char)>(QObject::tr("Edit Split Reconcile"),
|
||||
t, &TmpSplit::setReconcile,
|
||||
t.getReconcile(), newValue);
|
||||
}
|
||||
QUndoCommand* setTransactionNum(TmpTransaction& t, const QString& newValue)
|
||||
{
|
||||
return 0;
|
||||
return new CmdRef<TmpTransaction, QString>(QObject::tr("Edit Transaction Number"),
|
||||
t, &TmpTransaction::setNum,
|
||||
t.getNum(), newValue);
|
||||
}
|
||||
QUndoCommand* setTransactionDescription(TmpTransaction& t, const QString& newValue)
|
||||
{
|
||||
return 0;
|
||||
return new CmdRef<TmpTransaction, QString>(QObject::tr("Edit Transaction Description"),
|
||||
t, &TmpTransaction::setDescription,
|
||||
t.getDescription(), newValue);
|
||||
}
|
||||
QUndoCommand* setTransactionDate(TmpTransaction& t, const QDate& newValue)
|
||||
{
|
||||
return 0;
|
||||
return new CmdRef<TmpTransaction, QDate>(QObject::tr("Edit Transaction Date"),
|
||||
t, &TmpTransaction::setDatePosted,
|
||||
t.getDatePosted(), newValue);
|
||||
}
|
||||
|
||||
// ////////////////////////////////////////////////////////////
|
||||
|
||||
class TmpSplitValueAndAmountCmd : public QUndoCommand
|
||||
{
|
||||
public:
|
||||
typedef QUndoCommand base_class;
|
||||
typedef TmpSplit target_type;
|
||||
typedef Numeric value_type;
|
||||
|
||||
/** Constructor without a getter-function but instead the previous
|
||||
* value given directly.
|
||||
*/
|
||||
TmpSplitValueAndAmountCmd(const QString& text,
|
||||
target_type& targetRef,
|
||||
const value_type& previousValue,
|
||||
const value_type& newValue,
|
||||
QUndoCommand *parent = 0)
|
||||
: base_class(text, parent)
|
||||
, m_target(targetRef)
|
||||
, m_previousValue(previousValue)
|
||||
, m_newValue(newValue)
|
||||
{
|
||||
}
|
||||
|
||||
virtual void redo() { set(m_newValue); }
|
||||
virtual void undo() { set(m_previousValue); }
|
||||
private:
|
||||
void set(const value_type& value)
|
||||
{
|
||||
const TmpTransaction* p_trans = m_target.getParent();
|
||||
// if (trans.countSplits() != 2)
|
||||
// return;
|
||||
// Split other = m_target.getOtherSplit();
|
||||
// Q_ASSERT(other);
|
||||
// Commodity originCommodity = m_target.getAccount().getCommodity();
|
||||
// Commodity transCommodity = trans.getCurrency();
|
||||
// Commodity otherCommodity = other.getAccount().getCommodity();
|
||||
// if (originCommodity != transCommodity
|
||||
// || transCommodity != otherCommodity)
|
||||
// return;
|
||||
|
||||
// trans.beginEdit();
|
||||
m_target.setValue(value);
|
||||
m_target.setAmount(value);
|
||||
// Numeric valueNeg = value.neg();
|
||||
// other.setAmount(valueNeg);
|
||||
// other.setValue(valueNeg);
|
||||
// trans.commitEdit();
|
||||
}
|
||||
|
||||
protected:
|
||||
target_type& m_target;
|
||||
value_type m_previousValue;
|
||||
value_type m_newValue;
|
||||
|
||||
};
|
||||
|
||||
|
||||
QUndoCommand* setSplitValueAndAmount(TmpSplit& t, const Numeric& newValue)
|
||||
{
|
||||
return 0;
|
||||
return new TmpSplitValueAndAmountCmd(QObject::tr("Edit Transaction Value"),
|
||||
t, t.getValue(), newValue);
|
||||
}
|
||||
|
||||
// ////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
|
||||
class TransactionCreateCmd : public QUndoCommand
|
||||
{
|
||||
public:
|
||||
typedef QUndoCommand base_class;
|
||||
typedef TmpTransaction target_type;
|
||||
|
||||
/** Constructor
|
||||
*/
|
||||
TransactionCreateCmd(const QString& text,
|
||||
const target_type target,
|
||||
QUndoCommand *parent = 0)
|
||||
: base_class(text, parent)
|
||||
, m_template(target)
|
||||
, m_created(NULL)
|
||||
{}
|
||||
|
||||
virtual void redo()
|
||||
{
|
||||
m_created = m_template.createAsReal();
|
||||
}
|
||||
|
||||
virtual void undo()
|
||||
{
|
||||
xaccTransDestroy(m_created.get());
|
||||
m_created.reset();
|
||||
}
|
||||
|
||||
protected:
|
||||
target_type m_template;
|
||||
Transaction m_created;
|
||||
};
|
||||
|
||||
QUndoCommand* commitNewTransaction(const TmpTransaction& t)
|
||||
{
|
||||
return new TransactionCreateCmd(QObject::tr("Create Transaction"), t);
|
||||
}
|
||||
|
||||
|
||||
|
||||
} // END namespace cmd
|
||||
|
||||
|
@ -174,6 +174,7 @@ QUndoCommand* setTransactionDate(TmpTransaction& t, const QDate& newValue);
|
||||
QUndoCommand* setSplitValueAndAmount(Split& t, const Numeric& newValue);
|
||||
QUndoCommand* setSplitValueAndAmount(TmpSplit& t, const Numeric& newValue);
|
||||
QUndoCommand* destroyTransaction(Transaction& t);
|
||||
QUndoCommand* commitNewTransaction(const TmpTransaction& t);
|
||||
|
||||
} // END namespace cmd
|
||||
|
||||
|
@ -48,14 +48,14 @@ TmpSplit::TmpSplit(const Split& s, const TmpTransaction* parent_trans)
|
||||
, value(s.getValue())
|
||||
{}
|
||||
|
||||
TmpSplit::TmpSplit(::Account* account)
|
||||
TmpSplit::TmpSplit(::Account* _account)
|
||||
{
|
||||
clear(account);
|
||||
clear(_account);
|
||||
}
|
||||
|
||||
void TmpSplit::clear(::Account* account)
|
||||
void TmpSplit::clear(::Account* _account)
|
||||
{
|
||||
account = account;
|
||||
account = _account;
|
||||
parent = NULL;
|
||||
memo.clear();
|
||||
action.clear();
|
||||
|
@ -127,7 +127,7 @@ int SplitListModel::columnCount(const QModelIndex& parent) const
|
||||
// if (!parent.isValid())
|
||||
// return 0;
|
||||
// else
|
||||
return 8; // Fixed number for now
|
||||
return COLUMN_LAST; // Fixed number for now
|
||||
}
|
||||
|
||||
Qt::ItemFlags SplitListModel::flags(const QModelIndex &index) const
|
||||
@ -139,14 +139,16 @@ Qt::ItemFlags SplitListModel::flags(const QModelIndex &index) const
|
||||
Qt::ItemFlags result = Qt::ItemIsEnabled | Qt::ItemIsSelectable;
|
||||
switch (index.column())
|
||||
{
|
||||
case 0:
|
||||
case 1:
|
||||
case 2:
|
||||
case 4:
|
||||
case 5:
|
||||
case 6:
|
||||
case COLUMN_DATE:
|
||||
case COLUMN_NUM:
|
||||
case COLUMN_DESC:
|
||||
case COLUMN_RECONCILE:
|
||||
case COLUMN_INCREASE:
|
||||
case COLUMN_DECREASE:
|
||||
// Allow write access as well
|
||||
return result | Qt::ItemIsEditable;
|
||||
case COLUMN_ACCOUNT:
|
||||
case COLUMN_BALANCE:
|
||||
default:
|
||||
// Ensure read-only access only
|
||||
return result;
|
||||
@ -170,7 +172,7 @@ QVariant SplitListModel::data(const QModelIndex& index, int role) const
|
||||
PrintAmountInfo printInfo(m_account, false);
|
||||
switch (index.column())
|
||||
{
|
||||
case 0:
|
||||
case COLUMN_DATE:
|
||||
switch (role)
|
||||
{
|
||||
case Qt::DisplayRole:
|
||||
@ -179,7 +181,7 @@ QVariant SplitListModel::data(const QModelIndex& index, int role) const
|
||||
default:
|
||||
return QVariant();
|
||||
}
|
||||
case 1:
|
||||
case COLUMN_NUM:
|
||||
switch (role)
|
||||
{
|
||||
case Qt::DisplayRole:
|
||||
@ -188,7 +190,7 @@ QVariant SplitListModel::data(const QModelIndex& index, int role) const
|
||||
default:
|
||||
return QVariant();
|
||||
}
|
||||
case 2:
|
||||
case COLUMN_DESC:
|
||||
switch (role)
|
||||
{
|
||||
case Qt::DisplayRole:
|
||||
@ -197,7 +199,7 @@ QVariant SplitListModel::data(const QModelIndex& index, int role) const
|
||||
default:
|
||||
return QVariant();
|
||||
}
|
||||
case 3:
|
||||
case COLUMN_ACCOUNT:
|
||||
switch (role)
|
||||
{
|
||||
// case Qt::DisplayRole:
|
||||
@ -205,7 +207,7 @@ QVariant SplitListModel::data(const QModelIndex& index, int role) const
|
||||
default:
|
||||
return QVariant();
|
||||
}
|
||||
case 4:
|
||||
case COLUMN_RECONCILE:
|
||||
switch (role)
|
||||
{
|
||||
case Qt::DisplayRole:
|
||||
@ -214,31 +216,31 @@ QVariant SplitListModel::data(const QModelIndex& index, int role) const
|
||||
default:
|
||||
return QVariant();
|
||||
}
|
||||
case 5:
|
||||
case COLUMN_INCREASE:
|
||||
switch (role)
|
||||
{
|
||||
case Qt::DisplayRole:
|
||||
case Qt::EditRole:
|
||||
if (amount.positive_p())
|
||||
if (!amount.zero_p() && amount.positive_p())
|
||||
return amount.printAmount(printInfo);
|
||||
else
|
||||
return QString();
|
||||
default:
|
||||
return QVariant();
|
||||
}
|
||||
case 6:
|
||||
case COLUMN_DECREASE:
|
||||
switch (role)
|
||||
{
|
||||
case Qt::DisplayRole:
|
||||
case Qt::EditRole:
|
||||
if (amount.positive_p())
|
||||
if (amount.zero_p() || amount.positive_p())
|
||||
return QString();
|
||||
else
|
||||
return amount.neg().printAmount(printInfo);
|
||||
default:
|
||||
return QVariant();
|
||||
}
|
||||
case 7:
|
||||
case COLUMN_BALANCE:
|
||||
default:
|
||||
return QVariant();
|
||||
}
|
||||
@ -257,7 +259,7 @@ QVariant SplitListModel::data(const QModelIndex& index, int role) const
|
||||
|
||||
switch (index.column())
|
||||
{
|
||||
case 0:
|
||||
case COLUMN_DATE:
|
||||
switch (role)
|
||||
{
|
||||
case Qt::DisplayRole:
|
||||
@ -266,7 +268,7 @@ QVariant SplitListModel::data(const QModelIndex& index, int role) const
|
||||
default:
|
||||
return QVariant();
|
||||
}
|
||||
case 1:
|
||||
case COLUMN_NUM:
|
||||
switch (role)
|
||||
{
|
||||
case Qt::DisplayRole:
|
||||
@ -275,7 +277,7 @@ QVariant SplitListModel::data(const QModelIndex& index, int role) const
|
||||
default:
|
||||
return QVariant();
|
||||
}
|
||||
case 2:
|
||||
case COLUMN_DESC:
|
||||
switch (role)
|
||||
{
|
||||
case Qt::DisplayRole:
|
||||
@ -284,7 +286,7 @@ QVariant SplitListModel::data(const QModelIndex& index, int role) const
|
||||
default:
|
||||
return QVariant();
|
||||
}
|
||||
case 3:
|
||||
case COLUMN_ACCOUNT:
|
||||
switch (role)
|
||||
{
|
||||
case Qt::DisplayRole:
|
||||
@ -292,7 +294,7 @@ QVariant SplitListModel::data(const QModelIndex& index, int role) const
|
||||
default:
|
||||
return QVariant();
|
||||
}
|
||||
case 4:
|
||||
case COLUMN_RECONCILE:
|
||||
switch (role)
|
||||
{
|
||||
case Qt::DisplayRole:
|
||||
@ -301,7 +303,7 @@ QVariant SplitListModel::data(const QModelIndex& index, int role) const
|
||||
default:
|
||||
return QVariant();
|
||||
}
|
||||
case 5:
|
||||
case COLUMN_INCREASE:
|
||||
switch (role)
|
||||
{
|
||||
case Qt::DisplayRole:
|
||||
@ -313,7 +315,7 @@ QVariant SplitListModel::data(const QModelIndex& index, int role) const
|
||||
default:
|
||||
return QVariant();
|
||||
}
|
||||
case 6:
|
||||
case COLUMN_DECREASE:
|
||||
switch (role)
|
||||
{
|
||||
case Qt::DisplayRole:
|
||||
@ -325,7 +327,7 @@ QVariant SplitListModel::data(const QModelIndex& index, int role) const
|
||||
default:
|
||||
return QVariant();
|
||||
}
|
||||
case 7:
|
||||
case COLUMN_BALANCE:
|
||||
switch (role)
|
||||
{
|
||||
case Qt::DisplayRole:
|
||||
@ -352,21 +354,21 @@ QVariant SplitListModel::headerData(int section, Qt::Orientation orientation, in
|
||||
{
|
||||
switch (section)
|
||||
{
|
||||
case 0:
|
||||
case COLUMN_DATE:
|
||||
return tr("Date");
|
||||
case 1:
|
||||
case COLUMN_NUM:
|
||||
return tr("Num");
|
||||
case 2:
|
||||
case COLUMN_DESC:
|
||||
return tr("Description");
|
||||
case 3:
|
||||
case COLUMN_ACCOUNT:
|
||||
return tr("Transfer");
|
||||
case 4:
|
||||
case COLUMN_RECONCILE:
|
||||
return tr("R?");
|
||||
case 5:
|
||||
case COLUMN_INCREASE:
|
||||
return tr("Increase");
|
||||
case 6:
|
||||
case COLUMN_DECREASE:
|
||||
return tr("Decrease");
|
||||
case 7:
|
||||
case COLUMN_BALANCE:
|
||||
return tr("Balance");
|
||||
default:
|
||||
return QVariant();
|
||||
@ -396,7 +398,7 @@ bool SplitListModel::setData(const QModelIndex &index, const QVariant &value, in
|
||||
// spooky, doesn't it?
|
||||
switch (index.column())
|
||||
{
|
||||
case 0:
|
||||
case COLUMN_DATE:
|
||||
{
|
||||
QDate date = value.toDate();
|
||||
if (date.isValid())
|
||||
@ -405,13 +407,13 @@ bool SplitListModel::setData(const QModelIndex &index, const QVariant &value, in
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 1:
|
||||
case COLUMN_NUM:
|
||||
cmd = cmd::setTransactionNum(trans, value.toString());
|
||||
break;
|
||||
case 2:
|
||||
case COLUMN_DESC:
|
||||
cmd = cmd::setTransactionDescription(trans, value.toString());
|
||||
break;
|
||||
case 4:
|
||||
case COLUMN_RECONCILE:
|
||||
{
|
||||
QString str(value.toString());
|
||||
if (str.size() > 0)
|
||||
@ -432,22 +434,22 @@ bool SplitListModel::setData(const QModelIndex &index, const QVariant &value, in
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 5:
|
||||
case 6:
|
||||
case COLUMN_INCREASE:
|
||||
case COLUMN_DECREASE:
|
||||
{
|
||||
QString str(value.toString().simplified());
|
||||
Numeric n;
|
||||
QString errmsg = n.parse(str);
|
||||
if (errmsg.isEmpty())
|
||||
{
|
||||
qDebug() << "Does setting numeric work? numeric=" << n.to_string();
|
||||
if (index.column() == 6)
|
||||
qDebug() << "Successfully parsed string to numeric=" << n.to_string();
|
||||
if (index.column() == COLUMN_DECREASE)
|
||||
n = n.neg();
|
||||
// Check whether we have the simple case here
|
||||
if (trans.getSplits().size() != 1)
|
||||
if (trans.countSplits() != 1)
|
||||
{
|
||||
QMessageBox::warning(NULL, tr("Unimplemented"),
|
||||
tr("Sorry, but editing a transaction with more than two splits (here: %1) is not yet implemented.").arg(trans.getSplits().size()));
|
||||
tr("Sorry, but editing a transaction with more than two splits (here: %1) is not yet implemented.").arg(trans.countSplits()));
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -490,7 +492,7 @@ bool SplitListModel::setData(const QModelIndex &index, const QVariant &value, in
|
||||
// spooky, doesn't it?
|
||||
switch (index.column())
|
||||
{
|
||||
case 0:
|
||||
case COLUMN_DATE:
|
||||
{
|
||||
QDate date = value.toDate();
|
||||
if (date.isValid())
|
||||
@ -499,16 +501,16 @@ bool SplitListModel::setData(const QModelIndex &index, const QVariant &value, in
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 1:
|
||||
case COLUMN_NUM:
|
||||
cmd = cmd::setTransactionNum(trans, value.toString());
|
||||
break;
|
||||
case 2:
|
||||
case COLUMN_DESC:
|
||||
cmd = cmd::setTransactionDescription(trans, value.toString());
|
||||
break;
|
||||
case 4:
|
||||
case COLUMN_RECONCILE:
|
||||
{
|
||||
QString str(value.toString());
|
||||
if (str.size() > 0)
|
||||
if (!str.isEmpty())
|
||||
{
|
||||
char recn = str[0].toLatin1();
|
||||
switch (recn)
|
||||
@ -526,16 +528,16 @@ bool SplitListModel::setData(const QModelIndex &index, const QVariant &value, in
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 5:
|
||||
case 6:
|
||||
case COLUMN_INCREASE:
|
||||
case COLUMN_DECREASE:
|
||||
{
|
||||
QString str(value.toString().simplified());
|
||||
Numeric n;
|
||||
QString errmsg = n.parse(str);
|
||||
if (errmsg.isEmpty())
|
||||
{
|
||||
qDebug() << "Does setting numeric work? numeric=" << n.to_string();
|
||||
if (index.column() == 6)
|
||||
qDebug() << "Successfully parsed string to numeric=" << n.to_string();
|
||||
if (index.column() == COLUMN_DECREASE)
|
||||
n = n.neg();
|
||||
// Check whether we have the simple case here
|
||||
if (split.getParent().countSplits() != 2)
|
||||
@ -620,4 +622,51 @@ void SplitListModel::accountEvent( ::Account* acc, QofEventId event_type)
|
||||
}
|
||||
}
|
||||
|
||||
void SplitListModel::editorClosed(const QModelIndex& index,
|
||||
QAbstractItemDelegate::EndEditHint hint)
|
||||
{
|
||||
if (!index.isValid())
|
||||
return;
|
||||
|
||||
if (m_enableNewTransaction && index.row() == m_list.size())
|
||||
{
|
||||
// Special case: The line with the new transaction
|
||||
|
||||
switch (hint)
|
||||
{
|
||||
case QAbstractItemDelegate::SubmitModelCache:
|
||||
switch (index.column())
|
||||
{
|
||||
case COLUMN_DATE:
|
||||
case COLUMN_NUM:
|
||||
case COLUMN_DESC:
|
||||
case COLUMN_ACCOUNT:
|
||||
case COLUMN_RECONCILE:
|
||||
break; // we want to do nothing
|
||||
case COLUMN_INCREASE:
|
||||
case COLUMN_DECREASE:
|
||||
{
|
||||
// Commit the new transaction
|
||||
qDebug() << "Commit the new transaction as a real one";
|
||||
QUndoCommand* cmd = cmd::commitNewTransaction(m_tmpTransaction);
|
||||
recreateTmpTrans();
|
||||
m_undoStack->push(cmd);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break; // nothing to do
|
||||
}
|
||||
case QAbstractItemDelegate::RevertModelCache:
|
||||
recreateTmpTrans();
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// We are in the line of an existing transaction - no function
|
||||
// implemented yet.
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
} // END namespace gnc
|
||||
|
@ -34,6 +34,7 @@ extern "C"
|
||||
}
|
||||
|
||||
#include <QAbstractItemModel>
|
||||
#include <QAbstractItemDelegate>
|
||||
#include <QHash>
|
||||
class QUndoStack;
|
||||
|
||||
@ -46,6 +47,20 @@ class SplitListModel : public QAbstractItemModel
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
|
||||
enum ColumnNumbers
|
||||
{
|
||||
COLUMN_DATE = 0
|
||||
, COLUMN_NUM
|
||||
, COLUMN_DESC
|
||||
, COLUMN_ACCOUNT
|
||||
, COLUMN_RECONCILE
|
||||
, COLUMN_INCREASE
|
||||
, COLUMN_DECREASE
|
||||
, COLUMN_BALANCE
|
||||
, COLUMN_LAST
|
||||
};
|
||||
|
||||
SplitListModel(const Account& acc, QUndoStack* undoStack, QObject *parent = 0);
|
||||
~SplitListModel();
|
||||
|
||||
@ -65,6 +80,7 @@ public:
|
||||
public slots:
|
||||
void transactionEvent( ::Transaction* trans, QofEventId event_type);
|
||||
void accountEvent( ::Account* trans, QofEventId event_type);
|
||||
void editorClosed(const QModelIndex& index, QAbstractItemDelegate::EndEditHint hint);
|
||||
|
||||
private:
|
||||
void recreateCache();
|
||||
|
75
src/gnc/SplitListView.cpp
Normal file
75
src/gnc/SplitListView.cpp
Normal file
@ -0,0 +1,75 @@
|
||||
/*
|
||||
* SplitListView.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@gnu.org
|
||||
*/
|
||||
|
||||
#include "SplitListView.hpp"
|
||||
|
||||
#include "gnc/Account.hpp"
|
||||
#include "gnc/SplitListModel.hpp"
|
||||
|
||||
#include <QtGui/QAbstractItemDelegate>
|
||||
#include <QUndoStack>
|
||||
#include <QDebug>
|
||||
|
||||
namespace gnc
|
||||
{
|
||||
|
||||
SplitListView::SplitListView(Account account, QUndoStack* undoStack, QWidget* parent)
|
||||
: base_class(parent)
|
||||
{
|
||||
SplitListModel *smodel = new SplitListModel(account, undoStack, this);
|
||||
setModel(smodel);
|
||||
connect(this, SIGNAL(editorClosed(const QModelIndex&,QAbstractItemDelegate::EndEditHint)),
|
||||
smodel, SLOT(editorClosed(const QModelIndex&,QAbstractItemDelegate::EndEditHint)));
|
||||
|
||||
setAlternatingRowColors(true);
|
||||
|
||||
scrollToBottom();
|
||||
if (model()->rowCount() > 0)
|
||||
setCurrentIndex(model()->index(model()->rowCount() - 1, 0));
|
||||
}
|
||||
|
||||
void SplitListView::closeEditor(QWidget* editor, QAbstractItemDelegate::EndEditHint hint)
|
||||
{
|
||||
base_class::closeEditor(editor, hint);
|
||||
//qDebug() << "closeEditor, row=" << currentIndex().row() << "hint=" << hint;
|
||||
QModelIndex index = currentIndex();
|
||||
if (hint != QAbstractItemDelegate::NoHint)
|
||||
emit editorClosed(index, hint);
|
||||
if (index.isValid()
|
||||
&& hint == QAbstractItemDelegate::SubmitModelCache
|
||||
&& index.row() < model()->rowCount() - 1)
|
||||
{
|
||||
switch (index.column())
|
||||
{
|
||||
case SplitListModel::COLUMN_INCREASE:
|
||||
case SplitListModel::COLUMN_DECREASE:
|
||||
setCurrentIndex(model()->index(index.row() + 1,
|
||||
SplitListModel::COLUMN_DATE,
|
||||
index.parent()));
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
53
src/gnc/SplitListView.hpp
Normal file
53
src/gnc/SplitListView.hpp
Normal file
@ -0,0 +1,53 @@
|
||||
/*
|
||||
* SplitListView.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@gnu.org
|
||||
*/
|
||||
|
||||
#ifndef GNC_SPLITLISTVIEW_HPP
|
||||
#define GNC_SPLITLISTVIEW_HPP
|
||||
|
||||
#include "gnc/Account.hpp"
|
||||
#include "gnc/SplitListModel.hpp"
|
||||
|
||||
#include <QtGui/QTableView>
|
||||
#include <QtGui/QAbstractItemDelegate>
|
||||
#include <QUndoStack>
|
||||
#include <QDebug>
|
||||
|
||||
namespace gnc
|
||||
{
|
||||
|
||||
class SplitListView : public QTableView
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
typedef QTableView base_class;
|
||||
SplitListView(Account account, QUndoStack* undoStack, QWidget* parent = 0);
|
||||
|
||||
signals:
|
||||
void editorClosed(const QModelIndex& index, QAbstractItemDelegate::EndEditHint hint);
|
||||
|
||||
public slots:
|
||||
void closeEditor(QWidget* editor, QAbstractItemDelegate::EndEditHint hint);
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
@ -91,7 +91,7 @@ void TmpTransaction::copyTo(Transaction& t) const
|
||||
s.copyInto(t);
|
||||
}
|
||||
}
|
||||
void TmpTransaction::createAsReal() const
|
||||
Transaction TmpTransaction::createAsReal() const
|
||||
{
|
||||
Q_ASSERT (!splits.isEmpty());
|
||||
Account acc(splits.front().getAccount());
|
||||
@ -102,6 +102,7 @@ void TmpTransaction::createAsReal() const
|
||||
trans.beginEdit();
|
||||
copyTo(trans);
|
||||
trans.commitEdit();
|
||||
return trans;
|
||||
}
|
||||
void TmpTransaction::push_back(const TmpSplit& s)
|
||||
{
|
||||
|
@ -108,7 +108,7 @@ public:
|
||||
|
||||
void clear();
|
||||
void copyTo(Transaction& t) const;
|
||||
void createAsReal() const;
|
||||
Transaction createAsReal() const;
|
||||
|
||||
QString getNum() const { return num; }
|
||||
void setNum(const QString& v) { num = v; }
|
||||
@ -119,6 +119,7 @@ public:
|
||||
void push_back(const TmpSplit& s);
|
||||
const TmpSplitQList& getSplits() const { return splits; }
|
||||
TmpSplitQList& getSplits() { return splits; }
|
||||
int countSplits() const { return splits.size(); }
|
||||
|
||||
Commodity getCommodity() const { return commodity; }
|
||||
void setCommodity(const Commodity& v) { commodity = v; }
|
||||
|
@ -397,7 +397,9 @@ void MainWindow::loadFile(const QString &fileName)
|
||||
"or you may not have write permission for the directory. "
|
||||
"If you proceed you may not be able to save any changes. "
|
||||
"What would you like to do?"));
|
||||
QMessageBox msgBox;
|
||||
QMessageBox msgBox(this);
|
||||
msgBox.setWindowTitle(fmt1);
|
||||
msgBox.setText(fmt2);
|
||||
QPushButton *openAnyway = msgBox.addButton(tr("_Open Anyway"), QMessageBox::ActionRole);
|
||||
QPushButton *createNewFile = msgBox.addButton(tr("_Create New File"), QMessageBox::ActionRole);
|
||||
QPushButton *close = msgBox.addButton(QMessageBox::Close);
|
||||
|
@ -51,8 +51,7 @@ extern "C"
|
||||
#include "gnc/Split.hpp"
|
||||
#include "gnc/SplitListModel.hpp"
|
||||
#include "gnc/RecentFileMenu.hpp"
|
||||
|
||||
#include "gnc/Cmd.hpp"
|
||||
#include "gnc/SplitListView.hpp"
|
||||
|
||||
namespace gnc
|
||||
{
|
||||
@ -416,7 +415,7 @@ void MainWindow::accountItemActivated(const QModelIndex & index)
|
||||
if (index.model() != m_accountTreeModel
|
||||
&& index.model() != m_accountListModel)
|
||||
{
|
||||
qDebug() << "Wrong model";
|
||||
qDebug() << "Wrong model; row=" << (index.isValid()? index.row() : -1);
|
||||
return;
|
||||
}
|
||||
Account account(static_cast< ::Account*>(index.internalPointer()));
|
||||
@ -428,14 +427,9 @@ void MainWindow::accountItemActivated(const QModelIndex & index)
|
||||
|
||||
// We create a new model for this account which will query it for
|
||||
// its splits, and also a view widget for this list.
|
||||
QTableView *tableView = new QTableView(ui->tabWidget); // FIXME: Is this parent correct?
|
||||
SplitListModel *smodel = new SplitListModel(account, m_undoStack, tableView);
|
||||
tableView->setModel(smodel);
|
||||
tableView->setAlternatingRowColors(true);
|
||||
tableView->scrollToBottom();
|
||||
if (smodel->rowCount() > 0)
|
||||
tableView->setCurrentIndex(smodel->index(smodel->rowCount() - 1, 0));
|
||||
ui->actionCut->setEnabled(smodel->rowCount() > 0);
|
||||
QTableView *tableView =
|
||||
new SplitListView(account, m_undoStack, ui->tabWidget);
|
||||
ui->actionCut->setEnabled(tableView->model()->rowCount() > 0);
|
||||
|
||||
// Insert this as a new tab
|
||||
tableView->setProperty(PROPERTY_TAB_PREVIOUSPOS, ui->tabWidget->currentIndex());
|
||||
|
@ -68,11 +68,17 @@ p, li { white-space: pre-wrap; }
|
||||
<p style=" margin-top:18px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:12pt; font-weight:600;">Free Finance Software. Easy to develop, easy to use.</span></p>
|
||||
<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt;">Currently this is more or less a proof-of-concept for developers:</span></p>
|
||||
<ol style="margin-top: 0px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; -qt-list-indent: 1;"><li style=" font-family:'Sans'; font-size:10pt;" style=" margin-top:12px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Load an existing gnucash XML file</li>
|
||||
<li style=" font-family:'Sans'; font-size:10pt;" style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">It will show the account tree in a QTreeView</li>
|
||||
<li style=" font-family:'Sans'; font-size:10pt;" style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Additionally the accounts will be shown in a flat list in a QTableView</li>
|
||||
<li style=" font-family:'Sans'; font-size:10pt;" style=" margin-top:0px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Double-click on any account in either view; it will open the list of splits in that account.</li></ol>
|
||||
<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans'; font-size:10pt;">The list of splits in the account is comparable to gnucash's single line view. The amounts are already there. The dates are still missing, but that can't be hard, too.</span></p>
|
||||
<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans'; font-size:10pt;">This is all read-only access so far, although &quot;Save&quot; probably works but hasn't been tested.</span></p>
|
||||
<li style=" font-family:'Sans'; font-size:10pt;" style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">It will show the account tree in a tree view and also a list view </li>
|
||||
<li style=" font-family:'Sans'; font-size:10pt;" style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Double-click on any account in either view; it will open the list of splits in that account.</li>
|
||||
<li style=" font-family:'Sans'; font-size:10pt;" style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Save and Save-As works as normal.</li>
|
||||
<li style=" font-family:'Sans'; font-size:10pt;" style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Edit any of the existing transaction/splits: Date, Description, or Amount. Click Undo. Click Redo. Click Undo. Etc. etc.</li>
|
||||
<li style=" font-family:'Sans'; font-size:10pt;" style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Delete any of the existings transactions. Or entering a new one. Click Undo. Click Redo. Etc. etc.</li></ol>
|
||||
<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans'; font-size:10pt;">The list of splits in the account is comparable to gnucash's single line view. Amounts, balance, date, all there.</span></p>
|
||||
<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans'; font-size:10pt;">The following parts are still missing:</span></p>
|
||||
<ul style="margin-top: 0px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; -qt-list-indent: 1;"><li style=" font-size:8pt;" style=" margin-top:12px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"> Currently the accout selection of a transaction cannot be edited. </li>
|
||||
<li style=" font-size:8pt;" style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Editing or adding multi-split transactions are not yet supported (it shows only the string &quot;--Split Transaction--&quot;). </li>
|
||||
<li style=" font-size:8pt;" style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Editing or adding multi-currency transactions are not yet supported. </li>
|
||||
<li style=" font-size:8pt;" style=" margin-top:0px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Any of the more specialized account views are not yet implemented.</li></ul>
|
||||
<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt;">The fun part is how easy it was to add this. Let's see how far we will get...</span></p>
|
||||
<p style=" margin-top:16px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt; font-weight:600;">Images</span></p>
|
||||
<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><img src=":/pixmaps/gnucash_splash.png" /></p>
|
||||
@ -160,12 +166,12 @@ p, li { white-space: pre-wrap; }
|
||||
<addaction name="actionAbout_Qt"/>
|
||||
</widget>
|
||||
<widget class="QMenu" name="menuAccount">
|
||||
<property name="title">
|
||||
<string>&Account</string>
|
||||
</property>
|
||||
<property name="enabled">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="title">
|
||||
<string>&Account</string>
|
||||
</property>
|
||||
<addaction name="actionOpenAccount"/>
|
||||
<addaction name="actionNewAccount"/>
|
||||
<addaction name="actionDeleteAccount"/>
|
||||
@ -400,7 +406,7 @@ p, li { white-space: pre-wrap; }
|
||||
</action>
|
||||
<action name="actionCloseTab">
|
||||
<property name="icon">
|
||||
<iconset resource="gnucash.qrc">
|
||||
<iconset resource="gtk-icons.qrc">
|
||||
<normaloff>:/gtk-icons/gtk-close.png</normaloff>:/gtk-icons/gtk-close.png</iconset>
|
||||
</property>
|
||||
<property name="text">
|
||||
|
Loading…
Reference in New Issue
Block a user