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