summaryrefslogtreecommitdiffabout
path: root/microkde/keditlistbox.cpp
Unidiff
Diffstat (limited to 'microkde/keditlistbox.cpp') (more/less context) (ignore whitespace changes)
-rw-r--r--microkde/keditlistbox.cpp389
1 files changed, 389 insertions, 0 deletions
diff --git a/microkde/keditlistbox.cpp b/microkde/keditlistbox.cpp
new file mode 100644
index 0000000..55b7784
--- a/dev/null
+++ b/microkde/keditlistbox.cpp
@@ -0,0 +1,389 @@
1/* This file is part of the KDE libraries
2 Copyright (C) 2000 David Faure <faure@kde.org>, Alexander Neundorf <neundorf@kde.org>
3 2000, 2002 Carsten Pfeiffer <pfeiffer@kde.org>
4
5 This library is free software; you can redistribute it and/or
6 modify it under the terms of the GNU Library General Public
7 License as published by the Free Software Foundation; either
8 version 2 of the License, or (at your option) any later version.
9
10 This library is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Library General Public License for more details.
14
15 You should have received a copy of the GNU Library General Public License
16 along with this library; see the file COPYING.LIB. If not, write to
17 the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18 Boston, MA 02111-1307, USA.
19*/
20
21#include <qstringlist.h>
22#include <qpushbutton.h>
23#include <qlayout.h>
24#include <qgroupbox.h>
25#include <qlistbox.h>
26#include <qwhatsthis.h>
27#include <qlabel.h>
28
29#include <kcombobox.h>
30#include <kdebug.h>
31#include <kdialog.h>
32#include <klineedit.h>
33#include <klocale.h>
34#include <kapplication.h>
35#include <knotifyclient.h>
36
37#include "keditlistbox.h"
38
39#include <assert.h>
40
41class KEditListBoxPrivate
42{
43public:
44 bool m_checkAtEntering;
45 int buttons;
46};
47
48KEditListBox::KEditListBox(QWidget *parent, const char *name,
49 bool checkAtEntering, int buttons )
50 :QGroupBox(parent, name )
51{
52 init( checkAtEntering, buttons );
53}
54
55KEditListBox::KEditListBox(const QString& title, QWidget *parent,
56 const char *name, bool checkAtEntering, int buttons)
57 :QGroupBox(title, parent, name )
58{
59 init( checkAtEntering, buttons );
60}
61
62KEditListBox::KEditListBox(const QString& title, const CustomEditor& custom,
63 QWidget *parent, const char *name,
64 bool checkAtEntering, int buttons)
65 :QGroupBox(title, parent, name )
66{
67 m_lineEdit = custom.lineEdit();
68 init( checkAtEntering, buttons, custom.representationWidget() );
69}
70
71KEditListBox::~KEditListBox()
72{
73 delete d;
74 d=0;
75}
76
77void KEditListBox::init( bool checkAtEntering, int buttons,
78 QWidget *representationWidget )
79{
80 d=new KEditListBoxPrivate;
81 d->m_checkAtEntering=checkAtEntering;
82 d->buttons = buttons;
83
84 int lostButtons = 0;
85 if ( (buttons & Add) == 0 )
86 lostButtons++;
87 if ( (buttons & Remove) == 0 )
88 lostButtons++;
89 if ( (buttons & UpDown) == 0 )
90 lostButtons += 2;
91
92
93 servNewButton = servRemoveButton = servUpButton = servDownButton = 0L;
94 setSizePolicy(QSizePolicy(QSizePolicy::MinimumExpanding,
95 QSizePolicy::MinimumExpanding));
96
97 QWidget * gb = this;
98 QGridLayout * grid = new QGridLayout(gb, 7 - lostButtons, 2,
99 KDialog::marginHint(),
100 KDialog::spacingHint());
101 grid->addRowSpacing(0, fontMetrics().lineSpacing());
102 for ( int i = 1; i < 7 - lostButtons; i++ )
103 grid->setRowStretch(i, 1);
104
105 grid->setMargin(15);
106
107 if ( representationWidget )
108 representationWidget->reparent( gb, QPoint(0,0) );
109 else
110 m_lineEdit=new KLineEdit(gb);
111
112 m_listBox = new QListBox(gb);
113
114 QWidget *editingWidget = representationWidget ?
115 representationWidget : m_lineEdit;
116 grid->addMultiCellWidget(editingWidget,1,1,0,1);
117 grid->addMultiCellWidget(m_listBox, 2, 6 - lostButtons, 0, 0);
118 int row = 2;
119 if ( buttons & Add ) {
120 servNewButton = new QPushButton(i18n("&Add"), gb);
121 servNewButton->setEnabled(false);
122 connect(servNewButton, SIGNAL(clicked()), SLOT(addItem()));
123
124 grid->addWidget(servNewButton, row++, 1);
125 }
126
127 if ( buttons & Remove ) {
128 servRemoveButton = new QPushButton(i18n("&Remove"), gb);
129 servRemoveButton->setEnabled(false);
130 connect(servRemoveButton, SIGNAL(clicked()), SLOT(removeItem()));
131
132 grid->addWidget(servRemoveButton, row++, 1);
133 }
134
135 if ( buttons & UpDown ) {
136 servUpButton = new QPushButton(i18n("Move &Up"), gb);
137 servUpButton->setEnabled(false);
138 connect(servUpButton, SIGNAL(clicked()), SLOT(moveItemUp()));
139
140 servDownButton = new QPushButton(i18n("Move &Down"), gb);
141 servDownButton->setEnabled(false);
142 connect(servDownButton, SIGNAL(clicked()), SLOT(moveItemDown()));
143
144 grid->addWidget(servUpButton, row++, 1);
145 grid->addWidget(servDownButton, row++, 1);
146 }
147
148 connect(m_lineEdit,SIGNAL(textChanged(const QString&)),this,SLOT(typedSomething(const QString&)));
149 m_lineEdit->setTrapReturnKey(true);
150 connect(m_lineEdit,SIGNAL(returnPressed()),this,SLOT(addItem()));
151 connect(m_listBox, SIGNAL(highlighted(int)), SLOT(enableMoveButtons(int)));
152
153 // maybe supplied lineedit has some text already
154 typedSomething( m_lineEdit->text() );
155}
156
157void KEditListBox::typedSomething(const QString& text)
158{
159 if(currentItem() >= 0) {
160 if(currentText() != m_lineEdit->text())
161 {
162 // IMHO changeItem() shouldn't do anything with the value
163 // of currentItem() ... like changing it or emitting signals ...
164 // but TT disagree with me on this one (it's been that way since ages ... grrr)
165 bool block = m_listBox->signalsBlocked();
166 m_listBox->blockSignals( true );
167 m_listBox->changeItem(text, currentItem());
168 m_listBox->blockSignals( block );
169 emit changed();
170 }
171 }
172
173 if ( !servNewButton )
174 return;
175
176 if (!d->m_checkAtEntering)
177 servNewButton->setEnabled(!text.isEmpty());
178 else
179 {
180 if (text.isEmpty())
181 {
182 servNewButton->setEnabled(false);
183 }
184 else
185 {
186 bool enable = (m_listBox->findItem( text ) == 0L);
187 servNewButton->setEnabled( enable );
188 }
189 }
190}
191
192void KEditListBox::moveItemUp()
193{
194 if (!m_listBox->isEnabled())
195 {
196 KNotifyClient::beep();
197 return;
198 }
199
200 unsigned int selIndex = m_listBox->currentItem();
201 if (selIndex == 0)
202 {
203 KNotifyClient::beep();
204 return;
205 }
206
207 QListBoxItem *selItem = m_listBox->item(selIndex);
208 m_listBox->takeItem(selItem);
209 m_listBox->insertItem(selItem, selIndex-1);
210 m_listBox->setCurrentItem(selIndex - 1);
211
212 emit changed();
213}
214
215void KEditListBox::moveItemDown()
216{
217 if (!m_listBox->isEnabled())
218 {
219 KNotifyClient::beep();
220 return;
221 }
222
223 unsigned int selIndex = m_listBox->currentItem();
224 if (selIndex == m_listBox->count() - 1)
225 {
226 KNotifyClient::beep();
227 return;
228 }
229
230 QListBoxItem *selItem = m_listBox->item(selIndex);
231 m_listBox->takeItem(selItem);
232 m_listBox->insertItem(selItem, selIndex+1);
233 m_listBox->setCurrentItem(selIndex + 1);
234
235 emit changed();
236}
237
238void KEditListBox::addItem()
239{
240 // when m_checkAtEntering is true, the add-button is disabled, but this
241 // slot can still be called through Key_Return/Key_Enter. So we guard
242 // against this.
243 if ( !servNewButton || !servNewButton->isEnabled() )
244 return;
245
246 const QString& currentTextLE=m_lineEdit->text();
247 bool alreadyInList(false);
248 //if we didn't check for dupes at the inserting we have to do it now
249 if (!d->m_checkAtEntering)
250 {
251 // first check current item instead of dumb iterating the entire list
252 if ( m_listBox->currentText() == currentTextLE )
253 alreadyInList = true;
254 else
255 {
256 alreadyInList =(m_listBox->findItem(currentTextLE) != 0);
257 }
258 }
259
260 if ( servNewButton )
261 servNewButton->setEnabled(false);
262
263 bool block = m_lineEdit->signalsBlocked();
264 m_lineEdit->blockSignals(true);
265 m_lineEdit->clear();
266 m_lineEdit->blockSignals(block);
267
268 m_listBox->setSelected(currentItem(), false);
269
270 if (!alreadyInList)
271 {
272 block = m_listBox->signalsBlocked();
273 m_listBox->blockSignals( true );
274 m_listBox->insertItem(currentTextLE);
275 m_listBox->blockSignals( block );
276 emit changed();
277 }
278}
279
280int KEditListBox::currentItem() const
281{
282 int nr = m_listBox->currentItem();
283 if(nr >= 0 && !m_listBox->item(nr)->selected()) return -1;
284 return nr;
285}
286
287void KEditListBox::removeItem()
288{
289 int selected = m_listBox->currentItem();
290
291 if ( selected >= 0 )
292 {
293 m_listBox->removeItem( selected );
294 if ( count() > 0 )
295 m_listBox->setSelected( QMIN( selected, count() - 1 ), true );
296
297 emit changed();
298 }
299
300 if ( servRemoveButton && m_listBox->currentItem() == -1 )
301 servRemoveButton->setEnabled(false);
302}
303
304void KEditListBox::enableMoveButtons(int index)
305{
306 // Update the lineEdit when we select a different line.
307 if(currentText() != m_lineEdit->text())
308 m_lineEdit->setText(currentText());
309
310 bool moveEnabled = servUpButton && servDownButton;
311
312 if (moveEnabled )
313 {
314 if (m_listBox->count() <= 1)
315 {
316 servUpButton->setEnabled(false);
317 servDownButton->setEnabled(false);
318 }
319 else if ((uint) index == (m_listBox->count() - 1))
320 {
321 servUpButton->setEnabled(true);
322 servDownButton->setEnabled(false);
323 }
324 else if (index == 0)
325 {
326 servUpButton->setEnabled(false);
327 servDownButton->setEnabled(true);
328 }
329 else
330 {
331 servUpButton->setEnabled(true);
332 servDownButton->setEnabled(true);
333 }
334 }
335
336 if ( servRemoveButton )
337 servRemoveButton->setEnabled(true);
338}
339
340void KEditListBox::clear()
341{
342 m_lineEdit->clear();
343 m_listBox->clear();
344 emit changed();
345}
346
347void KEditListBox::insertStringList(const QStringList& list, int index)
348{
349 m_listBox->insertStringList(list,index);
350}
351
352void KEditListBox::insertStrList(const QStrList* list, int index)
353{
354 m_listBox->insertStrList(list,index);
355}
356
357void KEditListBox::insertStrList(const QStrList& list, int index)
358{
359 m_listBox->insertStrList(list,index);
360}
361
362void KEditListBox::insertStrList(const char ** list, int numStrings, int index)
363{
364 m_listBox->insertStrList(list,numStrings,index);
365}
366
367QStringList KEditListBox::items() const
368{
369 QStringList list;
370 for ( uint i = 0; i < m_listBox->count(); i++ )
371 list.append( m_listBox->text( i ));
372
373 return list;
374}
375
376void KEditListBox::virtual_hook( int, void* )
377{ /*BASE::virtual_hook( id, data );*/ }
378
379
380///////////////////////////////////////////////////////////////////
381///////////////////////////////////////////////////////////////////
382
383KEditListBox::CustomEditor::CustomEditor( KComboBox *combo )
384{
385 m_representationWidget = combo;
386 m_lineEdit = static_cast<KLineEdit*>( combo->lineEdit() );
387 assert( m_lineEdit );
388}
389