]> SALOME platform Git repositories - modules/gui.git/blob - src/Qtx/QtxTable.cxx
Salome HOME
eac69ea6008fa9117c3f0f132062f402405e3a66
[modules/gui.git] / src / Qtx / QtxTable.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:      QtxTable.cxx
20 // Author:    Sergey TELKOV
21
22 #include "QtxTable.h"
23
24 #ifndef QT_NO_TABLE
25
26 #include <qlineedit.h>
27
28 QtxTable::QtxTable( QWidget* parent, const char* name )
29 : QTable( parent, name ),
30 myHeaderEditor( 0 ),
31 myEditedHeader( 0 ),
32 myEditedSection( -1 )
33 {
34   connect( verticalHeader(), SIGNAL( sizeChange( int, int, int ) ),
35            this, SLOT( onHeaderSizeChange( int, int, int ) ) );
36   connect( horizontalHeader(), SIGNAL( sizeChange( int, int, int ) ),
37            this, SLOT( onHeaderSizeChange( int, int, int ) ) );
38   connect( verticalScrollBar(), SIGNAL( valueChanged( int ) ), this, SLOT( onScrollBarMoved( int ) ) );
39   connect( horizontalScrollBar(), SIGNAL( valueChanged( int ) ), this, SLOT( onScrollBarMoved( int ) ) );
40 }
41
42 QtxTable::QtxTable( int numRows, int numCols, QWidget* parent, const char* name )
43 : QTable( numRows, numCols, parent, name ),
44 myHeaderEditor( 0 ),
45 myEditedHeader( 0 ),
46 myEditedSection( -1 )
47 {
48   connect( verticalHeader(), SIGNAL( sizeChange( int, int, int ) ),
49            this, SLOT( onHeaderSizeChange( int, int, int ) ) );
50   connect( horizontalHeader(), SIGNAL( sizeChange( int, int, int ) ),
51            this, SLOT( onHeaderSizeChange( int, int, int ) ) );
52   connect( verticalScrollBar(), SIGNAL( valueChanged( int ) ), this, SLOT( onScrollBarMoved( int ) ) );
53   connect( horizontalScrollBar(), SIGNAL( valueChanged( int ) ), this, SLOT( onScrollBarMoved( int ) ) );
54 }
55
56 QtxTable::~QtxTable()
57 {
58 }
59
60 bool QtxTable::headerEditable( Orientation o ) const
61 {
62   return myHeaderEditable.contains( o ) ? myHeaderEditable[o] : false;
63 }
64
65 void QtxTable::setHeaderEditable( Orientation o, const bool on )
66 {
67   if ( headerEditable( o ) == on )
68     return;
69
70   myHeaderEditable.insert( o, on );
71
72   QHeader* hdr = header( o );
73
74   if ( !on && myEditedHeader == hdr )
75     endHeaderEdit( false );
76
77   if ( on )
78     hdr->installEventFilter( this );
79   else
80     hdr->removeEventFilter( this );
81 }
82
83 bool QtxTable::editHeader( Orientation o, const int sec )
84 {
85   return beginHeaderEdit( o, sec );
86 }
87
88 void QtxTable::endEditHeader( const bool accept )
89 {
90   endHeaderEdit( accept );
91 }
92
93 void QtxTable::hide()
94 {
95   endHeaderEdit();
96
97   QTable::hide();
98 }
99
100 bool QtxTable::eventFilter( QObject* o, QEvent* e )
101 {
102   if ( e->type() == QEvent::MouseButtonDblClick )
103   {
104     QMouseEvent* me = (QMouseEvent*)e;
105     if ( o == horizontalHeader() )
106     {
107       beginHeaderEdit( Horizontal, me->pos() );
108       return true;
109     }
110     else if ( o == verticalHeader() )
111     {
112       beginHeaderEdit( Vertical, me->pos() );
113       return true;
114     }
115   }
116
117   if ( o == myHeaderEditor && e->type() == QEvent::KeyPress && isHeaderEditing() )
118   {
119           QKeyEvent* ke = (QKeyEvent*)e;
120     if ( ke->key() == Key_Escape )
121     {
122       endHeaderEdit( false );
123       return true;
124     }
125
126     if ( ke->key() == Key_Return || ke->key() == Key_Enter )
127     {
128       endHeaderEdit( true );
129       return true;
130     }
131
132     return false;
133   }
134
135   if ( o == myHeaderEditor && e->type() == QEvent::FocusOut &&
136        isHeaderEditing() && ((QFocusEvent*)e)->reason() != QFocusEvent::Popup )
137   {
138                 endHeaderEdit();
139                 return true;
140   }
141
142   if ( e->type() == QEvent::Wheel && isHeaderEditing() )
143     return true;
144
145   return QTable::eventFilter( o, e );
146 }
147
148 void QtxTable::onScrollBarMoved( int )
149 {
150   updateHeaderEditor();
151 }
152
153 void QtxTable::onHeaderSizeChange( int, int, int )
154 {
155   if ( sender() == myEditedHeader )
156     updateHeaderEditor();
157 }
158
159 void QtxTable::resizeEvent( QResizeEvent* e )
160 {
161   QTable::resizeEvent( e );
162
163   updateHeaderEditor();
164 }
165
166 bool QtxTable::beginHeaderEdit( Orientation o, const int section )
167 {
168   if ( !headerEditable( o ) || !header( o ) || !header( o )->isVisibleTo( this ) )
169     return false;
170
171   endHeaderEdit();
172
173   QHeader* hdr = header( o );
174
175   QRect r = headerSectionRect( hdr, section );
176   if ( !r.isValid() )
177     return false;
178
179   if ( o == Horizontal )
180     r.setLeft( QMAX( r.left(), leftMargin() ) );
181   else
182     r.setTop( QMAX( r.top(), topMargin() ) );
183
184   myHeaderEditor = createHeaderEditor( hdr, section );
185   if ( !myHeaderEditor )
186     return false;
187
188   myEditedHeader = hdr;
189   myEditedSection = section;
190
191   myHeaderEditor->reparent( this, QPoint( 0, 0 ), false );
192
193   updateHeaderEditor();
194
195   myHeaderEditor->show();
196
197   myHeaderEditor->setActiveWindow();
198   myHeaderEditor->setFocus();
199
200   myHeaderEditor->installEventFilter( this );
201
202   return true;
203 }
204
205 void QtxTable::endHeaderEdit( const bool accept )
206 {
207   if ( !isHeaderEditing() )
208     return;
209
210   QString oldTxt = myEditedHeader ? myEditedHeader->label( myEditedSection ) : QString::null;
211
212   if ( accept && myEditedHeader )
213     setHeaderContentFromEditor( myEditedHeader, myEditedSection, myHeaderEditor );
214
215   QString newTxt = myEditedHeader ? myEditedHeader->label( myEditedSection ) : QString::null;
216
217   int sec = myEditedSection;
218   QHeader* hdr = myEditedHeader;
219
220   myEditedHeader = 0;
221   myEditedSection = -1;
222
223   myHeaderEditor->hide();
224   myHeaderEditor->deleteLater();
225   myHeaderEditor = 0;
226
227   if ( oldTxt != newTxt )
228   {
229     emit headerEdited( hdr, sec );
230     emit headerEdited( hdr == horizontalHeader() ? Horizontal : Vertical, sec );
231   }
232 }
233
234 bool QtxTable::isHeaderEditing() const
235 {
236   return myHeaderEditor && myEditedHeader && myEditedSection != -1;
237 }
238
239 QWidget* QtxTable::createHeaderEditor( QHeader* hdr, const int sec, const bool init )
240 {
241   QLineEdit* ed = new QLineEdit( 0 );
242
243   if ( init && hdr )
244     ed->setText( hdr->label( sec ) );
245
246   return ed;
247 }
248
249 void QtxTable::setHeaderContentFromEditor( QHeader* hdr, const int sec, QWidget* editor )
250 {
251   if ( !hdr || !editor )
252     return;
253
254   if ( editor->inherits( "QLineEdit" ) )
255     hdr->setLabel( sec, ((QLineEdit*)editor)->text() );
256 }
257
258 QHeader* QtxTable::header( Orientation o ) const
259 {
260   return o == Horizontal ? horizontalHeader() : verticalHeader();
261 }
262
263 void QtxTable::beginHeaderEdit( Orientation o, const QPoint& p )
264 {
265   QHeader* hdr = header( o );
266   if ( !hdr )
267     return;
268
269   int pos = o == Horizontal ? p.x() : p.y();
270   int sec = hdr->sectionAt( hdr->offset() + pos );
271
272   beginHeaderEdit( o, sec );
273 }
274
275 QRect QtxTable::headerSectionRect( QHeader* hdr, const int sec ) const
276 {
277   QRect r( -1, -1, -1, -1 );
278
279   if ( !hdr )
280     return r;
281
282   r = hdr->sectionRect( sec );
283   if ( r.isValid() )
284     r = QRect( mapFromGlobal( hdr->mapToGlobal( r.topLeft() ) ), r.size() );
285
286   return r;
287 }
288
289 void QtxTable::updateHeaderEditor()
290 {
291   if ( !myHeaderEditor || !myEditedHeader || myEditedSection < 0 )
292     return;
293
294   QRect r = headerSectionRect( myEditedHeader, myEditedSection );
295   if ( !r.isValid() )
296     return;
297
298   if ( myEditedHeader == horizontalHeader() )
299   {
300     r.setLeft( QMAX( r.left(), leftMargin() ) );
301     r.setRight( QMIN( r.right(), width() - rightMargin() - 2 ) );
302   }
303   else
304   {
305     r.setTop( QMAX( r.top(), topMargin() ) );
306     r.setBottom( QMIN( r.bottom(), height() - bottomMargin() - 2 ) );
307   }
308
309   myHeaderEditor->resize( r.size() );
310   myHeaderEditor->move( r.topLeft() );
311 }
312
313 #endif