kdeui Library API Documentation

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"
KDE Logo
This file is part of the documentation for kdeui Library Version 3.4.0.
Documentation copyright © 1996-2004 the KDE developers.
Generated on Thu Apr 14 00:10:11 2005 by doxygen 1.3.7 written by Dimitri van Heesch, © 1997-2003