Initial commit

A good base to start working
This commit is contained in:
Grégory Soutadé 2010-05-14 15:04:01 +02:00
commit ee8d4c0c8f
25 changed files with 1003 additions and 0 deletions

26
Makefile Normal file
View File

@ -0,0 +1,26 @@
CXXFLAGS=`wx-config --cxxflags` -Wall -I. -ggdb
CXXFLAGS+=-I./lib/wxsqlite3-1.9.9/include
CXXFLAGS+=-I./lib/freechart/include
LDFLAGS=`wx-config --libs`
LDFLAGS+=-L./lib/wxsqlite3-1.9.9/lib/ -lwxcode_gtk2u_wxsqlite3-2.8
LDFLAGS+=-L./lib/freechart/lib -lwxcode_gtk2u_freechart-2.8
CXX=g++
SOURCES=$(wildcard model/*.cpp)
SOURCES+=$(wildcard view/*.cpp)
SOURCES+=$(wildcard controller/*.cpp)
SOURCES+=main.cpp sha1.cpp
HEADERS=$(wildcard model/*.h)
HEADERS+=$(wildcard view/*.h)
HEADERS+=$(wildcard controller/*.h)
HEADERS+=main.h sha1.h
all: kc
clean:
rm -f *.o
kc: $(SOURCES) $(HEADERS)
$(CXX) $(CXXFLAGS) $(SOURCES) -o $@ $(LDFLAGS)

44
controller/KissCount.cpp Normal file
View File

@ -0,0 +1,44 @@
#include "KissCount.h"
KissCount::KissCount()
{
_wxUI = new wxUI(this, _("KissCount"), wxPoint(50, 50), wxSize(1024, 768));
_wxUI->Show(true);
_wxUI->Centre();
_wxUI->Disable();
try
{
_db = new Database();
}
catch (std::string s)
{
_wxUI->Close(true);
throw s;
}
_wxUI->ChangeUser();
_wxUI->Enable();
}
KissCount::~KissCount()
{
delete _db;
delete _wxUI;
}
std::list<wxString> KissCount::GetUsers()
{
return _db->GetUsers();
}
bool KissCount::IsValidUser(wxString user, wxString password)
{
return _db->IsValidUser(user, password) ;
}
void KissCount::LoadUser(wxString user)
{
}

29
controller/KissCount.h Normal file
View File

@ -0,0 +1,29 @@
#ifndef KISSCOUNT_H
#define KISSCOUNT_H
#include <fstream>
#include <iostream>
#include <list>
#include <model/User.h>
#include <model/Account.h>
#include <model/Database.h>
#include <view/wxUI.h>
class wxUI;
class KissCount
{
public:
KissCount();
~KissCount();
std::list<wxString> GetUsers();
bool IsValidUser(wxString user, wxString password);
void LoadUser(wxString user);
private:
wxUI* _wxUI;
Database* _db;
};
#endif

10
init.sql Normal file
View File

@ -0,0 +1,10 @@
CREATE TABLE user (id INTEGER PRIMARY KEY, name VARCHAR(255), password VARCHAR(255));
CREATE TABLE account(id INTEGER PRIMARY KEY, user REFERENCES user(id), name VARCHAR(255), number VARCHAR(255), shared CHAR(1), default CHAR(1));
CREATE TABLE operation(id INTEGER PRIMARY KEY, account REFERENCES account(id), year INTEGER, month INTEGER, day INTEGER, description VARCHAR(255), category VARCHAR(255), fix_cost CHAR(1));
CREATE TABLE preference(id INTEGER PRIMARY KEY, user REFERENCES user(id), type VARCHAR(255), name VARCHAR(255), value VARCHAR(255));
CREATE TABLE default_preference(id INTEGER PRIMARY KEY, type VARCHAR(255), name VARCHAR(255), value VARCHAR(255));
INSERT INTO default_preference ("type", "value") VALUES ("category", "Fixe");
INSERT INTO default_preference ("type", "value") VALUES ("category", "Courses");
INSERT INTO default_preference ("type", "value") VALUES ("category", "Loisirs");
INSERT INTO default_preference ("type", "value") VALUES ("category", "Frais de fonctionnement");
INSERT INTO default_preference ("type", "value") VALUES ("category", "Exceptionnel");

46
main.cpp Normal file
View File

@ -0,0 +1,46 @@
#include "main.h"
class MyApp: public wxApp
{
virtual bool OnInit()
{
try
{
new KissCount();
}
catch (std::string s)
{
std::cerr << "Error " << s << "\n";
return false;
}
return true;
}
};
IMPLEMENT_APP(MyApp);
// bool MyApp::OnInit()
// {
// Main app;
// MyFrame *frame = new MyFrame( _("Hello World"), wxPoint(50, 50), wxSize(1024, 768) );
// AccountPanel* f = new AccountPanel(frame);
// frame->Show(true);
// SetTopWindow(frame);
// frame->Centre();
// frame->Disable();
// try
// {
// app.Init();
// }
// catch (std::string s)
// {
// std::cout << "Error " << s << "\n";
// frame->Close(true);
// }
// frame->Enable();
// return true;
// }

7
main.h Normal file
View File

@ -0,0 +1,7 @@
#ifndef MAIN_H
#define MAIN_H
#include <wx/wx.h>
#include <controller/KissCount.h>
#endif

28
model/Account.h Normal file
View File

@ -0,0 +1,28 @@
#ifndef ACCOUNT_H
#define ACCOUNT_H
#include <list>
#include <map>
struct operation {
unsigned int day;
unsigned int month;
unsigned int year;
unsigned int amount;
std::string description;
std::string category;
bool fix_cost;
} ;
class Account
{
private:
std::string _name;
std::string _number;
std::map<unsigned int, std::map<unsigned int, std::list<operation> > > _operations;
bool _shared;
bool _default;
};
#endif

115
model/Database.cpp Normal file
View File

@ -0,0 +1,115 @@
#include "Database.h"
Database::Database()
{
std::ifstream bdd_file;
bdd_file.open(BDD_FILE);
if (!bdd_file)
{
CreateDatabase();
}
else
_db.Open(_(BDD_FILE));
bdd_file.close();
}
void Database::CreateDatabase()
{
std::ifstream init_script;
std::string line;
wxMessageBox(_("No database found, creating a new one"), _("KissCount"), wxICON_EXCLAMATION | wxOK );
init_script.open(INIT_SCRIPT);
if (!init_script)
{
wxMessageBox(_(INIT_SCRIPT " not found, aborting"), _("Error"), wxICON_ERROR | wxOK );
throw "init.sql not found, aborting";
}
_db.Open(_(BDD_FILE));
do
{
getline(init_script, line);
if (!_db.CheckSyntax(line.data()))
{
std::cout << line << " is invalid !\n" ;
continue;
}
try
{
_db.ExecuteUpdate(line.data());
}
catch (...)
{
wxMessageBox(_("Error creating original database"), _("Error"), wxICON_ERROR | wxOK );
throw line;
}
} while (init_script);
init_script.close();
}
std::list<wxString> Database::GetUsers()
{
std::list<wxString> res;
// Check whether value exists in table
wxSQLite3ResultSet set ;
try
{
set = _db.ExecuteQuery(wxT("SELECT name FROM user"));
}
catch (wxSQLite3Exception e)
{
std::cerr << e.GetMessage().mb_str() << "\n" ;
return res;
}
while (set.NextRow())
{
res.push_front(set.GetAsString(0));
}
set.Finalize();
return res;
}
bool Database::IsValidUser(wxString user, wxString password)
{
bool res;
blk_SHA_CTX sha_ctx;
unsigned char sha[20];
wxString req, wxSHA;
wxSQLite3ResultSet set;
blk_SHA1_Init(&sha_ctx);
blk_SHA1_Update(&sha_ctx, password.c_str(), password.Length());
blk_SHA1_Final(sha, &sha_ctx);
for(int i=0; i<20; i++)
wxSHA += wxString::Format(wxT("%02F"), (int)sha[i]);
req = _("SELECT name FROM user WHERE name='") + user + _("' AND password='") + wxSHA + _("'");
// Check whether value exists in table
try
{
set = _db.ExecuteQuery(req);
}
catch (wxSQLite3Exception e)
{
std::cerr << e.GetMessage().mb_str() << "\n" ;
return false;
}
res = set.NextRow() ;
set.Finalize();
return res;
}

26
model/Database.h Normal file
View File

@ -0,0 +1,26 @@
#ifndef DATABASE_H
#define DATABASE_H
#include <fstream>
#include <list>
#include <wx/wxsqlite3.h>
#include <wx/wx.h>
#include <sha1.h>
#define BDD_FILE "kc.bdd"
#define INIT_SCRIPT "init.sql"
class Database
{
public:
Database();
std::list<wxString> GetUsers();
bool IsValidUser(wxString user, wxString password);
private:
wxSQLite3Database _db;
void CreateDatabase();
};
#endif

13
model/Preferences.h Normal file
View File

@ -0,0 +1,13 @@
#ifndef PREFERENCES_H
#define PREFERENCES_H
#include <wx/colour.h>
#include <map>
class Preferences
{
private:
std::map<std::string, wxColour> _colors;
};
#endif

17
model/User.h Normal file
View File

@ -0,0 +1,17 @@
#ifndef USER_H
#define USER_H
#include <list>
#include "Account.h"
class User
{
private:
unsigned int _id;
wxString _name;
wxString _password;
std::list<Account> _accounts;
};
#endif

BIN
ressources/Clients-icon.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 52 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 25 KiB

BIN
ressources/chart-icon.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 23 KiB

BIN
ressources/options-icon.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 22 KiB

283
sha1.cpp Normal file
View File

@ -0,0 +1,283 @@
/*
* SHA1 routine optimized to do word accesses rather than byte accesses,
* and to avoid unnecessary copies into the context array.
*
* This was initially based on the Mozilla SHA1 implementation, although
* none of the original Mozilla code remains.
*/
/* this is only to get definitions for memcpy(), ntohl() and htonl() */
//#include "../git-compat-util.h"
#include <string.h>
#include <arpa/inet.h>
#include "sha1.h"
#if defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__))
/*
* Force usage of rol or ror by selecting the one with the smaller constant.
* It _can_ generate slightly smaller code (a constant of 1 is special), but
* perhaps more importantly it's possibly faster on any uarch that does a
* rotate with a loop.
*/
#define SHA_ASM(op, x, n) ({ unsigned int __res; __asm__(op " %1,%0":"=r" (__res):"i" (n), "0" (x)); __res; })
#define SHA_ROL(x,n) SHA_ASM("rol", x, n)
#define SHA_ROR(x,n) SHA_ASM("ror", x, n)
#else
#define SHA_ROT(X,l,r) (((X) << (l)) | ((X) >> (r)))
#define SHA_ROL(X,n) SHA_ROT(X,n,32-(n))
#define SHA_ROR(X,n) SHA_ROT(X,32-(n),n)
#endif
/*
* If you have 32 registers or more, the compiler can (and should)
* try to change the array[] accesses into registers. However, on
* machines with less than ~25 registers, that won't really work,
* and at least gcc will make an unholy mess of it.
*
* So to avoid that mess which just slows things down, we force
* the stores to memory to actually happen (we might be better off
* with a 'W(t)=(val);asm("":"+m" (W(t))' there instead, as
* suggested by Artur Skawina - that will also make gcc unable to
* try to do the silly "optimize away loads" part because it won't
* see what the value will be).
*
* Ben Herrenschmidt reports that on PPC, the C version comes close
* to the optimized asm with this (ie on PPC you don't want that
* 'volatile', since there are lots of registers).
*
* On ARM we get the best code generation by forcing a full memory barrier
* between each SHA_ROUND, otherwise gcc happily get wild with spilling and
* the stack frame size simply explode and performance goes down the drain.
*/
#if defined(__i386__) || defined(__x86_64__)
#define setW(x, val) (*(volatile unsigned int *)&W(x) = (val))
#elif defined(__GNUC__) && defined(__arm__)
#define setW(x, val) do { W(x) = (val); __asm__("":::"memory"); } while (0)
#else
#define setW(x, val) (W(x) = (val))
#endif
/*
* Performance might be improved if the CPU architecture is OK with
* unaligned 32-bit loads and a fast ntohl() is available.
* Otherwise fall back to byte loads and shifts which is portable,
* and is faster on architectures with memory alignment issues.
*/
#if defined(__i386__) || defined(__x86_64__) || \
defined(__ppc__) || defined(__ppc64__) || \
defined(__powerpc__) || defined(__powerpc64__) || \
defined(__s390__) || defined(__s390x__)
#define get_be32(p) ntohl(*(unsigned int *)(p))
#define put_be32(p, v) do { *(unsigned int *)(p) = htonl(v); } while (0)
#else
#define get_be32(p) ( \
(*((unsigned char *)(p) + 0) << 24) | \
(*((unsigned char *)(p) + 1) << 16) | \
(*((unsigned char *)(p) + 2) << 8) | \
(*((unsigned char *)(p) + 3) << 0) )
#define put_be32(p, v) do { \
unsigned int __v = (v); \
*((unsigned char *)(p) + 0) = __v >> 24; \
*((unsigned char *)(p) + 1) = __v >> 16; \
*((unsigned char *)(p) + 2) = __v >> 8; \
*((unsigned char *)(p) + 3) = __v >> 0; } while (0)
#endif
/* This "rolls" over the 512-bit array */
#define W(x) (array[(x)&15])
/*
* Where do we get the source from? The first 16 iterations get it from
* the input data, the next mix it from the 512-bit array.
*/
#define SHA_SRC(t) get_be32(data + t)
#define SHA_MIX(t) SHA_ROL(W(t+13) ^ W(t+8) ^ W(t+2) ^ W(t), 1)
#define SHA_ROUND(t, input, fn, constant, A, B, C, D, E) do { \
unsigned int TEMP = input(t); setW(t, TEMP); \
E += TEMP + SHA_ROL(A,5) + (fn) + (constant); \
B = SHA_ROR(B, 2); } while (0)
#define T_0_15(t, A, B, C, D, E) SHA_ROUND(t, SHA_SRC, (((C^D)&B)^D) , 0x5a827999, A, B, C, D, E )
#define T_16_19(t, A, B, C, D, E) SHA_ROUND(t, SHA_MIX, (((C^D)&B)^D) , 0x5a827999, A, B, C, D, E )
#define T_20_39(t, A, B, C, D, E) SHA_ROUND(t, SHA_MIX, (B^C^D) , 0x6ed9eba1, A, B, C, D, E )
#define T_40_59(t, A, B, C, D, E) SHA_ROUND(t, SHA_MIX, ((B&C)+(D&(B^C))) , 0x8f1bbcdc, A, B, C, D, E )
#define T_60_79(t, A, B, C, D, E) SHA_ROUND(t, SHA_MIX, (B^C^D) , 0xca62c1d6, A, B, C, D, E )
static void blk_SHA1_Block(blk_SHA_CTX *ctx, const unsigned int *data)
{
unsigned int A,B,C,D,E;
unsigned int array[16];
A = ctx->H[0];
B = ctx->H[1];
C = ctx->H[2];
D = ctx->H[3];
E = ctx->H[4];
/* Round 1 - iterations 0-16 take their input from 'data' */
T_0_15( 0, A, B, C, D, E);
T_0_15( 1, E, A, B, C, D);
T_0_15( 2, D, E, A, B, C);
T_0_15( 3, C, D, E, A, B);
T_0_15( 4, B, C, D, E, A);
T_0_15( 5, A, B, C, D, E);
T_0_15( 6, E, A, B, C, D);
T_0_15( 7, D, E, A, B, C);
T_0_15( 8, C, D, E, A, B);
T_0_15( 9, B, C, D, E, A);
T_0_15(10, A, B, C, D, E);
T_0_15(11, E, A, B, C, D);
T_0_15(12, D, E, A, B, C);
T_0_15(13, C, D, E, A, B);
T_0_15(14, B, C, D, E, A);
T_0_15(15, A, B, C, D, E);
/* Round 1 - tail. Input from 512-bit mixing array */
T_16_19(16, E, A, B, C, D);
T_16_19(17, D, E, A, B, C);
T_16_19(18, C, D, E, A, B);
T_16_19(19, B, C, D, E, A);
/* Round 2 */
T_20_39(20, A, B, C, D, E);
T_20_39(21, E, A, B, C, D);
T_20_39(22, D, E, A, B, C);
T_20_39(23, C, D, E, A, B);
T_20_39(24, B, C, D, E, A);
T_20_39(25, A, B, C, D, E);
T_20_39(26, E, A, B, C, D);
T_20_39(27, D, E, A, B, C);
T_20_39(28, C, D, E, A, B);
T_20_39(29, B, C, D, E, A);
T_20_39(30, A, B, C, D, E);
T_20_39(31, E, A, B, C, D);
T_20_39(32, D, E, A, B, C);
T_20_39(33, C, D, E, A, B);
T_20_39(34, B, C, D, E, A);
T_20_39(35, A, B, C, D, E);
T_20_39(36, E, A, B, C, D);
T_20_39(37, D, E, A, B, C);
T_20_39(38, C, D, E, A, B);
T_20_39(39, B, C, D, E, A);
/* Round 3 */
T_40_59(40, A, B, C, D, E);
T_40_59(41, E, A, B, C, D);
T_40_59(42, D, E, A, B, C);
T_40_59(43, C, D, E, A, B);
T_40_59(44, B, C, D, E, A);
T_40_59(45, A, B, C, D, E);
T_40_59(46, E, A, B, C, D);
T_40_59(47, D, E, A, B, C);
T_40_59(48, C, D, E, A, B);
T_40_59(49, B, C, D, E, A);
T_40_59(50, A, B, C, D, E);
T_40_59(51, E, A, B, C, D);
T_40_59(52, D, E, A, B, C);
T_40_59(53, C, D, E, A, B);
T_40_59(54, B, C, D, E, A);
T_40_59(55, A, B, C, D, E);
T_40_59(56, E, A, B, C, D);
T_40_59(57, D, E, A, B, C);
T_40_59(58, C, D, E, A, B);
T_40_59(59, B, C, D, E, A);
/* Round 4 */
T_60_79(60, A, B, C, D, E);
T_60_79(61, E, A, B, C, D);
T_60_79(62, D, E, A, B, C);
T_60_79(63, C, D, E, A, B);
T_60_79(64, B, C, D, E, A);
T_60_79(65, A, B, C, D, E);
T_60_79(66, E, A, B, C, D);
T_60_79(67, D, E, A, B, C);
T_60_79(68, C, D, E, A, B);
T_60_79(69, B, C, D, E, A);
T_60_79(70, A, B, C, D, E);
T_60_79(71, E, A, B, C, D);
T_60_79(72, D, E, A, B, C);
T_60_79(73, C, D, E, A, B);
T_60_79(74, B, C, D, E, A);
T_60_79(75, A, B, C, D, E);
T_60_79(76, E, A, B, C, D);
T_60_79(77, D, E, A, B, C);
T_60_79(78, C, D, E, A, B);
T_60_79(79, B, C, D, E, A);
ctx->H[0] += A;
ctx->H[1] += B;
ctx->H[2] += C;
ctx->H[3] += D;
ctx->H[4] += E;
}
void blk_SHA1_Init(blk_SHA_CTX *ctx)
{
ctx->size = 0;
/* Initialize H with the magic constants (see FIPS180 for constants) */
ctx->H[0] = 0x67452301;
ctx->H[1] = 0xefcdab89;
ctx->H[2] = 0x98badcfe;
ctx->H[3] = 0x10325476;
ctx->H[4] = 0xc3d2e1f0;
}
void blk_SHA1_Update(blk_SHA_CTX *ctx, const void *data, unsigned long len)
{
int lenW = ctx->size & 63;
ctx->size += len;
/* Read the data into W and process blocks as they get full */
if (lenW) {
unsigned long left = 64 - lenW;
if (len < left)
left = len;
memcpy(lenW + (char *)ctx->W, data, left);
lenW = (lenW + left) & 63;
len -= left;
data = ((const char *)data + left);
if (lenW)
return;
blk_SHA1_Block(ctx, ctx->W);
}
while (len >= 64) {
blk_SHA1_Block(ctx, (const unsigned int*) data);
data = ((const char *)data + 64);
len -= 64;
}
if (len)
memcpy(ctx->W, data, len);
}
void blk_SHA1_Final(unsigned char hashout[20], blk_SHA_CTX *ctx)
{
static const unsigned char pad[64] = { 0x80 };
unsigned int padlen[2];
int i;
/* Pad with a binary 1 (ie 0x80), then zeroes, then length */
padlen[0] = htonl(ctx->size >> 29);
padlen[1] = htonl(ctx->size << 3);
i = ctx->size & 63;
blk_SHA1_Update(ctx, pad, 1+ (63 & (55 - i)));
blk_SHA1_Update(ctx, padlen, 8);
/* Output hash */
for (i = 0; i < 5; i++)
put_be32(hashout + i*4, ctx->H[i]);
}

