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

oeditlistbox.cpp

Go to the documentation of this file.
00001 /* This file is part of the KDE libraries
00002    Copyright (C) 2000 David Faure <faure@kde.org>, Alexander Neundorf <neundorf@kde.org>
00003    2000, 2002 Carsten Pfeiffer <pfeiffer@kde.org>
00004 
00005    This library is free software; you can redistribute it and/or
00006    modify it under the terms of the GNU Library General Public
00007    License as published by the Free Software Foundation; either
00008    version 2 of the License, or (at your option) any later version.
00009 
00010    This library is distributed in the hope that it will be useful,
00011    but WITHOUT ANY WARRANTY; without even the implied warranty of
00012    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00013    Library General Public License for more details.
00014 
00015    You should have received a copy of the GNU Library General Public License
00016    along with this library; see the file COPYING.LIB.  If not, write to
00017    the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
00018    Boston, MA 02111-1307, USA.
00019 */
00020 
00021 /* QT */
00022 
00023 #include <qstringlist.h>
00024 #include <qpushbutton.h>
00025 #include <qlayout.h>
00026 #include <qgroupbox.h>
00027 #include <qlistbox.h>
00028 #include <qwhatsthis.h>
00029 #include <qlabel.h>
00030 
00031 /* OPIE */
00032 
00033 #include <opie2/ocombobox.h>
00034 #include <opie2/odialog.h>
00035 #include <opie2/olineedit.h>
00036 #include <opie2/oeditlistbox.h>
00037 
00038 /* UNIX */
00039 
00040 #include <assert.h>
00041 
00042 /*======================================================================================
00043  * OEditListBoxPrivate
00044  *======================================================================================*/
00045 
00046 class OEditListBoxPrivate
00047 {
00048 public:
00049     bool m_checkAtEntering;
00050     int buttons;
00051 };
00052 
00053 /*======================================================================================
00054  * OEditListBox
00055  *======================================================================================*/
00056 
00057 OEditListBox::OEditListBox(QWidget *parent, const char *name,
00058                            bool checkAtEntering, int buttons )
00059     :QGroupBox(parent, name )
00060 {
00061     init( checkAtEntering, buttons );
00062 }
00063 
00064 OEditListBox::OEditListBox(const QString& title, QWidget *parent,
00065                            const char *name, bool checkAtEntering, int buttons)
00066     :QGroupBox(title, parent, name )
00067 {
00068     init( checkAtEntering, buttons );
00069 }
00070 
00071 OEditListBox::OEditListBox(const QString& title, const CustomEditor& custom,
00072                            QWidget *parent, const char *name,
00073                            bool checkAtEntering, int buttons)
00074     :QGroupBox(title, parent, name )
00075 {
00076     m_lineEdit = custom.lineEdit();
00077     init( checkAtEntering, buttons, custom.representationWidget() );
00078 }
00079 
00080 OEditListBox::~OEditListBox()
00081 {
00082     delete d;
00083     d=0;
00084 }
00085 
00086 void OEditListBox::init( bool checkAtEntering, int buttons,
00087                          QWidget *representationWidget )
00088 {
00089     d=new OEditListBoxPrivate;
00090     d->m_checkAtEntering=checkAtEntering;
00091     d->buttons = buttons;
00092 
00093     int lostButtons = 0;
00094     if ( (buttons & Add) == 0 )
00095         lostButtons++;
00096     if ( (buttons & Remove) == 0 )
00097         lostButtons++;
00098     if ( (buttons & UpDown) == 0 )
00099         lostButtons += 2;
00100 
00101 
00102     servNewButton = servRemoveButton = servUpButton = servDownButton = 0L;
00103     setSizePolicy(QSizePolicy(QSizePolicy::MinimumExpanding,
00104                               QSizePolicy::MinimumExpanding));
00105 
00106     QWidget * gb = this;
00107     QGridLayout * grid = new QGridLayout(gb, 7 - lostButtons, 2,
00108                                          ODialog::marginHint(),
00109                                          ODialog::spacingHint());
00110     grid->addRowSpacing(0, fontMetrics().lineSpacing());
00111     for ( int i = 1; i < 7 - lostButtons; i++ )
00112         grid->setRowStretch(i, 1);
00113 
00114     grid->setMargin(15);
00115 
00116     if ( representationWidget )
00117         representationWidget->reparent( gb, QPoint(0,0) );
00118     else
00119         m_lineEdit=new OLineEdit(gb);
00120 
00121     m_listBox = new QListBox(gb);
00122 
00123     QWidget *editingWidget = representationWidget ?
00124                              representationWidget : m_lineEdit;
00125     grid->addMultiCellWidget(editingWidget,1,1,0,1);
00126     grid->addMultiCellWidget(m_listBox, 2, 6 - lostButtons, 0, 0);
00127     int row = 2;
00128     if ( buttons & Add ) {
00129         servNewButton = new QPushButton(tr("&Add"), gb);
00130         servNewButton->setEnabled(false);
00131         connect(servNewButton, SIGNAL(clicked()), SLOT(addItem()));
00132 
00133         grid->addWidget(servNewButton, row++, 1);
00134     }
00135 
00136     if ( buttons & Remove ) {
00137         servRemoveButton = new QPushButton(tr("&Remove"), gb);
00138         servRemoveButton->setEnabled(false);
00139         connect(servRemoveButton, SIGNAL(clicked()), SLOT(removeItem()));
00140 
00141         grid->addWidget(servRemoveButton, row++, 1);
00142     }
00143 
00144     if ( buttons & UpDown ) {
00145         servUpButton = new QPushButton(tr("Move &Up"), gb);
00146         servUpButton->setEnabled(false);
00147         connect(servUpButton, SIGNAL(clicked()), SLOT(moveItemUp()));
00148 
00149         servDownButton = new QPushButton(tr("Move &Down"), gb);
00150         servDownButton->setEnabled(false);
00151         connect(servDownButton, SIGNAL(clicked()), SLOT(moveItemDown()));
00152 
00153         grid->addWidget(servUpButton, row++, 1);
00154         grid->addWidget(servDownButton, row++, 1);
00155     }
00156 
00157     connect(m_lineEdit,SIGNAL(textChanged(const QString&)),this,SLOT(typedSomething(const QString&)));
00158     m_lineEdit->setTrapReturnKey(true);
00159     connect(m_lineEdit,SIGNAL(returnPressed()),this,SLOT(addItem()));
00160     connect(m_listBox, SIGNAL(highlighted(int)), SLOT(enableMoveButtons(int)));
00161 
00162     // maybe supplied lineedit has some text already
00163     typedSomething( m_lineEdit->text() );
00164 }
00165 
00166 void OEditListBox::typedSomething(const QString& text)
00167 {
00168     if(currentItem() >= 0) {
00169         if(currentText() != m_lineEdit->text())
00170         {
00171             // IMHO changeItem() shouldn't do anything with the value
00172             // of currentItem() ... like changing it or emitting signals ...
00173             // but TT disagree with me on this one (it's been that way since ages ... grrr)
00174             bool block = m_listBox->signalsBlocked();
00175             m_listBox->blockSignals( true );
00176             m_listBox->changeItem(text, currentItem());
00177             m_listBox->blockSignals( block );
00178             emit changed();
00179         }
00180     }
00181 
00182     if ( !servNewButton )
00183         return;
00184 
00185     if (!d->m_checkAtEntering)
00186         servNewButton->setEnabled(!text.isEmpty());
00187     else
00188     {
00189         if (text.isEmpty())
00190         {
00191             servNewButton->setEnabled(false);
00192         }
00193         else
00194         {
00195             #if QT_VERSION >= 0x030000
00196             StringComparisonMode mode = (StringComparisonMode) (ExactMatch | CaseSensitive );
00197             bool enable = (m_listBox->findItem( text, mode ) == 0L);
00198             #else
00199             bool enable = (m_listBox->findItem( text ) == 0L);
00200             #endif
00201             servNewButton->setEnabled( enable );
00202         }
00203     }
00204 }
00205 
00206 void OEditListBox::moveItemUp()
00207 {
00208     if (!m_listBox->isEnabled())
00209     {
00210         //ONotifyClient::beep();
00211         return;
00212     }
00213 
00214     unsigned int selIndex = m_listBox->currentItem();
00215     if (selIndex == 0)
00216     {
00217         //ONotifyClient::beep();
00218         return;
00219     }
00220 
00221     QListBoxItem *selItem = m_listBox->item(selIndex);
00222     m_listBox->takeItem(selItem);
00223     m_listBox->insertItem(selItem, selIndex-1);
00224     m_listBox->setCurrentItem(selIndex - 1);
00225 
00226     emit changed();
00227 }
00228 
00229 void OEditListBox::moveItemDown()
00230 {
00231     if (!m_listBox->isEnabled())
00232     {
00233         //ONotifyClient::beep();
00234         return;
00235     }
00236 
00237     unsigned int selIndex = m_listBox->currentItem();
00238     if (selIndex == m_listBox->count() - 1)
00239     {
00240         //ONotifyClient::beep();
00241         return;
00242     }
00243 
00244     QListBoxItem *selItem = m_listBox->item(selIndex);
00245     m_listBox->takeItem(selItem);
00246     m_listBox->insertItem(selItem, selIndex+1);
00247     m_listBox->setCurrentItem(selIndex + 1);
00248 
00249     emit changed();
00250 }
00251 
00252 void OEditListBox::addItem()
00253 {
00254     // when m_checkAtEntering is true, the add-button is disabled, but this
00255     // slot can still be called through Key_Return/Key_Enter. So we guard
00256     // against this.
00257     if ( !servNewButton || !servNewButton->isEnabled() )
00258         return;
00259 
00260     const QString& currentTextLE=m_lineEdit->text();
00261     bool alreadyInList(false);
00262     //if we didn't check for dupes at the inserting we have to do it now
00263     if (!d->m_checkAtEntering)
00264     {
00265         // first check current item instead of dumb iterating the entire list
00266         if ( m_listBox->currentText() == currentTextLE )
00267             alreadyInList = true;
00268         else
00269         {
00270             #if QT_VERSION >= 0x030000
00271             StringComparisonMode mode = (StringComparisonMode) (ExactMatch | CaseSensitive );
00272             alreadyInList =(m_listBox->findItem(currentTextLE, mode) != 0);
00273             #else
00274             alreadyInList =(m_listBox->findItem(currentTextLE) != 0);
00275             #endif
00276         }
00277     }
00278 
00279     if ( servNewButton )
00280         servNewButton->setEnabled(false);
00281 
00282     bool block = m_lineEdit->signalsBlocked();
00283     m_lineEdit->blockSignals(true);
00284     m_lineEdit->clear();
00285     m_lineEdit->blockSignals(block);
00286 
00287     m_listBox->setSelected(currentItem(), false);
00288 
00289     if (!alreadyInList)
00290     {
00291         block = m_listBox->signalsBlocked();
00292         m_listBox->blockSignals( true );
00293         m_listBox->insertItem(currentTextLE);
00294         m_listBox->blockSignals( block );
00295         emit changed();
00296         emit added( currentTextLE );
00297     }
00298 }
00299 
00300 int OEditListBox::currentItem() const 
00301 {
00302     int nr = m_listBox->currentItem();
00303     #if QT_VERSION >= 0x030000
00304     if(nr >= 0 && !m_listBox->item(nr)->isSelected()) return -1;
00305     #else
00306     if(nr >= 0 && !m_listBox->isSelected(m_listBox->item(nr))) return -1;
00307     #endif
00308     return nr;
00309 }
00310 
00311 void OEditListBox::removeItem()
00312 {
00313     int selected = m_listBox->currentItem();
00314 
00315     if ( selected >= 0 )
00316     {
00317         QString removedText = m_listBox->currentText();
00318 
00319         m_listBox->removeItem( selected );
00320         if ( count() > 0 )
00321             m_listBox->setSelected( QMIN( selected, count() - 1 ), true );
00322 
00323         emit changed();
00324         emit removed( removedText );
00325     }
00326 
00327     if ( servRemoveButton && m_listBox->currentItem() == -1 )
00328         servRemoveButton->setEnabled(false);
00329 }
00330 
00331 void OEditListBox::enableMoveButtons(int index)
00332 {
00333     // Update the lineEdit when we select a different line.
00334     if(currentText() != m_lineEdit->text())
00335         m_lineEdit->setText(currentText());
00336 
00337     bool moveEnabled = servUpButton && servDownButton;
00338 
00339     if (moveEnabled )
00340     {
00341         if (m_listBox->count() <= 1)
00342         {
00343             servUpButton->setEnabled(false);
00344             servDownButton->setEnabled(false);
00345         }
00346         else if ((uint) index == (m_listBox->count() - 1))
00347         {
00348             servUpButton->setEnabled(true);
00349             servDownButton->setEnabled(false);
00350         }
00351         else if (index == 0)
00352         {
00353             servUpButton->setEnabled(false);
00354             servDownButton->setEnabled(true);
00355         }
00356         else
00357         {
00358             servUpButton->setEnabled(true);
00359             servDownButton->setEnabled(true);
00360         }
00361     }
00362 
00363     if ( servRemoveButton )
00364         servRemoveButton->setEnabled(true);
00365 }
00366 
00367 void OEditListBox::clear()
00368 {
00369     m_lineEdit->clear();
00370     m_listBox->clear();
00371     emit changed();
00372 }
00373 
00374 void OEditListBox::insertStringList(const QStringList& list, int index)
00375 {
00376     m_listBox->insertStringList(list,index);
00377 }
00378 
00379 void OEditListBox::insertStrList(const QStrList* list, int index)
00380 {
00381     m_listBox->insertStrList(list,index);
00382 }
00383 
00384 void OEditListBox::insertStrList(const QStrList& list, int index)
00385 {
00386     m_listBox->insertStrList(list,index);
00387 }
00388 
00389 void OEditListBox::insertStrList(const char ** list, int numStrings, int index)
00390 {
00391     m_listBox->insertStrList(list,numStrings,index);
00392 }
00393 
00394 QStringList OEditListBox::items() const
00395 {
00396     QStringList list;
00397     for ( uint i = 0; i < m_listBox->count(); i++ )
00398         list.append( m_listBox->text( i ));
00399 
00400     return list;
00401 }
00402 
00403 void OEditListBox::virtual_hook( int, void* )
00404 { /*BASE::virtual_hook( id, data );*/ }
00405 
00406 
00407 /*======================================================================================
00408  * CustomEditor
00409  *======================================================================================*/
00410 
00411 OEditListBox::CustomEditor::CustomEditor( OComboBox *combo )
00412 {
00413     m_representationWidget = combo;
00414     assert( combo->lineEdit()->inherits( "OLineEdit" ) );
00415     m_lineEdit = static_cast<OLineEdit*>( combo->lineEdit() );
00416 
00417 }

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