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.
448 lines
13 KiB
448 lines
13 KiB
15 years ago
|
/*
|
||
|
* 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 <kdialogbase.h>
|
||
|
#include "characterswidget.moc"
|
||
|
#endif
|
||
|
|
||
|
#include "characterswidget.h"
|
||
|
#include "textrangeregexp.h"
|
||
|
#include "regexp.h"
|
||
|
#include "charselector.h"
|
||
|
#include "myfontmetrics.h"
|
||
|
#include "regexpconverter.h"
|
||
|
|
||
|
#include <qpainter.h>
|
||
|
#include <qgrid.h>
|
||
|
#include <iostream>
|
||
|
#include <qhgroupbox.h>
|
||
|
#include <qcursor.h>
|
||
|
#include <qcheckbox.h>
|
||
|
|
||
|
CharacterEdits* CharactersWidget::_configWindow = 0;
|
||
|
|
||
|
CharactersWidget::CharactersWidget(RegExpEditorWindow* editorWindow, QWidget *parent,
|
||
|
const char *name)
|
||
|
: RegExpWidget(editorWindow, parent, name)
|
||
|
{
|
||
|
_regexp = new TextRangeRegExp( false /* not used */);
|
||
|
}
|
||
|
|
||
|
CharactersWidget::CharactersWidget( TextRangeRegExp* regexp, RegExpEditorWindow* editorWindow,
|
||
|
QWidget* parent, const char* name )
|
||
|
: RegExpWidget( editorWindow, parent, name )
|
||
|
{
|
||
|
_regexp = dynamic_cast<TextRangeRegExp*>( regexp->clone() );
|
||
|
Q_ASSERT( _regexp );
|
||
|
}
|
||
|
|
||
|
CharactersWidget::~CharactersWidget()
|
||
|
{
|
||
|
delete _regexp;
|
||
|
}
|
||
|
|
||
|
|
||
|
QSize CharactersWidget::sizeHint() const
|
||
|
{
|
||
|
QFontMetrics metrics = fontMetrics();
|
||
|
_textSize = HackCalculateFontSize(metrics, title());
|
||
|
// _textSize = metrics.size(0, title());
|
||
|
|
||
|
QSize headerSize = QSize(_textSize.width() + 4 * bdSize,
|
||
|
_textSize.height());
|
||
|
|
||
|
_contentSize = HackCalculateFontSize(metrics,text());
|
||
|
// _contentSize = metrics.size(0, text());
|
||
|
|
||
|
return QSize(QMAX(headerSize.width(), bdSize + _contentSize.width() + bdSize+ 2*pw),
|
||
|
headerSize.height() + bdSize + _contentSize.height() + bdSize + 2*pw);
|
||
|
}
|
||
|
|
||
|
void CharactersWidget::paintEvent(QPaintEvent *e)
|
||
|
{
|
||
|
QSize mySize = sizeHint();
|
||
|
|
||
|
QPainter painter(this);
|
||
|
drawPossibleSelection( painter, mySize );
|
||
|
|
||
|
int center = _textSize.height()/2;
|
||
|
int offset = 0;
|
||
|
|
||
|
// draw the horizontal line and the label
|
||
|
painter.drawLine(pw,center, bdSize,center);
|
||
|
offset += pw + 2*bdSize;
|
||
|
|
||
|
painter.drawText(offset, 0, _textSize.width(), _textSize.height(), 0, title());
|
||
|
offset += _textSize.width() + bdSize;
|
||
|
|
||
|
painter.drawLine(offset, center, mySize.width(), center);
|
||
|
|
||
|
// Draw the rest of the lines
|
||
|
int y = mySize.width() - pw;
|
||
|
int x = mySize.height() -pw;
|
||
|
painter.drawLine(0,center,0,mySize.height());
|
||
|
painter.drawLine(y,center,y,mySize.height());
|
||
|
painter.drawLine(0,x,y,x);
|
||
|
|
||
|
// Draw the text
|
||
|
painter.drawText(bdSize, bdSize+_textSize.height(), _contentSize.width(),
|
||
|
_contentSize.height(), 0, text());
|
||
|
|
||
|
RegExpWidget::paintEvent(e);
|
||
|
}
|
||
|
|
||
|
RegExp* CharactersWidget::regExp() const
|
||
|
{
|
||
|
RegExp* r = _regexp->clone();
|
||
|
r->setSelected( isSelected() );
|
||
|
return r;
|
||
|
}
|
||
|
|
||
|
QString CharactersWidget::text() const
|
||
|
{
|
||
|
QString res = QString::fromLatin1("");
|
||
|
|
||
|
if (_regexp->wordChar())
|
||
|
res += i18n("- A word character\n");
|
||
|
|
||
|
if (_regexp->nonWordChar())
|
||
|
res += i18n("- A non-word character\n");
|
||
|
|
||
|
if (_regexp->digit())
|
||
|
res += i18n("- A digit character\n");
|
||
|
|
||
|
if (_regexp->nonDigit())
|
||
|
res += i18n("- A non-digit character\n");
|
||
|
|
||
|
if ( _regexp->space() )
|
||
|
res += i18n("- A space character\n");
|
||
|
|
||
|
if ( _regexp->nonSpace() )
|
||
|
res += i18n("- A non-space character\n");
|
||
|
|
||
|
// Single characters
|
||
|
QStringList chars = _regexp->chars();
|
||
|
if ( !chars.isEmpty() ) {
|
||
|
QString str = chars.join( QString::fromLocal8Bit(", ") );
|
||
|
res += QString::fromLocal8Bit("- ") + str + QString::fromLocal8Bit("\n");
|
||
|
}
|
||
|
|
||
|
// Ranges characters
|
||
|
QPtrList<StringPair> range = _regexp->range();
|
||
|
for ( QPtrListIterator<StringPair> it( range ); *it; ++it ) {
|
||
|
StringPair* elm = static_cast<StringPair*>(*it);
|
||
|
if (elm) {
|
||
|
QString fromText = elm->first();
|
||
|
QString toText = elm->second();
|
||
|
|
||
|
res += QString::fromLocal8Bit("- ") + i18n("from ") + fromText + i18n(" to ") + toText + QString::fromLocal8Bit("\n");
|
||
|
}
|
||
|
}
|
||
|
return res.left(res.length()-1);
|
||
|
}
|
||
|
|
||
|
|
||
|
QString CharactersWidget::title() const
|
||
|
{
|
||
|
if (_regexp->negate())
|
||
|
return i18n("Any Character Except");
|
||
|
else
|
||
|
return i18n("One of Following Characters");
|
||
|
}
|
||
|
|
||
|
|
||
|
RegExpWidget* CharactersWidget::findWidgetToEdit( QPoint globalPos )
|
||
|
{
|
||
|
if ( QRect(mapToGlobal(QPoint(0,0)), size()).contains( globalPos ) )
|
||
|
return this;
|
||
|
else
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
int CharactersWidget::edit()
|
||
|
{
|
||
|
if ( _configWindow == 0 ) {
|
||
|
QApplication::setOverrideCursor( WaitCursor );
|
||
|
// No parent here, as this window should continue to exists.
|
||
|
_configWindow = new CharacterEdits( 0, "CharactersWidget::_configWindow" );
|
||
|
QApplication::restoreOverrideCursor();
|
||
|
}
|
||
|
|
||
|
_configWindow->move(QCursor::pos() - QPoint(_configWindow->sizeHint().width()/2,
|
||
|
_configWindow->sizeHint().height()/2));
|
||
|
int ret = _configWindow->exec(_regexp );
|
||
|
if ( ret == QDialog::Accepted ) {
|
||
|
_editorWindow->updateContent( 0 );
|
||
|
update();
|
||
|
}
|
||
|
return ret;
|
||
|
}
|
||
|
|
||
|
void CharacterEdits::addCharacter( QString txt )
|
||
|
{
|
||
|
KMultiFormListBoxEntryList list = _single->elements();
|
||
|
for ( QPtrListIterator<KMultiFormListBoxEntry> it(list); *it; ++it ) {
|
||
|
SingleEntry* entry = dynamic_cast<SingleEntry*>( *it );
|
||
|
if ( entry && entry->isEmpty() ) {
|
||
|
entry->setText( txt );
|
||
|
return;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
SingleEntry* entry = new SingleEntry( _single );
|
||
|
entry->setText( txt );
|
||
|
_single->append( entry );
|
||
|
}
|
||
|
|
||
|
void CharacterEdits::addRange( QString from, QString to )
|
||
|
{
|
||
|
KMultiFormListBoxEntryList list = _range->elements();
|
||
|
for ( QPtrListIterator<KMultiFormListBoxEntry> it(list); *it; ++it ) {
|
||
|
RangeEntry* entry = dynamic_cast<RangeEntry*>( *it );
|
||
|
if ( entry && entry->isEmpty() ) {
|
||
|
entry->setFrom( from );
|
||
|
entry->setTo( to );
|
||
|
return;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
RangeEntry* entry = new RangeEntry( _range );
|
||
|
entry->setFrom( from );
|
||
|
entry->setTo( to );
|
||
|
_range->append( entry );
|
||
|
}
|
||
|
|
||
|
int CharacterEdits::exec( TextRangeRegExp* regexp )
|
||
|
{
|
||
|
_regexp = regexp;
|
||
|
negate->setChecked( regexp->negate() );
|
||
|
digit->setChecked( regexp->digit() );
|
||
|
_nonDigit->setChecked( regexp->nonDigit() );
|
||
|
space->setChecked( regexp->space() );
|
||
|
_nonSpace->setChecked( regexp->nonSpace() );
|
||
|
wordChar->setChecked( regexp->wordChar() );
|
||
|
_nonWordChar->setChecked( regexp->nonWordChar() );
|
||
|
|
||
|
bool enabled = (RegExpConverter::current()->features() & RegExpConverter::CharacterRangeNonItems);
|
||
|
_nonWordChar->setEnabled( enabled );
|
||
|
_nonDigit->setEnabled( enabled );
|
||
|
_nonSpace->setEnabled( enabled );
|
||
|
|
||
|
// Characters
|
||
|
|
||
|
KMultiFormListBoxEntryList list1 = _single->elements();
|
||
|
for ( QPtrListIterator<KMultiFormListBoxEntry> it(list1); *it; ++it ) {
|
||
|
SingleEntry* entry = dynamic_cast<SingleEntry*>( *it );
|
||
|
if (entry)
|
||
|
entry->setText( QString::fromLocal8Bit("") );
|
||
|
}
|
||
|
QStringList list2 = regexp->chars();
|
||
|
for ( QStringList::Iterator it2( list2.begin() ); ! (*it2).isNull(); ++it2 ) {
|
||
|
addCharacter( *it2 );
|
||
|
}
|
||
|
|
||
|
// Ranges
|
||
|
KMultiFormListBoxEntryList list3 = _range->elements();
|
||
|
for ( QPtrListIterator<KMultiFormListBoxEntry> it3(list3); *it3; ++it3 ) {
|
||
|
RangeEntry* entry = dynamic_cast<RangeEntry*>( *it3 );
|
||
|
if (entry) {
|
||
|
entry->setFrom( QString::fromLocal8Bit("") );
|
||
|
entry->setTo( QString::fromLocal8Bit("") );
|
||
|
}
|
||
|
}
|
||
|
|
||
|
QPtrList<StringPair> ranges = regexp->range();
|
||
|
for ( QPtrListIterator<StringPair> it4(ranges); *it4; ++it4 ) {
|
||
|
QString from = (*it4)->first();
|
||
|
QString to = (*it4)->second();
|
||
|
addRange(from,to);
|
||
|
}
|
||
|
|
||
|
int res = KDialogBase::exec();
|
||
|
_regexp = 0;
|
||
|
return res;
|
||
|
}
|
||
|
|
||
|
|
||
|
CharacterEdits::CharacterEdits( QWidget *parent, const char *name)
|
||
|
: KDialogBase( parent, name == 0 ? "CharacterEdits" : name, true,
|
||
|
i18n("Specify Characters"),
|
||
|
KDialogBase::Ok | KDialogBase::Cancel)
|
||
|
{
|
||
|
QWidget* top = new QWidget( this );
|
||
|
QVBoxLayout *topLayout = new QVBoxLayout(top, 6);
|
||
|
setMainWidget( top );
|
||
|
|
||
|
negate = new QCheckBox(i18n("Do not match the characters specified here"),
|
||
|
top);
|
||
|
topLayout->addWidget( negate );
|
||
|
|
||
|
|
||
|
// The predefined box
|
||
|
QHGroupBox* predefined = new QHGroupBox(i18n("Predefined Character Ranges"),top);
|
||
|
topLayout->addWidget(predefined);
|
||
|
QGrid* grid = new QGrid(3, predefined );
|
||
|
|
||
|
wordChar = new QCheckBox(i18n("A word character"),grid);
|
||
|
digit = new QCheckBox(i18n("A digit character"),grid);
|
||
|
space = new QCheckBox(i18n("A space character"), grid);
|
||
|
|
||
|
_nonWordChar = new QCheckBox(i18n("A non-word character"),grid);
|
||
|
_nonDigit = new QCheckBox(i18n("A non-digit character"),grid);
|
||
|
_nonSpace = new QCheckBox(i18n("A non-space character"), grid);
|
||
|
|
||
|
// Single characters
|
||
|
QVGroupBox* singleBox = new QVGroupBox(i18n("Single Characters"), top );
|
||
|
topLayout->addWidget( singleBox );
|
||
|
_single = new KMultiFormListBox(new SingleFactory(), KMultiFormListBox::MultiVisible,
|
||
|
singleBox);
|
||
|
_single->addElement(); _single->addElement(); _single->addElement();
|
||
|
|
||
|
QWidget* moreW = new QWidget( singleBox );
|
||
|
QHBoxLayout* moreLay = new QHBoxLayout( moreW );
|
||
|
QPushButton* more = new QPushButton( i18n("More Entries"), moreW );
|
||
|
moreLay->addWidget( more );
|
||
|
moreLay->addStretch( 1 );
|
||
|
|
||
|
connect(more,SIGNAL(clicked()), _single, SLOT(addElement()));
|
||
|
|
||
|
// Ranges
|
||
|
QVGroupBox* rangeBox = new QVGroupBox(i18n("Character Ranges"), top );
|
||
|
topLayout->addWidget( rangeBox );
|
||
|
|
||
|
_range = new KMultiFormListBox(new RangeFactory(), KMultiFormListBox::MultiVisible,
|
||
|
rangeBox);
|
||
|
_range->addElement(); _range->addElement(); _range->addElement();
|
||
|
|
||
|
moreW = new QWidget( rangeBox );
|
||
|
moreLay = new QHBoxLayout( moreW );
|
||
|
more = new QPushButton( i18n("More Entries"), moreW );
|
||
|
moreLay->addWidget( more );
|
||
|
moreLay->addStretch( 1 );
|
||
|
connect(more,SIGNAL(clicked()), _range, SLOT(addElement()));
|
||
|
// Buttons
|
||
|
connect(this, SIGNAL(okClicked()), this, SLOT(slotOK()));
|
||
|
}
|
||
|
|
||
|
void CharacterEdits::slotOK()
|
||
|
{
|
||
|
_regexp->setNegate( negate->isChecked() );
|
||
|
|
||
|
_regexp->setWordChar( wordChar->isChecked() );
|
||
|
_regexp->setNonWordChar( _nonWordChar->isChecked() );
|
||
|
|
||
|
_regexp->setDigit( digit->isChecked() );
|
||
|
_regexp->setNonDigit( _nonDigit->isChecked() );
|
||
|
|
||
|
_regexp->setSpace( space->isChecked() );
|
||
|
_regexp->setNonSpace( _nonSpace->isChecked() );
|
||
|
|
||
|
// single characters
|
||
|
_regexp->clearChars();
|
||
|
KMultiFormListBoxEntryList list = _single->elements();
|
||
|
for ( QPtrListIterator<KMultiFormListBoxEntry> it( list ); *it; ++it ) {
|
||
|
SingleEntry* entry = dynamic_cast<SingleEntry*>(*it);
|
||
|
if ( entry && !entry->isEmpty() ) {
|
||
|
_regexp->addCharacter( entry->text() );
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// Ranges
|
||
|
_regexp->clearRange();
|
||
|
list = _range->elements();
|
||
|
for ( QPtrListIterator<KMultiFormListBoxEntry> it2( list ); *it2; ++it2 ) {
|
||
|
RangeEntry* entry = dynamic_cast<RangeEntry*>(*it2);
|
||
|
if ( entry && !entry->isEmpty() ) {
|
||
|
_regexp->addRange( entry->fromText(), entry->toText() );
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
|
||
|
SingleEntry::SingleEntry(QWidget* parent, const char* name )
|
||
|
:KMultiFormListBoxEntry( parent, name )
|
||
|
{
|
||
|
QHBoxLayout* layout = new QHBoxLayout( this, 3, 6 );
|
||
|
_selector = new CharSelector( this );
|
||
|
layout->addWidget( _selector );
|
||
|
layout->addStretch(1);
|
||
|
}
|
||
|
|
||
|
QString SingleEntry::text() const
|
||
|
{
|
||
|
return _selector->text();
|
||
|
}
|
||
|
|
||
|
void SingleEntry::setText( QString text )
|
||
|
{
|
||
|
_selector->setText( text );
|
||
|
}
|
||
|
|
||
|
bool SingleEntry::isEmpty() const
|
||
|
{
|
||
|
return _selector->isEmpty();
|
||
|
}
|
||
|
|
||
|
|
||
|
RangeEntry::RangeEntry(QWidget* parent, const char* name )
|
||
|
:KMultiFormListBoxEntry( parent, name )
|
||
|
{
|
||
|
QHBoxLayout* layout = new QHBoxLayout( this, 3, 6 );
|
||
|
|
||
|
QLabel* label = new QLabel(i18n("From:"), this );
|
||
|
_from = new CharSelector( this );
|
||
|
layout->addWidget( label );
|
||
|
layout->addWidget( _from );
|
||
|
|
||
|
layout->addStretch(1);
|
||
|
|
||
|
label = new QLabel(i18n("end of range","To:"), this );
|
||
|
_to = new CharSelector( this );
|
||
|
layout->addWidget( label );
|
||
|
layout->addWidget( _to );
|
||
|
}
|
||
|
|
||
|
QString RangeEntry::fromText() const
|
||
|
{
|
||
|
return _from->text();
|
||
|
}
|
||
|
|
||
|
QString RangeEntry::toText() const
|
||
|
{
|
||
|
return _to->text();
|
||
|
}
|
||
|
|
||
|
void RangeEntry::setFrom( QString text )
|
||
|
{
|
||
|
_from->setText( text );
|
||
|
}
|
||
|
|
||
|
void RangeEntry::setTo( QString text )
|
||
|
{
|
||
|
_to->setText( text );
|
||
|
}
|
||
|
|
||
|
bool RangeEntry::isEmpty() const
|
||
|
{
|
||
|
return _from->isEmpty() || _to->isEmpty();
|
||
|
}
|
||
|
|