summaryrefslogtreecommitdiff
path: root/noncore/apps/checkbook/listedit.cpp
Unidiff
Diffstat (limited to 'noncore/apps/checkbook/listedit.cpp') (more/less context) (ignore whitespace changes)
-rw-r--r--noncore/apps/checkbook/listedit.cpp340
1 files changed, 340 insertions, 0 deletions
diff --git a/noncore/apps/checkbook/listedit.cpp b/noncore/apps/checkbook/listedit.cpp
new file mode 100644
index 0000000..99a6531
--- a/dev/null
+++ b/noncore/apps/checkbook/listedit.cpp
@@ -0,0 +1,340 @@
1/*
2                This file is part of the OPIE Project
3 =.
4             .=l. Copyright (c) 2002 Dan Williams <drw@handhelds.org>
5           .>+-=
6 _;:,     .>    :=|. This file is free software; you can
7.> <`_,   >  .   <= redistribute it and/or modify it under
8:`=1 )Y*s>-.--   : the terms of the GNU General Public
9.="- .-=="i,     .._ License as published by the Free Software
10 - .   .-<_>     .<> Foundation; either version 2 of the License,
11     ._= =}       : or (at your option) any later version.
12    .%`+i>       _;_.
13    .i_,=:_.      -<s. This file is distributed in the hope that
14     +  .  -:.       = it will be useful, but WITHOUT ANY WARRANTY;
15    : ..    .:,     . . . without even the implied warranty of
16    =_        +     =;=|` MERCHANTABILITY or FITNESS FOR A
17  _.=:.       :    :=>`: PARTICULAR PURPOSE. See the GNU General
18..}^=.=       =       ; Public License for more details.
19++=   -.     .`     .:
20 :     =  ...= . :.=- You should have received a copy of the GNU
21 -.   .:....=;==+<; General Public License along with this file;
22  -_. . .   )=.  = see the file COPYING. If not, write to the
23    --        :-=` Free Software Foundation, Inc.,
24 59 Temple Place - Suite 330,
25 Boston, MA 02111-1307, USA.
26
27*/
28
29#include "listedit.h"
30#include <qlayout.h>
31#include <qlineedit.h>
32#include <qlistview.h>
33#include <qwidgetstack.h>
34#include <qcombobox.h>
35#include <qpushbutton.h>
36#include <qpe/resource.h>
37
38
39// --- ListEdit ---------------------------------------------------------------
40ListEdit::ListEdit( QWidget *parent, const char *sName )
41 : QWidget(parent, sName), TableDef(sName)
42{
43 // get font height
44 int fh = fontMetrics().height();
45
46 // create layout
47 QGridLayout *layout=new QGridLayout(this);
48 layout->setSpacing( 2 );
49 layout->setMargin( 4 );
50
51 // type table
52 _typeTable = new QListView( this );
53 ColumnDef *def=first();
54 while( def ) {
55 _typeTable->addColumn( def->getName() );
56 def=next();
57 }
58 connect( _typeTable, SIGNAL( clicked(QListViewItem *, const QPoint &, int) ), this, SLOT( slotClick(QListViewItem *, const QPoint &, int ) ) );
59 layout->addMultiCellWidget(_typeTable, 0,4,0,4);
60 _currentItem=NULL;
61
62 // edit field
63 _stack=new QWidgetStack( this );
64 _stack->setMaximumHeight(fh+5);
65 layout->addMultiCellWidget(_stack, 5,5,0,2);
66 _typeEdit = new QLineEdit( _stack );
67 _stack->raiseWidget(_typeEdit );
68 connect( _typeEdit, SIGNAL( textChanged(const QString &) ), this, SLOT( slotEditChanged(const QString &) ) );
69
70 // combo box
71 _box=new QComboBox( _stack );
72 connect( _box, SIGNAL( activated(const QString &) ), this, SLOT( slotActivated(const QString &) ) );
73
74
75 // add button
76 QPushButton *btn = new QPushButton( Resource::loadPixmap( "checkbook/add" ), tr( "Add" ), this );
77 connect( btn, SIGNAL( clicked() ), this, SLOT( slotAdd() ) );
78 layout->addWidget( btn, 5, 3 );
79
80 // delete button
81 btn = new QPushButton( Resource::loadPixmap( "trash" ), tr( "Delete" ), this );
82 connect( btn, SIGNAL( clicked() ), this, SLOT( slotDel() ) );
83 layout->addWidget( btn, 5, 4 );
84}
85
86// --- ~ListEdit --------------------------------------------------------------
87ListEdit::~ListEdit()
88{
89}
90
91
92// --- slotEditTypeChanged ----------------------------------------------------
93void ListEdit::slotEditChanged(const QString &str)
94{
95 if( !_currentItem || _currentColumn<0 ) return;
96 _currentItem->setText(_currentColumn, str);
97}
98
99// --- slotAddType ------------------------------------------------------------
100void ListEdit::slotAdd()
101{
102 // construct new row
103 QString args[8];
104 ColumnDef *pCol=this->first();
105 int i=0;
106 while( pCol && i<8 ) {
107 args[i++]=pCol->getNewValue();
108 pCol=this->next();
109 }
110 _currentItem=new QListViewItem(_typeTable, args[0], args[1], args[2], args[3], args[4], args[5], args[6], args[7] );
111
112 // fix uniques
113 fixTypes();
114
115 // display col 0 of new value
116 QPoint pnt;
117 slotClick(_currentItem, pnt, 0);
118 _typeTable->setSelected( _currentItem, true );
119}
120
121// --- slotDel -------------------------------------------------------------
122void ListEdit::slotDel()
123{
124 if( !_currentItem ) return;
125 delete _currentItem;
126 _currentItem=NULL;
127 _typeEdit->setText("");
128 _stack->raiseWidget(_typeEdit);
129}
130
131
132// --- fixTypes ----------------------------------------------------------------
133// Makes sure all entries have a unique name and empty entries are replaced
134// by a generic string. The first version performs the operation on a particular
135// column, whereas the 2nd does it for all unique columns.
136class ColMap {
137 public:
138 ColMap(QString sValue, QListViewItem *pEntry) {
139 _sValue=sValue;
140 _pEntry=pEntry;
141 }
142 QString &getValue() { return(_sValue); }
143 QListViewItem *getItem() { return(_pEntry); }
144
145 protected:
146 QString _sValue;
147 QListViewItem *_pEntry;
148};
149
150class ColList : public QList<QString>
151{
152 public:
153 ColList() : QList<QString>() { }
154
155 protected:
156 int compareItems(QCollection::Item, QCollection::Item);
157};
158
159int ColList::compareItems(QCollection::Item i1, QCollection::Item i2) {
160 return( ((QString *)i1)->compare(*(QString *)i2) );
161}
162
163void ListEdit::fixTypes(int iColumn)
164{
165 // get column def
166 ColumnDef *pDef=this->at(iColumn);
167
168 // create map of entries
169 if( !_typeTable->childCount() ) return;
170 ColMap **colMap=new (ColMap *)[_typeTable->childCount()];
171 QListViewItem *cur=_typeTable->firstChild();
172 ColList lst;
173 for(int i=0; i<_typeTable->childCount(); i++) {
174 colMap[i]=new ColMap(cur->text(iColumn), cur);
175 lst.append( &(colMap[i]->getValue()) );
176 cur=cur->nextSibling();
177 }
178
179 // fix empty entries
180 int i=0;
181 for(QString *ptr=lst.first(); ptr; ptr=lst.next()) {
182 *ptr=ptr->stripWhiteSpace();
183 if( ptr->isEmpty() ) {
184 i++;
185 if( i==1 ) *ptr=pDef->getNewValue();
186 else ptr->sprintf("%s %d", (const char *)pDef->getNewValue(), i);
187 }
188 }
189
190 // fix dups
191 lst.sort();
192 QString repl;
193 for(uint iCur=0; iCur<lst.count()-1; iCur++) {
194 QString *current=lst.at(iCur);
195 for(uint iNext=iCur+1; iNext<lst.count(); iNext++ ) {
196 if( *current!=*lst.at(iNext) ) continue;
197 for(int i=2; ; i++) {
198 repl.sprintf("%s %d", (const char *)*current, i);
199 bool bDup=false;
200 uint iChk=iNext+1;
201 while( iChk<lst.count() ) {
202 QString *chk=lst.at(iChk);
203 if( !chk->startsWith(*current) ) break;
204 if( *chk==repl ) {
205 bDup=true;
206 break;
207 }
208 iChk++;
209 }
210 if( !bDup ) {
211 *lst.at(iNext)=repl;
212 break;
213 }
214 }
215 }
216 }
217 lst.sort();
218
219 // copy back clean up col map
220 for(int i=0; i<_typeTable->childCount(); i++) {
221 colMap[i]->getItem()->setText(iColumn, colMap[i]->getValue());
222 delete colMap[i];
223 }
224 delete colMap;
225}
226
227void ListEdit::fixTypes()
228{
229 int i;
230 ColumnDef *pDef;
231 for(pDef=this->first(), i=0; pDef; pDef=this->next(), i++) {
232 if( pDef->hasFlag(ColumnDef::typeUnique) )
233 fixTypes(i);
234 }
235 _typeTable->sort();
236}
237
238
239// --- storeInList ------------------------------------------------------------
240void ListEdit::storeInList(QStringList &lst)
241{
242 // delete old content
243 lst.clear();
244
245 // add new one
246 fixTypes();
247 QListViewItem *itm=_typeTable->firstChild();
248 while( itm ) {
249 int i=0;
250 QString sAdd;
251 ColumnDef *pDef;
252 for(pDef=this->first(), i=0; pDef; pDef=this->next(), i++) {
253 if( i>=1 ) sAdd+=";";
254 sAdd += itm->text(i);
255 }
256 lst.append( sAdd );
257 itm=itm->nextSibling();
258 }
259}
260
261
262// --- slotClicked ------------------------------------------------------------
263void ListEdit::slotClick(QListViewItem *itm, const QPoint &pnt, int col)
264{
265 (void)pnt; // get rid of unused warning;
266
267 // save values
268 _currentItem=itm;
269 _currentColumn=col;
270 if( itm==NULL ) {
271 _typeEdit->setText("");
272 _stack->raiseWidget(_typeEdit);
273 return;
274 }
275
276 // display value
277 if( _currentColumn<0 ) _currentColumn=0;
278 ColumnDef *pDef=this->at(_currentColumn);
279 if( pDef->isType(ColumnDef::typeString) ) {
280 _typeEdit->setText( _currentItem->text(_currentColumn) );
281 _stack->raiseWidget(_typeEdit);
282 } else if( pDef->isType(ColumnDef::typeList) ){
283 _box->clear();
284 _box->insertStringList( pDef->getValueList() );
285 QStringList::Iterator itr;
286 int i=0;
287 for(itr=pDef->getValueList().begin(); itr!=pDef->getValueList().end(); itr++) {
288 if( (*itr)==_currentItem->text(_currentColumn) ) {
289 _box->setCurrentItem(i);
290 i=-1;
291 break;
292 }
293 i++;
294 }
295 if( i>=0 ) {
296 _box->insertItem( _currentItem->text(_currentColumn) );
297 _box->setCurrentItem(i);
298 }
299 _stack->raiseWidget(_box);
300 } else {
301 qDebug( "Unsupported column type for column %s", (const char *)pDef->getName() );
302 _typeEdit->setText("");
303 _stack->raiseWidget(_typeEdit);
304 }
305}
306
307
308// --- addColumnDef -----------------------------------------------------------
309void ListEdit::addColumnDef(ColumnDef *pDef)
310{
311 _typeTable->addColumn( pDef->getName() );
312 _vColumns.append(pDef);
313}
314
315// --- addData ----------------------------------------------------------------
316void ListEdit::addData(QStringList &lst)
317{
318 // run through list
319 QStringList::Iterator itr;
320 for(itr=lst.begin(); itr!=lst.end(); itr++) {
321 QStringList split=QStringList::split(";", *itr, true);
322 QStringList::Iterator entry;
323 QString args[8];
324 int i=0;
325 for(entry=split.begin(); entry!=split.end() && i<8; entry++, i++) {
326 args[i]= (*entry);
327 }
328 while(i<8) {
329 args[i++]="";
330 }
331 new QListViewItem(_typeTable, args[0], args[1], args[2], args[3], args[4], args[5], args[6], args[7]);
332 }
333}
334
335// --- slotActivated ----------------------------------------------------------
336void ListEdit::slotActivated(const QString &str)
337{
338 if( _currentItem==NULL || _currentColumn<0 ) return;
339 _currentItem->setText(_currentColumn, str);
340}