diff options
Diffstat (limited to 'kregexpeditor/repeatwidget.cpp')
-rw-r--r-- | kregexpeditor/repeatwidget.cpp | 326 |
1 files changed, 326 insertions, 0 deletions
diff --git a/kregexpeditor/repeatwidget.cpp b/kregexpeditor/repeatwidget.cpp new file mode 100644 index 0000000..27215e4 --- /dev/null +++ b/kregexpeditor/repeatwidget.cpp @@ -0,0 +1,326 @@ +/* + * Copyright (c) 2002-2003 Jesper K. Pedersen <blackie@kde.org> + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License version 2 as published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public License + * along with this library; see the file COPYING.LIB. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + **/ +#ifdef QT_ONLY + #include "compat.h" +#else + #include <klocale.h> + #include <kdialogbase.h> + #include "repeatwidget.moc" +#endif + +#include "repeatwidget.h" +#include "concwidget.h" +#include "repeatregexp.h" +#include <qpainter.h> +#include <qcursor.h> +#include <qspinbox.h> +#include <qradiobutton.h> +#include <qlayout.h> +#include <qgrid.h> +#include <qvbuttongroup.h> +#include "kwidgetstreamer.h" + +RepeatWidget::RepeatWidget(RegExpEditorWindow* editorWindow, QWidget *parent, + const char *name) + : SingleContainerWidget(editorWindow, parent, name ? name : "RepeatWidget") +{ + _child = new ConcWidget(editorWindow, this); + init(); +} + +RepeatWidget::RepeatWidget( RepeatRegExp* regexp, RegExpEditorWindow* editorWindow, + QWidget* parent, const char* name ) + :SingleContainerWidget( editorWindow, parent, name ) +{ + init(); + RegExpWidget* child = WidgetFactory::createWidget( regexp->child(), editorWindow, this ); + if ( ! (_child = dynamic_cast<ConcWidget*>( child ) ) ) + _child = new ConcWidget( editorWindow, child, this ); + + if ( regexp->max() == -1 ) { + if ( regexp->min() == 0 ) { + _content->set( RepeatRangeWindow::ANY, regexp->min(), regexp->max() ); + } + else { + _content->set( RepeatRangeWindow::ATLEAST, regexp->min(), regexp->max() ); + } + } + else { + if ( regexp->min() == 0 ) { + _content->set( RepeatRangeWindow::ATMOST, regexp->min(), regexp->max() ); + } + else if ( regexp->min() == regexp->max() ) { + _content->set( RepeatRangeWindow::EXACTLY, regexp->min(), regexp->max() ); + } + else { + _content->set( RepeatRangeWindow::MINMAX, regexp->min(), regexp->max() ); + } + } +} + +void RepeatWidget::init() +{ + _configWindow = new KDialogBase( this, "_configWindow", true, + i18n("Number of Times to Repeat Content"), + KDialogBase::Ok | KDialogBase::Cancel); + _content = new RepeatRangeWindow( _configWindow ); + _configWindow->setMainWidget( _content ); + connect( _configWindow, SIGNAL( cancelClicked() ), this, SLOT( slotConfigCanceled() ) ); + connect(_configWindow, SIGNAL(finished()), this, SLOT(slotConfigWindowClosed())); +} + + +QSize RepeatWidget::sizeHint() const +{ + // TODO: Merge with LookAheadWidget::sizeHint + QFontMetrics metrics = fontMetrics(); + _textSize = metrics.size( 0, _content->text() ); + + _childSize = _child->sizeHint(); + + int height = _textSize.height() + bdSize + _childSize.height() + bdSize + 2*pw; + int width = 2 * pw + QMAX(_childSize.width(), 4*bdSize + _textSize.width()); + return QSize(width,height); +} + +void RepeatWidget::paintEvent( QPaintEvent *e ) +{ + // TODO: Merge with LookAheadWidget::paintEvent + QSize mySize = sizeHint(); + QPainter painter(this); + + drawPossibleSelection( painter, mySize ); + + // move the child to its position and resize it. + _child->move(pw,_textSize.height()+bdSize); + QSize curChildSize = _child->size(); + QSize newChildSize = QSize(mySize.width() - 2*pw, _childSize.height()); + if ( curChildSize != newChildSize ) { + _child->resize(newChildSize); + // I resized the child, so give it a chance to relect thus. + _child->update(); + } + + // Draw the border and the text. + int startY = _textSize.height()/2; + + // Top lines and text + painter.drawLine(pw,startY,bdSize,startY); + painter.drawText(pw+2*bdSize,0,_textSize.width(), _textSize.height(),0, + _content->text()); + int offset = pw + 3*bdSize + _textSize.width(); + painter.drawLine(offset,startY,mySize.width()-pw,startY); + + // horizontal lines + painter.drawLine(0,startY,0,mySize.height()-pw); + painter.drawLine(mySize.width()-pw,startY,mySize.width()-pw, mySize.height()-pw); + + // buttom line + painter.drawLine(0, mySize.height()-pw, mySize.width()-pw, mySize.height()-pw); + + SingleContainerWidget::paintEvent(e); +} + +RegExp* RepeatWidget::regExp() const +{ + return new RepeatRegExp( isSelected(), _content->min(), _content->max(), _child->regExp() ); +} + +void RepeatWidget::slotConfigWindowClosed() +{ + _editorWindow->updateContent( 0 ); + update(); +} + +void RepeatWidget::slotConfigCanceled() +{ + QDataStream stream( _backup, IO_ReadOnly ); + KWidgetStreamer streamer; + streamer.fromStream( stream, _content ); + repaint(); +} + +int RepeatWidget::edit() +{ + _configWindow->move(QCursor::pos() - QPoint(_configWindow->sizeHint().width()/2, + _configWindow->sizeHint().height()/2) ); + QDataStream stream( _backup, IO_WriteOnly ); + KWidgetStreamer streamer; + streamer.toStream( _content, stream ); + + return _configWindow->exec(); +} + +//-------------------------------------------------------------------------------- +RepeatRangeWindow::RepeatRangeWindow( QWidget* parent, const char* name ) + : QVBox( parent, name ? name : "RepeatRangeWindow" ) +{ + setSpacing( 6 ); + + _group = new QVButtonGroup( i18n("Times to Match"), this, "groupbox" ); + + // Any number of times + QRadioButton* radioBut = new QRadioButton(i18n("Any number of times (including zero times)"), + _group, + "RepeatRangeWindow::choice any times"); + + _group->insert(radioBut, ANY); + + QWidget* container = new QWidget( _group ); + QHBoxLayout* lay = new QHBoxLayout( container ); + QGrid* grid = new QGrid( 3, container ); + grid->setSpacing( 5 ); + + lay->addWidget( grid ); + lay->addStretch( 1 ); + + createLine( grid, i18n( "At least" ), &_leastTimes, ATLEAST ); + createLine( grid, i18n( "At most" ), &_mostTimes, ATMOST ); + createLine( grid, i18n( "Exactly" ), &_exactlyTimes, EXACTLY ); + + // from ___ to ___ times + radioBut = new QRadioButton(i18n( "From" ), grid, "RepeatRangeWindow::from"); + _group->insert( radioBut, MINMAX ); + + _rangeFrom = new QSpinBox( 1, 999, 1, grid); + + QHBox* box = new QHBox( grid ); + box->setSpacing( 5 ); + + (void) new QLabel(i18n( "to" ), box); + _rangeTo = new QSpinBox( 1, 999, 1, box ); + (void) new QLabel( i18n( "time(s)" ), box ); + + connect( _rangeFrom, SIGNAL( valueChanged( int ) ), this, SLOT( slotUpdateMaxVal( int ) ) ); + connect( _rangeTo, SIGNAL( valueChanged( int ) ), this, SLOT( slotUpdateMinVal( int ) ) ); + + // set a default button. + _group->setButton(ANY); + slotItemChange( ANY ); + + + connect( _group, SIGNAL( clicked( int ) ), this, SLOT( slotItemChange( int ) ) ); +} + + +void RepeatRangeWindow::createLine( QWidget* parent, QString text, QSpinBox** spin, REPEATTYPE tp ) +{ + + QRadioButton* radioBut = new QRadioButton(text, parent); + *spin = new QSpinBox( 1, 999, 1, parent); + (*spin)->setValue(1); + + (void) new QLabel(i18n("time(s)"), parent); + _group->insert(radioBut, tp); +} + +void RepeatRangeWindow::slotItemChange( int which ) +{ + _leastTimes->setEnabled( false ); + _mostTimes->setEnabled( false ); + _exactlyTimes->setEnabled( false ); + _rangeFrom->setEnabled( false ); + _rangeTo->setEnabled( false ); + + switch ( which ) { + case ANY: break; + case ATLEAST: _leastTimes->setEnabled( true ); break; + case ATMOST: _mostTimes->setEnabled( true ); break; + case EXACTLY: _exactlyTimes->setEnabled( true ); break; + case MINMAX: + _rangeFrom->setEnabled( true ); + _rangeTo->setEnabled( true ); + break; + } +} + +void RepeatRangeWindow::slotUpdateMinVal( int maxVal ) +{ + if ( _rangeFrom->value() > maxVal ) { + _rangeFrom->setValue( maxVal ); + } +} + +void RepeatRangeWindow::slotUpdateMaxVal( int minVal ) +{ + if ( _rangeTo->value() < minVal ) { + _rangeTo->setValue( minVal ); + } +} + +QString RepeatRangeWindow::text() +{ + switch ( _group->id(_group->selected()) ) { + case ANY: return i18n("Repeated Any Number of Times"); + case ATLEAST: return i18n("Repeated at Least 1 Time", "Repeated at Least %n Times", _leastTimes->value() ); + case ATMOST: return i18n("Repeated at Most 1 Time", "Repeated at Most %n Times", _mostTimes->value() ); + case EXACTLY: return i18n("Repeated Exactly 1 Time", "Repeated Exactly %n Times", _exactlyTimes->value() ); + case MINMAX: return i18n("Repeated From %1 to %2 Times") + .arg( _rangeFrom->value() ).arg( _rangeTo->value() ); + } + qFatal("Fall through!"); + return QString::fromLocal8Bit(""); +} + +int RepeatRangeWindow::min() +{ + switch ( _group->id(_group->selected()) ) { + case ANY: return 0; + case ATLEAST: return _leastTimes->value(); + case ATMOST: return 0; + case EXACTLY: return _exactlyTimes->value(); + case MINMAX: return _rangeFrom->value(); + } + qFatal("Fall through!"); + return -1; +} + +int RepeatRangeWindow::max() +{ + switch ( _group->id(_group->selected()) ) { + case ANY: return -1; + case ATLEAST: return -1; + case ATMOST: return _mostTimes->value(); + case EXACTLY: return _exactlyTimes->value(); + case MINMAX: return _rangeTo->value(); + } + qFatal("Fall through!"); + return -1; +} + +void RepeatRangeWindow::set( REPEATTYPE tp, int min, int max ) +{ + _group->setButton( tp ); + switch ( tp ) { + case ANY: + break; + case ATLEAST: + _leastTimes->setValue( min ); + break; + case ATMOST: + _mostTimes->setValue( max ); + break; + case EXACTLY: + _exactlyTimes->setValue( min ); + break; + case MINMAX: + _rangeFrom->setValue( min ); + _rangeTo->setValue( max ); + break; + } +} |