kdeui Library: keditlistbox.cpp Source File (kdeui Library)

| # kdeui Library API Documentation
Overview | Class Hierarchy | Classes | Classes (annotated) | Members | Namespaces | Source Files

# keditlistbox.cpp

    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 #include <qstringlist.h>
    00022 #include <qpushbutton.h>
    00023 #include <qlayout.h>
    00024 #include <qgroupbox.h>
    00025 #include <qlistbox.h>
    00026 #include <qwhatsthis.h>
    00027 #include <qlabel.h>
    00028
    00029 #include <kcombobox.h>
    00030 #include <kdebug.h>
    00031 #include <kdialog.h>
    00032 #include <klineedit.h>
    00033 #include <klocale.h>
    00034 #include <kapplication.h>
    00035 #include <knotifyclient.h>
    00036
    00037 #include "keditlistbox.h"
    00038
    00039 #include <assert.h>
    00040
    00041 class KEditListBoxPrivate
    00042 {
    00043 public:
    00044     bool m_checkAtEntering;
    00045     uint buttons;
    00046 };
    00047
    00048 KEditListBox::KEditListBox(QWidget *parent, const char *name,
    00049                bool checkAtEntering, int buttons )
    00050     :QGroupBox(parent, name ), d(new KEditListBoxPrivate)
    00051 {
    00052     init( checkAtEntering, buttons );
    00053 }
    00054
    00055 KEditListBox::KEditListBox(const QString& title, QWidget *parent,
    00056                const char *name, bool checkAtEntering, int buttons)
    00057     :QGroupBox(title, parent, name ), d(new KEditListBoxPrivate)
    00058 {
    00059     init( checkAtEntering, buttons );
    00060 }
    00061
    00062 KEditListBox::KEditListBox(const QString& title, const CustomEditor& custom,
    00063                            QWidget *parent, const char *name,
    00064                            bool checkAtEntering, int buttons)
    00065     :QGroupBox(title, parent, name ), d(new KEditListBoxPrivate)
    00066 {
    00067     m_lineEdit = custom.lineEdit();
    00068     init( checkAtEntering, buttons, custom.representationWidget() );
    00069 }
    00070
    00071 KEditListBox::~KEditListBox()
    00072 {
    00073     delete d;
    00074 }
    00075
    00076 void KEditListBox::init( bool checkAtEntering, int buttons,
    00077                          QWidget *representationWidget )
    00078 {
    00079     d->m_checkAtEntering = checkAtEntering;
    00080
    00081     servNewButton = servRemoveButton = servUpButton = servDownButton = 0L;
    00082     setSizePolicy(QSizePolicy(QSizePolicy::MinimumExpanding,
    00083                               QSizePolicy::MinimumExpanding));
    00084
    00085     QGridLayout * grid = new QGridLayout(this, 7, 2,
    00086                                          KDialog::marginHint(),
    00087                                          KDialog::spacingHint());
    00088     grid->addRowSpacing(0, fontMetrics().lineSpacing());
    00089     grid->setRowStretch( 6, 1 );
    00090
    00091     grid->setMargin(15);
    00092
    00093     if ( representationWidget )
    00094         representationWidget->reparent( this, QPoint(0,0) );
    00095     else
    00096         m_lineEdit=new KLineEdit(this);
    00097
    00098     m_listBox = new QListBox(this);
    00099
    00100     QWidget *editingWidget = representationWidget ?
    00101                              representationWidget : m_lineEdit;
    00102     grid->addMultiCellWidget(editingWidget,1,1,0,1);
    00103     grid->addMultiCellWidget(m_listBox, 2, 6, 0, 0);
    00104
    00105     setButtons( buttons );
    00106
    00107     connect(m_lineEdit,SIGNAL(textChanged(const QString&)),this,SLOT(typedSomething(const QString&)));
    00108     m_lineEdit->setTrapReturnKey(true);
    00109     connect(m_lineEdit,SIGNAL(returnPressed()),this,SLOT(addItem()));
    00110     connect(m_listBox, SIGNAL(highlighted(int)), SLOT(enableMoveButtons(int)));
    00111
    00112     // maybe supplied lineedit has some text already
    00113     typedSomething( m_lineEdit->text() );
    00114 }
    00115
    00116 void KEditListBox::setButtons( uint buttons )
    00117 {
    00118     if ( d->buttons == buttons )
    00119         return;
    00120
    00121     QGridLayout* grid = static_cast<QGridLayout *>( layout() );
    00122     if ( ( buttons & Add ) && !servNewButton ) {
    00123         servNewButton = new QPushButton(i18n("&Add"), this);
    00124         servNewButton->setEnabled(false);
    00125         servNewButton->show();
    00126         connect(servNewButton, SIGNAL(clicked()), SLOT(addItem()));
    00127
    00128         grid->addWidget(servNewButton, 2, 1);
    00129     } else if ( ( buttons & Add ) == 0 && servNewButton ) {
    00130         delete servNewButton;
    00131         servNewButton = 0;
    00132     }
    00133
    00134     if ( ( buttons & Remove ) && !servRemoveButton ) {
    00135         servRemoveButton = new QPushButton(i18n("&Remove"), this);
    00136         servRemoveButton->setEnabled(false);
    00137         servRemoveButton->show();
    00138         connect(servRemoveButton, SIGNAL(clicked()), SLOT(removeItem()));
    00139
    00140         grid->addWidget(servRemoveButton, 3, 1);
    00141     } else if ( ( buttons & Remove ) == 0 && servRemoveButton ) {
    00142         delete servRemoveButton;
    00143         servRemoveButton = 0;
    00144     }
    00145
    00146     if ( ( buttons & UpDown ) && !servUpButton ) {
    00147         servUpButton = new QPushButton(i18n("Move &Up"), this);
    00148         servUpButton->setEnabled(false);
    00149         servUpButton->show();
    00150         connect(servUpButton, SIGNAL(clicked()), SLOT(moveItemUp()));
    00151
    00152         servDownButton = new QPushButton(i18n("Move &Down"), this);
    00153         servDownButton->setEnabled(false);
    00154         servDownButton->show();
    00155         connect(servDownButton, SIGNAL(clicked()), SLOT(moveItemDown()));
    00156
    00157         grid->addWidget(servUpButton, 4, 1);
    00158         grid->addWidget(servDownButton, 5, 1);
    00159     } else if ( ( buttons & UpDown ) == 0 && servUpButton ) {
    00160         delete servUpButton; servUpButton = 0;
    00161         delete servDownButton; servDownButton = 0;
    00162     }
    00163
    00164     d->buttons = buttons;
    00165 }
    00166
    00167 void KEditListBox::typedSomething(const QString& text)
    00168 {
    00169     if(currentItem() >= 0) {
    00170         if(currentText() != m_lineEdit->text())
    00171         {
    00172             // IMHO changeItem() shouldn't do anything with the value
    00173             // of currentItem() ... like changing it or emitting signals ...
    00174             // but TT disagree with me on this one (it's been that way since ages ... grrr)
    00175             bool block = m_listBox->signalsBlocked();
    00176             m_listBox->blockSignals( true );
    00177             m_listBox->changeItem(text, currentItem());
    00178             m_listBox->blockSignals( block );
    00179             emit changed();
    00180         }
    00181     }
    00182
    00183     if ( !servNewButton )
    00184         return;
    00185
    00186     if (!d->m_checkAtEntering)
    00187         servNewButton->setEnabled(!text.isEmpty());
    00188     else
    00189     {
    00190         if (text.isEmpty())
    00191         {
    00192             servNewButton->setEnabled(false);
    00193         }
    00194         else
    00195         {
    00196             StringComparisonMode mode = (StringComparisonMode) (ExactMatch | CaseSensitive );
    00197             bool enable = (!m_listBox->findItem( text, mode ));
    00198             servNewButton->setEnabled( enable );
    00199         }
    00200     }
    00201 }
    00202
    00203 void KEditListBox::moveItemUp()
    00204 {
    00205     if (!m_listBox->isEnabled())
    00206     {
    00207         KNotifyClient::beep();
    00208         return;
    00209     }
    00210
    00211     const unsigned int selIndex = m_listBox->currentItem();
    00212     if (selIndex == 0)
    00213     {
    00214         KNotifyClient::beep();
    00215         return;
    00216     }
    00217
    00218     QListBoxItem *selItem = m_listBox->item(selIndex);
    00219     m_listBox->takeItem(selItem);
    00220     m_listBox->insertItem(selItem, selIndex-1);
    00221     m_listBox->setCurrentItem(selIndex - 1);
    00222
    00223     emit changed();
    00224 }
    00225
    00226 void KEditListBox::moveItemDown()
    00227 {
    00228     if (!m_listBox->isEnabled())
    00229     {
    00230         KNotifyClient::beep();
    00231         return;
    00232     }
    00233
    00234     unsigned int selIndex = m_listBox->currentItem();
    00235     if (selIndex == m_listBox->count() - 1)
    00236     {
    00237         KNotifyClient::beep();
    00238         return;
    00239     }
    00240
    00241     QListBoxItem *selItem = m_listBox->item(selIndex);
    00242     m_listBox->takeItem(selItem);
    00243     m_listBox->insertItem(selItem, selIndex+1);
    00244     m_listBox->setCurrentItem(selIndex + 1);
    00245
    00246     emit changed();
    00247 }
    00248
    00249 void KEditListBox::addItem()
    00250 {
    00251     // when m_checkAtEntering is true, the add-button is disabled, but this
    00252     // slot can still be called through Key_Return/Key_Enter. So we guard
    00253     // against this.
    00254     if ( !servNewButton || !servNewButton->isEnabled() )
    00255         return;
    00256
    00257     const QString& currentTextLE=m_lineEdit->text();
    00258     bool alreadyInList(false);
    00259     //if we didn't check for dupes at the inserting we have to do it now
    00260     if (!d->m_checkAtEntering)
    00261     {
    00262         // first check current item instead of dumb iterating the entire list
    00263         if ( m_listBox->currentText() == currentTextLE )
    00264             alreadyInList = true;
    00265         else
    00266         {
    00267             StringComparisonMode mode = (StringComparisonMode) (ExactMatch | CaseSensitive );
    00268             alreadyInList =(m_listBox->findItem(currentTextLE, mode) );
    00269         }
    00270     }
    00271
    00272     if ( servNewButton )
    00273         servNewButton->setEnabled(false);
    00274
    00275     bool block = m_lineEdit->signalsBlocked();
    00276     m_lineEdit->blockSignals(true);
    00277     m_lineEdit->clear();
    00278     m_lineEdit->blockSignals(block);
    00279
    00280     m_listBox->setSelected(currentItem(), false);
    00281
    00282     if (!alreadyInList)
    00283     {
    00284         block = m_listBox->signalsBlocked();
    00285         m_listBox->blockSignals( true );
    00286         m_listBox->insertItem(currentTextLE);
    00287         m_listBox->blockSignals( block );
    00288         emit changed();
    00289     emit added( currentTextLE );
    00290     }
    00291 }
    00292
    00293 int KEditListBox::currentItem() const
    00294 {
    00295     int nr = m_listBox->currentItem();
    00296     if(nr >= 0 && !m_listBox->item(nr)->isSelected()) return -1;
    00297     return nr;
    00298 }
    00299
    00300 void KEditListBox::removeItem()
    00301 {
    00302     int selected = m_listBox->currentItem();
    00303
    00304     if ( selected >= 0 )
    00305     {
    00306     QString removedText = m_listBox->currentText();
    00307
    00308         m_listBox->removeItem( selected );
    00309         if ( count() > 0 )
    00310             m_listBox->setSelected( QMIN( selected, count() - 1 ), true );
    00311
    00312         emit changed();
    00313     emit removed( removedText );
    00314     }
    00315
    00316     if ( servRemoveButton && m_listBox->currentItem() == -1 )
    00317         servRemoveButton->setEnabled(false);
    00318 }
    00319
    00320 void KEditListBox::enableMoveButtons(int index)
    00321 {
    00322     // Update the lineEdit when we select a different line.
    00323     if(currentText() != m_lineEdit->text())
    00324         m_lineEdit->setText(currentText());
    00325
    00326     bool moveEnabled = servUpButton && servDownButton;
    00327
    00328     if (moveEnabled )
    00329     {
    00330         if (m_listBox->count() <= 1)
    00331         {
    00332             servUpButton->setEnabled(false);
    00333             servDownButton->setEnabled(false);
    00334         }
    00335         else if ((uint) index == (m_listBox->count() - 1))
    00336         {
    00337             servUpButton->setEnabled(true);
    00338             servDownButton->setEnabled(false);
    00339         }
    00340         else if (index == 0)
    00341         {
    00342             servUpButton->setEnabled(false);
    00343             servDownButton->setEnabled(true);
    00344         }
    00345         else
    00346         {
    00347             servUpButton->setEnabled(true);
    00348             servDownButton->setEnabled(true);
    00349         }
    00350     }
    00351
    00352     if ( servRemoveButton )
    00353         servRemoveButton->setEnabled(true);
    00354 }
    00355
    00356 void KEditListBox::clear()
    00357 {
    00358     m_lineEdit->clear();
    00359     m_listBox->clear();
    00360     emit changed();
    00361 }
    00362
    00363 void KEditListBox::insertStringList(const QStringList& list, int index)
    00364 {
    00365     m_listBox->insertStringList(list,index);
    00366 }
    00367
    00368 void KEditListBox::insertStrList(const QStrList* list, int index)
    00369 {
    00370     m_listBox->insertStrList(list,index);
    00371 }
    00372
    00373 void KEditListBox::insertStrList(const QStrList& list, int index)
    00374 {
    00375     m_listBox->insertStrList(list,index);
    00376 }
    00377
    00378 void KEditListBox::insertStrList(const char ** list, int numStrings, int index)
    00379 {
    00380     m_listBox->insertStrList(list,numStrings,index);
    00381 }
    00382
    00383 QStringList KEditListBox::items() const
    00384 {
    00385     QStringList list;
    00386     for (QListBoxItem const * i = m_listBox->firstItem(); i != 0; i = i->next() )
    00387     list.append( i->text());
    00388
    00389     return list;
    00390 }
    00391
    00392 void KEditListBox::setItems(const QStringList& items)
    00393 {
    00394   m_listBox->clear();
    00395   m_listBox->insertStringList(items, 0);
    00396 }
    00397
    00398 int KEditListBox::buttons() const
    00399 {
    00400   return d->buttons;
    00401 }
    00402
    00403 void KEditListBox::virtual_hook( int, void* )
    00404 { /*BASE::virtual_hook( id, data );*/ }
    00405
    00406
    00409
    00410 KEditListBox::CustomEditor::CustomEditor( KComboBox *combo )
    00411 {
    00412     m_representationWidget = combo;
    00413     m_lineEdit = dynamic_cast<KLineEdit*>( combo->lineEdit() );
    00414     assert( m_lineEdit );
    00415 }
    00416
    00417 #include "keditlistbox.moc"

This file is part of the documentation for kdeui Library Version 3.4.1.
Documentation copyright © 1996-2004 the KDE developers.
Generated on Sat Jun 11 20:20:16 2005 by doxygen 1.4.1 written by Dimitri van Heesch, © 1997-2003