Salome HOME
Repaint of list view
[modules/gui.git] / src / Qtx / QtxListView.cxx
1
2 #include "QtxListView.h"
3
4 #include <qheader.h>
5 #include <qpopupmenu.h>
6 #include <qpushbutton.h>
7
8 static const char* list_xpm[] = {
9 "16 16 6 1",
10 ". c None",
11 "a c #E3E9EB",
12 "b c #798391",
13 "c c #EBEBEB",
14 "d c #ABB4BE",
15 "e c #030E1F",
16 "................",
17 "................",
18 "................",
19 "...aaaaaaaaaa...",
20 "..abbbbbbbbbbe..",
21 "..abecbecbecbe..",
22 "..abbbbbbbbbbe..",
23 "..abecbecbecbe..",
24 "..abecaaaaaaaa..",
25 "..abeccdbbbbbb..",
26 "..abecccdbbbbe..",
27 "..abbbbe.dbbe...",
28 "...eeeee..de....",
29 "................",
30 "................",
31 "................" };
32
33 QtxListView::QtxListView( const int state, QWidget* parent, const char* name, WFlags f )
34 : QListView( parent, name, f ),
35 myButton( 0 ),
36 myHeaderState( state )
37 {
38   initialize();
39 }
40
41 QtxListView::QtxListView( QWidget* parent, const char* name, WFlags f )
42 : QListView( parent, name, f ),
43 myButton( 0 ),
44 myHeaderState( HeaderAuto )
45 {
46   initialize();
47 }
48
49 void QtxListView::initialize()
50 {
51   if ( myHeaderState == HeaderButton )
52   {
53     QPixmap p( list_xpm );
54
55     QPushButton* but = new QPushButton( this );
56     but->setDefault( false );
57     but->setFlat( true );
58     but->setIconSet( p );
59     but->setBackgroundPixmap( p );
60     if ( p.mask() )
61             but->setMask( *p.mask() );
62     myButton = but;
63
64     connect( myButton, SIGNAL( clicked() ), this, SLOT( onButtonClicked() ) );
65   }
66   else
67   {
68     header()->installEventFilter( this );
69   }
70
71   myPopup = new QPopupMenu( this );
72   connect( myPopup, SIGNAL( activated( int ) ), this, SLOT( onShowHide( int ) ) );
73   connect( header(), SIGNAL( sizeChange( int, int, int ) ), this, SLOT( onHeaderResized() ) );
74 }
75
76 QtxListView::~QtxListView()
77 {
78 }
79
80 int QtxListView::addColumn( const QString& label, int width )
81 {
82   int res = QListView::addColumn( label, width );
83   for ( int i = myAppropriate.count(); i <= res; i++ )
84     myAppropriate.append( 1 );
85   onHeaderResized();
86   return res;
87 }
88
89 int QtxListView::addColumn( const QIconSet& iconset, const QString& label, int width ) 
90 {
91   int res = QListView::addColumn( iconset, label, width );
92   for ( int i = myAppropriate.count(); i <= res; i++ )
93     myAppropriate.append( 1 );
94   onHeaderResized();
95   return res;
96 }
97
98 void QtxListView::removeColumn( int index ) 
99 {
100   QListView::removeColumn( index );
101   if ( index >= 0 && index < (int)myAppropriate.count() )
102     myAppropriate.remove( myAppropriate.at( index ) );
103   onHeaderResized();
104 }
105
106 bool QtxListView::appropriate( const int index ) const
107 {
108   return index >= 0 && index < (int)myAppropriate.count() && myAppropriate[index];
109 }
110
111 void QtxListView::setAppropriate( const int index, const bool on )
112 {
113   if ( index < 0 || index >= (int)myAppropriate.count() )
114     return;
115
116   myAppropriate[index] = on ? 1 : 0;
117 }
118
119 void QtxListView::resize( int w, int h )
120 {
121   QListView::resize( w, h );
122   onHeaderResized();
123 }
124
125 void QtxListView::show()
126 {
127   QListView::show();
128   onHeaderResized();
129 }
130
131 void QtxListView::resizeContents( int w, int h )
132 {
133 /*
134   if ( myButton && myButton->isVisibleTo( myButton->parentWidget() ) )
135   {
136     if ( header()->orientation() == Qt::Horizontal )
137       w += myButton->width();
138     else
139       h += myButton->width();
140   }
141 */
142   QListView::resizeContents( w, h );
143
144   onHeaderResized();
145 }
146
147 void QtxListView::show( int ind )
148 {
149   setShown( ind, true );
150 }
151
152 void QtxListView::hide( int ind )
153 {
154   setShown( ind, false );
155 }
156
157 bool QtxListView::isShown( int ind ) const
158 {
159   if ( ind>=0 && ind<header()->count() )
160     return columnWidth( ind ) > 0 || header()->isResizeEnabled( ind );
161   else
162     return false;
163 }
164
165 void QtxListView::setShown( int ind, bool sh )
166 {
167   if( ind<0 || ind>=header()->count() || isShown( ind )==sh )
168     return;
169
170   ColumnData& data = myColumns[ind];
171   if ( sh )
172   {
173     int w = data.width;
174     bool resizeable = data.resizeable;
175     myColumns.remove( ind );
176
177     setColumnWidth( ind, w );
178     header()->setResizeEnabled( resizeable, ind );
179   }
180   else
181   {
182     int w = columnWidth( ind );
183     bool r = header()->isResizeEnabled( ind );
184     setColumnWidth( ind, 0 );
185     header()->setResizeEnabled( false, ind );
186     data.width = w;
187     data.resizeable = r;
188   }
189   updateContents();
190 }
191
192 void QtxListView::setColumnWidth( int c, int w )
193 {
194   if ( myColumns.contains( c ) )
195     myColumns[c].width = w;
196
197   QListView::setColumnWidth( c, !myColumns.contains( c ) ? w : 0 );
198 }
199
200 QSize QtxListView::sizeHint() const
201 {
202   QSize sz = QListView::sizeHint();
203
204   if ( myButton && myButton->isVisibleTo( myButton->parentWidget() ) )
205     sz.setWidth( sz.width() + 2 + myButton->width() );
206
207   return sz;
208 }
209
210 QSize QtxListView::minimumSizeHint() const
211 {
212   QSize sz = QListView::minimumSizeHint();
213
214   if ( myButton && myButton->isVisibleTo( myButton->parentWidget() ) )
215     sz.setWidth( sz.width() + 2 + myButton->width() );
216
217   return sz;
218 }
219
220 void QtxListView::onHeaderResized()
221 {
222   if ( myHeaderState == HeaderAuto )
223   {
224     int c = 0;
225     for ( int i = 0; i < columns(); i++ )
226     {
227       if ( !header()->label( i ).isEmpty() ||
228            ( header()->iconSet( i ) && !header()->iconSet( i )->isNull() ) )
229         c++;
230     }
231
232     if ( c > 1 )
233       header()->show();
234     else
235       header()->hide();
236   }
237
238   if ( !myButton || !header()->isVisibleTo( this ) )
239     return;
240
241   int lw = lineWidth();
242   int h = header()->size().height() - 1;
243   myButton->setFixedSize( h, h );
244
245   int x = header()->headerWidth() - header()->offset() + 2;
246   if ( x < header()->width() - h )
247     x = header()->width() - h;
248
249   if ( myHeaderState == HeaderButton )
250   {
251     if ( header()->orientation() == Qt::Horizontal )
252       myButton->move( lw+x, lw );
253     else
254       myButton->move( lw, lw+x );
255   }
256 }
257
258 void QtxListView::showPopup( const int x, const int y )
259 {
260   myPopup->clear();
261   for ( int i = 0; i < columns(); i++ )
262   {
263     if ( appropriate( i ) )
264     {
265       int id = myPopup->insertItem( header()->label( i ), i );
266       myPopup->setItemChecked( id, isShown( i ) );
267     }
268   }
269
270   if( myPopup->count() )
271     myPopup->exec( mapToGlobal( QPoint( x, y ) ) );
272 }
273
274 void QtxListView::onButtonClicked()
275 {
276   if ( myHeaderState != HeaderButton )
277     return;
278
279   int x = myButton->x(),
280       y = myButton->y() + myButton->height();
281
282   showPopup( x, y );
283 }
284
285 void QtxListView::onShowHide( int id )
286 {
287   //if ( myHeaderState != HeaderButton )
288   //  return;
289
290   setShown( id, !isShown( id ) );
291 }
292
293 void QtxListView::viewportResizeEvent( QResizeEvent* e )
294 {
295   QListView::viewportResizeEvent( e );
296   onHeaderResized();
297 }
298
299 bool QtxListView::eventFilter( QObject* o, QEvent* e )
300 {
301   if( o==header() && e->type()==QEvent::MouseButtonPress )
302   {
303     QMouseEvent* me = ( QMouseEvent* )e;
304     if( me->button()==Qt::RightButton )
305     {
306       showPopup( me->x()+2, me->y()+2 );
307       return true;
308     }
309   }
310   
311   return QListView::eventFilter( o, e );
312 }