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 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
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
00173
00174
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
00252
00253
00254 if ( !servNewButton || !servNewButton->isEnabled() )
00255 return;
00256
00257 const QString& currentTextLE=m_lineEdit->text();
00258 bool alreadyInList(false);
00259
00260 if (!d->m_checkAtEntering)
00261 {
00262
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
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 { }
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"