Salome HOME
6d2ce0cd97e05ceeca0c76bfd5e12c505da2ea19
[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/
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 QtxListBox::QtxListBox( QWidget* parent, const char* name, WFlags f )
28 : QListBox( parent, name, f ),
29 myEditor( 0 ),
30 myEditIndex( -1 ),
31 myEditState( false ),
32 myEditDefault( true ),
33 myModifEnabled( true )
34 {
35   connect( this, SIGNAL( contentsMoving( int, int ) ),
36            this, SLOT( onContentsMoving( int, int ) ) );
37 }
38
39 QtxListBox::~QtxListBox()
40 {
41 }
42
43 bool QtxListBox::isEditEnabled() const
44 {
45   return myEditState;
46 }
47
48 void QtxListBox::setEditEnabled( bool on )
49 {
50   if ( isEditEnabled() == on )
51     return;
52
53   myEditState = on;
54
55   if ( !isEditEnabled() )
56     endEdition( defaultEditAction() );
57 }
58
59 bool QtxListBox::defaultEditAction() const
60 {
61   return myEditDefault;
62 }
63
64 void QtxListBox::setDefaultEditAction( bool def )
65 {
66   myEditDefault = def;
67 }
68
69 bool QtxListBox::isModificationEnabled() const
70 {
71   return myModifEnabled;
72 }
73
74 void QtxListBox::setModificationEnabled( bool on )
75 {
76   myModifEnabled = on;
77 }
78
79 QListBoxItem* QtxListBox::editedItem() const
80 {
81   return item( editedIndex() );
82 }
83
84 int QtxListBox::editedIndex() const
85 {
86   return myEditIndex;
87 }
88
89 void QtxListBox::startEdition( const int idx )
90 {
91   if ( idx < 0 || editedIndex() == idx || !isEditEnabled() )
92     return;
93
94   QLineEdit* ed = editor();
95   if ( !ed )
96     return;
97
98   endEdition( defaultEditAction() );
99
100   myEditIndex = idx;
101
102   ensureItemVisible( myEditIndex );
103
104   ed->setText( text( myEditIndex ) );
105   updateEditor();
106   ed->show();
107
108   ed->setFocus();
109 }
110
111 void QtxListBox::startEdition( const QListBoxItem* item )
112 {
113   startEdition( index( item ) );
114 }
115
116 void QtxListBox::endEdition( const bool action )
117 {
118   int idx = editedIndex();
119   QLineEdit* ed = editor();
120
121   if ( idx < 0 || !ed )
122     return;
123
124   myEditIndex = -1;
125
126   ed->hide();
127
128   if ( action )
129   {
130     int cur = currentItem();
131
132     if ( pixmap( idx ) )
133       changeItem( *pixmap( idx ), ed->text(), idx );
134     else
135       changeItem( ed->text(), idx );
136
137     setCurrentItem( cur );
138
139     emit itemEdited( idx );
140     emit itemEdited( item( idx ) );
141   }
142 }
143
144 void QtxListBox::ensureItemVisible( const int idx )
145 {
146   if ( idx < 0 )
147     return;
148
149   if ( itemVisible( idx ) )
150     return;
151
152   setTopItem( idx );
153 }
154
155 void QtxListBox::ensureItemVisible( const QListBoxItem* item )
156 {
157   ensureItemVisible( index( item ) );
158 }
159
160 const QValidator* QtxListBox::validator() const
161 {
162   const QValidator* v = 0;
163   if ( editor() )
164     v = editor()->validator();
165   return v;
166 }
167
168 void QtxListBox::clearValidator()
169 {
170   if ( editor() )
171     editor()->clearValidator();
172 }
173
174 void QtxListBox::setValidator( const QValidator* v )
175 {
176   if ( editor() )
177     editor()->setValidator( v );
178 }
179
180 void QtxListBox::moveItemToTop( const int idx )
181 {
182   moveItem( idx, -idx );
183 }
184
185 void QtxListBox::moveItemToBottom( const int idx )
186 {
187   moveItem( idx, count() - idx );
188 }
189
190 void QtxListBox::moveItem( const int idx, const int step )
191 {
192   QListBoxItem* i = item( idx );
193   if ( !i || step == 0 )
194     return;
195
196   QListBoxItem* cur = item( currentItem() );
197
198   takeItem( i );
199   insertItem( i, QMAX( 0, idx + step ) );
200
201   setCurrentItem( index( cur ) );
202
203   int pos = index( i );
204   if ( myEditIndex == idx )
205     myEditIndex = pos;
206
207   updateEditor();
208
209   if ( idx != pos )
210     emit itemMoved( idx, pos );
211 }
212
213 void QtxListBox::createItem( const int i )
214 {
215   if ( !isEditEnabled() )
216     return;
217
218   int idx = i < 0 ? currentItem() : i;
219   idx = idx < 0 ? count() : idx;
220   idx = QMIN( (int)count(), idx );
221
222   insertItem( "", idx );
223   setCurrentItem( idx );
224   startEdition( idx );
225 }
226
227 void QtxListBox::deleteItem( const int i )
228 {
229   if ( !isEditEnabled() )
230     return;
231
232   int idx = i < 0 ? currentItem() : i;
233   if ( idx < 0 )
234     return;
235
236   if ( editedIndex() == idx )
237     endEdition( defaultEditAction() );
238
239   removeItem( idx );
240   updateEditor();
241 }
242
243 void QtxListBox::setContentsPos( int x, int y )
244 {
245   QListBox::setContentsPos( x, y );
246
247   updateEditor();
248 }
249
250 bool QtxListBox::eventFilter( QObject* o, QEvent* e )
251 {
252   if ( editor() == o )
253   {
254     if ( e->type() == QEvent::FocusOut )
255       endEdition( defaultEditAction() );
256
257     if ( e->type() == QEvent::KeyPress )
258     {
259       QKeyEvent* ke = (QKeyEvent*)e;
260       if ( ke->key() == Key_Escape )
261         endEdition( false );
262       else if ( ke->key() == Key_Enter || ke->key() == Key_Return )
263         endEdition( true );
264     }
265   }
266
267   return QListBox::eventFilter( o, e );
268 }
269
270 void QtxListBox::keyPressEvent( QKeyEvent* e )
271 {
272   if ( e->key() == Key_Up && e->state() & ControlButton && isModificationEnabled() )
273     moveItem( currentItem(), -1 );
274   else if ( e->key() == Key_Down && e->state() & ControlButton && isModificationEnabled() )
275     moveItem( currentItem(), 1 );
276   else if ( e->key() == Key_Home && e->state() & ControlButton && isModificationEnabled() )
277     moveItemToTop( currentItem() );
278   else if ( e->key() == Key_End && e->state() & ControlButton && isModificationEnabled() )
279     moveItemToBottom( currentItem() );
280   else if ( e->key() == Key_Insert && e->state() & ControlButton )
281     createItem( currentItem() );
282   else if ( e->key() == Key_Delete && e->state() & ControlButton )
283     deleteItem( currentItem() );
284   else
285     QListBox::keyPressEvent( e );
286 }
287
288 void QtxListBox::viewportResizeEvent( QResizeEvent* e )
289 {
290   QListBox::viewportResizeEvent( e );
291
292   updateEditor();
293 }
294
295 void QtxListBox::mouseDoubleClickEvent( QMouseEvent* e )
296 {
297   if ( isEditEnabled() )
298     startEdition( itemAt( e->pos() ) );
299   else
300     QListBox::mouseDoubleClickEvent( e );
301 }
302
303 void QtxListBox::onContentsMoving( int, int )
304 {
305   updateEditor();
306 }
307
308 QLineEdit* QtxListBox::editor() const
309 {
310   if ( !myEditor )
311   {
312     QtxListBox* that = (QtxListBox*)this;
313     that->createEditor();
314   }
315   return myEditor;
316 }
317
318 void QtxListBox::createEditor()
319 {
320   if ( myEditor )
321     return;
322
323   myEditor = new QLineEdit( viewport() );
324
325   myEditor->setLineWidth( 1 );
326   myEditor->setMidLineWidth( 0 );
327   myEditor->setFrameStyle( QFrame::Box | QFrame::Plain );
328   myEditor->installEventFilter( this );
329
330   myEditor->hide();
331
332   addChild( myEditor );
333 }
334
335 void QtxListBox::updateEditor()
336 {
337   if ( !editedItem() || !editor() )
338     return;
339
340   QRect r = itemRect( editedItem() );
341   if ( !r.isValid() )
342     return;
343
344   int m = editor()->lineWidth();
345   r.addCoords( m, 0, 0, 0 );
346
347   const QPixmap* pix = pixmap( editedIndex() );
348   if ( pix )
349     r.addCoords( pix->width() + 2, 0, 0, 0 );
350
351   editor()->setGeometry( r );
352 }