You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
tdeutils/kregexpeditor/repeatwidget.cpp

327 lines
9.8 KiB

/*
* 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 TQT_ONLY
#include "compat.h"
#else
#include <tdelocale.h>
#include <kdialogbase.h>
#include "repeatwidget.moc"
#endif
#include "repeatwidget.h"
#include "concwidget.h"
#include "repeatregexp.h"
#include <tqpainter.h>
#include <tqcursor.h>
#include <tqspinbox.h>
#include <tqradiobutton.h>
#include <tqlayout.h>
#include <tqgrid.h>
#include <tqvbuttongroup.h>
#include "kwidgetstreamer.h"
RepeatWidget::RepeatWidget(RegExpEditorWindow* editorWindow, TQWidget *parent,
const char *name)
: SingleContainerWidget(editorWindow, parent, name ? name : "RepeatWidget")
{
_child = new ConcWidget(editorWindow, this);
init();
}
RepeatWidget::RepeatWidget( RepeatRegExp* regexp, RegExpEditorWindow* editorWindow,
TQWidget* 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, TQ_SIGNAL( cancelClicked() ), this, TQ_SLOT( slotConfigCanceled() ) );
connect(_configWindow, TQ_SIGNAL(finished()), this, TQ_SLOT(slotConfigWindowClosed()));
}
TQSize RepeatWidget::sizeHint() const
{
// TODO: Merge with LookAheadWidget::sizeHint
TQFontMetrics 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 + TQMAX(_childSize.width(), 4*bdSize + _textSize.width());
return TQSize(width,height);
}
void RepeatWidget::paintEvent( TQPaintEvent *e )
{
// TODO: Merge with LookAheadWidget::paintEvent
TQSize mySize = sizeHint();
TQPainter painter(this);
drawPossibleSelection( painter, mySize );
// move the child to its position and resize it.
_child->move(pw,_textSize.height()+bdSize);
TQSize curChildSize = _child->size();
TQSize newChildSize = TQSize(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()
{
TQDataStream stream( _backup, IO_ReadOnly );
KWidgetStreamer streamer;
streamer.fromStream( stream, _content );
repaint();
}
int RepeatWidget::edit()
{
_configWindow->move(TQCursor::pos() - TQPoint(_configWindow->sizeHint().width()/2,
_configWindow->sizeHint().height()/2) );
TQDataStream stream( _backup, IO_WriteOnly );
KWidgetStreamer streamer;
streamer.toStream( _content, stream );
return _configWindow->exec();
}
//--------------------------------------------------------------------------------
RepeatRangeWindow::RepeatRangeWindow( TQWidget* parent, const char* name )
: TQVBox( parent, name ? name : "RepeatRangeWindow" )
{
setSpacing( 6 );
_group = new TQVButtonGroup( i18n("Times to Match"), this, "groupbox" );
// Any number of times
TQRadioButton* radioBut = new TQRadioButton(i18n("Any number of times (including zero times)"),
_group,
"RepeatRangeWindow::choice any times");
_group->insert(radioBut, ANY);
TQWidget* container = new TQWidget( _group );
TQHBoxLayout* lay = new TQHBoxLayout( container );
TQGrid* grid = new TQGrid( 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 TQRadioButton(i18n( "From" ), grid, "RepeatRangeWindow::from");
_group->insert( radioBut, MINMAX );
_rangeFrom = new TQSpinBox( 1, 999, 1, grid);
TQHBox* box = new TQHBox( grid );
box->setSpacing( 5 );
(void) new TQLabel(i18n( "to" ), box);
_rangeTo = new TQSpinBox( 1, 999, 1, box );
(void) new TQLabel( i18n( "time(s)" ), box );
connect( _rangeFrom, TQ_SIGNAL( valueChanged( int ) ), this, TQ_SLOT( slotUpdateMaxVal( int ) ) );
connect( _rangeTo, TQ_SIGNAL( valueChanged( int ) ), this, TQ_SLOT( slotUpdateMinVal( int ) ) );
// set a default button.
_group->setButton(ANY);
slotItemChange( ANY );
connect( _group, TQ_SIGNAL( clicked( int ) ), this, TQ_SLOT( slotItemChange( int ) ) );
}
void RepeatRangeWindow::createLine( TQWidget* parent, TQString text, TQSpinBox** spin, REPEATTYPE tp )
{
TQRadioButton* radioBut = new TQRadioButton(text, parent);
*spin = new TQSpinBox( 1, 999, 1, parent);
(*spin)->setValue(1);
(void) new TQLabel(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 );
}
}
TQString 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() );
}
tqFatal("Fall through!");
return TQString::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();
}
tqFatal("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();
}
tqFatal("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;
}
}