Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Namespace Members | Class Members | File Members | Related Pages

listedit.cpp

Go to the documentation of this file.
00001 /*
00002                      This file is part of the OPIE Project
00003                =.
00004       .=l.            Copyright (c)  2002 Dan Williams <drw@handhelds.org>
00005      .>+-=
00006 _;:,   .>  :=|.         This file is free software; you can
00007 .> <`_,  > .  <=          redistribute it and/or modify it under
00008 :`=1 )Y*s>-.--  :           the terms of the GNU General Public
00009 .="- .-=="i,   .._         License as published by the Free Software
00010 - .  .-<_>   .<>         Foundation; either version 2 of the License,
00011   ._= =}    :          or (at your option) any later version.
00012   .%`+i>    _;_.
00013   .i_,=:_.   -<s.       This file is distributed in the hope that
00014   + . -:.    =       it will be useful, but WITHOUT ANY WARRANTY;
00015   : ..  .:,   . . .    without even the implied warranty of
00016   =_    +   =;=|`    MERCHANTABILITY or FITNESS FOR A
00017  _.=:.    :  :=>`:     PARTICULAR PURPOSE. See the GNU General
00018 ..}^=.=    =    ;      Public License for more details.
00019 ++=  -.   .`   .:
00020 :   = ...= . :.=-        You should have received a copy of the GNU
00021 -.  .:....=;==+<;          General Public License along with this file;
00022  -_. . .  )=. =           see the file COPYING. If not, write to the
00023   --    :-=`           Free Software Foundation, Inc.,
00024                              59 Temple Place - Suite 330,
00025                              Boston, MA 02111-1307, USA.
00026 
00027 */
00028 
00029 #include "listedit.h"
00030 
00031 /* OPIE */
00032 #include <opie2/odebug.h>
00033 #include <opie2/oresource.h>
00034 
00035 #include <qpe/applnk.h>
00036 
00037 using namespace Opie::Core;
00038 
00039 /* QT */
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 // --- ListEdit ---------------------------------------------------------------
00048 ListEdit::ListEdit( QWidget *parent, const char *sName )
00049     : QWidget(parent, sName), TableDef(sName)
00050 {
00051     // get font height
00052     int fh = fontMetrics().height();
00053 
00054     // create layout
00055     QGridLayout *layout=new QGridLayout(this);
00056     layout->setSpacing( 2 );
00057         layout->setMargin( 4 );
00058 
00059     // type table
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     // edit field
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     // combo box
00079     _box=new QComboBox( _stack );
00080     connect( _box, SIGNAL( activated(const QString&) ), this, SLOT( slotActivated(const QString&) ) );
00081 
00082 
00083     // add button
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     // delete button
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 // --- ~ListEdit --------------------------------------------------------------
00098 ListEdit::~ListEdit()
00099 {
00100 }
00101 
00102 
00103 // --- slotEditTypeChanged ----------------------------------------------------
00104 void ListEdit::slotEditChanged(const QString &str)
00105 {
00106     if( !_currentItem || _currentColumn<0 ) return;
00107     _currentItem->setText(_currentColumn, str);
00108 }
00109 
00110 // --- slotAddType ------------------------------------------------------------
00111 void ListEdit::slotAdd()
00112 {
00113     // construct new row
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     // fix uniques
00124     fixTypes();
00125 
00126     // display col 0 of new value
00127     QPoint pnt;
00128     slotClick(_currentItem, pnt, 0);
00129     _typeTable->setSelected( _currentItem, true );
00130 
00131     // make it selected
00132     _typeEdit->setCursorPosition(0);
00133     _typeEdit->setSelection(0, _typeEdit->text().length() );
00134 }
00135 
00136 // --- slotDel -------------------------------------------------------------
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 // --- fixTypes ----------------------------------------------------------------
00148 // Makes sure all entries have a unique name and empty entries are replaced
00149 // by a generic string. The first version performs the operation on a particular
00150 // column, whereas the 2nd does it for all unique columns.
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     // get column def
00181     ColumnDef *pDef=this->at(iColumn);
00182 
00183     // create map of entries
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     // fix empty entries
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     // fix dups
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     // copy back clean up col map
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 // --- storeInList ------------------------------------------------------------
00255 void ListEdit::storeInList(QStringList &lst)
00256 {
00257     // delete old content
00258     lst.clear();
00259 
00260     // add new one
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 // --- slotClicked ------------------------------------------------------------
00278 void ListEdit::slotClick(QListViewItem *itm, const QPoint &pnt, int col)
00279 {
00280     (void)pnt; // get rid of unused warning;
00281 
00282     // save values
00283     _currentItem=itm;
00284     _currentColumn=col;
00285     if( itm==NULL ) {
00286         _typeEdit->setText("");
00287         _stack->raiseWidget(_typeEdit);
00288         return;
00289     }
00290 
00291     // display value
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 // --- addColumnDef -----------------------------------------------------------
00324 void ListEdit::addColumnDef(ColumnDef *pDef)
00325 {
00326     _typeTable->addColumn( pDef->getName() );
00327     _vColumns.append(pDef);
00328 }
00329 
00330 // --- addData ----------------------------------------------------------------
00331 void ListEdit::addData(QStringList &lst)
00332 {
00333     // run through list
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 // --- slotActivated ----------------------------------------------------------
00351 void ListEdit::slotActivated(const QString &str)
00352 {
00353     if( _currentItem==NULL || _currentColumn<0 ) return;
00354     _currentItem->setText(_currentColumn, str);
00355 }

Generated on Sat Nov 5 16:16:47 2005 for OPIE by  doxygen 1.4.2