22
sha1.h Normal file
View File

@ -0,0 +1,22 @@
/*
* SHA1 routine optimized to do word accesses rather than byte accesses,
* and to avoid unnecessary copies into the context array.
*
* This was initially based on the Mozilla SHA1 implementation, although
* none of the original Mozilla code remains.
*/
typedef struct {
unsigned long long size;
unsigned int H[5];
unsigned int W[16];
} blk_SHA_CTX;
void blk_SHA1_Init(blk_SHA_CTX *ctx);
void blk_SHA1_Update(blk_SHA_CTX *ctx, const void *dataIn, unsigned long len);
void blk_SHA1_Final(unsigned char hashout[20], blk_SHA_CTX *ctx);
#define git_SHA_CTX blk_SHA_CTX
#define git_SHA1_Init blk_SHA1_Init
#define git_SHA1_Update blk_SHA1_Update
#define git_SHA1_Final blk_SHA1_Final

21
view/AccountPanel.cpp Normal file
View File

@ -0,0 +1,21 @@
#include "AccountPanel.h"
AccountPanel::AccountPanel(KissCount* kiss, wxUI *parent) : wxPanel(&(*parent)), _kiss(kiss), _wxUI(parent), _tree(this, -1), _grid(this, -1)
{
wxBoxSizer *hbox = new wxBoxSizer(wxHORIZONTAL);
wxChartPanel* chart ;
SetSizer(hbox);
_pie = new PiePlot();
_grid.CreateGrid(10, 7);
chart = new wxChartPanel(this);
chart->SetChart(new Chart(_pie, _("Cost repartition")));
hbox->Add(&_tree, 0);
hbox->Add(&_grid, 0);
hbox->Add(chart, 0);
Fit();
SetMinSize(GetSize());
}

