]> SALOME platform Git repositories - modules/gui.git/blob - src/Qtx/QtxListView.cxx
Salome HOME
83e74d95d6236a4e25b82bd6c7ecb1a5be1ca792
[modules/gui.git] / src / Qtx / QtxListView.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
20 #include "QtxListView.h"
21
22 #include <qheader.h>
23 #include <qpopupmenu.h>
24 #include <qpushbutton.h>
25
26 static const char* list_xpm[] = {
27 "16 16 6 1",
28 ". c None",
29 "a c #E3E9EB",
30 "b c #798391",
31 "c c #EBEBEB",
32 "d c #ABB4BE",
33 "e c #030E1F",
34 "................",
35 "................",
36 "................",
37 "...aaaaaaaaaa...",
38 "..abbbbbbbbbbe..",
39 "..abecbecbecbe..",
40 "..abbbbbbbbbbe..",
41 "..abecbecbecbe..",
42 "..abecaaaaaaaa..",
43 "..abeccdbbbbbb..",
44 "..abecccdbbbbe..",
45 "..abbbbe.dbbe...",
46 "...eeeee..de....",
47 "................",
48 "................",
49 "................" };
50
51 /*!
52   Constructor
53 */
54 QtxListView::QtxListView( const int state, QWidget* parent, const char* name, WFlags f )
55 : QListView( parent, name, f ),
56 myButton( 0 ),
57 myHeaderState( state )
58 {
59   initialize();
60 }
61
62 /*!
63   Constructor
64 */
65 QtxListView::QtxListView( QWidget* parent, const char* name, WFlags f )
66 : QListView( parent, name, f ),
67 myButton( 0 ),
68 myHeaderState( HeaderAuto )
69 {
70   initialize();
71 }
72
73 /*!
74   Initialization
75 */
76 void QtxListView::initialize()
77 {
78   if ( myHeaderState == HeaderButton )
79   {
80     QPixmap p( list_xpm );
81
82     QPushButton* but = new QPushButton( this );
83     but->setDefault( false );
84     but->setFlat( true );
85     but->setIconSet( p );
86     but->setBackgroundPixmap( p );
87     if ( p.mask() )
88             but->setMask( *p.mask() );
89     myButton = but;
90
91     connect( myButton, SIGNAL( clicked() ), this, SLOT( onButtonClicked() ) );
92   }
93   else
94   {
95     header()->installEventFilter( this );
96   }
97
98   myPopup = new QPopupMenu( this );
99   connect( myPopup, SIGNAL( activated( int ) ), this, SLOT( onShowHide( int ) ) );
100   connect( header(), SIGNAL( sizeChange( int, int, int ) ), this, SLOT( onHeaderResized() ) );
101 }
102
103 /*!
104   Destructor
105 */
106 QtxListView::~QtxListView()
107 {
108 }
109
110 /*!
111   Add new column
112   \param label - column title
113   \param width - column width
114 */
115 int QtxListView::addColumn( const QString& label, int width )
116 {
117   int res = QListView::addColumn( label, width );
118   for ( int i = myAppropriate.count(); i <= res; i++ )
119     myAppropriate.append( 1 );
120   onHeaderResized();
121   return res;
122 }
123
124 /*!
125   Add new column
126   \param iconset - column icon
127   \param label - column title
128   \param width - column width
129 */
130 int QtxListView::addColumn( const QIconSet& iconset, const QString& label, int width ) 
131 {
132   int res = QListView::addColumn( iconset, label, width );
133   for ( int i = myAppropriate.count(); i <= res; i++ )
134     myAppropriate.append( 1 );
135   onHeaderResized();
136   return res;
137 }
138
139 /*!
140   Removes column
141   \param index - column index
142 */
143 void QtxListView::removeColumn( int index ) 
144 {
145   QListView::removeColumn( index );
146   if ( index >= 0 && index < (int)myAppropriate.count() )
147     myAppropriate.remove( myAppropriate.at( index ) );
148   onHeaderResized();
149 }
150
151 /*!
152   \return true if column is situated in popup for show/hide columns
153 */
154 bool QtxListView::appropriate( const int index ) const
155 {
156   return index >= 0 && index < (int)myAppropriate.count() && myAppropriate[index];
157 }
158
159 /*!
160   Sets appropriate state: whether column is situated in popup for show/hide columns
161   \param index - column index
162   \param on - new state
163 */
164 void QtxListView::setAppropriate( const int index, const bool on )
165 {
166   if ( index < 0 || index >= (int)myAppropriate.count() )
167     return;
168
169   myAppropriate[index] = on ? 1 : 0;
170 }
171
172 /*!
173   Resizes list view and header
174 */
175 void QtxListView::resize( int w, int h )
176 {
177   QListView::resize( w, h );
178   onHeaderResized();
179 }
180
181 /*!
182   Shows list view
183 */
184 void QtxListView::show()
185 {
186   QListView::show();
187   onHeaderResized();
188 }
189
190 /*!
191   Update on resize contents
192 */
193 void QtxListView::resizeContents( int w, int h )
194 {
195 /*
196   if ( myButton && myButton->isVisibleTo( myButton->parentWidget() ) )
197   {
198     if ( header()->orientation() == Qt::Horizontal )
199       w += myButton->width();
200     else
201       h += myButton->width();
202   }
203 */
204   QListView::resizeContents( w, h );
205
206   onHeaderResized();
207 }
208
209 /*!
210   Shows column
211   \param ind - column index
212 */
213 void QtxListView::show( int ind )
214 {
215   setShown( ind, true );
216 }
217
218 /*!
219   Hides column
220   \param ind - column index
221 */
222 void QtxListView::hide( int ind )
223 {
224   setShown( ind, false );
225 }
226
227 /*!
228   \return true if column is shown
229   \param ind - column index
230 */
231 bool QtxListView::isShown( int ind ) const
232 {
233   if ( ind>=0 && ind<header()->count() )
234     return columnWidth( ind ) > 0 || header()->isResizeEnabled( ind );
235   else
236     return false;
237 }
238
239 /*!
240   Shows/hides column
241   \param ind - column index
242   \param sh - new is shown state
243 */
244 void QtxListView::setShown( int ind, bool sh )
245 {
246   if( ind<0 || ind>=header()->count() || isShown( ind )==sh )
247     return;
248
249   ColumnData& data = myColumns[ind];
250   if ( sh )
251   {
252     int w = data.width;
253     bool resizeable = data.resizeable;
254     myColumns.remove( ind );
255
256     setColumnWidth( ind, w );
257     header()->setResizeEnabled( resizeable, ind );
258   }
259   else
260   {
261     int w = columnWidth( ind );
262     bool r = header()->isResizeEnabled( ind );
263     setColumnWidth( ind, 0 );
264     header()->setResizeEnabled( false, ind );
265     data.width = w;
266     data.resizeable = r;
267   }
268   updateContents();
269 }
270
271 /*!
272   Changes column width
273   \param c - column index
274   \param w - new width
275 */
276 void QtxListView::setColumnWidth( int c, int w )
277 {
278   if ( myColumns.contains( c ) )
279     myColumns[c].width = w;
280
281   QListView::setColumnWidth( c, !myColumns.contains( c ) ? w : 0 );
282 }
283
284 /*!
285   \return the recommended size for the widget
286 */
287 QSize QtxListView::sizeHint() const
288 {
289   QSize sz = QListView::sizeHint();
290
291   if ( myButton && myButton->isVisibleTo( myButton->parentWidget() ) )
292     sz.setWidth( sz.width() + 2 + myButton->width() );
293
294   return sz;
295 }
296
297 /*!
298   \return the recommended minimum size for the widget
299 */
300 QSize QtxListView::minimumSizeHint() const
301 {
302   QSize sz = QListView::minimumSizeHint();
303
304   if ( myButton && myButton->isVisibleTo( myButton->parentWidget() ) )
305     sz.setWidth( sz.width() + 2 + myButton->width() );
306
307   return sz;
308 }
309
310 /*!
311   SLOT: called if header is resized
312 */
313 void QtxListView::onHeaderResized()
314 {
315   if ( myHeaderState == HeaderAuto )
316   {
317     int c = 0;
318     for ( int i = 0; i < columns(); i++ )
319     {
320       if ( !header()->label( i ).isEmpty() ||
321            ( header()->iconSet( i ) && !header()->iconSet( i )->isNull() ) )
322         c++;
323     }
324
325     if ( c > 1 )
326       header()->show();
327     else
328       header()->hide();
329   }
330
331   if ( !myButton || !header()->isVisibleTo( this ) )
332     return;
333
334   int lw = lineWidth();
335   int h = header()->size().height() - 1;
336   myButton->setFixedSize( h, h );
337
338   int x = header()->headerWidth() - header()->offset() + 2;
339   if ( x < header()->width() - h )
340     x = header()->width() - h;
341
342   if ( myHeaderState == HeaderButton )
343   {
344     if ( header()->orientation() == Qt::Horizontal )
345       myButton->move( lw+x, lw );
346     else
347       myButton->move( lw, lw+x );
348   }
349 }
350
351 /*!
352   Shows popup filled with column names to show/hide column
353   \param x, y - position of popup
354 */
355 void QtxListView::showPopup( const int x, const int y )
356 {
357   myPopup->clear();
358   for ( int i = 0; i < columns(); i++ )
359   {
360     if ( appropriate( i ) )
361     {
362       int id = myPopup->insertItem( header()->label( i ), i );
363       myPopup->setItemChecked( id, isShown( i ) );
364     }
365   }
366
367   if( myPopup->count() )
368     myPopup->exec( mapToGlobal( QPoint( x, y ) ) );
369 }
370
371 /*!
372   SLOT: shows popup on button ".." click
373 */
374 void QtxListView::onButtonClicked()
375 {
376   if ( myHeaderState != HeaderButton )
377     return;
378
379   int x = myButton->x(),
380       y = myButton->y() + myButton->height();
381
382   showPopup( x, y );
383 }
384
385 /*!
386   SLOT: called on popup action is activated, toggles shown state of column
387   \param id - column index
388 */
389 void QtxListView::onShowHide( int id )
390 {
391   //if ( myHeaderState != HeaderButton )
392   //  return;
393
394   setShown( id, !isShown( id ) );
395 }
396
397 /*!
398   Receives all resize events sent to the viewport
399 */
400 void QtxListView::viewportResizeEvent( QResizeEvent* e )
401 {
402   QListView::viewportResizeEvent( e );
403   onHeaderResized();
404 }
405
406 /*!
407   Custom event filter, shows popup on right button click
408 */
409 bool QtxListView::eventFilter( QObject* o, QEvent* e )
410 {
411   if( o==header() && e->type()==QEvent::MouseButtonPress )
412   {
413     QMouseEvent* me = ( QMouseEvent* )e;
414     if( me->button()==Qt::RightButton )
415     {
416       showPopup( me->x()+2, me->y()+2 );
417       return true;
418     }
419   }
420   
421   return QListView::eventFilter( o, e );
422 }