]> SALOME platform Git repositories - modules/gui.git/blob - src/Qtx/QtxListBox.cxx
Salome HOME
Join modifications from branch BR_DEBUG_3_2_0b1
[modules/gui.git] / src / Qtx / QtxListBox.cxx
1 // Copyright (C) 2005  OPEN CASCADE, CEA/DEN, EDF R&D, PRINCIPIA R&D
2 // 
3 // This library is free software; you can redistribute it and/or
4 // modify it under the terms of the GNU Lesser General Public
5 // License as published by the Free Software Foundation; either 
6 // version 2.1 of the License.
7 // 
8 // This library is distributed in the hope that it will be useful 
9 // but WITHOUT ANY WARRANTY; without even the implied warranty of 
10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU 
11 // Lesser General Public License for more details.
12 //
13 // You should have received a copy of the GNU Lesser General Public  
14 // License along with this library; if not, write to the Free Software 
15 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
16 //
17 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
18 //
19 // File:      QtxListBox.cxx
20 // Author:    Sergey TELKOV
21
22 #include "QtxListBox.h"
23
24 #include <qpixmap.h>
25 #include <qlineedit.h>
26
27 /*!
28   Constructor
29 */
30 QtxListBox::QtxListBox( QWidget* parent, const char* name, WFlags f )
31 : QListBox( parent, name, f ),
32 myEditor( 0 ),
33 myEditIndex( -1 ),
34 myEditState( false ),
35 myEditDefault( true ),
36 myModifEnabled( true )
37 {
38   connect( this, SIGNAL( contentsMoving( int, int ) ),
39            this, SLOT( onContentsMoving( int, int ) ) );
40 }
41
42 /*!
43   Destructor
44 */
45 QtxListBox::~QtxListBox()
46 {
47 }
48
49 /*!
50   \return true if editing is enabled
51 */
52 bool QtxListBox::isEditEnabled() const
53 {
54   return myEditState;
55 }
56
57 /*!
58   Enables/disables editing
59   \param on - new state
60 */
61 void QtxListBox::setEditEnabled( bool on )
62 {
63   if ( isEditEnabled() == on )
64     return;
65
66   myEditState = on;
67
68   if ( !isEditEnabled() )
69     endEdition( defaultEditAction() );
70 }
71
72 /*!
73   \return default edit action
74   \sa setDefaultEditAction()
75 */
76 bool QtxListBox::defaultEditAction() const
77 {
78   return myEditDefault;
79 }
80
81 /*!
82   Changes default edit action. 
83   Pressing of ENTER button always accepts new value of edited item.
84   But other ways, such as focus out or edition of other item accepts
85   new value of edited item only if "default edit action" is true
86   \param def - new value
87 */
88 void QtxListBox::setDefaultEditAction( bool def )
89 {
90   myEditDefault = def;
91 }
92
93 /*!
94   \return modification enabled state
95   \sa setModificationEnabled()
96 */
97 bool QtxListBox::isModificationEnabled() const
98 {
99   return myModifEnabled;
100 }
101
102 /*!
103   Changes "modification enabled" state
104   If it is true, then pressing of CTRL + { Up, Down, Home, End } allows move items in list
105   \param on - new state
106 */
107 void QtxListBox::setModificationEnabled( bool on )
108 {
109   myModifEnabled = on;
110 }
111
112 /*!
113   \return current edited item
114 */
115 QListBoxItem* QtxListBox::editedItem() const
116 {
117   return item( editedIndex() );
118 }
119
120 /*!
121   \return current edited index
122 */
123 int QtxListBox::editedIndex() const
124 {
125   return myEditIndex;
126 }
127
128 /*!
129   Starts edition of item
130   \param idx - index of item
131 */
132 void QtxListBox::startEdition( const int idx )
133 {
134   if ( idx < 0 || editedIndex() == idx || !isEditEnabled() )
135     return;
136
137   QLineEdit* ed = editor();
138   if ( !ed )
139     return;
140
141   endEdition( defaultEditAction() );
142
143   myEditIndex = idx;
144
145   ensureItemVisible( myEditIndex );
146
147   ed->setText( text( myEditIndex ) );
148   updateEditor();
149   ed->show();
150
151   ed->setFocus();
152 }
153
154 /*!
155   Starts edition of item
156   \param item - item to be edited
157 */
158 void QtxListBox::startEdition( const QListBoxItem* item )
159 {
160   startEdition( index( item ) );
161 }
162
163 /*!
164   Finishes edition of item
165   \param action - if it is true, then new values must be accepted
166 */
167 void QtxListBox::endEdition( const bool action )
168 {
169   int idx = editedIndex();
170   QLineEdit* ed = editor();
171
172   if ( idx < 0 || !ed )
173     return;
174
175   myEditIndex = -1;
176
177   ed->hide();
178
179   if ( action )
180   {
181     int cur = currentItem();
182
183     if ( pixmap( idx ) )
184       changeItem( *pixmap( idx ), ed->text(), idx );
185     else
186       changeItem( ed->text(), idx );
187
188     setCurrentItem( cur );
189
190     emit itemEdited( idx );
191     emit itemEdited( item( idx ) );
192   }
193 }
194
195 /*!
196   Ensures that the item is visible.
197   \param idx - index of item
198 */
199 void QtxListBox::ensureItemVisible( const int idx )
200 {
201   if ( idx < 0 )
202     return;
203
204   if ( itemVisible( idx ) )
205     return;
206
207   setTopItem( idx );
208 }
209
210 /*!
211   Ensures that the item is visible.
212   \param item - item to be made visible
213 */
214 void QtxListBox::ensureItemVisible( const QListBoxItem* item )
215 {
216   ensureItemVisible( index( item ) );
217 }
218
219 /*!
220   \return validator of item editor
221 */
222 const QValidator* QtxListBox::validator() const
223 {
224   const QValidator* v = 0;
225   if ( editor() )
226     v = editor()->validator();
227   return v;
228 }
229
230 /*!
231   Removes validator of item editor
232 */
233 void QtxListBox::clearValidator()
234 {
235   if ( editor() )
236     editor()->clearValidator();
237 }
238
239 /*!
240   Changes validator of item editor
241   \param v - new validator
242 */
243 void QtxListBox::setValidator( const QValidator* v )
244 {
245   if ( editor() )
246     editor()->setValidator( v );
247 }
248
249 /*!
250   Moves item to top
251   \param idx - index of item
252 */
253 void QtxListBox::moveItemToTop( const int idx )
254 {
255   moveItem( idx, -idx );
256 }
257
258 /*!
259   Moves item to bottom
260   \param idx - index of item
261 */
262 void QtxListBox::moveItemToBottom( const int idx )
263 {
264   moveItem( idx, count() - idx );
265 }
266
267 /*!
268   Moves item
269   \param idx - index of item
270   \param step - changing of position
271 */
272 void QtxListBox::moveItem( const int idx, const int step )
273 {
274   QListBoxItem* i = item( idx );
275   if ( !i || step == 0 )
276     return;
277
278   QListBoxItem* cur = item( currentItem() );
279
280   takeItem( i );
281   insertItem( i, QMAX( 0, idx + step ) );
282
283   setCurrentItem( index( cur ) );
284
285   int pos = index( i );
286   if ( myEditIndex == idx )
287     myEditIndex = pos;
288
289   updateEditor();
290
291   if ( idx != pos )
292     emit itemMoved( idx, pos );
293 }
294
295 /*!
296   Inserts empty item
297   \param i - position of item (if it is less than 0, then current position is used)
298 */
299 void QtxListBox::createItem( const int i )
300 {
301   if ( !isEditEnabled() )
302     return;
303
304   int idx = i < 0 ? currentItem() : i;
305   idx = idx < 0 ? count() : idx;
306   idx = QMIN( (int)count(), idx );
307
308   insertItem( "", idx );
309   setCurrentItem( idx );
310   startEdition( idx );
311 }
312
313 /*!
314   Removes item
315   \param i - position of item (if it is less than 0, then current position is used)
316 */
317 void QtxListBox::deleteItem( const int i )
318 {
319   if ( !isEditEnabled() )
320     return;
321
322   int idx = i < 0 ? currentItem() : i;
323   if ( idx < 0 )
324     return;
325
326   if ( editedIndex() == idx )
327     endEdition( defaultEditAction() );
328
329   removeItem( idx );
330   updateEditor();
331 }
332
333 /*!
334   Scrolls the content so that the point is in the top-left corner.
335   \param x, y - point co-ordinates
336 */
337 void QtxListBox::setContentsPos( int x, int y )
338 {
339   QListBox::setContentsPos( x, y );
340
341   updateEditor();
342 }
343
344 /*!
345   Custom event filter, performs finish of edition on focus out, escape/return/enter pressing
346 */
347 bool QtxListBox::eventFilter( QObject* o, QEvent* e )
348 {
349   if ( editor() == o )
350   {
351     if ( e->type() == QEvent::FocusOut )
352       endEdition( defaultEditAction() );
353
354     if ( e->type() == QEvent::KeyPress )
355     {
356       QKeyEvent* ke = (QKeyEvent*)e;
357       if ( ke->key() == Key_Escape )
358         endEdition( false );
359       else if ( ke->key() == Key_Enter || ke->key() == Key_Return )
360         endEdition( true );
361     }
362   }
363
364   return QListBox::eventFilter( o, e );
365 }
366
367 /*!
368   Custom key press event handler
369   Allows to move items by CTRL + { Up, Down, Home, End }
370 */
371 void QtxListBox::keyPressEvent( QKeyEvent* e )
372 {
373   if ( e->key() == Key_Up && e->state() & ControlButton && isModificationEnabled() )
374     moveItem( currentItem(), -1 );
375   else if ( e->key() == Key_Down && e->state() & ControlButton && isModificationEnabled() )
376     moveItem( currentItem(), 1 );
377   else if ( e->key() == Key_Home && e->state() & ControlButton && isModificationEnabled() )
378     moveItemToTop( currentItem() );
379   else if ( e->key() == Key_End && e->state() & ControlButton && isModificationEnabled() )
380     moveItemToBottom( currentItem() );
381   else if ( e->key() == Key_Insert && e->state() & ControlButton )
382     createItem( currentItem() );
383   else if ( e->key() == Key_Delete && e->state() & ControlButton )
384     deleteItem( currentItem() );
385   else
386     QListBox::keyPressEvent( e );
387 }
388
389 /*!
390   Custom resize event handler
391 */
392 void QtxListBox::viewportResizeEvent( QResizeEvent* e )
393 {
394   QListBox::viewportResizeEvent( e );
395
396   updateEditor();
397 }
398
399 /*!
400   Custom mouse double click event handler
401 */
402 void QtxListBox::mouseDoubleClickEvent( QMouseEvent* e )
403 {
404   if ( isEditEnabled() )
405     startEdition( itemAt( e->pos() ) );
406   else
407     QListBox::mouseDoubleClickEvent( e );
408 }
409
410 /*!
411   Updates editor on contents moving
412 */
413 void QtxListBox::onContentsMoving( int, int )
414 {
415   updateEditor();
416 }
417
418 /*!
419   \return item editor
420 */
421 QLineEdit* QtxListBox::editor() const
422 {
423   if ( !myEditor )
424   {
425     QtxListBox* that = (QtxListBox*)this;
426     that->createEditor();
427   }
428   return myEditor;
429 }
430
431 /*!
432   Creates item editor
433 */
434 void QtxListBox::createEditor()
435 {
436   if ( myEditor )
437     return;
438
439   myEditor = new QLineEdit( viewport() );
440
441   myEditor->setLineWidth( 1 );
442   myEditor->setMidLineWidth( 0 );
443   myEditor->setFrameStyle( QFrame::Box | QFrame::Plain );
444   myEditor->installEventFilter( this );
445
446   myEditor->hide();
447
448   addChild( myEditor );
449 }
450
451 /*!
452   Updates item editor
453 */
454 void QtxListBox::updateEditor()
455 {
456   if ( !editedItem() || !editor() )
457     return;
458
459   QRect r = itemRect( editedItem() );
460   if ( !r.isValid() )
461     return;
462
463   int m = editor()->lineWidth();
464   r.addCoords( m, 0, 0, 0 );
465
466   const QPixmap* pix = pixmap( editedIndex() );
467   if ( pix )
468     r.addCoords( pix->width() + 2, 0, 0, 0 );
469
470   editor()->setGeometry( r );
471 }