30
view/AccountPanel.h Normal file
View File

@ -0,0 +1,30 @@
#ifndef ACCOUNTPANEL_H
#define ACCOUNTPANEL_H
#include <wx/wx.h>
#include <wx/grid.h>
#include <wx/treectrl.h>
#include <wx/pie/pieplot.h>
#include <wx/chartpanel.h>
#include <controller/KissCount.h>
#include "wxUI.h"
class wxUI;
class KissCount;
class AccountPanel: public wxPanel
{
public:
AccountPanel(KissCount* kiss, wxUI *parent);
private:
KissCount* _kiss;
wxUI* _wxUI;
wxTreeCtrl _tree;
wxGrid _grid;
PiePlot* _pie;
};
#endif

39
view/ButtonPanel.cpp Normal file
View File

@ -0,0 +1,39 @@
#include "ButtonPanel.h"
enum {ID_BUTTON_ACCOUNT=1, ID_BUTTON_STATS, ID_BUTTON_PREFS, ID_BUTTON_CHANGE_USER};
BEGIN_EVENT_TABLE(ButtonPanel, wxPanel)
EVT_BUTTON(ID_BUTTON_CHANGE_USER, ButtonPanel::OnChangeUser)
END_EVENT_TABLE()
ButtonPanel::ButtonPanel(KissCount* kiss, wxUI *parent) : wxPanel(&(*parent)), _kiss(kiss), _wxUI(parent)
{
wxBoxSizer *hbox = new wxBoxSizer(wxHORIZONTAL);
_account = new wxBitmapButton(this, ID_BUTTON_ACCOUNT, wxBitmap(_(ACCOUNT_ICON)));
_stats = new wxBitmapButton(this, ID_BUTTON_STATS, wxBitmap(_(STATS_ICON)));
_prefs = new wxBitmapButton(this, ID_BUTTON_PREFS, wxBitmap(_(PREFS_ICON)));
_changeUser = new wxBitmapButton(this, ID_BUTTON_CHANGE_USER, wxBitmap(_(CHANGE_USER_ICON)));
SetSizer(hbox);
hbox->Add(_account);
hbox->Add(_stats);
hbox->Add(_prefs);
hbox->Add(_changeUser);
Fit();
SetMinSize(GetSize());
}
ButtonPanel::~ButtonPanel()
{
delete _account;
delete _stats;
delete _prefs;
delete _changeUser;
}
void ButtonPanel::OnChangeUser(wxCommandEvent& event)
{
_wxUI->ChangeUser();
}

