00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
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 d->buttons = 0;
00106 setButtons( buttons );
00107
00108 connect(m_lineEdit,SIGNAL(textChanged(const QString&)),this,SLOT(typedSomething(const QString&)));
00109 m_lineEdit->setTrapReturnKey(true);
00110 connect(m_lineEdit,SIGNAL(returnPressed()),this,SLOT(addItem()));
00111 connect(m_listBox, SIGNAL(highlighted(int)), SLOT(enableMoveButtons(int)));
00112
00113
00114 typedSomething( m_lineEdit->text() );
00115 }
00116
00117 void KEditListBox::setButtons( uint buttons )
00118 {
00119 if ( d->buttons == buttons )
00120 return;
00121
00122 QGridLayout* grid = static_cast<QGridLayout *>( layout() );
00123 if ( ( buttons & Add ) && !servNewButton ) {
00124 servNewButton = new QPushButton(i18n("&Add"), this);
00125 servNewButton->setEnabled(false);
00126 servNewButton->show();
00127 connect(servNewButton, SIGNAL(clicked()), SLOT(addItem()));
00128
00129 grid->addWidget(servNewButton, 2, 1);
00130 } else if ( ( buttons & Add ) == 0 && servNewButton ) {
00131 delete servNewButton;
00132 servNewButton = 0;
00133 }
00134
00135 if ( ( buttons & Remove ) && !servRemoveButton ) {
00136 servRemoveButton = new QPushButton(i18n("&Remove"), this);
00137 servRemoveButton->setEnabled(false);
00138 servRemoveButton->show();
00139 connect(servRemoveButton, SIGNAL(clicked()), SLOT(removeItem()));
00140
00141 grid->addWidget(servRemoveButton, 3, 1);
00142 } else if ( ( buttons & Remove ) == 0 && servRemoveButton ) {
00143 delete servRemoveButton;
00144 servRemoveButton = 0;
00145 }
00146
00147 if ( ( buttons & UpDown ) && !servUpButton ) {
00148 servUpButton = new QPushButton(i18n("Move &Up"), this);
00149 servUpButton->setEnabled(false);
00150 servUpButton->show();
00151 connect(servUpButton, SIGNAL(clicked()), SLOT(moveItemUp()));
00152
00153 servDownButton = new QPushButton(i18n("Move &Down"), this);
00154 servDownButton->setEnabled(false);
00155 servDownButton->show();
00156 connect(servDownButton, SIGNAL(clicked()), SLOT(moveItemDown()));
00157
00158 grid->addWidget(servUpButton, 4, 1);
00159 grid->addWidget(servDownButton, 5, 1);
00160 } else if ( ( buttons & UpDown ) == 0 && servUpButton ) {
00161 delete servUpButton; servUpButton = 0;
00162 delete servDownButton; servDownButton = 0;
00163 }
00164
00165 d->buttons = buttons;
00166 }
00167
00168 void KEditListBox::typedSomething(const QString& text)
00169 {
00170 if(currentItem() >= 0) {
00171 if(currentText() != m_lineEdit->text())
00172 {
00173
00174
00175
00176 bool block = m_listBox->signalsBlocked();
00177 m_listBox->blockSignals( true );
00178 m_listBox->changeItem(text, currentItem());
00179 m_listBox->blockSignals( block );
00180 emit changed();
00181 }
00182 }
00183
00184 if ( !servNewButton )
00185 return;
00186
00187 if (!d->m_checkAtEntering)
00188 servNewButton->setEnabled(!text.isEmpty());
00189 else
00190 {
00191 if (text.isEmpty())
00192 {
00193 servNewButton->setEnabled(false);
00194 }
00195 else
00196 {
00197 StringComparisonMode mode = (StringComparisonMode) (ExactMatch | CaseSensitive );
00198 bool enable = (!m_listBox->findItem( text, mode ));
00199 servNewButton->setEnabled( enable );
00200 }
00201 }
00202 }
00203
00204 void KEditListBox::moveItemUp()
00205 {
00206 if (!m_listBox->isEnabled())
00207 {
00208 KNotifyClient::beep();
00209 return;
00210 }
00211
00212 const unsigned int selIndex = m_listBox->currentItem();
00213 if (selIndex == 0)
00214 {
00215 KNotifyClient::beep();
00216 return;
00217 }
00218
00219 QListBoxItem *selItem = m_listBox->item(selIndex);
00220 m_listBox->takeItem(selItem);
00221 m_listBox->insertItem(selItem, selIndex-1);
00222 m_listBox->setCurrentItem(selIndex - 1);
00223
00224 emit changed();
00225 }
00226
00227 void KEditListBox::moveItemDown()
00228 {
00229 if (!m_listBox->isEnabled())
00230 {
00231 KNotifyClient::beep();
00232 return;
00233 }
00234
00235 unsigned int selIndex = m_listBox->currentItem();
00236 if (selIndex == m_listBox->count() - 1)
00237 {
00238 KNotifyClient::beep();
00239 return;
00240 }
00241
00242 QListBoxItem *selItem = m_listBox->item(selIndex);
00243 m_listBox->takeItem(selItem);
00244 m_listBox->insertItem(selItem, selIndex+1);
00245 m_listBox->setCurrentItem(selIndex + 1);
00246
00247 emit changed();
00248 }
00249
00250 void KEditListBox::addItem()
00251 {
00252
00253
00254
00255 if ( !servNewButton || !servNewButton->isEnabled() )
00256 return;
00257
00258 const QString& currentTextLE=m_lineEdit->text();
00259 bool alreadyInList(false);
00260
00261 if (!d->m_checkAtEntering)
00262 {
00263
00264 if ( m_listBox->currentText() == currentTextLE )
00265 alreadyInList = true;
00266 else
00267 {
00268 StringComparisonMode mode = (StringComparisonMode) (ExactMatch | CaseSensitive );
00269 alreadyInList =(m_listBox->findItem(currentTextLE, mode) );
00270 }
00271 }
00272
00273 if ( servNewButton )
00274 servNewButton->setEnabled(false);
00275
00276 bool block = m_lineEdit->signalsBlocked();
00277 m_lineEdit->blockSignals(true);
00278 m_lineEdit->clear();
00279 m_lineEdit->blockSignals(block);
00280
00281 m_listBox->setSelected(currentItem(), false);
00282
00283 if (!alreadyInList)
00284 {
00285 block = m_listBox->signalsBlocked();
00286 m_listBox->blockSignals( true );
00287 m_listBox->insertItem(currentTextLE);
00288 m_listBox->blockSignals( block );
00289 emit changed();
00290 emit added( currentTextLE );
00291 }
00292 }
00293
00294 int KEditListBox::currentItem() const
00295 {
00296 int nr = m_listBox->currentItem();
00297 if(nr >= 0 && !m_listBox->item(nr)->isSelected()) return -1;
00298 return nr;
00299 }
00300
00301 void KEditListBox::removeItem()
00302 {
00303 int selected = m_listBox->currentItem();
00304
00305 if ( selected >= 0 )
00306 {
00307 QString removedText = m_listBox->currentText();
00308
00309 m_listBox->removeItem( selected );
00310 if ( count() > 0 )
00311 m_listBox->setSelected( QMIN( selected, count() - 1 ), true );
00312
00313 emit changed();
00314 emit removed( removedText );
00315 }
00316
00317 if ( servRemoveButton && m_listBox->currentItem() == -1 )
00318 servRemoveButton->setEnabled(false);
00319 }
00320
00321 void KEditListBox::enableMoveButtons(int index)
00322 {
00323
00324 if(currentText() != m_lineEdit->text())
00325 m_lineEdit->setText(currentText());
00326
00327 bool moveEnabled = servUpButton && servDownButton;
00328
00329 if (moveEnabled )
00330 {
00331 if (m_listBox->count() <= 1)
00332 {
00333 servUpButton->setEnabled(false);
00334 servDownButton->setEnabled(false);
00335 }
00336 else if ((uint) index == (m_listBox->count() - 1))
00337 {
00338 servUpButton->setEnabled(true);
00339 servDownButton->setEnabled(false);
00340 }
00341 else if (index == 0)
00342 {
00343 servUpButton->setEnabled(false);
00344 servDownButton->setEnabled(true);
00345 }
00346 else
00347 {
00348 servUpButton->setEnabled(true);
00349 servDownButton->setEnabled(true);
00350 }
00351 }
00352
00353 if ( servRemoveButton )
00354 servRemoveButton->setEnabled(true);
00355 }
00356
00357 void KEditListBox::clear()
00358 {
00359 m_lineEdit->clear();
00360 m_listBox->clear();
00361 emit changed();
00362 }
00363
00364 void KEditListBox::insertStringList(const QStringList& list, int index)
00365 {
00366 m_listBox->insertStringList(list,index);
00367 }
00368
00369 void KEditListBox::insertStrList(const QStrList* list, int index)
00370 {
00371 m_listBox->insertStrList(list,index);
00372 }
00373
00374 void KEditListBox::insertStrList(const QStrList& list, int index)
00375 {
00376 m_listBox->insertStrList(list,index);
00377 }
00378
00379 void KEditListBox::insertStrList(const char ** list, int numStrings, int index)
00380 {
00381 m_listBox->insertStrList(list,numStrings,index);
00382 }
00383
00384 QStringList KEditListBox::items() const
00385 {
00386 QStringList list;
00387 for (QListBoxItem const * i = m_listBox->firstItem(); i != 0; i = i->next() )
00388 list.append( i->text());
00389
00390 return list;
00391 }
00392
00393 void KEditListBox::setItems(const QStringList& items)
00394 {
00395 m_listBox->clear();
00396 m_listBox->insertStringList(items, 0);
00397 }
00398
00399 int KEditListBox::buttons() const
00400 {
00401 return d->buttons;
00402 }
00403
00404 void KEditListBox::virtual_hook( int, void* )
00405 { }
00406
00407
00410
00411 KEditListBox::CustomEditor::CustomEditor( KComboBox *combo )
00412 {
00413 m_representationWidget = combo;
00414 m_lineEdit = dynamic_cast<KLineEdit*>( combo->lineEdit() );
00415 assert( m_lineEdit );
00416 }
00417
00418 #include "keditlistbox.moc"