diff options
author | toma <toma@283d02a7-25f6-0310-bc7c-ecb5cbfe19da> | 2009-11-25 17:56:58 +0000 |
---|---|---|
committer | toma <toma@283d02a7-25f6-0310-bc7c-ecb5cbfe19da> | 2009-11-25 17:56:58 +0000 |
commit | 2bda8f7717adf28da4af0d34fb82f63d2868c31d (patch) | |
tree | 8d927b7b47a90c4adb646482a52613f58acd6f8c /kregexpeditor/editorwindow.cpp | |
download | tdeutils-2bda8f7717adf28da4af0d34fb82f63d2868c31d.tar.gz tdeutils-2bda8f7717adf28da4af0d34fb82f63d2868c31d.zip |
Copy the KDE 3.5 branch to branches/trinity for new KDE 3.5 features.
BUG:215923
git-svn-id: svn://anonsvn.kde.org/home/kde/branches/trinity/kdeutils@1054174 283d02a7-25f6-0310-bc7c-ecb5cbfe19da
Diffstat (limited to 'kregexpeditor/editorwindow.cpp')
-rw-r--r-- | kregexpeditor/editorwindow.cpp | 453 |
1 files changed, 453 insertions, 0 deletions
diff --git a/kregexpeditor/editorwindow.cpp b/kregexpeditor/editorwindow.cpp new file mode 100644 index 0000000..e8c4ac8 --- /dev/null +++ b/kregexpeditor/editorwindow.cpp @@ -0,0 +1,453 @@ +/* + * 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" + #include "images.h" +#else + #include <klocale.h> + #include <kmessagebox.h> +// #include <kfiledialog.h> + #include <kstandarddirs.h> + #include <kiconloader.h> + #include "editorwindow.moc" + #include <klineeditdlg.h> +#endif + +#include "editorwindow.h" +#include "concwidget.h" +#include <qlayout.h> +#include <qpainter.h> +#include <qaccel.h> +#include <qcursor.h> +#include <qclipboard.h> +#include <qpopupmenu.h> +#include "regexp.h" +#include "userdefinedregexps.h" +#include <qfileinfo.h> + +RegExpEditorWindow::RegExpEditorWindow( QWidget *parent, const char *name) + : QWidget(parent, name, Qt::WPaintUnclipped) +{ + _top = new ConcWidget(this, this); + _layout = new QHBoxLayout( this); + _layout->addWidget(_top); + _top->setToplevel(); + _undrawSelection = false; + _menu = 0; + _insertInAction = false; + _pasteInAction = false; + _pasteData = 0; + + QAccel* accel = new QAccel( this ); + accel->connectItem( accel->insertItem( CTRL+Key_C ), this, SLOT( slotCopy() ) ); + accel->connectItem( accel->insertItem( CTRL+Key_X ), this, SLOT( slotCut() ) ); + accel->connectItem( accel->insertItem( Key_Delete ), this, SLOT( slotCut() ) ); + accel->connectItem( accel->insertItem( Key_BackSpace ), this, SLOT( slotCut() ) ); + accel->connectItem( accel->insertItem( CTRL+Key_V ), this, SLOT( slotStartPasteAction() ) ); + accel->connectItem( accel->insertItem( Key_Escape ), this, SLOT( slotEndActions() ) ); + accel->connectItem( accel->insertItem( CTRL+Key_S ), this, SLOT( slotSave() ) ); + + connect( this, SIGNAL( change() ), this, SLOT( emitVerifyRegExp() ) ); +} + +RegExp* RegExpEditorWindow::regExp() const +{ + return _top->regExp(); +} + +void RegExpEditorWindow::mousePressEvent ( QMouseEvent* event ) +{ + setFocus(); + updateContent( 0 ); + + _start = event->pos(); + _lastPoint = QPoint(0,0); + + if ( pointSelected( event->globalPos() ) ) { + _isDndOperation = true; + } + else { + _isDndOperation = false; + _selection = QRect(); + _top->updateSelection( false ); + + QWidget::mousePressEvent( event ); + } + grabMouse(); +} + +bool RegExpEditorWindow::pointSelected( QPoint p ) const +{ + QRect rect = _top->selectionRect(); + return rect.contains(p); +} + +void RegExpEditorWindow::mouseMoveEvent ( QMouseEvent* event ) +{ + if ( _isDndOperation ) { + if ( ( _start - event->pos() ).manhattanLength() > QApplication::startDragDistance() ) { + RegExp* regexp = _top->selection(); + if ( !regexp ) + return; + QDragObject *d = new RegExpWidgetDrag( regexp, this ); + delete regexp; + + bool del = d->drag(); + if ( del ) + slotDeleteSelection(); + else { + clearSelection( true ); + } + releaseMouse(); + emit change(); + emit canSave( _top->hasAnyChildren() ); + } + } + else { + QPainter p( this ); + p.setRasterOp( Qt::NotROP ); + p.setPen( Qt::DotLine ); + + // remove last selection rectangle + if ( ! _lastPoint.isNull() && _undrawSelection ) { + p.drawRect(QRect(_start, _lastPoint)); + } + + // Note this line must come after the old rect has been removed + // and before the new one is draw otherwise the update event which this + // line invokes, will remove a line, which later will be drawn instead of + // removed during NotROP. + _top->updateSelection( false ); + emit scrolling( event->pos() ); + + p.drawRect(QRect(_start, event->pos())); + _undrawSelection = true; + _lastPoint = event->pos(); + + _selection = QRect(mapToGlobal(_start), mapToGlobal(_lastPoint)).normalize(); + } +} + +void RegExpEditorWindow::mouseReleaseEvent( QMouseEvent *event) +{ + releaseMouse(); + QWidget::mouseReleaseEvent( event); + + // remove last selection rectangle + QPainter p( this ); + p.setRasterOp( Qt::NotROP ); + p.setPen( Qt::DotLine ); + if ( ! _lastPoint.isNull() ) { + p.drawRect(QRect(_start, _lastPoint)); + } + _top->validateSelection(); + _top->updateAll(); + emit anythingSelected( hasSelection() ); + if ( hasSelection() ) { + emit verifyRegExp(); + } +} + +bool RegExpEditorWindow::selectionOverlap( QPoint pos, QSize size ) const +{ + QRect child(pos, size); + + return (_selection.intersects(child) && ! child.contains(_selection)); +} + +bool RegExpEditorWindow::hasSelection() const +{ + return _top->hasSelection(); +} + +void RegExpEditorWindow::clearSelection( bool update ) +{ + _top->clearSelection(); + if ( update ) + _top->updateAll(); + emit anythingSelected(false); +} + +void RegExpEditorWindow::slotInsertRegExp( RegExpType type ) +{ + _insertInAction = true; + _insertTp = type; + + updateCursorUnderPoint(); + setFocus(); +} + +void RegExpEditorWindow::slotInsertRegExp( RegExp* regexp ) +{ + if ( _pasteData ) + delete _pasteData; + + _pasteData = regexp->clone(); + _pasteInAction = true; + updateCursorUnderPoint(); + setFocus(); +} + +void RegExpEditorWindow::slotDoSelect() +{ + _pasteInAction = false; + _insertInAction = false; + + // I need to update the cursor recursively, as a repaint may not have been issued yet + // when this method is invoked. This means that when the repaint comes, the cursor may + // move to an other widget. + _top->updateCursorRecursively(); +} + +void RegExpEditorWindow::slotDeleteSelection() +{ + if ( ! hasSelection() ) { + KMessageBox::information(this, i18n( "There is no selection."), i18n("Missing Selection") ); + } + else { + _top->deleteSelection(); + } + updateContent( 0 ); +} + +void RegExpEditorWindow::updateContent( QWidget* focusChild) +{ + QPoint p(0,0); + if ( focusChild ) + p = focusChild->mapTo( this, QPoint(0,0) ); + + _top->update(); + emit contentChanged( p ); +} + +QSize RegExpEditorWindow::sizeHint() const +{ + return _top->sizeHint(); +} + +void RegExpEditorWindow::paintEvent( QPaintEvent* event ) +{ + QWidget::paintEvent( event ); + _undrawSelection = false; +} + +void RegExpEditorWindow::slotCut() +{ + cut( QCursor::pos() ); + emit change(); + emit canSave( _top->hasAnyChildren() ); +} + +void RegExpEditorWindow::cut( QPoint pos ) +{ + cutCopyAux( pos ); + slotDeleteSelection(); +} + +void RegExpEditorWindow::slotCopy() +{ + copy( QCursor::pos() ); +} + +void RegExpEditorWindow::copy( QPoint pos ) +{ + cutCopyAux( pos ); + clearSelection( true ); +} + + +void RegExpEditorWindow::cutCopyAux( QPoint pos ) +{ + if ( !hasSelection() ) { + RegExpWidget* widget = _top->widgetUnderPoint( pos, true ); + if ( !widget ) { + KMessageBox::information(this, i18n("There is no widget under cursor."), i18n("Invalid Operation") ); + return; + } + else { + widget->updateSelection( true ); // HACK! + } + } + + RegExp* regexp = _top->selection(); + RegExpWidgetDrag *clipboardData = new RegExpWidgetDrag( regexp, this ); + delete regexp; + + QClipboard* clipboard = qApp->clipboard(); + clipboard->setData( clipboardData ); + emit anythingOnClipboard( true ); + emit canSave( _top->hasAnyChildren() ); +} + + +void RegExpEditorWindow::slotStartPasteAction() +{ + QByteArray data = qApp->clipboard()->data()->encodedData( "KRegExpEditor/widgetdrag" ); + QTextStream stream( data, IO_ReadOnly ); + QString str = stream.read(); + + RegExp* regexp = WidgetFactory::createRegExp( str ); + if ( regexp ) + slotInsertRegExp( regexp ); +} + +void RegExpEditorWindow::slotEndActions() { + emit doneEditing(); + emit change(); + emit canSave( _top->hasAnyChildren() ); +} + +void RegExpEditorWindow::showRMBMenu( bool enableCutCopy ) +{ + enum CHOICES { CUT, COPY, PASTE, SAVE, EDIT }; + + if ( !_menu ) { + _menu = new QPopupMenu( 0 ); + _menu->insertItem(getIcon(QString::fromLocal8Bit("editcut")), + i18n("C&ut"), CUT); + _menu->insertItem(getIcon(QString::fromLocal8Bit("editcopy")), + i18n("&Copy"), COPY); + _menu->insertItem(getIcon(QString::fromLocal8Bit("editpaste")), + i18n("&Paste"), PASTE); + _menu->insertSeparator(); + _menu->insertItem(getIcon(QString::fromLocal8Bit("edit")), + i18n("&Edit"), EDIT); + _menu->insertItem(getIcon(QString::fromLocal8Bit("filesave")), + i18n("&Save Regular Expression..."), SAVE); + } + + _menu->setItemEnabled( CUT, enableCutCopy ); + _menu->setItemEnabled( COPY, enableCutCopy ); + + if ( ! qApp->clipboard()->data()->provides( "KRegExpEditor/widgetdrag" ) ) + _menu->setItemEnabled( PASTE, false ); + else + _menu->setItemEnabled( PASTE, true ); + + _menu->setItemEnabled( SAVE, _top->hasAnyChildren() ); + + RegExpWidget* editWidget = _top->findWidgetToEdit( QCursor::pos() ); + + _menu->setItemEnabled( EDIT, editWidget ); + + QPoint pos = QCursor::pos(); + int choice = _menu->exec( pos ); + switch ( choice ) { + case COPY: copy( pos ); break; + case CUT: cut( pos ); break; + case PASTE: slotStartPasteAction(); break; + case SAVE: slotSave(); break; + case EDIT: editWidget->edit(); break; + } + emit change(); + emit canSave( _top->hasAnyChildren() ); +} + +void RegExpEditorWindow::applyRegExpToSelection( RegExpType tp ) +{ + _top->applyRegExpToSelection( tp ); +} + +void RegExpEditorWindow::slotSave() +{ + QString dir = WidgetWinItem::path(); + QString txt; + +#ifdef QT_ONLY + txt = QInputDialog::getText( tr("Name for regexp"), tr("Enter name:") ); + if ( txt.isNull() ) + return; +#else + KLineEditDlg dlg(i18n("Enter name:"), QString::null, this); + dlg.setCaption(i18n("Name for Regular Expression")); + if (!dlg.exec()) return; + txt = dlg.text(); +#endif + + QString fileName = dir + QString::fromLocal8Bit("/") + txt + QString::fromLocal8Bit(".regexp"); + QFileInfo finfo( fileName ); + if ( finfo.exists() ) { + int answer = KMessageBox::warningContinueCancel( this, i18n("<p>Overwrite named regular expression <b>%1</b></p>").arg(txt), QString::null, i18n("Overwrite")); + if ( answer != KMessageBox::Continue ) + return; + } + + QFile file( fileName ); + if ( ! file.open(IO_WriteOnly) ) { + KMessageBox::sorry( this, i18n("Could not open file for writing: %1").arg(fileName) ); + return; + } + + // Convert to XML. + RegExp* regexp = _top->regExp(); + QString xml = regexp->toXmlString(); + delete regexp; + + QTextStream stream(&file); + stream << xml; + + file.close(); + emit savedRegexp(); +} + + +void RegExpEditorWindow::slotSetRegExp( RegExp* regexp ) +{ + // I have no clue why the following line is necesarry, but if it is not here + // then the editor area is messed up when calling slotSetRegExp before starting the eventloop. + qApp->processEvents(); + + delete _top; + RegExpWidget* widget = WidgetFactory::createWidget( regexp, this, this ); + if ( ! (_top = dynamic_cast<ConcWidget*>( widget ) ) ) { + // It was not a ConcWidget + _top = new ConcWidget( this, widget, this ); + } + _top->setToplevel(); + + _top->show(); + _layout->addWidget( _top ); + clearSelection( true ); // HACK? + emit canSave( _top->hasAnyChildren() ); +} + +void RegExpEditorWindow::updateCursorUnderPoint() +{ + RegExpWidget* widget = _top->widgetUnderPoint( QCursor::pos(), false ); + if ( widget ) + widget->updateCursorShape(); +} + +void RegExpEditorWindow::emitVerifyRegExp() +{ + emit verifyRegExp(); +} + + +QIconSet RegExpEditorWindow::getIcon( const QString& name ) +{ +#ifdef QT_ONLY + QPixmap pix; + pix.convertFromImage( qembed_findImage( name ) ); + return pix; +#else + return SmallIconSet( name ); +#endif +} + |