38
view/ButtonPanel.h Normal file
View File

@ -0,0 +1,38 @@
#ifndef BUTTONPANEL_H
#define BUTTONPANEL_H
#include <wx/wx.h>
#include <wx/bmpbuttn.h>
#include <controller/KissCount.h>
#include "wxUI.h"
#define ACCOUNT_ICON "ressources/administrator-icon.png"
#define STATS_ICON "ressources/chart-icon.png"
#define PREFS_ICON "ressources/options-icon.png"
#define CHANGE_USER_ICON "ressources/Clients-icon.png"
class KissCount;
class wxUI;
class ButtonPanel: public wxPanel
{
public:
ButtonPanel(KissCount* kiss, wxUI *parent);
~ButtonPanel();
void OnChangeUser(wxCommandEvent& event);
private:
KissCount* _kiss;
wxUI* _wxUI;
wxBitmapButton* _account;
wxBitmapButton* _stats;
wxBitmapButton* _prefs;
wxBitmapButton* _changeUser;
DECLARE_EVENT_TABLE();
};
#endif

73
view/UsersDialog.cpp Normal file
View File

@ -0,0 +1,73 @@
#include "UsersDialog.h"
enum {ID_BUTTON_OK=1, ID_BUTTON_CANCEL};
BEGIN_EVENT_TABLE(UsersDialog, wxDialog)
EVT_BUTTON(ID_BUTTON_OK, UsersDialog::OnOK)
EVT_BUTTON(ID_BUTTON_CANCEL, UsersDialog::OnCancel)
END_EVENT_TABLE()
UsersDialog::UsersDialog(KissCount* kiss, wxUI *parent) : wxDialog(&(*parent), -1, _("Users")), _kiss(kiss), _wxUI(parent)
{
wxBoxSizer *vbox = new wxBoxSizer(wxVERTICAL);
wxBoxSizer *hbox = new wxBoxSizer(wxHORIZONTAL);
wxBoxSizer *vbox1 = new wxBoxSizer(wxVERTICAL);
wxBoxSizer *hbox1 = new wxBoxSizer(wxHORIZONTAL);
_users = new wxChoice(this, wxID_ANY);
_password = new wxTextCtrl(this, wxID_ANY);
_password->SetWindowStyle(wxTE_PASSWORD);
wxButton* ok = new wxButton(this, ID_BUTTON_OK, _("OK"));
wxButton* cancel = new wxButton(this, ID_BUTTON_CANCEL, _("Cancel"));
std::list<wxString> users_list = _kiss->GetUsers();
for(std::list<wxString>::iterator i = users_list.begin(); i != users_list.end(); i++)
{
_users->Append(*i);
}
vbox1->Add(_users);
vbox1->Add(-1, 10);
vbox1->Add(_password);
hbox->Add(vbox1, 0, wxEXPAND, 10);
hbox1->Add(ok);
hbox1->Add(-1, 10);
hbox1->Add(cancel);
vbox->Add(hbox, 0, wxALIGN_RIGHT | wxRIGHT | wxTOP, 10);
vbox->Add(-1, 40);
vbox->Add(hbox1, 0, wxALIGN_RIGHT | wxRIGHT | wxBOTTOM, 10);
Center();
SetSizer(vbox);
Layout();
}
void UsersDialog::OnOK(wxCommandEvent& event)
{
// No users in database
if (!_users->GetStringSelection().Length())
{
Close();
}
if (!_kiss->IsValidUser(_users->GetStringSelection(), _password->GetLineText(0)))
{
wxMessageBox(_("Invalid password"), _("Error"), wxICON_ERROR | wxOK );
}
else
{
_kiss->LoadUser(_users->GetStringSelection());
Close();
}
}
void UsersDialog::OnCancel(wxCommandEvent& event)
{
Close();
}

