Diffstat (limited to 'noncore/apps/checkbook/listedit.cpp') (more/less context) (ignore whitespace changes)
-rw-r--r-- | noncore/apps/checkbook/listedit.cpp | 340 |
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 --------------------------------------------------------------- | ||
40 | ListEdit::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 -------------------------------------------------------------- | ||
87 | ListEdit::~ListEdit() | ||
88 | { | ||
89 | } | ||
90 | |||
91 | |||
92 | // --- slotEditTypeChanged ---------------------------------------------------- | ||
93 | void ListEdit::slotEditChanged(const QString &str) | ||
94 | { | ||
95 | if( !_currentItem || _currentColumn<0 ) return; | ||
96 | _currentItem->setText(_currentColumn, str); | ||
97 | } | ||
98 | |||
99 | // --- slotAddType ------------------------------------------------------------ | ||
100 | void 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 ------------------------------------------------------------- | ||
122 | void 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. | ||
136 | class 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 | |||
150 | class ColList : public QList<QString> | ||
151 | { | ||
152 | public: | ||
153 | ColList() : QList<QString>() { } | ||
154 | |||
155 | protected: | ||
156 | int compareItems(QCollection::Item, QCollection::Item); | ||
157 | }; | ||
158 | |||
159 | int ColList::compareItems(QCollection::Item i1, QCollection::Item i2) { | ||
160 | return( ((QString *)i1)->compare(*(QString *)i2) ); | ||
161 | } | ||
162 | |||
163 | void 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 | |||
227 | void 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 ------------------------------------------------------------ | ||
240 | void 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 ------------------------------------------------------------ | ||
263 | void 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 ----------------------------------------------------------- | ||
309 | void ListEdit::addColumnDef(ColumnDef *pDef) | ||
310 | { | ||
311 | _typeTable->addColumn( pDef->getName() ); | ||
312 | _vColumns.append(pDef); | ||
313 | } | ||
314 | |||
315 | // --- addData ---------------------------------------------------------------- | ||
316 | void 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 ---------------------------------------------------------- | ||
336 | void ListEdit::slotActivated(const QString &str) | ||
337 | { | ||
338 | if( _currentItem==NULL || _currentColumn<0 ) return; | ||
339 | _currentItem->setText(_currentColumn, str); | ||
340 | } | ||