1 // Copyright (C) 2005 OPEN CASCADE, CEA/DEN, EDF R&D, PRINCIPIA R&D
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.
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.
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
17 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
20 // Author: Sergey TELKOV
26 #include <qlineedit.h>
31 QtxTable::QtxTable( QWidget* parent, const char* name )
32 : QTable( parent, name ),
37 connect( verticalHeader(), SIGNAL( sizeChange( int, int, int ) ),
38 this, SLOT( onHeaderSizeChange( int, int, int ) ) );
39 connect( horizontalHeader(), SIGNAL( sizeChange( int, int, int ) ),
40 this, SLOT( onHeaderSizeChange( int, int, int ) ) );
41 connect( verticalScrollBar(), SIGNAL( valueChanged( int ) ), this, SLOT( onScrollBarMoved( int ) ) );
42 connect( horizontalScrollBar(), SIGNAL( valueChanged( int ) ), this, SLOT( onScrollBarMoved( int ) ) );
48 QtxTable::QtxTable( int numRows, int numCols, QWidget* parent, const char* name )
49 : QTable( numRows, numCols, parent, name ),
54 connect( verticalHeader(), SIGNAL( sizeChange( int, int, int ) ),
55 this, SLOT( onHeaderSizeChange( int, int, int ) ) );
56 connect( horizontalHeader(), SIGNAL( sizeChange( int, int, int ) ),
57 this, SLOT( onHeaderSizeChange( int, int, int ) ) );
58 connect( verticalScrollBar(), SIGNAL( valueChanged( int ) ), this, SLOT( onScrollBarMoved( int ) ) );
59 connect( horizontalScrollBar(), SIGNAL( valueChanged( int ) ), this, SLOT( onScrollBarMoved( int ) ) );
70 \return true if header is editable
71 \param o - header orientation
73 bool QtxTable::headerEditable( Orientation o ) const
75 return myHeaderEditable.contains( o ) ? myHeaderEditable[o] : false;
79 Changes editable state of header
80 \param o - header orientation
83 void QtxTable::setHeaderEditable( Orientation o, const bool on )
85 if ( headerEditable( o ) == on )
88 myHeaderEditable.insert( o, on );
90 QHeader* hdr = header( o );
92 if ( !on && myEditedHeader == hdr )
93 endHeaderEdit( false );
96 hdr->installEventFilter( this );
98 hdr->removeEventFilter( this );
102 Starts edition of header
103 \param o - header orientation
104 \param sec - column/row
106 bool QtxTable::editHeader( Orientation o, const int sec )
108 return beginHeaderEdit( o, sec );
112 Finishes edition of header
113 \param accept - whether new value must be accepted
115 void QtxTable::endEditHeader( const bool accept )
117 endHeaderEdit( accept );
121 Finishes edition and hides table
123 void QtxTable::hide()
132 Starts edition of header by double click
133 Finishes edition by escape/return/enter pressing
135 bool QtxTable::eventFilter( QObject* o, QEvent* e )
137 if ( e->type() == QEvent::MouseButtonDblClick )
139 QMouseEvent* me = (QMouseEvent*)e;
140 if ( o == horizontalHeader() )
142 beginHeaderEdit( Horizontal, me->pos() );
145 else if ( o == verticalHeader() )
147 beginHeaderEdit( Vertical, me->pos() );
152 if ( o == myHeaderEditor && e->type() == QEvent::KeyPress && isHeaderEditing() )
154 QKeyEvent* ke = (QKeyEvent*)e;
155 if ( ke->key() == Key_Escape )
157 endHeaderEdit( false );
161 if ( ke->key() == Key_Return || ke->key() == Key_Enter )
163 endHeaderEdit( true );
170 if ( o == myHeaderEditor && e->type() == QEvent::FocusOut &&
171 isHeaderEditing() && ((QFocusEvent*)e)->reason() != QFocusEvent::Popup )
177 if ( e->type() == QEvent::Wheel && isHeaderEditing() )
180 return QTable::eventFilter( o, e );
184 SLOT: called on scroll
186 void QtxTable::onScrollBarMoved( int )
188 updateHeaderEditor();
192 SLOT: called on header size changing
194 void QtxTable::onHeaderSizeChange( int, int, int )
196 if ( sender() == myEditedHeader )
197 updateHeaderEditor();
201 Custom resize event handler
203 void QtxTable::resizeEvent( QResizeEvent* e )
205 QTable::resizeEvent( e );
207 updateHeaderEditor();
211 Starts edition of header
212 \param o - header orientation
213 \param sec - column/row
215 bool QtxTable::beginHeaderEdit( Orientation o, const int section )
217 if ( !headerEditable( o ) || !header( o ) || !header( o )->isVisibleTo( this ) )
222 QHeader* hdr = header( o );
224 QRect r = headerSectionRect( hdr, section );
228 if ( o == Horizontal )
229 r.setLeft( QMAX( r.left(), leftMargin() ) );
231 r.setTop( QMAX( r.top(), topMargin() ) );
233 myHeaderEditor = createHeaderEditor( hdr, section );
234 if ( !myHeaderEditor )
237 myEditedHeader = hdr;
238 myEditedSection = section;
240 myHeaderEditor->reparent( this, QPoint( 0, 0 ), false );
242 updateHeaderEditor();
244 myHeaderEditor->show();
246 myHeaderEditor->setActiveWindow();
247 myHeaderEditor->setFocus();
249 myHeaderEditor->installEventFilter( this );
255 Finishes edition of header
256 \param accept - whether new value must be accepted
258 void QtxTable::endHeaderEdit( const bool accept )
260 if ( !isHeaderEditing() )
263 QString oldTxt = myEditedHeader ? myEditedHeader->label( myEditedSection ) : QString::null;
265 if ( accept && myEditedHeader )
266 setHeaderContentFromEditor( myEditedHeader, myEditedSection, myHeaderEditor );
268 QString newTxt = myEditedHeader ? myEditedHeader->label( myEditedSection ) : QString::null;
270 int sec = myEditedSection;
271 QHeader* hdr = myEditedHeader;
274 myEditedSection = -1;
276 myHeaderEditor->hide();
277 myHeaderEditor->deleteLater();
280 if ( oldTxt != newTxt )
282 emit headerEdited( hdr, sec );
283 emit headerEdited( hdr == horizontalHeader() ? Horizontal : Vertical, sec );
288 \return true if header is being edited
290 bool QtxTable::isHeaderEditing() const
292 return myHeaderEditor && myEditedHeader && myEditedSection != -1;
296 Creates and \return header editor
298 \param sec - column/row
299 \param init - init editor with value
301 QWidget* QtxTable::createHeaderEditor( QHeader* hdr, const int sec, const bool init )
303 QLineEdit* ed = new QLineEdit( 0 );
306 ed->setText( hdr->label( sec ) );
312 Initialize editor with value
314 \param sec - column/row
315 \param editor - editor
317 void QtxTable::setHeaderContentFromEditor( QHeader* hdr, const int sec, QWidget* editor )
319 if ( !hdr || !editor )
322 if ( editor->inherits( "QLineEdit" ) )
323 hdr->setLabel( sec, ((QLineEdit*)editor)->text() );
328 \param o - orientation
330 QHeader* QtxTable::header( Orientation o ) const
332 return o == Horizontal ? horizontalHeader() : verticalHeader();
336 Starts edition of header
337 \param o - header orientation
340 void QtxTable::beginHeaderEdit( Orientation o, const QPoint& p )
342 QHeader* hdr = header( o );
346 int pos = o == Horizontal ? p.x() : p.y();
347 int sec = hdr->sectionAt( hdr->offset() + pos );
349 beginHeaderEdit( o, sec );
353 \return rectangle of header section
355 \param sec - column/row
357 QRect QtxTable::headerSectionRect( QHeader* hdr, const int sec ) const
359 QRect r( -1, -1, -1, -1 );
364 r = hdr->sectionRect( sec );
366 r = QRect( mapFromGlobal( hdr->mapToGlobal( r.topLeft() ) ), r.size() );
372 Updates header editor
374 void QtxTable::updateHeaderEditor()
376 if ( !myHeaderEditor || !myEditedHeader || myEditedSection < 0 )
379 QRect r = headerSectionRect( myEditedHeader, myEditedSection );
383 if ( myEditedHeader == horizontalHeader() )
385 r.setLeft( QMAX( r.left(), leftMargin() ) );
386 r.setRight( QMIN( r.right(), width() - rightMargin() - 2 ) );
390 r.setTop( QMAX( r.top(), topMargin() ) );
391 r.setBottom( QMIN( r.bottom(), height() - bottomMargin() - 2 ) );
394 myHeaderEditor->resize( r.size() );
395 myHeaderEditor->move( r.topLeft() );