00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029 #include "listedit.h"
00030
00031
00032 #include <opie2/odebug.h>
00033 #include <opie2/oresource.h>
00034
00035 #include <qpe/applnk.h>
00036
00037 using namespace Opie::Core;
00038
00039
00040 #include <qlayout.h>
00041 #include <qlineedit.h>
00042 #include <qlistview.h>
00043 #include <qwidgetstack.h>
00044 #include <qcombobox.h>
00045 #include <qpushbutton.h>
00046
00047
00048 ListEdit::ListEdit( QWidget *parent, const char *sName )
00049 : QWidget(parent, sName), TableDef(sName)
00050 {
00051
00052 int fh = fontMetrics().height();
00053
00054
00055 QGridLayout *layout=new QGridLayout(this);
00056 layout->setSpacing( 2 );
00057 layout->setMargin( 4 );
00058
00059
00060 _typeTable = new QListView( this );
00061 ColumnDef *def=first();
00062 while( def ) {
00063 _typeTable->addColumn( def->getName() );
00064 def=next();
00065 }
00066 connect( _typeTable, SIGNAL( clicked(QListViewItem*,const QPoint&,int) ), this, SLOT( slotClick(QListViewItem*,const QPoint&,int) ) );
00067 layout->addMultiCellWidget(_typeTable, 0,4,0,4);
00068 _currentItem=NULL;
00069
00070
00071 _stack=new QWidgetStack( this );
00072 _stack->setMaximumHeight(fh+5);
00073 layout->addMultiCellWidget(_stack, 5,5,0,2);
00074 _typeEdit = new QLineEdit( _stack );
00075 _stack->raiseWidget(_typeEdit );
00076 connect( _typeEdit, SIGNAL( textChanged(const QString&) ), this, SLOT( slotEditChanged(const QString&) ) );
00077
00078
00079 _box=new QComboBox( _stack );
00080 connect( _box, SIGNAL( activated(const QString&) ), this, SLOT( slotActivated(const QString&) ) );
00081
00082
00083
00084 QPushButton *btn = new QPushButton( Opie::Core::OResource::loadPixmap( "new", Opie::Core::OResource::SmallIcon ),
00085 tr( "Add" ), this );
00086 btn->setFixedHeight( AppLnk::smallIconSize()+4 );
00087 connect( btn, SIGNAL( clicked() ), this, SLOT( slotAdd() ) );
00088 layout->addWidget( btn, 5, 3 );
00089
00090
00091 btn = new QPushButton( Opie::Core::OResource::loadPixmap( "trash", Opie::Core::OResource::SmallIcon ), tr( "Delete" ), this );
00092 btn->setFixedHeight( AppLnk::smallIconSize()+4 );
00093 connect( btn, SIGNAL( clicked() ), this, SLOT( slotDel() ) );
00094 layout->addWidget( btn, 5, 4 );
00095 }
00096
00097
00098 ListEdit::~ListEdit()
00099 {
00100 }
00101
00102
00103
00104 void ListEdit::slotEditChanged(const QString &str)
00105 {
00106 if( !_currentItem || _currentColumn<0 ) return;
00107 _currentItem->setText(_currentColumn, str);
00108 }
00109
00110
00111 void ListEdit::slotAdd()
00112 {
00113
00114 QString args[8];
00115 ColumnDef *pCol=this->first();
00116 int i=0;
00117 while( pCol && i<8 ) {
00118 args[i++]=pCol->getNewValue();
00119 pCol=this->next();
00120 }
00121 _currentItem=new QListViewItem(_typeTable, args[0], args[1], args[2], args[3], args[4], args[5], args[6], args[7] );
00122
00123
00124 fixTypes();
00125
00126
00127 QPoint pnt;
00128 slotClick(_currentItem, pnt, 0);
00129 _typeTable->setSelected( _currentItem, true );
00130
00131
00132 _typeEdit->setCursorPosition(0);
00133 _typeEdit->setSelection(0, _typeEdit->text().length() );
00134 }
00135
00136
00137 void ListEdit::slotDel()
00138 {
00139 if( !_currentItem ) return;
00140 delete _currentItem;
00141 _currentItem=NULL;
00142 _typeEdit->setText("");
00143 _stack->raiseWidget(_typeEdit);
00144 }
00145
00146
00147
00148
00149
00150
00151 class ColMap {
00152 public:
00153 ColMap(QString sValue, QListViewItem *pEntry) {
00154 _sValue=sValue;
00155 _pEntry=pEntry;
00156 }
00157 QString &getValue() { return(_sValue); }
00158 QListViewItem *getItem() { return(_pEntry); }
00159
00160 protected:
00161 QString _sValue;
00162 QListViewItem *_pEntry;
00163 };
00164
00165 class ColList : public QList<QString>
00166 {
00167 public:
00168 ColList() : QList<QString>() { }
00169
00170 protected:
00171 int compareItems(QCollection::Item, QCollection::Item);
00172 };
00173
00174 int ColList::compareItems(QCollection::Item i1, QCollection::Item i2) {
00175 return( ((QString *)i1)->compare(*(QString *)i2) );
00176 }
00177
00178 void ListEdit::fixTypes(int iColumn)
00179 {
00180
00181 ColumnDef *pDef=this->at(iColumn);
00182
00183
00184 if( !_typeTable->childCount() ) return;
00185 ColMap **colMap=new ColMap *[_typeTable->childCount()];
00186 QListViewItem *cur=_typeTable->firstChild();
00187 ColList lst;
00188 for(int i=0; i<_typeTable->childCount(); i++) {
00189 colMap[i]=new ColMap(cur->text(iColumn), cur);
00190 lst.append( &(colMap[i]->getValue()) );
00191 cur=cur->nextSibling();
00192 }
00193
00194
00195 int i=0;
00196 for(QString *ptr=lst.first(); ptr; ptr=lst.next()) {
00197 *ptr=ptr->stripWhiteSpace();
00198 if( ptr->isEmpty() ) {
00199 i++;
00200 if( i==1 ) *ptr=pDef->getNewValue();
00201 else ptr->sprintf("%s %d", (const char *)pDef->getNewValue(), i);
00202 }
00203 }
00204
00205
00206 lst.sort();
00207 QString repl;
00208 for(uint iCur=0; iCur<lst.count()-1; iCur++) {
00209 QString *current=lst.at(iCur);
00210 for(uint iNext=iCur+1; iNext<lst.count(); iNext++ ) {
00211 if( *current!=*lst.at(iNext) ) continue;
00212 for(int i=2; ; i++) {
00213 repl.sprintf("%s %d", (const char *)*current, i);
00214 bool bDup=false;
00215 uint iChk=iNext+1;
00216 while( iChk<lst.count() ) {
00217 QString *chk=lst.at(iChk);
00218 if( !chk->startsWith(*current) ) break;
00219 if( *chk==repl ) {
00220 bDup=true;
00221 break;
00222 }
00223 iChk++;
00224 }
00225 if( !bDup ) {
00226 *lst.at(iNext)=repl;
00227 break;
00228 }
00229 }
00230 }
00231 }
00232 lst.sort();
00233
00234
00235 for(int i=0; i<_typeTable->childCount(); i++) {
00236 colMap[i]->getItem()->setText(iColumn, colMap[i]->getValue());
00237 delete colMap[i];
00238 }
00239 delete colMap;
00240 }
00241
00242 void ListEdit::fixTypes()
00243 {
00244 int i;
00245 ColumnDef *pDef;
00246 for(pDef=this->first(), i=0; pDef; pDef=this->next(), i++) {
00247 if( pDef->hasFlag(ColumnDef::typeUnique) )
00248 fixTypes(i);
00249 }
00250 _typeTable->sort();
00251 }
00252
00253
00254
00255 void ListEdit::storeInList(QStringList &lst)
00256 {
00257
00258 lst.clear();
00259
00260
00261 fixTypes();
00262 QListViewItem *itm=_typeTable->firstChild();
00263 while( itm ) {
00264 int i=0;
00265 QString sAdd;
00266 ColumnDef *pDef;
00267 for(pDef=this->first(), i=0; pDef; pDef=this->next(), i++) {
00268 if( i>=1 ) sAdd+=";";
00269 sAdd += itm->text(i);
00270 }
00271 lst.append( sAdd );
00272 itm=itm->nextSibling();
00273 }
00274 }
00275
00276
00277
00278 void ListEdit::slotClick(QListViewItem *itm, const QPoint &pnt, int col)
00279 {
00280 (void)pnt;
00281
00282
00283 _currentItem=itm;
00284 _currentColumn=col;
00285 if( itm==NULL ) {
00286 _typeEdit->setText("");
00287 _stack->raiseWidget(_typeEdit);
00288 return;
00289 }
00290
00291
00292 if( _currentColumn<0 ) _currentColumn=0;
00293 ColumnDef *pDef=this->at(_currentColumn);
00294 if( pDef->isType(ColumnDef::typeString) ) {
00295 _typeEdit->setText( _currentItem->text(_currentColumn) );
00296 _stack->raiseWidget(_typeEdit);
00297 } else if( pDef->isType(ColumnDef::typeList) ){
00298 _box->clear();
00299 _box->insertStringList( pDef->getValueList() );
00300 QStringList::Iterator itr;
00301 int i=0;
00302 for(itr=pDef->getValueList().begin(); itr!=pDef->getValueList().end(); itr++) {
00303 if( (*itr)==_currentItem->text(_currentColumn) ) {
00304 _box->setCurrentItem(i);
00305 i=-1;
00306 break;
00307 }
00308 i++;
00309 }
00310 if( i>=0 ) {
00311 _box->insertItem( _currentItem->text(_currentColumn) );
00312 _box->setCurrentItem(i);
00313 }
00314 _stack->raiseWidget(_box);
00315 } else {
00316 odebug << "Unsupported column type for column " << (const char *)pDef->getName() << "" << oendl;
00317 _typeEdit->setText("");
00318 _stack->raiseWidget(_typeEdit);
00319 }
00320 }
00321
00322
00323
00324 void ListEdit::addColumnDef(ColumnDef *pDef)
00325 {
00326 _typeTable->addColumn( pDef->getName() );
00327 _vColumns.append(pDef);
00328 }
00329
00330
00331 void ListEdit::addData(QStringList &lst)
00332 {
00333
00334 QStringList::Iterator itr;
00335 for(itr=lst.begin(); itr!=lst.end(); itr++) {
00336 QStringList split=QStringList::split(";", *itr, true);
00337 QStringList::Iterator entry;
00338 QString args[8];
00339 int i=0;
00340 for(entry=split.begin(); entry!=split.end() && i<8; entry++, i++) {
00341 args[i]= (*entry);
00342 }
00343 while(i<8) {
00344 args[i++]="";
00345 }
00346 new QListViewItem(_typeTable, args[0], args[1], args[2], args[3], args[4], args[5], args[6], args[7]);
00347 }
00348 }
00349
00350
00351 void ListEdit::slotActivated(const QString &str)
00352 {
00353 if( _currentItem==NULL || _currentColumn<0 ) return;
00354 _currentItem->setText(_currentColumn, str);
00355 }