32
view/UsersDialog.h Normal file
View File

@ -0,0 +1,32 @@
#ifndef USERSDIALOG_H
#define USERSDIALOG_H
#include <list>
#include <wx/wx.h>
#include <wx/choice.h>
#include <wx/textctrl.h>
#include <controller/KissCount.h>
#include "wxUI.h"
class wxUI;
class KissCount;
class UsersDialog : public wxDialog
{
public:
UsersDialog(KissCount* kiss, wxUI *parent);
void OnOK(wxCommandEvent& event);
void OnCancel(wxCommandEvent& event);
private:
KissCount* _kiss;
wxUI* _wxUI;
wxChoice* _users;
wxTextCtrl* _password;
DECLARE_EVENT_TABLE()
};
#endif

65
view/wxUI.cpp Normal file
View File

@ -0,0 +1,65 @@
#include "wxUI.h"
BEGIN_EVENT_TABLE(wxUI, wxFrame)
EVT_MENU(ID_Quit, wxUI::OnQuit)
EVT_MENU(ID_About, wxUI::OnAbout)
END_EVENT_TABLE()
wxUI::wxUI(KissCount* kiss, const wxString& title, const wxPoint& pos, const wxSize& size)
: wxFrame(NULL, -1, title, pos, size), _kiss(kiss)
{
_hbox = new wxBoxSizer(wxVERTICAL);
ButtonPanel* buttons = new ButtonPanel(_kiss, this);
wxMenu *menuFile = new wxMenu;
menuFile->Append( ID_About, _("&About...") );
menuFile->AppendSeparator();
menuFile->Append( ID_Quit, _("E&xit") );
wxMenuBar *menuBar = new wxMenuBar;
menuBar->Append( menuFile, _("&File") );
SetMenuBar( menuBar );
CreateStatusBar();
SetStatusText( _("Welcome to wxWidgets!") );
SetSizer(_hbox);
_hbox->Add(buttons);
}
wxUI::~wxUI()
{
if (_accountPanel) delete _accountPanel;
}
void wxUI::OnQuit(wxCommandEvent& WXUNUSED(event))
{
Close(true);
}
void wxUI::OnAbout(wxCommandEvent& WXUNUSED(event))
{
wxMessageBox( _("This is a wxWidgets Hello world sample"),
_("About Hello World"),
wxOK | wxICON_INFORMATION, this );
}
void wxUI::ChangeUser()
{
UsersDialog u(_kiss, this);
u.ShowModal();
}
void wxUI::LoadUser()
{
if (_accountPanel)
{
_hbox->Detach(_accountPanel);
delete _accountPanel;
}
_accountPanel = new AccountPanel(_kiss, this);
_hbox->Add(_accountPanel);
Layout();
}

39
view/wxUI.h Normal file
View File

@ -0,0 +1,39 @@
#ifndef WXUI_H
#define WXUI_H
#include <wx/wx.h>
#include "AccountPanel.h"
#include "ButtonPanel.h"
#include "UsersDialog.h"
#include <controller/KissCount.h>
class KissCount;
class AccountPanel;
class wxUI: public wxFrame
{
public:
wxUI(KissCount* kiss, const wxString& title, const wxPoint& pos, const wxSize& size);
~wxUI();
void OnQuit(wxCommandEvent& event);
void OnAbout(wxCommandEvent& event);
void ChangeUser();
void LoadUser();
DECLARE_EVENT_TABLE();
private:
wxBoxSizer *_hbox;
AccountPanel *_accountPanel;
KissCount *_kiss;
};
enum
{
ID_Quit = 1,
ID_About,
};
#endif