From 60238d4e9781ad18475a3b45bceaad1d30ea1b8b Mon Sep 17 00:00:00 2001 From: harlekin Date: Fri, 05 Jul 2002 13:00:41 +0000 Subject: spendings tracking app by Nick Betcher (who quit qte development .-( ) --- diff --git a/noncore/apps/checkbook/TODO b/noncore/apps/checkbook/TODO new file mode 100644 index 0000000..adc9665 --- a/dev/null +++ b/noncore/apps/checkbook/TODO @@ -0,0 +1,5 @@ +TODO: + * Date widget + * Various bug fixes + * Fix "the" crash + * Fix graph's legend not showing up \ No newline at end of file diff --git a/noncore/apps/checkbook/config.cpp b/noncore/apps/checkbook/config.cpp new file mode 100644 index 0000000..e6c6dcc --- a/dev/null +++ b/noncore/apps/checkbook/config.cpp @@ -0,0 +1,560 @@ +/********************************************************************** +** Copyright (C) 2000 Trolltech AS. All rights reserved. +** +** This file is part of Qtopia Environment. +** +** This file may be distributed and/or modified under the terms of the +** GNU General Public License version 2 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. +** +** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +** +** See http://www.trolltech.com/gpl/ for GPL licensing information. +** +** Contact info@trolltech.com if any conditions of this licensing are +** not clear to you. +** +**********************************************************************/ + +#include +#include +#include +#include +#if QT_VERSION <= 230 && defined(QT_NO_CODECS) +#include +#endif +#include + +#include +#include +#include +#include +#include + +#include "config.h" + + +/*! + \internal +*/ +QString Config::configFilename(const QString& name, Domain d) +{ + switch (d) { + case File: + return name; + case User: { + QDir dir = (QString(getenv("HOME")) + "/Settings"); + if ( !dir.exists() ) + mkdir(dir.path().local8Bit(),0700); + return dir.path() + "/" + name + ".conf"; + } + } + return name; +} + +/*! + \class Config config.h + \brief The Config class provides for saving application cofniguration state. + + You should keep a Config in existence only while you do not want others + to be able to change the state. There is no locking currently, but there + may be in the future. +*/ + +/*! + \enum Config::ConfigGroup + \internal +*/ + +/*! + \enum Config::Domain + + \value File + \value User + + See Config for details. +*/ + +/*! + Constructs a config that will load or create a configuration with the + given \a name in the given \a domain. + + You must call setGroup() before doing much else with the Config. + + In the default Domain, \e User, + the configuration is user-specific. \a name should not contain "/" in + this case, and in general should be the name of the C++ class that is + primarily responsible for maintaining the configuration. + + In the File Domain, \a name is an absolute filename. +*/ +Config::Config( const QString &name, Domain domain ) + : filename( configFilename(name,domain) ) +{ + git = groups.end(); + read(); + + lang = getenv("LANG"); + int i = lang.find("."); + if ( i > 0 ) + lang = lang.left( i ); + i = lang.find( "_" ); + if ( i > 0 ) + glang = lang.left(i); +} + +/*! + Writes any changes to disk and destroys the in-memory object. +*/ +Config::~Config() +{ + if ( changed ) + write(); +} + +/*! + Returns whether the current group has an entry called \a key. +*/ +bool Config::hasKey( const QString &key ) const +{ + if ( groups.end() == git ) + return FALSE; + ConfigGroup::ConstIterator it = ( *git ).find( key ); + return it != ( *git ).end(); +} + +/*! + Sets the current group for subsequent reading and writing of + entries to \a gname. Grouping allows the application to partition the namespace. + + This function must be called prior to any reading or writing + of entries. + + The \a gname must not be empty. +*/ +void Config::setGroup( const QString &gname ) +{ + QMap< QString, ConfigGroup>::Iterator it = groups.find( gname ); + if ( it == groups.end() ) { + git = groups.insert( gname, ConfigGroup() ); + changed = TRUE; + return; + } + git = it; +} + +/*! + Writes a (\a key, \a value) entry to the current group. + + \sa readEntry() +*/ +void Config::writeEntry( const QString &key, const char* value ) +{ + writeEntry(key,QString(value)); +} + +/*! + Writes a (\a key, \a value) entry to the current group. + + \sa readEntry() +*/ +void Config::writeEntry( const QString &key, const QString &value ) +{ + if ( git == groups.end() ) { + qWarning( "no group set" ); + return; + } + if ( (*git)[key] != value ) { + ( *git ).insert( key, value ); + changed = TRUE; + } +} + +/* + Note that the degree of protection offered by the encryption here is + only sufficient to avoid the most casual observation of the configuration + files. People with access to the files can write down the contents and + decrypt it using this source code. + + Conceivably, and at some burden to the user, this encryption could + be improved. +*/ +static QString encipher(const QString& plain) +{ + // mainly, we make it long + QString cipher; + int mix=28730492; + for (int i=0; i<(int)plain.length(); i++) { + int u = plain[i].unicode(); + int c = u ^ mix; + QString x = QString::number(c,36); + cipher.append(QChar('a'+x.length())); + cipher.append(x); + mix *= u; + } + return cipher; +} + +static QString decipher(const QString& cipher) +{ + QString plain; + int mix=28730492; + for (int i=0; i<(int)cipher.length();) { + int l = cipher[i].unicode()-'a'; + QString x = cipher.mid(i+1,l); i+=l+1; + int u = x.toInt(0,36) ^ mix; + plain.append(QChar(u)); + mix *= u; + } + return plain; +} + +/*! + Writes an encrypted (\a key, \a value) entry to the current group. + + Note that the degree of protection offered by the encryption is + only sufficient to avoid the most casual observation of the configuration + files. + + \sa readEntry() +*/ +void Config::writeEntryCrypt( const QString &key, const QString &value ) +{ + if ( git == groups.end() ) { + qWarning( "no group set" ); + return; + } + QString evalue = encipher(value); + if ( (*git)[key] != evalue ) { + ( *git ).insert( key, evalue ); + changed = TRUE; + } +} + +/*! + Writes a (\a key, \a num) entry to the current group. + + \sa readNumEntry() +*/ +void Config::writeEntry( const QString &key, int num ) +{ + QString s; + s.setNum( num ); + writeEntry( key, s ); +} + +#ifdef Q_HAS_BOOL_TYPE +/*! + Writes a (\a key, \a b) entry to the current group. This is equivalent + to writing a 0 or 1 as an integer entry. + + \sa readBoolEntry() +*/ +void Config::writeEntry( const QString &key, bool b ) +{ + QString s; + s.setNum( ( int )b ); + writeEntry( key, s ); +} +#endif + +/*! + Writes a (\a key, \a lst) entry to the current group. The list + is separated by \a sep, so the strings must not contain that character. + + \sa readListEntry() +*/ +void Config::writeEntry( const QString &key, const QStringList &lst, const QChar &sep ) +{ + QString s; + QStringList::ConstIterator it = lst.begin(); + for ( ; it != lst.end(); ++it ) + s += *it + sep; + writeEntry( key, s ); +} + +/*! + Removes the \a key entry from the current group. Does nothing if + there is no such entry. +*/ + +void Config::removeEntry( const QString &key ) +{ + if ( git == groups.end() ) { + qWarning( "no group set" ); + return; + } + ( *git ).remove( key ); + changed = TRUE; +} + +/*! + \fn bool Config::operator == ( const Config & other ) const + + Tests for equality with \a other. Config objects are equal if they refer to the same filename. +*/ + +/*! + \fn bool Config::operator != ( const Config & other ) const + + Tests for inequality with \a other. Config objects are equal if they refer to the same filename. +*/ + +/*! + \fn QString Config::readEntry( const QString &key, const QString &deflt ) const + + Reads a string entry stored with \a key, defaulting to \a deflt if there is no entry. +*/ + +/*! + \internal + For compatibility, non-const version. +*/ +QString Config::readEntry( const QString &key, const QString &deflt ) +{ + QString res = readEntryDirect( key+"["+lang+"]" ); + if ( !res.isNull() ) + return res; + if ( !glang.isEmpty() ) { + res = readEntryDirect( key+"["+glang+"]" ); + if ( !res.isNull() ) + return res; + } + return readEntryDirect( key, deflt ); +} + +/*! + \fn QString Config::readEntryCrypt( const QString &key, const QString &deflt ) const + + Reads an encrypted string entry stored with \a key, defaulting to \a deflt if there is no entry. +*/ + +/*! + \internal + For compatibility, non-const version. +*/ +QString Config::readEntryCrypt( const QString &key, const QString &deflt ) +{ + QString res = readEntryDirect( key+"["+lang+"]" ); + if ( res.isNull() && glang.isEmpty() ) + res = readEntryDirect( key+"["+glang+"]" ); + if ( res.isNull() ) + res = readEntryDirect( key, QString::null ); + if ( res.isNull() ) + return deflt; + return decipher(res); +} + +/*! + \fn QString Config::readEntryDirect( const QString &key, const QString &deflt ) const + \internal +*/ + +/*! + \internal + For compatibility, non-const version. +*/ +QString Config::readEntryDirect( const QString &key, const QString &deflt ) +{ + if ( git == groups.end() ) { + //qWarning( "no group set" ); + return deflt; + } + ConfigGroup::ConstIterator it = ( *git ).find( key ); + if ( it != ( *git ).end() ) + return *it; + else + return deflt; +} + +/*! + \fn int Config::readNumEntry( const QString &key, int deflt ) const + Reads a numeric entry stored with \a key, defaulting to \a deflt if there is no entry. +*/ + +/*! + \internal + For compatibility, non-const version. +*/ +int Config::readNumEntry( const QString &key, int deflt ) +{ + QString s = readEntry( key ); + if ( s.isEmpty() ) + return deflt; + else + return s.toInt(); +} + +/*! + \fn bool Config::readBoolEntry( const QString &key, bool deflt ) const + Reads a bool entry stored with \a key, defaulting to \a deflt if there is no entry. +*/ + +/*! + \internal + For compatibility, non-const version. +*/ +bool Config::readBoolEntry( const QString &key, bool deflt ) +{ + QString s = readEntry( key ); + if ( s.isEmpty() ) + return deflt; + else + return (bool)s.toInt(); +} + +/*! + \fn QStringList Config::readListEntry( const QString &key, const QChar &sep ) const + Reads a string list entry stored with \a key, and with \a sep as the separator. +*/ + +/*! + \internal + For compatibility, non-const version. +*/ + +/*! + Removes all entries from the current group. +*/ +void Config::clearGroup() +{ + if ( git == groups.end() ) { + qWarning( "no group set" ); + return; + } + if ( !(*git).isEmpty() ) { + ( *git ).clear(); + changed = TRUE; + } +} + +void Config::removeGroup() +{ + if ( git == groups.end() ) { + qWarning( "no group set" ); + return; + } + + groups.remove(git); + changed = TRUE; +} + +/*! + \internal +*/ +void Config::write( const QString &fn ) +{ + QString strNewFile; + if ( !fn.isEmpty() ) + filename = fn; + strNewFile = filename + ".new"; + + QFile f( strNewFile ); + if ( !f.open( IO_WriteOnly|IO_Raw ) ) { + qWarning( "could not open for writing `%s'", strNewFile.latin1() ); + git = groups.end(); + return; + } + + QString str; + QCString cstr; + QMap< QString, ConfigGroup >::Iterator g_it = groups.begin(); + + for ( ; g_it != groups.end(); ++g_it ) { + str += "[" + g_it.key() + "]\n"; + ConfigGroup::Iterator e_it = ( *g_it ).begin(); + for ( ; e_it != ( *g_it ).end(); ++e_it ) + str += e_it.key() + " = " + *e_it + "\n"; + } + cstr = str.utf8(); + + int total_length; + total_length = f.writeBlock( cstr.data(), cstr.length() ); + if ( total_length != int(cstr.length()) ) { + QMessageBox::critical( 0, QObject::tr("Out of Space"), + QObject::tr("There was a problem creating\nConfiguration Information \nfor this program.\n\nPlease free up some space and\ntry again.") ); + f.close(); + QFile::remove( strNewFile ); + return; + } + + f.close(); + // now rename the file... + if ( rename( strNewFile, filename ) < 0 ) { + qWarning( "problem renaming the file %s to %s", strNewFile.latin1(), + filename.latin1() ); + QFile::remove( strNewFile ); + } +} + +/*! + Returns whether the Config is in a valid state. +*/ +bool Config::isValid() const +{ + return groups.end() != git; +} + +/*! + \internal +*/ +void Config::read() +{ + changed = FALSE; + + if ( !QFileInfo( filename ).exists() ) { + git = groups.end(); + return; + } + + QFile f( filename ); + if ( !f.open( IO_ReadOnly ) ) { + git = groups.end(); + return; + } + + QTextStream s( &f ); +#if QT_VERSION <= 230 && defined(QT_NO_CODECS) + // The below should work, but doesn't in Qt 2.3.0 + s.setCodec( QTextCodec::codecForMib( 106 ) ); +#else + s.setEncoding( QTextStream::UnicodeUTF8 ); +#endif + + QStringList list = QStringList::split('\n', s.read() ); + f.close(); + + for ( QStringList::Iterator it = list.begin(); it != list.end(); ++it ) { + if ( !parse( *it ) ) { + git = groups.end(); + return; + } + } +} + +/*! + \internal +*/ +bool Config::parse( const QString &l ) +{ + QString line = l.stripWhiteSpace(); + if ( line[ 0 ] == QChar( '[' ) ) { + QString gname = line; + gname = gname.remove( 0, 1 ); + if ( gname[ (int)gname.length() - 1 ] == QChar( ']' ) ) + gname = gname.remove( gname.length() - 1, 1 ); + git = groups.insert( gname, ConfigGroup() ); + } else if ( !line.isEmpty() ) { + if ( git == groups.end() ) + return FALSE; + int eq = line.find( '=' ); + if ( eq == -1 ) + return FALSE; + QString key = line.left(eq).stripWhiteSpace(); + QString value = line.mid(eq+1).stripWhiteSpace(); + ( *git ).insert( key, value ); + } + return TRUE; +} diff --git a/noncore/apps/checkbook/config.h b/noncore/apps/checkbook/config.h new file mode 100644 index 0000000..b3a8561 --- a/dev/null +++ b/noncore/apps/checkbook/config.h @@ -0,0 +1,99 @@ +/********************************************************************** +** Copyright (C) 2000 Trolltech AS. All rights reserved. +** +** This file is part of Qtopia Environment. +** +** This file may be distributed and/or modified under the terms of the +** GNU General Public License version 2 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. +** +** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +** +** See http://www.trolltech.com/gpl/ for GPL licensing information. +** +** Contact info@trolltech.com if any conditions of this licensing are +** not clear to you. +** +**********************************************************************/ + +#ifndef CONFIG_H +#define CONFIG_H + +// ##### could use QSettings with Qt 3.0 + +#include +#include + +class ConfigPrivate; +class Config +{ +public: + typedef QMap< QString, QString > ConfigGroup; + + enum Domain { File, User }; + Config( const QString &name, Domain domain=User ); + ~Config(); + + bool operator == ( const Config & other ) const { return (filename == other.filename); } + bool operator != ( const Config & other ) const { return (filename != other.filename); } + + bool isValid() const; + bool hasKey( const QString &key ) const; + + void setGroup( const QString &gname ); + void writeEntry( const QString &key, const char* value ); + void writeEntry( const QString &key, const QString &value ); + void writeEntryCrypt( const QString &key, const QString &value ); + void writeEntry( const QString &key, int num ); +#ifdef Q_HAS_BOOL_TYPE + void writeEntry( const QString &key, bool b ); +#endif + void writeEntry( const QString &key, const QStringList &lst, const QChar &sep ); + void removeEntry( const QString &key ); + + QString readEntry( const QString &key, const QString &deflt = QString::null ) const; + QString readEntryCrypt( const QString &key, const QString &deflt = QString::null ) const; + QString readEntryDirect( const QString &key, const QString &deflt = QString::null ) const; + int readNumEntry( const QString &key, int deflt = -1 ) const; + bool readBoolEntry( const QString &key, bool deflt = FALSE ) const; + + // For compatibility, non-const versions. + QString readEntry( const QString &key, const QString &deflt ); + QString readEntryCrypt( const QString &key, const QString &deflt ); + QString readEntryDirect( const QString &key, const QString &deflt ); + int readNumEntry( const QString &key, int deflt ); + bool readBoolEntry( const QString &key, bool deflt ); + + void clearGroup(); + void removeGroup(); + + void write( const QString &fn = QString::null ); + +protected: + void read(); + bool parse( const QString &line ); + + QMap< QString, ConfigGroup > groups; + QMap< QString, ConfigGroup >::Iterator git; + QString filename; + QString lang; + QString glang; + bool changed; + ConfigPrivate *d; + static QString configFilename(const QString& name, Domain); +}; + +inline QString Config::readEntry( const QString &key, const QString &deflt ) const +{ return ((Config*)this)->readEntry(key,deflt); } +inline QString Config::readEntryCrypt( const QString &key, const QString &deflt ) const +{ return ((Config*)this)->readEntryCrypt(key,deflt); } +inline QString Config::readEntryDirect( const QString &key, const QString &deflt ) const +{ return ((Config*)this)->readEntryDirect(key,deflt); } +inline int Config::readNumEntry( const QString &key, int deflt ) const +{ return ((Config*)this)->readNumEntry(key,deflt); } +inline bool Config::readBoolEntry( const QString &key, bool deflt ) const +{ return ((Config*)this)->readBoolEntry(key,deflt); } + +#endif diff --git a/noncore/apps/checkbook/main.cpp b/noncore/apps/checkbook/main.cpp new file mode 100644 index 0000000..68f00e6 --- a/dev/null +++ b/noncore/apps/checkbook/main.cpp @@ -0,0 +1,11 @@ +#include +#include "qcheckbook.h" + +int main(int argc, char **argv) +{ + QPEApplication app(argc, argv); + QCheckBook *qcb = new QCheckBook(); + app.setMainWidget(qcb); + qcb->showMaximized(); + return app.exec(); +} diff --git a/noncore/apps/checkbook/qcheckbook.cpp b/noncore/apps/checkbook/qcheckbook.cpp new file mode 100644 index 0000000..797127e --- a/dev/null +++ b/noncore/apps/checkbook/qcheckbook.cpp @@ -0,0 +1,149 @@ +#include "qcheckbook.h" + +#include +#include +#include +#include +#include +#include + +QCheckBook::QCheckBook() + : QMainWindow(), + m_view(), + m_view2(), + m_view3() +{ + initCheck = false; + initMM = false; + setCaption("Checking"); + statusBar()->hide(); + menuBar()->hide(); + + bar = new QToolBar(this); + bar->setHorizontalStretchable( TRUE ); + + addToolBar(bar); + + Config config("qcheckbook"); + config.setGroup("Global"); + QString lastCheck = config.readEntry("LastCheckBook", QString("")); + + QString checkdirname = QDir::homeDirPath(); + checkdirname.append("/.checkbooks/"); + checkdirname.append(lastCheck); + QFile f(checkdirname); + + + if (lastCheck.isEmpty() == false && lastCheck != "" && f.exists() == true) + { + newCheck(lastCheck); + } else { + initMainMenus(); + } + + setToolBarsMovable( FALSE ); +} + +void QCheckBook::newCheck(const QString &filename) +{ + if (filename.isEmpty() == false) + { + initCheck = true; + if (m_view != 0) + { + delete m_view; + } + m_view = new QCheckView(this, filename); + m_view->hide(); + connect(m_view, SIGNAL(reload(const QString &)), this, SLOT(newCheck(const QString &))); + + if (initMM == true) + { + delete nb1; + } + + bar->clear(); + + mbar = new QMenuBar(bar); + mbar->setMargin(0); + + QPixmap newIcon = Resource::loadPixmap( "new" ); + nb2 = new QToolButton( newIcon, "New", QString::null, m_view, SLOT(newClicked()), bar, "new item" ); + QPixmap pixmap = Resource::loadPixmap( "pixmap" ); + m_filename = filename; + nb3 = new QToolButton( pixmap, "Graph", QString::null, this, SLOT(newGraph()), bar, "new graph" ); + + QPixmap closeIcon = Resource::loadPixmap( "close" ); + nb4 = new QToolButton( closeIcon, "Close", QString::null, this, SLOT(initMainMenus()), bar, "close graph" ); + + popup = new QPopupMenu(m_view); + popup->insertItem("&New Entry", m_view, SLOT(newClicked())); + popup->insertItem("&Graph Checkbook", this, SLOT(newGraph())); + popup->insertItem("&Close Checkbook", this, SLOT(initMainMenus())); + popup->insertItem("&Exit", this, SLOT(close())); + mbar->insertItem("&File", popup); + + setCentralWidget(m_view); + m_view->show(); + + Config config("qcheckbook"); + config.setGroup("Global"); + config.writeEntry("LastCheckBook", filename); + initMM = false; + } +} + +void QCheckBook::close() +{ + QApplication::exit(); +} + +void QCheckBook::newGraph() +{ + if (m_filename.isEmpty() == false) + { + m_view2 = new QCheckGraph(m_filename); + m_view2->showMaximized(); + } +} + +void QCheckBook::initMainMenus() +{ + Config config("qcheckbook"); + config.setGroup("Global"); + config.writeEntry("LastCheckBook", QString("")); + initMM = true; + m_filename = ""; + if (m_view3 != 0) + { + delete m_view3; + } + m_view3 = new QCheckMainMenu(this); + m_view3->hide(); + + if (initCheck == true) + { + delete nb2; + delete nb3; + delete nb4; + } + + bar->clear(); + + mbar = new QMenuBar(bar); + mbar->setMargin(0); + + QPixmap newIcon = Resource::loadPixmap( "new" ); + nb1 = new QToolButton( newIcon, "New", QString::null, m_view3, SLOT(newClicked()), bar, "new book" ); + + popup = new QPopupMenu(); + popup->insertItem("&New", m_view3, SLOT(newClicked())); + popup->insertItem("&Exit", this, SLOT(close())); + mbar->insertItem("&File", popup); + + setCentralWidget(m_view3); + m_view3->show(); + + connect(m_view3, SIGNAL(itemSelected(const QString &)), this, SLOT(newCheck(const QString &))); + initCheck = false; +} diff --git a/noncore/apps/checkbook/qcheckbook.h b/noncore/apps/checkbook/qcheckbook.h new file mode 100644 index 0000000..52c0d40 --- a/dev/null +++ b/noncore/apps/checkbook/qcheckbook.h @@ -0,0 +1,37 @@ +#include "qcheckview.h" +#include "qcheckgraph.h" +#include "qcheckmainmenu.h" + +#include +#include +#include +#include +#include "config.h" +#include + +class QCheckBook : public QMainWindow +{ + Q_OBJECT + public: + QCheckBook(); + private slots: + void newCheck(const QString &filename); + void newGraph(); + void close(); + void initMainMenus(); + private: + QCheckView *m_view; + QCheckGraph *m_view2; + QCheckMainMenu *m_view3; + QToolBar *bar; + QMenuBar *mbar; + int filemenuid; + QString m_filename; + QToolButton *nb1; + QToolButton *nb2; + QToolButton *nb3; + QToolButton *nb4; + bool initCheck; + bool initMM; + QPopupMenu *popup; +}; diff --git a/noncore/apps/checkbook/qcheckbook.pro b/noncore/apps/checkbook/qcheckbook.pro new file mode 100644 index 0000000..f601f6d --- a/dev/null +++ b/noncore/apps/checkbook/qcheckbook.pro @@ -0,0 +1,33 @@ +TEMPLATE = app +CONFIG = qt warn_on release +HEADERS = config.h \ + qcheckbook.h \ + qcheckdetails.h \ + qcheckentry.h \ + qcheckgraph.h \ + qcheckmainmenu.h \ + qcheckname.h \ + qcheckview.h \ + qrestrictedcombo.h \ + qrestrictedline.h +SOURCES = config.cpp \ + main.cpp \ + qcheckbook.cpp \ + qcheckdetails.cpp \ + qcheckentry.cpp \ + qcheckgraph.cpp \ + qcheckmainmenu.cpp \ + qcheckname.cpp \ + qcheckview.cpp \ + qrestrictedcombo.cpp \ + qrestrictedline.cpp +INTERFACES = qcheckdetailsbase.ui \ + qcheckentrybase.ui \ + qcheckgraphbase.ui \ + qcheckmmbase.ui \ + qchecknamebase.ui \ + qcheckviewbase.ui +INCLUDEPATH += $(OPIEDIR)/include +DEPENDPATH += $(OPIEDIR)/include +LIBS += -lqpe +TARGET = $(OPIEDIR)/bin/checkbook \ No newline at end of file diff --git a/noncore/apps/checkbook/qcheckdetails.cpp b/noncore/apps/checkbook/qcheckdetails.cpp new file mode 100644 index 0000000..19a5e82 --- a/dev/null +++ b/noncore/apps/checkbook/qcheckdetails.cpp @@ -0,0 +1,119 @@ +#include "qcheckdetails.h" + +QCheckDetails::QCheckDetails(int row, int col, const QStringList item) + : QMainWindow(), + m_view() +{ + m_view = new QCheckDetailsBase(this); + setCentralWidget(m_view); + + m_row = row; + m_col = col; + + QToolBar *bar = new QToolBar(this); + bar->setHorizontalStretchable( TRUE ); + + QPixmap newIcon = Resource::loadPixmap( "edit" ); + QPixmap trashIcon = Resource::loadPixmap( "trash" ); + QToolButton *nb1 = new QToolButton( newIcon, "Edit", QString::null, this, SLOT(editCheck()), bar, "edit transaction" ); + QToolButton *nb2 = new QToolButton( trashIcon, "Delete", QString::null, this, SLOT(deleteCheck()), bar, "delete transaction" ); + addToolBar(bar); + + QString text = ""; + if (item[0] == "true") + { + text.append("Payment to "); + text.append(item[1]); + } + if (item[0] == "false") + { + text.append("Deposit from "); + text.append(item[1]); + } + text.append(" on "); + text.append(item[7]); + text.append(" for "); + text.append(QString("$" + item[5])); + + text.append(", to make your balance $"); + text.append(item[9]); + text.append("."); + + text.append("

"); + text.append("Category: "); + text.append(item[2]); + text.append("
"); + text.append("Type: "); + + QString type = "No Type"; + if (item[0] == "true") + { + if(item[3] == "0") + { + type = "Debit Charge"; + } + if(item[3] == "1") + { + type = "Written Check"; + } + if(item[3] == "2") + { + type = "Transfer"; + } + if(item[3] == "3") + { + type = "Credit Card"; + } + } + + if (item[0] == "false") + { + if(item[3] == "0") + { + type = "Written Check"; + } + if(item[3] == "1") + { + type = "Automatic Payment"; + } + if(item[3] == "2") + { + type = "Transfer"; + } + if(item[3] == "3") + { + type = "Cash"; + } + } + + text.append(type); + text.append("
"); + if (item[4] != "0") + { + text.append("Check Number: "); + text.append(item[4]); + text.append("
"); + } + if (item[6] != ".00") + { + text.append("Extra Fee: "); + text.append(QString("$" + item[6])); + m_view->checkDetails->setText(text); + } + if (item[8] != "") + { + text.append("
Additional Comments: "); + text.append(item[8]); + } + m_view->checkDetails->setText(text); +} + +void QCheckDetails::editCheck() +{ + emit editClicked(m_row, m_col); +} + +void QCheckDetails::deleteCheck() +{ + emit deleteClicked(m_row, m_col); +} diff --git a/noncore/apps/checkbook/qcheckdetails.h b/noncore/apps/checkbook/qcheckdetails.h new file mode 100644 index 0000000..fe5fe1a --- a/dev/null +++ b/noncore/apps/checkbook/qcheckdetails.h @@ -0,0 +1,27 @@ +#include "qcheckdetailsbase.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include + +class QCheckDetails : public QMainWindow +{ + Q_OBJECT + public: + QCheckDetails(int row, int col, const QStringList item); + signals: + void editClicked(int, int); + void deleteClicked(int, int); + public slots: + void editCheck(); + void deleteCheck(); + private: + int m_row; + int m_col; + QCheckDetailsBase *m_view; +}; diff --git a/noncore/apps/checkbook/qcheckdetailsbase.ui b/noncore/apps/checkbook/qcheckdetailsbase.ui new file mode 100644 index 0000000..d94ba5e --- a/dev/null +++ b/noncore/apps/checkbook/qcheckdetailsbase.ui @@ -0,0 +1,62 @@ + +QCheckDetailsBase + + QWidget + + name + QCheckDetailsBase + + + geometry + + 0 + 0 + 240 + 265 + + + + caption + Transaction Details + + + + margin + 4 + + + spacing + 0 + + + QTextView + + name + checkDetails + + + + + + + QWidget +
qwidget.h
+ + -1 + -1 + + 0 + + 5 + 5 + + image0 +
+
+ + + image0 + 789c6dd2c10ac2300c00d07bbf2234b7229d1ddec44f503c0ae2a154410f53d0ed20e2bf6bdb656dd6861dd23d9a66591b0587fd1654235ebded6f0edcd53e419d87ae7b1f4f9b8f906d0bfe012317426a70b07bdc2f3ec77f8ed6b89559061a0343d06a124cc105596482585094bc0ae599b04646c9018926491b2205e140c485cace25755c175d0a967b622ff900b8cc9c7d29af594ea722d589167f813aa852ba07d94b9dce296e883fe7bb163f23896753 + + +
diff --git a/noncore/apps/checkbook/qcheckentry.cpp b/noncore/apps/checkbook/qcheckentry.cpp new file mode 100644 index 0000000..9ff02c9 --- a/dev/null +++ b/noncore/apps/checkbook/qcheckentry.cpp @@ -0,0 +1,251 @@ +#include "qcheckentry.h" + +QCheckEntry::QCheckEntry() + : QCheckEntryBase() +{ + connect(transAmount, SIGNAL(textChanged(const QString &)), this, SLOT(amountChanged(const QString &))); + connect(transFee, SIGNAL(textChanged(const QString &)), this, SLOT(transFeeChanged(const QString &))); + connect(payment, SIGNAL(clicked()), this, SLOT(paymentClicked())); + connect(deposit, SIGNAL(clicked()), this, SLOT(depositClicked())); + + QString todaysdate = QString::number(QDate::currentDate().month()); + todaysdate.append("/"); + todaysdate.append(QString::number(QDate::currentDate().day())); + todaysdate.append("/"); + todaysdate.append(QString::number(QDate::currentDate().year())); + dateEdit->setText(todaysdate); + + descriptionCombo->setFocus(); + + dateEdit->setValidChars("0123456789./-"); + dateEdit->setMaxLength(10); + + descriptionCombo->lineEdit()->setMaxLength(30); + + checkNumber->setValidChars("0123456789-"); + checkNumber->setMaxLength(10); + + transAmount->setValidChars("0123456789."); + + transFee->setMaxLength(5); + transFee->setValidChars("0123456789."); +} + +void QCheckEntry::paymentClicked() +{ + cmbCategory->clear(); + cmbCategory->insertItem( tr( "Automobile" ) ); + cmbCategory->insertItem( tr( "Bills" ) ); + cmbCategory->insertItem( tr( "CDs" ) ); + cmbCategory->insertItem( tr( "Clothing" ) ); + cmbCategory->insertItem( tr( "Computer" ) ); + cmbCategory->insertItem( tr( "DVDs" ) ); + cmbCategory->insertItem( tr( "Eletronics" ) ); + cmbCategory->insertItem( tr( "Entertainment" ) ); + cmbCategory->insertItem( tr( "Food" ) ); + cmbCategory->insertItem( tr( "Gasoline" ) ); + cmbCategory->insertItem( tr( "Misc" ) ); + cmbCategory->insertItem( tr( "Movies" ) ); + cmbCategory->insertItem( tr( "Rent" ) ); + cmbCategory->insertItem( tr( "Travel" ) ); + cmbCategory->setCurrentItem( 0 ); + transType->clear(); + transType->insertItem( tr( "Debit Charge" ) ); + transType->insertItem( tr( "Written Check" ) ); + transType->insertItem( tr( "Transfer" ) ); + transType->insertItem( tr( "Credit Card" ) ); +} + +void QCheckEntry::depositClicked() +{ + cmbCategory->clear(); + cmbCategory->insertItem( tr( "Work" ) ); + cmbCategory->insertItem( tr( "Family Member" ) ); + cmbCategory->insertItem( tr( "Misc. Credit" ) ); + cmbCategory->setCurrentItem( 0 ); + transType->clear(); + transType->insertItem( tr( "Written Check" ) ); + transType->insertItem( tr( "Automatic Payment" ) ); + transType->insertItem( tr( "Transfer" ) ); + transType->insertItem( tr( "Cash" ) ); +} + +QStringList QCheckEntry::popupEntry(const QStringList &originaldata) +{ + QCheckEntry qce; + + // This is how the list looks: + // 0: true or false, true == payment, false == deposit + // 1: description of the transaction + // 2: category name + // 3: transaction type (stores the integer value of the index of the combobox) + // 4: check number of the transaction (if any) + // 5: transaction amount + // 6: transaction fee (e.g. service charge, or ATM charge). + // 7: date of the transaction + // 8: additional notes + // 9: recently used descriptions + if (originaldata.count() > 1) + { + if (originaldata[0] == "true") + { + qce.payment->setChecked(true); + qce.paymentClicked(); + } else { + if (originaldata[0] == "false") + { + qce.deposit->setChecked(true); + qce.depositClicked(); + } + } + qce.descriptionCombo->lineEdit()->setText(originaldata[1]); + qce.cmbCategory->lineEdit()->setText(originaldata[2]); + qce.transType->setCurrentItem(originaldata[3].toInt()); + qce.checkNumber->setText(originaldata[4]); + qce.transAmount->setText(originaldata[5]); + qce.transFee->setText(originaldata[6]); + qce.dateEdit->setText(originaldata[7]); + qce.additionalNotes->setText(originaldata[8]); + QStringList recentlist; + if (!originaldata[9].isEmpty()) + { + recentlist = QStringList::split(',', originaldata[9], false); + } + if (!recentlist.isEmpty()) + { + qce.descriptionCombo->insertStringList(recentlist); + } + } else { + QStringList recentlist; + if (!originaldata[0].isEmpty()) + { + recentlist = QStringList::split(',', originaldata[0], false); + } + if (!recentlist.isEmpty()) + { + qce.descriptionCombo->insertStringList(recentlist); + } + } + + qce.setWFlags(Qt::WType_Modal); + qce.showMaximized(); + + qce.descriptionCombo->lineEdit()->clear(); + + if (qce.exec() == QDialog::Accepted) + { + // Validate that the user has inputed a valid dollar amount + if (qce.transFee->text().contains('.') == 0) + { + QString text = qce.transFee->text(); + text.append(".00"); + qce.transFee->setText(text); + } else { + QString tmp = qce.transFee->text(); + if (tmp.mid(tmp.find('.'), tmp.length()).length() == 1) + { + tmp.append("00"); + qce.transFee->setText(tmp); + } else { + if (tmp.mid(tmp.find('.'), tmp.length()).length() == 2) + { + tmp.append("0"); + qce.transFee->setText(tmp); + } + } + } + if (qce.transAmount->text().contains('.') == 0) + { + QString text = qce.transAmount->text(); + text.append(".00"); + qce.transAmount->setText(text); + } else { + QString tmp = qce.transAmount->text(); + if (tmp.mid(tmp.find('.'), tmp.length()).length() == 1) + { + tmp.append("00"); + qce.transAmount->setText(tmp); + } else { + if (tmp.mid(tmp.find('.'), tmp.length()).length() == 2) + { + tmp.append("0"); + qce.transAmount->setText(tmp); + } + } + } + + QString recent; + if (qce.descriptionCombo->count() != 0) + { + QStringList recentlist = QStringList::split(',', originaldata[9], false); + if (recentlist.count() >= 10) + { + recentlist.remove(recentlist.last()); + } + recentlist.prepend(qce.descriptionCombo->lineEdit()->text()); + recent = recentlist.join(","); + } else { + recent = qce.descriptionCombo->lineEdit()->text(); + } + + QString checkNumberString = qce.checkNumber->text(); + if (checkNumberString.isEmpty() == true) + { + checkNumberString = "0"; + } + + QString paymentChecked = "true"; + if (qce.payment->isChecked() == false) + { + paymentChecked = "false"; + } + QStringList returnvalue; + returnvalue << paymentChecked << qce.descriptionCombo->lineEdit()->text() << qce.cmbCategory->lineEdit()->text() << QString::number(qce.transType->currentItem()) << checkNumberString << qce.transAmount->text() << qce.transFee->text() << qce.dateEdit->text() << qce.additionalNotes->text() << recent; + return returnvalue; + } else { + QStringList blank; + return blank; + } +} + +void QCheckEntry::transFeeChanged(const QString &input) +{ + QString tmpinput = input; + if (tmpinput.contains('.') > 1) + { + int first = tmpinput.find('.'); + tmpinput = tmpinput.remove(tmpinput.find('.', (first + 1)), 1); + } + if (tmpinput.contains(QRegExp("\\.[0-9][0-9]{2}$")) >= 1) + { + tmpinput = tmpinput.remove((tmpinput.length() - 1), 1); + } + transFee->setText(tmpinput); +} + +void QCheckEntry::amountChanged(const QString &input) +{ + QString tmpinput = input; + if (tmpinput.contains('.') > 1) + { + int first = tmpinput.find('.'); + tmpinput = tmpinput.remove(tmpinput.find('.', (first + 1)), 1); + } + if (tmpinput.contains(QRegExp("\\.[0-9][0-9]{2}$")) >= 1) + { + tmpinput = tmpinput.remove((tmpinput.length() - 1), 1); + } + transAmount->setText(tmpinput); +} + +void QCheckEntry::accept() +{ + // Does the description combo not have any text in it? Do something if it doesn't! + if (descriptionCombo->lineEdit()->text().isEmpty() == true) + { + QMessageBox::critical(this, "Field Missing.", "You didn't enter a description for this transaction. Please fill out the \"Transaction Description\" field and try again."); + descriptionCombo->setFocus(); + return; + } + QDialog::accept(); +} diff --git a/noncore/apps/checkbook/qcheckentry.h b/noncore/apps/checkbook/qcheckentry.h new file mode 100644 index 0000000..f361bbf --- a/dev/null +++ b/noncore/apps/checkbook/qcheckentry.h @@ -0,0 +1,31 @@ +#include +#include +#include "qrestrictedline.h" +#include +#include +#include +#include +#include "qcheckentrybase.h" +#include +#include +#include +#include +#include +#include +#include +#include "config.h" + +class QCheckEntry : public QCheckEntryBase +{ + Q_OBJECT + public: + QCheckEntry(); + static QStringList popupEntry(const QStringList &originaldata); + private slots: + void amountChanged(const QString &); + void transFeeChanged(const QString &); + void paymentClicked(); + void depositClicked(); + protected slots: + virtual void accept(); +}; diff --git a/noncore/apps/checkbook/qcheckentrybase.ui b/noncore/apps/checkbook/qcheckentrybase.ui new file mode 100644 index 0000000..a57d761 --- a/dev/null +++ b/noncore/apps/checkbook/qcheckentrybase.ui @@ -0,0 +1,603 @@ + +QCheckEntryBase + + QDialog + + name + QCheckEntryBase + + + geometry + + 0 + 0 + 228 + 291 + + + + caption + Account Transaction + + + layoutMargin + + + layoutSpacing + + + + margin + 5 + + + spacing + 2 + + + + name + Spacer3 + + + orientation + Horizontal + + + sizeType + Expanding + + + sizeHint + + 20 + 20 + + + + + + name + Spacer5 + + + orientation + Horizontal + + + sizeType + Expanding + + + sizeHint + + 20 + 20 + + + + + QLabel + + name + TextLabel6 + + + font + + adobe-helvetica + 1 + + + + text + $ + + + + + name + Spacer8 + + + orientation + Horizontal + + + sizeType + Expanding + + + sizeHint + + 20 + 20 + + + + + QLabel + + name + TextLabel2 + + + text + Category: + + + + + name + Spacer7 + + + orientation + Horizontal + + + sizeType + Expanding + + + sizeHint + + 20 + 20 + + + + + + name + Spacer4 + + + orientation + Horizontal + + + sizeType + Expanding + + + sizeHint + + 20 + 20 + + + + + + name + Spacer6 + + + orientation + Horizontal + + + sizeType + Expanding + + + sizeHint + + 20 + 20 + + + + + QRestrictedLine + + name + transAmount + + + + QLabel + + name + TextLabel1 + + + text + Description: + + + + QLabel + + name + TextLabel3 + + + text + Type: + + + + QLabel + + name + TextLabel5 + + + text + Amount: + + + + QComboBox + + + text + Automobile + + + + + text + Bills + + + + + text + CDs + + + + + text + Clothing + + + + + text + Computer + + + + + text + DVDs + + + + + text + Eletronics + + + + + text + Entertainment + + + + + text + Food + + + + + text + Gasoline + + + + + text + Misc + + + + + text + Movies + + + + + text + Rent + + + + + text + Travel + + + + name + cmbCategory + + + editable + true + + + currentItem + 0 + + + autoCompletion + true + + + duplicatesEnabled + false + + + + QLabel + + name + TextLabel4 + + + text + Check Number: + + + + QLabel + + name + TextLabel6_2 + + + font + + adobe-helvetica + 1 + + + + text + $ + + + + QRestrictedLine + + name + transFee + + + + QLabel + + name + TextLabel7 + + + text + Extra Fee: + + + + QLabel + + name + TextLabel8 + + + text + Additional Notes: + + + + QComboBox + + name + descriptionCombo + + + editable + true + + + maxCount + 10 + + + insertionPolicy + BeforeCurrent + + + autoCompletion + true + + + duplicatesEnabled + false + + + + QLabel + + name + TextLabel9 + + + minimumSize + + 0 + 0 + + + + maximumSize + + 32767 + 32767 + + + + caption + + + + text + Date: + + + + QRestrictedLine + + name + dateEdit + + + + QRestrictedLine + + name + checkNumber + + + + QComboBox + + + text + Debit Charge + + + + + text + Written Check + + + + + text + Transfer + + + + + text + Credit Card + + + + name + transType + + + + QMultiLineEdit + + name + additionalNotes + + + + QButtonGroup + + name + ButtonGroup3 + + + sizePolicy + + 7 + 7 + + + + title + + + + layoutMargin + + + layoutSpacing + + + + margin + 4 + + + spacing + 0 + + + QRadioButton + + name + deposit + + + sizePolicy + + 1 + 1 + + + + text + Deposit + + + + QRadioButton + + name + payment + + + sizePolicy + + 1 + 1 + + + + text + Payment + + + checked + true + + + + + + + + + QRestrictedLine +
qrestrictedline.h
+ + -1 + -1 + + 0 + + 5 + 5 + + image0 +
+
+ + + image0 + 789c6dd23b0ec2300c00d03da7b0e22d42e9476c88232031222186c80c3074813220c4dd214dddd84dac0e759fe2386e1a07a7e3015c639e6318ef04740b0f70d7d730bccf97fdc7d8be87f8406737c62210606869dbb531f531a57f4a299d03a7e06c11cca1055508412c2889acc2ef425423b34840a645f28244936860d2c265d7923bae8b2f05cb35a91739002d2b5727d535cbe954a43ad1e22f700755caf7407cf4799fe286c47dbe3bf303014167a2 + + +
diff --git a/noncore/apps/checkbook/qcheckgraph.cpp b/noncore/apps/checkbook/qcheckgraph.cpp new file mode 100644 index 0000000..5b21ad8 --- a/dev/null +++ b/noncore/apps/checkbook/qcheckgraph.cpp @@ -0,0 +1,258 @@ +#include "qcheckgraph.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +QCheckGraph::QCheckGraph(const QString filename) + : QCheckGraphBase() +{ + QMenuBar *bar = new QMenuBar(this); + bar->setMargin(0); + QPopupMenu *popup = new QPopupMenu; + popup->insertItem("&Save Graph...", this, SLOT(saveGraphAsPicture())); + bar->insertItem("&File", popup); + + pixmapready = false; + config = new Config(filename, Config::File); + QString forresult = ""; + QString forresult2 = ""; + int i = 1; + for (; forresult != "Not Found"; i++) + { + config->setGroup(QString::number(i)); + forresult = config->readEntry("Description", QString("Not Found")); + forresult2 = config->readEntry("Category", QString("Not Found")); + if (forresult != "Not Found") + { + if (list.contains(forresult2) == 0) + { + config->setGroup("Totals"); + QString larger = config->readEntry("Spent", QString("no")); + QString smaller = config->readEntry(forresult2, QString("no")); + if (larger != "no" && smaller != "no") + { + list << forresult2; + QString percentage = calculator(smaller, larger, true); + + // Here we calculate how many pixels tall it will be by multiplying it by 200. + QString pixels = calculator(percentage, QString("200"), false); + + // This is done because it really doesn't need to have a decimal... just an int, and + // QString rounds doubles up to the nearest whole number in order to convert + // to an int (which is correct). + pixels = pixels.remove(pixels.find('.'), pixels.length()); + + if (pixels.toInt() <= 5) + { + pixels = "6"; + } + + list2 << pixels; + } + } + } else { + continue; + } + // We want to break this loop on the 7th (remember, starts at 0->6 == 7) item. + if (list.count() == 6) + { + break; + } + } + for (QStringList::Iterator it = list.begin(); it != list.end(); it++) + { + if ((*it).length() > 11) + { + (*it).truncate(8); + (*it).append("..."); + } + } + graphPixmap(); +} + +void QCheckGraph::graphPixmap() +{ + pixmapready = false; + graph = QPixmap(240,250); + QPainter p; + p.begin(&graph); + p.fillRect(0, 0, 240, 300, QColor(255,255,255)); + // Draw the graph lines + + // Y + p.drawLine( 40, 50, 40, 252 ); + + // X + p.drawLine( 40, 252, 203, 252 ); + + // Y stepup lines + p.drawLine( 40, 50, 37, 50); + p.drawLine( 40, 70, 37, 70); + p.drawLine( 40, 90, 37, 90); + p.drawLine( 40, 110, 37, 110); + p.drawLine( 40, 130, 37, 130); + p.drawLine( 40, 150, 37, 150); + p.drawLine( 40, 170, 37, 170); + p.drawLine( 40, 190, 37, 190); + p.drawLine( 40, 210, 37, 210); + p.drawLine( 40, 230, 37, 230); + p.drawLine( 40, 245, 37, 245); + + + // Y stepup values + p.drawText((35 - p.fontMetrics().width("100")), (50 + (p.fontMetrics().height() / 2)), "100"); + p.drawText((35 - p.fontMetrics().width("90")), (70 + (p.fontMetrics().height() / 2)), "90"); + p.drawText((35 - p.fontMetrics().width("80")), (90 + (p.fontMetrics().height() / 2)), "80"); + p.drawText((35 - p.fontMetrics().width("70")), (110 + (p.fontMetrics().height() / 2)), "70"); + p.drawText((35 - p.fontMetrics().width("60")), (130 + (p.fontMetrics().height() / 2)), "60"); + p.drawText((35 - p.fontMetrics().width("50")), (150 + (p.fontMetrics().height() / 2)), "50"); + p.drawText((35 - p.fontMetrics().width("40")), (170 + (p.fontMetrics().height() / 2)), "40"); + p.drawText((35 - p.fontMetrics().width("30")), (190 + (p.fontMetrics().height() / 2)), "30"); + p.drawText((35 - p.fontMetrics().width("20")), (210 + (p.fontMetrics().height() / 2)), "20"); + p.drawText((35 - p.fontMetrics().width("10")), (230 + (p.fontMetrics().height() / 2)), "10"); + p.drawText((35 - p.fontMetrics().width("<10")), (245 + (p.fontMetrics().height() / 2)), "<10"); + + // Draw the axis[sic?] labels + QString ylabel = "Percentage"; + int pixel = 100; + for (unsigned int i = 0; i != ylabel.length(); i++) + { + p.setBrush(QColor(0,0,0)); + p.drawText(5,pixel, QString(ylabel[i])); + pixel = pixel + p.fontMetrics().height(); + } + p.drawText(95, 265, "Category"); + + int i = 0; + // Hack: Using if()'s... switch was acting all wierd :{ + QStringList::Iterator it2 = list2.begin(); + for (QStringList::Iterator it = list.begin(); it != list.end(); it++) + { + qWarning(QString::number(i)); + if (i ==0) + { + // For the color code: + p.setBrush(QColor(255,0,0)); + p.drawRect(8,12, 8, 8); + + // Now the text: + p.setBrush(QColor(0,0,0)); + p.drawText(18,20, (*it)); + + // Last, but not least, we have the actual bar graph height. + p.setBrush(QColor(255,0,0)); + p.drawRect(47, ((202 - (*it2).toInt()) + 50), 15, (*it2).toInt()); + } + if (i ==1) + { + p.setBrush(QColor(255,255,0)); + p.drawRect(78,12, 8, 8); + + p.setBrush(QColor(0,0,0)); + p.drawText(88,20, (*it)); + + p.setBrush(QColor(255,255,0)); + p.drawRect(70, ((202 - (*it2).toInt()) + 50), 15, (*it2).toInt()); + } + if (i==2) + { + p.setBrush(QColor(0,255,0)); + p.drawRect(153,12, 8, 8); + p.setBrush(QColor(0,0,0)); + p.drawText(163,20, (*it)); + + p.setBrush(QColor(0,255,0)); + p.drawRect(98, ((202 - (*it2).toInt()) + 50), 15, (*it2).toInt()); + } + if (i==3) + { + p.setBrush(QColor(89,12,54)); + p.drawRect(8,27, 8, 8); + p.setBrush(QColor(0,0,0)); + p.drawText(18,35, (*it)); + + p.setBrush(QColor(89,12,54)); + p.drawRect(126, ((202 - (*it2).toInt()) + 50), 15, (*it2).toInt()); + } + if (i==4) + { + p.setBrush(QColor(0,0,255)); + p.drawRect(78,27, 8, 8); + p.setBrush(QColor(0,0,0)); + p.drawText(88,35, (*it)); + p.setBrush(QColor(0,0,255)); + p.drawRect(154, ((202 - (*it2).toInt()) + 50), 15, (*it2).toInt()); + } + if (i==5) + { + p.setBrush(QColor(100,40,0)); + p.drawRect(153,27, 8, 8); + p.setBrush(QColor(0,0,0)); + p.drawText(163,35, (*it)); + p.setBrush(QColor(100,40,0)); + p.drawRect(182, ((202 - (*it2).toInt()) + 50), 15, (*it2).toInt()); + } + i++; + it2++; + } + + p.end(); + pixmapready = true; + graphWidget->setBackgroundPixmap(graph); +} + +QString QCheckGraph::calculator(QString largervalue, QString smallervalue, bool divide) +{ +// largervalue = largervalue.remove(largervalue.find(".", 0, false), 1); +// smallervalue = smallervalue.remove(smallervalue.find(".", 0, false), 1); + + double largercents = largervalue.toDouble(); + double smallercents = smallervalue.toDouble(); + + double finalammount = 0; + + if (divide == true) + { + finalammount = (largercents / smallercents); + } else { + finalammount = (largercents * smallercents); + } + + qWarning(QString::number(finalammount)); + + return QString::number(finalammount); +} + +/*void QCheckGraph::paintEvent(QPaintEvent *e) +{ + if (pixmapready == true) + { + bitBlt((QPaintDevice *)(graphWidget), 0, 0, graph, 0,0); + QWidget::paintEvent(e); + } +} +*/ +void QCheckGraph::saveGraphAsPicture() +{ + QString homedir = QDir::homeDirPath(); + QDate current = QDate::currentDate(); + QString datestring = QString::number(current.month()); + datestring.append(QString::number(current.day())); + datestring.append(QString::number(current.year())); + QString filename = homedir; + filename.append("/Documents/graph"); + filename.append(datestring); + filename.append(".png"); + graph.save(filename, "PNG", 85); + QString graphmessage = "The graph was saved as graph"; + graphmessage.append(datestring); + graphmessage.append(".png. You may access it by returning to your home screen and clicking on the \"Documents\" tab in the upper right hand screen"); + QMessageBox::information(0, "File Saved", graphmessage); +} diff --git a/noncore/apps/checkbook/qcheckgraph.h b/noncore/apps/checkbook/qcheckgraph.h new file mode 100644 index 0000000..1cafef8 --- a/dev/null +++ b/noncore/apps/checkbook/qcheckgraph.h @@ -0,0 +1,25 @@ +#include +#include +#include +#include +#include +#include "config.h" + +#include "qcheckgraphbase.h" + +class QCheckGraph : public QCheckGraphBase +{ + Q_OBJECT + public: + QCheckGraph(const QString); + private: + QStringList list; + QStringList list2; + QString calculator(QString larger, QString smaller, bool divide); + QPixmap graph; + void graphPixmap(); + bool pixmapready; + Config *config; + private slots: + void saveGraphAsPicture(); +}; diff --git a/noncore/apps/checkbook/qcheckgraphbase.ui b/noncore/apps/checkbook/qcheckgraphbase.ui new file mode 100644 index 0000000..2763839 --- a/dev/null +++ b/noncore/apps/checkbook/qcheckgraphbase.ui @@ -0,0 +1,62 @@ + +QCheckGraphBase + + QDialog + + name + QCheckGraphBase + + + geometry + + 0 + 0 + 236 + 285 + + + + caption + Account Graph + + + + margin + 0 + + + spacing + 0 + + + QWidget + + name + graphWidget + + + + + + + QWidget +
qwidget.h
+ + -1 + -1 + + 0 + + 5 + 5 + + image0 +
+
+ + + image0 + 789c6dd2c10ac2300c00d07bbf2234b7229d1ddec44f503c0ae2a154410f53d0ed20e2bf6bdb656dd6861dd23d9a66591b0587fd1654235ebded6f0edcd53e419d87ae7b1f4f9b8f906d0bfe012317426a70b07bdc2f3ec77f8ed6b89559061a0343d06a124cc105596482585094bc0ae599b04646c9018926491b2205e140c485cace25755c175d0a967b622ff900b8cc9c7d29af594ea722d589167f813aa852ba07d94b9dce296e883fe7bb163f23896753 + + +
diff --git a/noncore/apps/checkbook/qcheckmainmenu.cpp b/noncore/apps/checkbook/qcheckmainmenu.cpp new file mode 100644 index 0000000..2382513 --- a/dev/null +++ b/noncore/apps/checkbook/qcheckmainmenu.cpp @@ -0,0 +1,74 @@ +#include "qcheckmainmenu.h" +#include "qcheckname.h" + +QCheckMainMenu::QCheckMainMenu(QWidget *parent) + : QCheckMMBase(parent) +{ + init(); +} + +void QCheckMainMenu::init() +{ + lstCheckBooks->clear(); + QString checkdirname = QDir::homeDirPath(); + checkdirname.append("/.checkbooks"); + QDir checkdir(checkdirname); + if (checkdir.exists() == true) + { + QStringList checkbooks = checkdir.entryList("*.qcb", QDir::Files|QDir::Readable|QDir::Writable, QDir::Time); + for (QStringList::Iterator it = checkbooks.begin(); it != checkbooks.end(); it++) + { + (*it) = (*it).remove((*it).find('.'), (*it).length()); + } + lstCheckBooks->insertStringList(checkbooks); + } + lstCheckBooks->clearSelection(); + connect(lstCheckBooks, SIGNAL(clicked(QListBoxItem *)), this, SLOT(slotSelected(QListBoxItem *))); + lstCheckBooks->clearSelection(); +} + +void QCheckMainMenu::slotSelected(QListBoxItem *item) +{ + if (item != 0) + { + QString text = item->text(); + if (text.isEmpty() == false) + { + text.append(".qcb"); + QString checkdirname = QDir::homeDirPath(); + checkdirname.append("/.checkbooks/"); + text.prepend(checkdirname); + emit itemSelected(text); + } + } +} + +void QCheckMainMenu::newClicked() +{ + QString checkname = QCheckName::getName(); + if (checkname.isEmpty() == false) + { + QString checkdirname = QDir::homeDirPath(); + checkdirname.append("/.checkbooks"); + QDir checkdir(checkdirname); + if (checkdir.exists() == false) + { + checkdir.mkdir(checkdirname); + } + checkdirname.append("/"); + checkdirname.append(checkname); + checkdirname.append(".qcb"); + QFile file(checkdirname); + if (file.exists() == false) + { + file.open(IO_WriteOnly); + QTextStream os(&file); + os << ""; + file.close(); + } + QFileInfo fi(file); + QString noextension = fi.fileName(); + noextension = noextension.remove(noextension.find('.'), noextension.length()); + lstCheckBooks->insertItem(noextension); + } +} diff --git a/noncore/apps/checkbook/qcheckmainmenu.h b/noncore/apps/checkbook/qcheckmainmenu.h new file mode 100644 index 0000000..456d3df --- a/dev/null +++ b/noncore/apps/checkbook/qcheckmainmenu.h @@ -0,0 +1,27 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "qcheckmmbase.h" + +class QCheckMainMenu : public QCheckMMBase +{ + Q_OBJECT + public: + QCheckMainMenu(QWidget *); + signals: + void itemSelected(const QString &); + private: + void init(); + private slots: + void slotSelected(QListBoxItem *); + public slots: + void newClicked(); +}; + diff --git a/noncore/apps/checkbook/qcheckmmbase.ui b/noncore/apps/checkbook/qcheckmmbase.ui new file mode 100644 index 0000000..efde990 --- a/dev/null +++ b/noncore/apps/checkbook/qcheckmmbase.ui @@ -0,0 +1,80 @@ + +QCheckMMBase + + QWidget + + name + QCheckMMBase + + + geometry + + 0 + 0 + 256 + 311 + + + + caption + Main Menu + + + + margin + 7 + + + spacing + 3 + + + QLabel + + name + TextLabel2 + + + text + Select from the check books below or click the "New" icon in the toolbar. + + + alignment + WordBreak|AlignVCenter|AlignLeft + + + wordwrap + + + + QListBox + + name + lstCheckBooks + + + + + + + QWidget +
qwidget.h
+ + -1 + -1 + + 0 + + 5 + 5 + + image0 +
+
+ + + image0 + 789c6dd2c10ac2300c00d07bbf2234b7229d1ddec44f503c0ae2a154410f53d0ed20e2bf6bdb656dd6861dd23d9a66591b0587fd1654235ebded6f0edcd53e419d87ae7b1f4f9b8f906d0bfe012317426a70b07bdc2f3ec77f8ed6b89559061a0343d06a124cc105596482585094bc0ae599b04646c9018926491b2205e140c485cace25755c175d0a967b622ff900b8cc9c7d29af594ea722d589167f813aa852ba07d94b9dce296e883fe7bb163f23896753 + + +
diff --git a/noncore/apps/checkbook/qcheckname.cpp b/noncore/apps/checkbook/qcheckname.cpp new file mode 100644 index 0000000..0e4d71c --- a/dev/null +++ b/noncore/apps/checkbook/qcheckname.cpp @@ -0,0 +1,36 @@ +#include "qcheckname.h" +#include +#include +#include +#include +#include "qrestrictedline.h" + +QCheckName::QCheckName() + : QCheckNameBase() +{ + connect(cmdDone, SIGNAL(clicked()), this, SLOT(clicked())); +} + +QString QCheckName::getName() +{ + QCheckName qcn; + qcn.setWFlags(Qt::WType_Modal); + qcn.leText->setValidChars("abcdefghijklmnopqrstuvwxyz0123456789 ABCDEFGHIJKLMNOPQRSTUVWXYZ"); + if (qcn.exec() == QDialog::Accepted) + { + return qcn.leText->text(); + } else { + return QString(""); + } +} + +void QCheckName::clicked() +{ + if (leText->text().isEmpty() == false) + { + hide(); + accept(); + } else { + QMessageBox::critical(this, "Missing Information", "Please enter the name of your Check Book and try again."); + } +} diff --git a/noncore/apps/checkbook/qcheckname.h b/noncore/apps/checkbook/qcheckname.h new file mode 100644 index 0000000..c47c4f9 --- a/dev/null +++ b/noncore/apps/checkbook/qcheckname.h @@ -0,0 +1,15 @@ +#include "qchecknamebase.h" +#include +#include + +class QCheckName : public QCheckNameBase +{ + Q_OBJECT + public: + QCheckName(); + static QString getName(); + private: + QWidget *m_parent; + private slots: + void clicked(); +}; diff --git a/noncore/apps/checkbook/qchecknamebase.ui b/noncore/apps/checkbook/qchecknamebase.ui new file mode 100644 index 0000000..b9bda19 --- a/dev/null +++ b/noncore/apps/checkbook/qchecknamebase.ui @@ -0,0 +1,136 @@ + +QCheckNameBase + + QDialog + + name + QCheckNameBase + + + geometry + + 0 + 0 + 228 + 108 + + + + caption + Check Book Name + + + QLabel + + name + TextLabel3 + + + geometry + + 10 + 5 + 70 + 16 + + + + font + + BDF-helvetica + 19 + 1 + + + + text + Name... + + + + QLabel + + name + TextLabel4 + + + geometry + + 10 + 25 + 210 + 25 + + + + text + Please name your check book (limit: 15 characters): + + + alignment + WordBreak|AlignVCenter|AlignLeft + + + wordwrap + + + + QPushButton + + name + cmdDone + + + geometry + + 75 + 80 + 75 + 25 + + + + text + &Done + + + + QRestrictedLine + + name + leText + + + geometry + + 5 + 51 + 216 + 25 + + + + + + + QRestrictedLine +
qrestrictedline.h
+ + -1 + -1 + + 0 + + 5 + 5 + + image0 +
+
+ + + image0 + 789c6dd23b0ec2300c00d03da7b0e22d42e9476c88232031222186c80c3074813220c4dd214dddd84dac0e759fe2386e1a07a7e3015c639e6318ef04740b0f70d7d730bccf97fdc7d8be87f8406737c62210606869dbb531f531a57f4a299d03a7e06c11cca1055508412c2889acc2ef425423b34840a645f28244936860d2c265d7923bae8b2f05cb35a91739002d2b5727d535cbe954a43ad1e22f700755caf7407cf4799fe286c47dbe3bf303014167a2 + + +
diff --git a/noncore/apps/checkbook/qcheckview.cpp b/noncore/apps/checkbook/qcheckview.cpp new file mode 100644 index 0000000..6f103e2 --- a/dev/null +++ b/noncore/apps/checkbook/qcheckview.cpp @@ -0,0 +1,458 @@ +#include "qcheckview.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +QCheckView::QCheckView(QWidget *parent, QString filename) + : QCheckViewBase(parent) +{ + tblTransactions->setHScrollBarMode( QTable::AlwaysOff ); + tblTransactions->setNumRows( 0 ); + tblTransactions->setNumCols( 4 ); + tblTransactions->setShowGrid( FALSE ); + tblTransactions->horizontalHeader()->setLabel(0, "Num", 29); + tblTransactions->horizontalHeader()->setLabel(1, "Description", 81); + tblTransactions->horizontalHeader()->setLabel(2, "Date", 57); + tblTransactions->horizontalHeader()->setLabel(3, "Amount", 59); + tblTransactions->verticalHeader()->hide(); + tblTransactions->setLeftMargin( 0 ); + tblTransactions->setSelectionMode(QTable::NoSelection); + + m_filename = filename; + load(filename); +} + +void QCheckView::deleteClicked(int row, int col) +{ + QStringList existing; + QString rowText = tblTransactions->text(row, 0); + config->setGroup(rowText); + QString originalamount = config->readEntry("Amount", "0.00"); + + config->setGroup("Data"); + int lastCheck = config->readNumEntry("LastCheck", 0); + + qWarning(rowText); + config->setGroup(rowText); + QString payment = config->readEntry("Payment", "true"); + if ( payment == QString("true") && rowText.toInt() <= lastCheck) + { + for(int i = row; i != (lastCheck); i++) + { + config->setGroup(tblTransactions->text(i, 0)); + QString ibalance = config->readEntry("Balance", "0.00"); + // this adds the old amount on to the transaction and then takes the new amount away + QString newbalance = calculator(ibalance, originalamount, false); + config->writeEntry("Balance", newbalance); + + if (i == (lastCheck - 1)) + { + config->setGroup("Totals"); + config->writeEntry("Balance", newbalance); + break; + } + } + QString category = config->readEntry("Category", "Error"); + if (category != QString("Error")) + { + config->setGroup("Totals"); + config->writeEntry("Spent", calculator(config->readEntry("Spent", QString("0")), originalamount, true)); + QString categorytotal = config->readEntry(category, QString("0")); + categorytotal = calculator(categorytotal, originalamount, true); + config->writeEntry(category, categorytotal); + } + } + if ( payment == QString("false") && rowText.toInt() <= lastCheck) + { + for(int i = row; i != (lastCheck); i++) + { + config->setGroup(tblTransactions->text(i, 0)); + QString ibalance = config->readEntry("Balance", "0.00"); + // this subtracts the old amount on to the transaction and then adds the new amount on + QString newbalance = calculator(ibalance, originalamount, true); + config->writeEntry("Balance", newbalance); + + if (i == lastCheck - 1) + { + config->setGroup("Totals"); + config->writeEntry("Balance", newbalance); + break; + } + } + config->setGroup("Totals"); + config->writeEntry("Deposited", calculator(config->readEntry("Deposited", QString("0")), originalamount, true)); + } + for (int i = rowText.toInt(); i != lastCheck; i++) + { + qWarning(QString::number(i +1)); + config->setGroup(QString::number(i +1)); + QString origamount = config->readEntry("Amount", "0"); + qWarning(origamount); + QString origbalance = config->readEntry("Balance", "0"); + QString origchecknumber = config->readEntry("CheckNumber", "0"); + QString origcomments = config->readEntry("Comments", ""); + QString origdate = config->readEntry("Date", "01/01/2000"); + QString origdescription = config->readEntry("Description", "No Description"); + QString origpayment = config->readEntry("Payment", "true"); + QString origtransactionfee = config->readEntry("TransactionFee", "0"); + QString origtype = config->readEntry("Type", "0"); + + if (config->hasKey("Category")) + { + QString origcategory = config->readEntry("Category", "No Category"); + config->removeGroup(); + config->setGroup(QString::number(i)); + config->clearGroup(); + config->writeEntry("Category", origcategory); + } else { + config->removeGroup(); + config->setGroup(QString::number(i)); + config->clearGroup(); + } + config->writeEntry("Amount", origamount); + config->writeEntry("Balance", origbalance); + config->writeEntry("CheckNumber", origchecknumber); + config->writeEntry("Comments", origcomments); + config->writeEntry("Date", origdate); + config->writeEntry("Description", origdescription); + config->writeEntry("Payment", origpayment); + config->writeEntry("TransactionFee", origtransactionfee); + config->writeEntry("Type", origtype); + } + tblTransactions->clearCell(row, col); + labelBalance->setText(QString("$" + config->readEntry("Balance", QString("0.00")))); + config->setGroup("Data"); + config->writeEntry("LastCheck", QString::number(QString(config->readEntry("LastCheck", 0)).toInt() -1)); + config->write(); + delete qcd; + emit reload(m_filename); + +} + +void QCheckView::load(const QString filename) +{ + config = new Config(filename, Config::File); + + connect(tblTransactions, SIGNAL(clicked(int, int, int, const QPoint &)), this, SLOT(tableClicked(int, int, int, const QPoint &))); + + config->setGroup("Totals"); + labelBalance->setText(QString("$" + config->readEntry("Balance", QString("0.00")))); + + config->setGroup("Data"); + int lastCheck = config->readNumEntry("LastCheck", 1); + for (int i = 1; i != (lastCheck + 1); i++) + { + config->setGroup(QString::number(i)); + QString item = config->readEntry("Description", QString("Not Found")); + if (item != "Not Found") + { + QTableItem *qti = new QTableItem(tblTransactions, QTableItem::Never, QString::number(i)); + QTableItem *qti1 = new QTableItem(tblTransactions, QTableItem::Never, config->readEntry("Description", QString("None"))); + QTableItem *qti2 = new QTableItem(tblTransactions, QTableItem::Never, config->readEntry("Date", QString("None"))); + QTableItem *qti3 = new QTableItem(tblTransactions, QTableItem::Never, QString("$" + config->readEntry("Amount", QString("0.00")))); + int row = tblTransactions->numRows(); + tblTransactions->setNumRows(row + 1); + tblTransactions->setItem(row,0, qti); + tblTransactions->setItem(row,1, qti1); + tblTransactions->setItem(row,2, qti2); + tblTransactions->setItem(row,3, qti3); + tblTransactions->updateCell(row, 0); + tblTransactions->updateCell(row, 1); + tblTransactions->updateCell(row, 2); + tblTransactions->updateCell(row, 3); + } + } +} + +void QCheckView::editClicked(int row, int col) +{ + delete qcd; + QStringList existing; + QString rowText = tblTransactions->text(row, 0); + config->setGroup("Data"); + QString recent = config->readEntry("Recent", ""); + + config->setGroup(rowText); + //We need the original amount to add or subtract to check's blanaces written after this edited check + QString originalamount = config->readEntry("Amount", "0.00"); + QString originalcategory = config->readEntry("Category", "None"); + + existing << config->readEntry("Payment", "true") << config->readEntry("Description", "No Description Found") << config->readEntry("Category", "Misc.") << config->readEntry("Type", "0") << config->readEntry("CheckNumber", "0") << originalamount << config->readEntry("TransactionFee", "") << config->readEntry("Date", "01/01/2001") << config->readEntry("Comments", "") << recent; + QStringList result = QCheckEntry::popupEntry(existing); + if (result.isEmpty() == false) + { + config->setGroup("Data"); + int lastCheck = config->readNumEntry("LastCheck", 0); + config->writeEntry("Recent", result[9]); + + config->setGroup(rowText); + + tblTransactions->setText(row, 1, result[1]); + tblTransactions->updateCell(row, 1); + + tblTransactions->setText(row, 2, result[7]); + tblTransactions->updateCell(row, 2); + + tblTransactions->setText(row, 3, QString("$" + result[5])); + tblTransactions->updateCell(row, 3); + + // This is how the list looks: + // 0: true or false, true == payment, false == deposit + // 1: description of the transaction + // 2: category name + // 3: transaction type (stores the integer value of the index of the combobox) + // 4: check number of the transaction (if any) + // 5: transaction amount + // 6: transaction fee (e.g. service charge, or ATM charge). + // 7: date of the transaction + // 8: additional comments + config->writeEntry("Payment", result[0]); + config->writeEntry("Description", result[1]); + if (result[0] == QString("true")) + { + config->writeEntry("Category", result[2]); + } + config->writeEntry("Type", result[3]); + config->writeEntry("CheckNumber", result[4]); + config->writeEntry("Amount", result[5]); + config->writeEntry("TransactionFee", result[6]); + config->writeEntry("Date", result[7]); + config->writeEntry("Comments", result[8]); + if (result[0] == QString("true")) + { + if (rowText.toInt() <= lastCheck) + { + for(int i = (rowText.toInt() - 1); i != (lastCheck); i++) + { + config->setGroup(tblTransactions->text(i, 0)); + QString ibalance = config->readEntry("Balance", "0.00"); + + // this adds the old amount on to the transaction and then takes the new amount away + QString newbalance = calculator(calculator(ibalance, originalamount, false), result[5], true); + config->writeEntry("Balance", newbalance); + if (i == (lastCheck - 1)) + { + config->setGroup("Totals"); + config->writeEntry("Balance", newbalance); + break; + } + } + } + config->setGroup("Totals"); + config->writeEntry("Spent", calculator(config->readEntry("Spent", QString("0")), originalamount, true)); + config->writeEntry("Spent", calculator(config->readEntry("Spent", QString("0")), result[5], false)); + + if (result[2] == originalcategory) + { + QString categorytotal = config->readEntry(result[2], QString("0")); + categorytotal = calculator(categorytotal, originalamount, true); + categorytotal = calculator(categorytotal, result[5], false); + config->writeEntry(result[2], categorytotal); + } else { + QString origtotal = config->readEntry(originalcategory, QString("0")); + QString origfinal = calculator(origtotal, result[5], true); + if (origfinal == "0" || origfinal == "0.00") + { + config->removeEntry(originalcategory); + } else { + config->writeEntry(originalcategory, origfinal); + } + QString categorytotal = config->readEntry(result[2], QString("0")); + categorytotal = calculator(categorytotal, originalamount, false); + config->writeEntry(result[2],categorytotal); + } + } + if (result[0] == QString("false")) + { + if (rowText.toInt() <= lastCheck) + { + for(int i = (rowText.toInt() - 1 ); i != (lastCheck); i++) + { + config->setGroup(tblTransactions->text(i, 0)); + QString ibalance = config->readEntry("Balance", "0.00"); + + // this subtracts the old amount on to the transaction and then adds the new amount on + QString newbalance = calculator(calculator(ibalance, originalamount, true), result[5], false); + config->writeEntry("Balance", newbalance); + if (i == lastCheck - 1) + { + config->setGroup("Totals"); + config->writeEntry("Balance", newbalance); + break; + } + } + } + config->setGroup("Totals"); + config->writeEntry("Deposited", calculator(config->readEntry("Deposited", QString("0")), originalamount, true)); + config->writeEntry("Deposited", calculator(config->readEntry("Deposited", QString("0")), result[5], false)); + } + labelBalance->setText(QString("$" + config->readEntry("Balance", QString("0.00")))); + config->write(); + } +} +void QCheckView::tableClicked(int row, int col, int mouseButton, const QPoint &mousePos) +{ + if (tblTransactions->text(row, col).isEmpty() == false) + { + QStringList existing; + config->setGroup(tblTransactions->text(row, 0)); + existing << config->readEntry("Payment", "true") << config->readEntry("Description", "No Description Found") << config->readEntry("Category", "Misc.") << config->readEntry("Type", "0") << config->readEntry("CheckNumber", "0") << config->readEntry("Amount", "0.00") << config->readEntry("TransactionFee", "0.00") << config->readEntry("Date", "01/01/2001") << config->readEntry("Comments", "") << config->readEntry("Balance", "0.00"); + qcd = new QCheckDetails(row, col, existing); + qcd->showMaximized(); + connect(qcd, SIGNAL(editClicked(int, int)), this, SLOT(editClicked(int, int))); + connect(qcd, SIGNAL(deleteClicked(int, int)), this, SLOT(deleteClicked(int, int))); + } +} + +void QCheckView::newClicked() +{ + config->setGroup("Data"); + QString recent = config->readEntry("Recent", ""); + QStringList kindablank; + kindablank << recent; + QStringList result = QCheckEntry::popupEntry(kindablank); + if (result.count() > 1) + { + QTableItem *qti = new QTableItem(tblTransactions, QTableItem::Never, result[1]); + int row = tblTransactions->numRows(); + tblTransactions->setNumRows(row + 1); + tblTransactions->setItem(row,1, qti); + tblTransactions->updateCell(row, 1); + config->setGroup("Data"); + config->writeEntry("Recent", result[9]); + int lastCheck = config->readNumEntry("LastCheck", 0); + if (lastCheck == 0) + { + config->writeEntry("LastCheck", 1); + } else { + config->writeEntry("LastCheck", (lastCheck + 1)); + } + QString number = QString::number(lastCheck + 1); + config->setGroup(number); + + QTableItem *qti1 = new QTableItem(tblTransactions, QTableItem::Never, number); + tblTransactions->setItem(row, 0, qti1); + tblTransactions->updateCell(row, 0); + + QTableItem *qti2 = new QTableItem(tblTransactions, QTableItem::Never, result[7]); + tblTransactions->setItem(row, 2, qti2); + tblTransactions->updateCell(row, 2); + + QTableItem *qti3 = new QTableItem(tblTransactions, QTableItem::Never, QString("$" + result[5])); + tblTransactions->setItem(row, 3, qti3); + tblTransactions->updateCell(row, 3); + + // This is how the list looks: + // 0: true or false, true == payment, false == deposit + // 1: description of the transaction + // 2: category name + // 3: transaction type (stores the integer value of the index of the combobox) + // 4: check number of the transaction (if any) + // 5: transaction amount + // 6: transaction fee (e.g. service charge, or ATM charge). + // 7: date of the transaction + config->writeEntry("Payment", result[0]); + config->writeEntry("Description", result[1]); + if (result[0] == QString("true")) + { + config->writeEntry("Category", result[2]); + } + config->writeEntry("Type", result[3]); + config->writeEntry("CheckNumber", result[4]); + config->writeEntry("Amount", result[5]); + config->writeEntry("TransactionFee", result[6]); + config->writeEntry("Date", result[7]); + config->writeEntry("Comments", result[8]); + config->setGroup("Totals"); + if (result[0] == QString("true")) + { + QString totalspent = config->readEntry("Spent", QString("0")); + totalspent = calculator(totalspent, result[5], false); + config->writeEntry("Spent", totalspent); + QString balance = config->readEntry("Balance", QString("0")); + balance = calculator(balance, result[5], true); + + // Make sure to add the fee on, if any + balance = calculator(balance, result[6], true); + + config->writeEntry("Balance", balance); + + config->setGroup(number); + config->writeEntry("Balance", balance); + + config->setGroup("Totals"); + QString categorytotal = config->readEntry(result[2], QString("0")); + categorytotal = calculator(categorytotal, result[5], false); + config->writeEntry(result[2], categorytotal); + } + if (result[0] == QString("false")) + { + QString totaldeposited = config->readEntry("Deposited", QString("0")); + totaldeposited = calculator(totaldeposited, result[5], false); + config->writeEntry("Deposited", totaldeposited); + QString balance = config->readEntry("Balance", QString("0")); + balance = calculator(balance, result[5], false); + + // Make sure to add the fee on, if any + balance = calculator(balance, result[6], true); + + config->writeEntry("Balance", balance); + + config->setGroup(number); + config->writeEntry("Balance", balance); + } + } + config->setGroup("Totals"); + labelBalance->setText(QString("$" + config->readEntry("Balance", QString("0.00")))); + config->write(); +} + +QString QCheckView::calculator(QString largervalue, QString smallervalue, bool subtract) +{ + // This class provides a way to eliminate the ARM processor problem of not being able to handle + // decimals. I just take the two QString'ed numbers and find the decimal point, then I remove the decimal + // point seperating the number into two. Then I convert it to cents (times it times 100) and add/ + // substract the two together. Put the decimals back in, and return. + + largervalue = largervalue.remove(largervalue.find(".", 0, false), 1); + smallervalue = smallervalue.remove(smallervalue.find(".", 0, false), 1); + + int largercents = largervalue.toInt(); + int smallercents = smallervalue.toInt(); + + int finalammount = 0; + + if (subtract == true) + { + finalammount = largercents - smallercents; + } else { + finalammount = largercents + smallercents; + } + + QString returnvalue = QString::number(finalammount); + if (returnvalue.length() >= 2) + { + returnvalue.insert((returnvalue.length() - 2), "."); + } else { + if (returnvalue.length() == 1) + { + returnvalue.prepend("0.0"); + } + } + return returnvalue; +} diff --git a/noncore/apps/checkbook/qcheckview.h b/noncore/apps/checkbook/qcheckview.h new file mode 100644 index 0000000..840dc8b --- a/dev/null +++ b/noncore/apps/checkbook/qcheckview.h @@ -0,0 +1,33 @@ +#include "qcheckviewbase.h" +#include "qrestrictedline.h" +#include "qcheckentry.h" +#include "qcheckdetails.h" + +#include +#include "config.h" +#include +#include +#include + +class QCheckView : public QCheckViewBase +{ + Q_OBJECT + public: + QCheckView(QWidget *, QString filename); + void load(const QString filename); + private: + Config *config; + QString calculator(QString largervalue, QString smallervalue, bool subtract); + int lastSortCol; + bool ascend; + QCheckDetails *qcd; + QString m_filename; + private slots: +// void entryActivated(int); + void newClicked(); + void tableClicked(int, int, int, const QPoint &mousePos); + void editClicked(int, int); + void deleteClicked(int, int); + signals: + void reload(const QString &filename); +}; diff --git a/noncore/apps/checkbook/qcheckviewbase.ui b/noncore/apps/checkbook/qcheckviewbase.ui new file mode 100644 index 0000000..00ed7dd --- a/dev/null +++ b/noncore/apps/checkbook/qcheckviewbase.ui @@ -0,0 +1,122 @@ + +QCheckViewBase + + QWidget + + name + QCheckViewBase + + + geometry + + 0 + 0 + 242 + 312 + + + + caption + Account Transactions + + + + margin + 5 + + + spacing + 1 + + + QLabel + + name + labelBalance + + + frameShape + MShape + + + frameShadow + MShadow + + + text + $0.00 + + + alignment + AlignCenter + + + hAlign + + + + QTable + + name + tblTransactions + + + hScrollBarMode + AlwaysOff + + + numRows + 0 + + + numCols + 4 + + + showGrid + false + + + + QLabel + + name + TextLabel3 + + + text + Balance: + + + alignment + AlignVCenter|AlignRight + + + hAlign + + + + + + + QWidget +
qwidget.h
+ + -1 + -1 + + 0 + + 5 + 5 + + image0 +
+
+ + + image0 + 789c6dd2c10ac2300c00d07bbf2234b7229d1ddec44f503c0ae2a154410f53d0ed20e2bf6bdb656dd6861dd23d9a66591b0587fd1654235ebded6f0edcd53e419d87ae7b1f4f9b8f906d0bfe012317426a70b07bdc2f3ec77f8ed6b89559061a0343d06a124cc105596482585094bc0ae599b04646c9018926491b2205e140c485cace25755c175d0a967b622ff900b8cc9c7d29af594ea722d589167f813aa852ba07d94b9dce296e883fe7bb163f23896753 + + +
diff --git a/noncore/apps/checkbook/qrestrictedcombo.cpp b/noncore/apps/checkbook/qrestrictedcombo.cpp new file mode 100644 index 0000000..e1533f6 --- a/dev/null +++ b/noncore/apps/checkbook/qrestrictedcombo.cpp @@ -0,0 +1,78 @@ +/* + * + * $Id$ + * + * Implementation of QRestrictedCombo + * + * Copyright (C) 1997 Michael Wiedmann, + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library 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 + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the Free + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + +#include + +#include "qrestrictedcombo.h" + +QRestrictedCombo::QRestrictedCombo( QWidget *parent, + const char *name, + const QString& valid ) + : QComboBox( parent, name ) +{ + qsValidChars = valid; +} + +QRestrictedCombo::~QRestrictedCombo() +{ + ; +} + + +void QRestrictedCombo::keyPressEvent( QKeyEvent *e ) +{ + // let QLineEdit process "special" keys and return/enter + // so that we still can use the default key binding + if (e->key() == Key_Enter || e->key() == Key_Return || e->key() == Key_Delete || e->ascii() < 32) + { + QComboBox::keyPressEvent(e); + return; + } + + // do we have a list of valid chars && + // is the pressed key in the list of valid chars? + if (!qsValidChars.isEmpty() && !qsValidChars.contains(e->ascii())) + { + // invalid char, emit signal and return + emit (invalidChar(e->key())); + return; + } + else + // valid char: let QLineEdit process this key as usual + QComboBox::keyPressEvent(e); + + return; +} + + +void QRestrictedCombo::setValidChars( const QString& valid) +{ + qsValidChars = valid; +} + +QString QRestrictedCombo::validChars() const +{ + return qsValidChars; +} + diff --git a/noncore/apps/checkbook/qrestrictedcombo.h b/noncore/apps/checkbook/qrestrictedcombo.h new file mode 100644 index 0000000..50ea59f --- a/dev/null +++ b/noncore/apps/checkbook/qrestrictedcombo.h @@ -0,0 +1,96 @@ +/* + * + * Definition of QRestrictedCombo + * + * Copyright (C) 1997 Michael Wiedmann, + * + * Edited 2001 by Nick Betcher to work + * with Qt-only. Changed class name from LRestrictedLine to + * QRestrictedCombo in order to accomidate Combo Boxes. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library 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 + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the Free + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + +#ifndef QRESTRICTEDCOMBO_H +#define QRESTRICTEDCOMBO_H + +#include + +/** + * The QRestrictedCombo widget is a variant of @ref QComboBox which + * accepts only a restricted set of characters as input. + * All other characters will be discarded and the signal @ref #invalidChar() + * will be emitted for each of them. + * + * Valid characters can be passed as a QString to the constructor + * or set afterwards via @ref #setValidChars(). + * The default key bindings of @ref QComboBox are still in effect. + * + * @short A line editor for restricted character sets. + * @author Michael Wiedmann + * @version 0.0.1 + */ +class QRestrictedCombo : public QComboBox +{ + Q_OBJECT + Q_PROPERTY( QString validChars READ validChars WRITE setValidChars ) + +public: + + /** + * Constructor: This contructor takes three - optional - arguments. + * The first two parameters are simply passed on to @ref QLineEdit. + * @param parent pointer to the parent widget + * @param name pointer to the name of this widget + * @param valid pointer to set of valid characters + */ + QRestrictedCombo( QWidget *parent=0, const char *name=0, + const QString& valid = QString::null); + + /** + * Destructs the restricted line editor. + */ + ~QRestrictedCombo(); + + /** + * All characters in the string valid are treated as + * acceptable characters. + */ + void setValidChars(const QString& valid); + /** + * @return the string of acceptable characters. + */ + QString validChars() const; + +signals: + + /** + * Emitted when an invalid character was typed. + */ + void invalidChar(int); + +protected: + /** + * @reimplemented + */ + void keyPressEvent( QKeyEvent *e ); + +private: + /// QString of valid characters for this line + QString qsValidChars; +}; + +#endif // QRESTRICTEDCOMBO_H diff --git a/noncore/apps/checkbook/qrestrictedline.cpp b/noncore/apps/checkbook/qrestrictedline.cpp new file mode 100644 index 0000000..8508c33 --- a/dev/null +++ b/noncore/apps/checkbook/qrestrictedline.cpp @@ -0,0 +1,78 @@ +/* + * + * $Id$ + * + * Implementation of QRestrictedLine + * + * Copyright (C) 1997 Michael Wiedmann, + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library 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 + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the Free + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + +#include + +#include "qrestrictedline.h" + +QRestrictedLine::QRestrictedLine( QWidget *parent, + const char *name, + const QString& valid ) + : QLineEdit( parent, name ) +{ + qsValidChars = valid; +} + +QRestrictedLine::~QRestrictedLine() +{ + ; +} + + +void QRestrictedLine::keyPressEvent( QKeyEvent *e ) +{ + // let QLineEdit process "special" keys and return/enter + // so that we still can use the default key binding + if (e->key() == Key_Enter || e->key() == Key_Return || e->key() == Key_Delete || e->ascii() < 32) + { + QLineEdit::keyPressEvent(e); + return; + } + + // do we have a list of valid chars && + // is the pressed key in the list of valid chars? + if (!qsValidChars.isEmpty() && !qsValidChars.contains(e->ascii())) + { + // invalid char, emit signal and return + emit (invalidChar(e->key())); + return; + } + else + // valid char: let QLineEdit process this key as usual + QLineEdit::keyPressEvent(e); + + return; +} + + +void QRestrictedLine::setValidChars( const QString& valid) +{ + qsValidChars = valid; +} + +QString QRestrictedLine::validChars() const +{ + return qsValidChars; +} + diff --git a/noncore/apps/checkbook/qrestrictedline.h b/noncore/apps/checkbook/qrestrictedline.h new file mode 100644 index 0000000..7e41cd9 --- a/dev/null +++ b/noncore/apps/checkbook/qrestrictedline.h @@ -0,0 +1,96 @@ +/* + * + * Definition of QRestrictedLine + * + * Copyright (C) 1997 Michael Wiedmann, + * + * Edited 2001 by Nick Betcher to work + * with Qt-only. Changed class name from QRestrictedLine to + * QRestrictedLine. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library 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 + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the Free + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + +#ifndef QRESTRICTEDLINE_H +#define QRESTRICTEDLINE_H + +#include + +/** + * The QRestrictedLine widget is a variant of @ref QLineEdit which + * accepts only a restricted set of characters as input. + * All other characters will be discarded and the signal @ref #invalidChar() + * will be emitted for each of them. + * + * Valid characters can be passed as a QString to the constructor + * or set afterwards via @ref #setValidChars(). + * The default key bindings of @ref QLineEdit are still in effect. + * + * @short A line editor for restricted character sets. + * @author Michael Wiedmann + * @version 0.0.1 + */ +class QRestrictedLine : public QLineEdit +{ + Q_OBJECT + Q_PROPERTY( QString validChars READ validChars WRITE setValidChars ) + +public: + + /** + * Constructor: This contructor takes three - optional - arguments. + * The first two parameters are simply passed on to @ref QLineEdit. + * @param parent pointer to the parent widget + * @param name pointer to the name of this widget + * @param valid pointer to set of valid characters + */ + QRestrictedLine( QWidget *parent=0, const char *name=0, + const QString& valid = QString::null); + + /** + * Destructs the restricted line editor. + */ + ~QRestrictedLine(); + + /** + * All characters in the string valid are treated as + * acceptable characters. + */ + void setValidChars(const QString& valid); + /** + * @return the string of acceptable characters. + */ + QString validChars() const; + +signals: + + /** + * Emitted when an invalid character was typed. + */ + void invalidChar(int); + +protected: + /** + * @reimplemented + */ + void keyPressEvent( QKeyEvent *e ); + +private: + /// QString of valid characters for this line + QString qsValidChars; +}; + +#endif // QRESTRICTEDLINE_H -- cgit v0.9.0.2