diff options
Diffstat (limited to 'karbon/dockers')
-rw-r--r-- | karbon/dockers/Makefile.am | 36 | ||||
-rw-r--r-- | karbon/dockers/vcolordocker.cc | 283 | ||||
-rw-r--r-- | karbon/dockers/vcolordocker.h | 80 | ||||
-rw-r--r-- | karbon/dockers/vdocumentdocker.cc | 1460 | ||||
-rw-r--r-- | karbon/dockers/vdocumentdocker.h | 256 | ||||
-rw-r--r-- | karbon/dockers/vstrokedocker.cc | 211 | ||||
-rw-r--r-- | karbon/dockers/vstrokedocker.h | 63 | ||||
-rw-r--r-- | karbon/dockers/vstyledocker.cc | 303 | ||||
-rw-r--r-- | karbon/dockers/vstyledocker.h | 89 | ||||
-rw-r--r-- | karbon/dockers/vtransformdocker.cc | 265 | ||||
-rw-r--r-- | karbon/dockers/vtransformdocker.h | 60 |
11 files changed, 3106 insertions, 0 deletions
diff --git a/karbon/dockers/Makefile.am b/karbon/dockers/Makefile.am new file mode 100644 index 00000000..9df79e8b --- /dev/null +++ b/karbon/dockers/Makefile.am @@ -0,0 +1,36 @@ +INCLUDES = $(KOFFICE_INCLUDES) $(KOPAINTER_INCLUDES) \ + -I$(srcdir)/.. \ + -I$(srcdir)/../core \ + -I$(srcdir)/../commands \ + -I$(srcdir)/../render \ + -I$(srcdir)/../tools \ + -I$(srcdir)/../widgets \ + -I$(srcdir)/../dialogs \ + $(all_includes) + +noinst_LTLIBRARIES = \ + libkarbondockers.la + +noinst_HEADERS = \ + vcolordocker.h \ + vdocumentdocker.h \ + vstrokedocker.h \ + vstyledocker.h \ + vtransformdocker.h + +libkarbondockers_la_SOURCES = \ + dummy.cc \ + vcolordocker.cc \ + vdocumentdocker.cc \ + vstrokedocker.cc \ + vstyledocker.cc \ + vtransformdocker.cc + +libkarbondockers_la_METASOURCES = AUTO + +DISTCLEANFILES = \ + dummy.cc + +dummy.cc: + echo > dummy.cc + diff --git a/karbon/dockers/vcolordocker.cc b/karbon/dockers/vcolordocker.cc new file mode 100644 index 00000000..c5037967 --- /dev/null +++ b/karbon/dockers/vcolordocker.cc @@ -0,0 +1,283 @@ +/* This file is part of the KDE project + Made by Tomislav Lukman (tomislav.lukman@ck.tel.hr) + Copyright (C) 2002 - 2005, The Karbon Developers + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + 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. +*/ + +#include <qlabel.h> +#include <qlayout.h> +#include <qtabwidget.h> +#include <qwidget.h> +#include <qcolor.h> +#include <qtooltip.h> +#include <qevent.h> +#include <qptrlist.h> + +#include <klocale.h> +#include <KoMainWindow.h> + +#include "karbon_part.h" +#include "karbon_view.h" +#include "karbon_factory.h" +#include "karbon_resourceserver.h" +#include "vcolor.h" +#include "vcolorslider.h" +#include "vselection.h" +#include "vfillcmd.h" +#include "vstrokecmd.h" +#include "vcommand.h" +#include "vobject.h" + +#include "vcolordocker.h" + +#include <ko_hsv_widget.h> +#include <ko_cmyk_widget.h> +#include <ko_rgb_widget.h> +#include <koColor.h> + +#include <kdebug.h> + +VColorDocker::VColorDocker( KarbonPart* part, KarbonView* parent, const char* /*name*/ ) + : QWidget(), m_part ( part ), m_view( parent ) +{ + m_isStrokeDocker = false; + setCaption( i18n( "Color Chooser" ) ); + + m_opacity = 1; + + m_fillCmd = 0; + m_strokeCmd = 0; + + mTabWidget = new QTabWidget( this ); + + /* ##### HSV WIDGET ##### */ + mHSVWidget = new KoHSVWidget( mTabWidget ); + connect( mHSVWidget, SIGNAL( sigFgColorChanged( const QColor &) ), this, SLOT( updateFgColor( const QColor &) ) ); + connect( mHSVWidget, SIGNAL( sigBgColorChanged( const QColor &) ), this, SLOT( updateBgColor( const QColor &) ) ); + connect(this, SIGNAL(fgColorChanged(const QColor &)), mHSVWidget, SLOT(setFgColor(const QColor &))); + connect(this, SIGNAL(bgColorChanged(const QColor &)), mHSVWidget, SLOT(setBgColor(const QColor &))); + connect( mHSVWidget, SIGNAL( sigModeChanged(KDualColorButton::DualColor) ), this, SLOT( updateMode( KDualColorButton::DualColor ) ) ); + mTabWidget->addTab( mHSVWidget, i18n( "HSV" ) ); + + /* ##### RGB WIDGET ##### */ + mRGBWidget = new KoRGBWidget( mTabWidget ); + connect( mRGBWidget, SIGNAL( sigFgColorChanged( const QColor &) ), this, SLOT( updateFgColor( const QColor &) ) ); + connect( mRGBWidget, SIGNAL( sigBgColorChanged( const QColor &) ), this, SLOT( updateBgColor( const QColor &) ) ); + connect(this, SIGNAL(fgColorChanged(const QColor &)), mRGBWidget, SLOT(setFgColor(const QColor &))); + connect(this, SIGNAL(bgColorChanged(const QColor &)), mRGBWidget, SLOT(setBgColor(const QColor &))); + connect( mRGBWidget, SIGNAL( sigModeChanged(KDualColorButton::DualColor) ), this, SLOT( updateMode( KDualColorButton::DualColor ) ) ); + mTabWidget->addTab( mRGBWidget, i18n( "RGB" ) ); + + /* ##### CMYK WIDGET ##### */ + /*mCMYKWidget = new KoCMYKWidget( mTabWidget ); + connect( mCMYKWidget, SIGNAL( sigFgColorChanged( const QColor &) ), this, SLOT( updateFgColor( const QColor &) ) ); + connect( mCMYKWidget, SIGNAL( sigBgColorChanged( const QColor &) ), this, SLOT( updateBgColor( const QColor &) ) ); + mTabWidget->addTab( mCMYKWidget, i18n( "CMYK" ) );*/ + + //Opacity + mOpacity = new VColorSlider( i18n( "Opacity:" ), QColor( "white" ), QColor( "black" ), 0, 100, 100, this ); + //TODO: Make "white" a transparent color + connect( mOpacity, SIGNAL( valueChanged ( int ) ), this, SLOT( updateOpacity() ) ); + QToolTip::add( mOpacity, i18n( "Alpha (opacity)" ) ); + + QVBoxLayout *mainWidgetLayout = new QVBoxLayout( this, 3 ); + mainWidgetLayout->addWidget( mTabWidget ); + mainWidgetLayout->addWidget( mOpacity ); + mainWidgetLayout->activate(); + setMaximumHeight( 174 ); + setMinimumWidth( 194 ); + +} + +VColorDocker::~VColorDocker() +{ +} + +void VColorDocker::updateFgColor(const QColor &c) +{ + m_color = c; + + VColor v = VColor(c); + v.setOpacity( m_opacity ); + + // check if we have objects selected + QPtrList<VObject> VNewObjectList = m_part->document().selection()->objects(); + if( ! VNewObjectList.count() ) + return; + + mHSVWidget->blockSignals(true); + mRGBWidget->blockSignals(true); + //mCMYKWidget->blockSignals(true); + + VCommandHistory* history = m_part->commandHistory(); + const QPtrList<VCommand>* commandList = history->commands(); + VStrokeCmd* command = dynamic_cast<VStrokeCmd*>(commandList->getLast()); + + if(command == 0 || m_strokeCmd == 0) + { + m_strokeCmd = new VStrokeCmd( &m_part->document(), v ); + m_part->addCommand( m_strokeCmd, true ); + } + else + { + QPtrList<VObject> VOldObjectList = command->getSelection()->objects(); + + if( VOldObjectList == VNewObjectList ) + { + m_strokeCmd->changeStroke(v); + m_part->repaintAllViews(); + } + else + { + m_strokeCmd = new VStrokeCmd( &m_part->document(), v ); + m_part->addCommand( m_strokeCmd, true ); + } + } + + emit fgColorChanged( c ); + + mHSVWidget->blockSignals(false); + mRGBWidget->blockSignals(false); + //mCMYKWidget->blockSignals(false); +} + +void VColorDocker::updateBgColor(const QColor &c) +{ + m_color = c; + + VColor v = VColor(c); + v.setOpacity( m_opacity ); + + // check if we have objects selected + QPtrList<VObject> VNewObjectList = m_part->document().selection()->objects(); + if( ! VNewObjectList.count() ) + return; + + mHSVWidget->blockSignals(true); + mRGBWidget->blockSignals(true); + //mCMYKWidget->blockSignals(true); + + VCommandHistory* history = m_part->commandHistory(); + const QPtrList<VCommand>* commandList = history->commands(); + VFillCmd* command = dynamic_cast<VFillCmd*>(commandList->getLast()); + + if(command == 0 || m_fillCmd == 0) + { + m_fillCmd = new VFillCmd( &m_part->document(), VFill(v) ); + m_part->addCommand( m_fillCmd, true ); + } + else + { + QPtrList<VObject> VOldObjectList = command->getSelection()->objects(); + + if( VOldObjectList == VNewObjectList ) + { + m_fillCmd->changeFill(VFill(v)); + m_part->repaintAllViews(); + } + else + { + m_fillCmd = new VFillCmd( &m_part->document(), VFill(v) ); + m_part->addCommand( m_fillCmd, true ); + } + } + + emit bgColorChanged( c ); + + mHSVWidget->blockSignals(false); + mRGBWidget->blockSignals(false); + //mCMYKWidget->blockSignals(false); +} + +void VColorDocker::updateOpacity() +{ + m_opacity = mOpacity->value() / 100.0; + + VColor c = VColor(m_color); + c.setOpacity( m_opacity ); + + if ( isStrokeDocker() ) + m_part->addCommand( new VStrokeCmd( &m_part->document(), c ), true ); + else + m_part->addCommand( new VFillCmd( &m_part->document(), VFill( c ) ), true ); +} + +void +VColorDocker::mouseReleaseEvent( QMouseEvent * ) +{ + //changeColor(); +} + +void VColorDocker::setFillDocker() +{ + m_isStrokeDocker = false; + mHSVWidget->setMode( KDualColorButton::Background ); + mRGBWidget->setMode( KDualColorButton::Background ); + update(); +} + +void VColorDocker::setStrokeDocker() +{ + m_isStrokeDocker = true; + mHSVWidget->setMode( KDualColorButton::Foreground ); + mRGBWidget->setMode( KDualColorButton::Foreground ); + update(); +} + +void VColorDocker::update() +{ + mHSVWidget->blockSignals(true); + mRGBWidget->blockSignals(true); + //mCMYKWidget->blockSignals(true); + + int objCnt = m_part->document().selection()->objects().count(); + + if( objCnt > 0 ) + { + VObject *obj = m_part->document().selection()->objects().getFirst(); + + QColor fgColor = QColor(obj->stroke() ? obj->stroke()->color() : VColor() ); + QColor bgColor = QColor(obj->fill() ? obj->fill()->color() : VColor() ); + + mHSVWidget->setFgColor(fgColor); + mRGBWidget->setFgColor(fgColor); + //mCMYKWidget->setFgColor(fgColor); + + mHSVWidget->setBgColor(bgColor); + mRGBWidget->setBgColor(bgColor); + //mCMYKWidget->setBgColor(bgColor); + + if( m_isStrokeDocker ) + m_color = fgColor; + else + m_color = bgColor; + } + + mHSVWidget->blockSignals(false); + mRGBWidget->blockSignals(false); + //mCMYKWidget->blockSignals(false); +} + +void VColorDocker::updateMode( KDualColorButton::DualColor s ) +{ + m_isStrokeDocker = (s == KDualColorButton::Foreground); + update(); + emit modeChanged( s ); +} + +#include "vcolordocker.moc" + diff --git a/karbon/dockers/vcolordocker.h b/karbon/dockers/vcolordocker.h new file mode 100644 index 00000000..e5e791d7 --- /dev/null +++ b/karbon/dockers/vcolordocker.h @@ -0,0 +1,80 @@ +/* This file is part of the KDE project + Made by Tomislav Lukman (tomislav.lukman@ck.tel.hr) + Copyright (C) 2002 - 2005, The Karbon Developers + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + 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. +*/ + +#ifndef __VCOLORDOCKER_H__ +#define __VCOLORDOCKER_H__ + +class QTabWidget; +class QWidget; +class QColor; +class KarbonView; +class VColor; +class VColorSlider; +class KoHSVWidget; +class KoCMYKWidget; +class KoRGBWidget; + +class VColorDocker : public QWidget +{ + Q_OBJECT + +public: + VColorDocker( KarbonPart* part, KarbonView* parent = 0L, const char* name = 0L ); + virtual ~VColorDocker(); + + virtual bool isStrokeDocker() { return m_isStrokeDocker; }; + VColor color() { return m_color; } + +public slots: + virtual void setFillDocker(); + virtual void setStrokeDocker(); + virtual void update(); + +private: + virtual void mouseReleaseEvent( QMouseEvent *e ); + + QTabWidget *mTabWidget; + KoHSVWidget *mHSVWidget; + //KoCMYKWidget *mCMYKWidget; + KoRGBWidget *mRGBWidget; + VColorSlider *mOpacity; + +signals: + void fgColorChanged( const QColor &c ); + void bgColorChanged( const QColor &c ); + void modeChanged( KDualColorButton::DualColor s); +private slots: + void updateFgColor(const QColor &c); + void updateBgColor(const QColor &c); + void updateOpacity(); + void updateMode( KDualColorButton::DualColor s ); +protected: + bool m_isStrokeDocker; //Are we setting stroke color ( true ) or fill color ( false ) + QColor m_color; + float m_opacity; +private: + KarbonPart *m_part; + KarbonView *m_view; + VFillCmd *m_fillCmd; + VStrokeCmd *m_strokeCmd; +}; + +#endif + diff --git a/karbon/dockers/vdocumentdocker.cc b/karbon/dockers/vdocumentdocker.cc new file mode 100644 index 00000000..ccbbf711 --- /dev/null +++ b/karbon/dockers/vdocumentdocker.cc @@ -0,0 +1,1460 @@ +/* This file is part of the KDE project + Copyright (C) 2001, 2002, 2003 The Karbon Developers + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + 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. +*/ + +#include <qhbuttongroup.h> +#include <qinputdialog.h> +#include <qlayout.h> +#include <qcheckbox.h> +#include <qlistview.h> +#include <qptrvector.h> +#include <qtoolbutton.h> +#include <qpainter.h> +#include <qtabwidget.h> +#include <qlabel.h> +#include <qcursor.h> + +#include <klocale.h> +#include <kglobal.h> +#include <KoMainWindow.h> +#include <kdebug.h> +#include <kiconloader.h> +#include <klineeditdlg.h> +#include <kinputdialog.h> + +#include "karbon_part.h" +#include "karbon_view.h" +#include "karbon_factory.h" +#include "karbon_resourceserver.h" +#include "vdocument.h" +#include "vkopainter.h" +#include "vlayer.h" +#include "vlayercmd.h" +#include "vdeletecmd.h" +#include "vzordercmd.h" +#include "vgroupcmd.h" +#include "vungroupcmd.h" +#include "vselection.h" +#include "vstroke.h" +#include "vcanvas.h" +#include "vdocumentdocker.h" +#include <visitors/vselectiondesc.h> + +static long g_lastKey = 0; + +/************************************************************************* + * Document tab * + *************************************************************************/ + +VDocumentPreview::VDocumentPreview( KarbonView* view, QWidget* parent ) + : QWidget( parent, "DocumentPreview" ), m_document( &view->part()->document() ), m_view( view ) +{ + update(); + installEventFilter( this ); + setBackgroundMode( Qt::NoBackground ); + setMouseTracking( true ); + m_dragging = false; + m_docpixmap = 0L; +} // VDocumentPreview::VDocumentPreview + +VDocumentPreview::~VDocumentPreview() +{ + delete m_docpixmap; +} // VDocumentPreview::~VDocumentPreview + +void +VDocumentPreview::reset() +{ + delete m_docpixmap; + m_docpixmap = 0L; +} + +bool +VDocumentPreview::eventFilter( QObject* object, QEvent* event ) +{ + double scaleFactor; + double xoffset = 0.; + double yoffset = 0.; + if ( ( height() - 4 ) / m_document->height() > ( width() - 4 ) / m_document->width() ) + { + scaleFactor = ( width() - 4 ) / m_document->width(); + yoffset = ( ( height() - 4 ) / scaleFactor - m_document->height() ) / 2; + } + else + { + scaleFactor = ( height() - 4 ) / m_document->height(); + xoffset = ( ( width() - 4 ) / scaleFactor - m_document->width() ) / 2; + } + KoRect rect = m_view->canvasWidget()->boundingBox(); + + QMouseEvent* mouseEvent = static_cast<QMouseEvent*>( event ); + if( event->type() == QEvent::MouseButtonPress ) + { + m_firstPoint.setX( mouseEvent->pos().x() ); + m_firstPoint.setY( mouseEvent->pos().y() ); + m_lastPoint = m_firstPoint; + KoPoint p3( m_firstPoint.x() / scaleFactor - xoffset, + ( height() - m_firstPoint.y() ) / scaleFactor - yoffset ); + m_dragging = rect.contains( p3 ); + } + else if( event->type() == QEvent::MouseButtonRelease ) + { + if( m_dragging ) + { + m_lastPoint.setX( mouseEvent->pos().x() ); + m_lastPoint.setY( mouseEvent->pos().y() ); + double dx = m_lastPoint.x() - m_firstPoint.x(); + double dy = m_lastPoint.y() - m_firstPoint.y(); + scaleFactor /= m_view->zoom(); + m_view->canvasWidget()->scrollBy( int( dx / scaleFactor ), int( dy / scaleFactor ) ); + m_firstPoint = m_lastPoint; + m_dragging = false; + update(); + } + } + else if( event->type() == QEvent::MouseMove ) + { + if( m_dragging ) + { + m_lastPoint.setX( mouseEvent->pos().x() ); + m_lastPoint.setY( mouseEvent->pos().y() ); + update(); + /*double dx = m_lastPoint.x() - m_firstPoint.x(); + double dy = m_lastPoint.y() - m_firstPoint.y(); + scaleFactor /= m_view->zoom(); + m_view->canvasWidget()->scrollBy( int( dx / scaleFactor ), int( dy / scaleFactor ) ); + m_firstPoint = m_lastPoint;*/ + } + else + { + KoPoint p3( mouseEvent->pos().x() / scaleFactor - xoffset, + ( height() - mouseEvent->pos().y() ) / scaleFactor - yoffset ); + setCursor( rect.contains( p3 ) ? QCursor::SizeAllCursor : QCursor( Qt::arrowCursor ) ); + } + } + + return QWidget::eventFilter( object, event ); +} + +void +VDocumentPreview::paintEvent( QPaintEvent* ) +{ + // TODO : use NotROP, otherwise too slow + QPixmap pixmap( width(), height() ); + double xoffset = 0.; + double yoffset = 0.; + double scaleFactor; + if ( ( height() - 4 ) / m_document->height() > ( width() - 4 ) / m_document->width() ) + { + scaleFactor = ( width() - 4 ) / m_document->width(); + yoffset = ( ( height() - 4 ) / scaleFactor - m_document->height() ) / 2; + } + else + { + scaleFactor = ( height() - 4 ) / m_document->height(); + xoffset = ( ( width() - 4 ) / scaleFactor - m_document->width() ) / 2; + } + xoffset += 2 / scaleFactor; + yoffset += 2 / scaleFactor; + if( !m_docpixmap || m_docpixmap->width() != width() || m_docpixmap->height() != height() ) + { + delete m_docpixmap; + m_docpixmap = new QPixmap( width(), height() ); + VKoPainter p( m_docpixmap, width(), height() ); + p.clear( QColor( 195, 194, 193 ) ); + p.setWorldMatrix( QWMatrix( 1, 0, 0, -1, xoffset * scaleFactor, height() - yoffset * scaleFactor ) ); + p.setZoomFactor( scaleFactor ); + KoRect rect( -xoffset, -yoffset, m_document->width() + xoffset, m_document->height() + yoffset ); + // draw doc outline + VColor c( Qt::black ); + VStroke stroke( c, 0L, 1.0 / scaleFactor ); + p.setPen( stroke ); + p.setBrush( Qt::white ); + p.drawRect( KoRect( 2, 2, m_document->width() - 2, m_document->height() - 2 ) ); + m_document->draw( &p, &rect ); + p.end(); + } + bitBlt( &pixmap, 0, 0, m_docpixmap, 0, 0, width(), height() ); + + // draw viewport rect + { + QPainter p( &pixmap ); + p.setWorldMatrix( QWMatrix( scaleFactor, 0, 0, -scaleFactor, xoffset * scaleFactor, height() - yoffset * scaleFactor ) ); + p.setPen( Qt::red ); + double dx = ( m_lastPoint.x() - m_firstPoint.x() ) * m_view->zoom(); + double dy = ( m_lastPoint.y() - m_firstPoint.y() ) * m_view->zoom(); + KoPoint p1( dx / scaleFactor, dy / scaleFactor ); + p1 = m_view->canvasWidget()->toContents( p1 ); + KoPoint p2( dx / scaleFactor + m_view->canvasWidget()->width(), dy / scaleFactor + m_view->canvasWidget()->height() ); + p2 = m_view->canvasWidget()->toContents( p2 ); + p.drawRect( int( p1.x() ), int( p1.y() ), int( p2.x() - p1.x() ), int( p2.y() - p1.y() ) ); + } + + QPainter pw( &pixmap ); + pw.setPen( colorGroup().light() ); + pw.drawLine( 1, 1, 1, height() - 2 ); + pw.drawLine( 1, 1, width() - 2, 1 ); + pw.drawLine( width() - 1, height() - 1, 0, height() - 1 ); + pw.drawLine( width() - 1, height() - 1, width() - 1, 0 ); + pw.setPen( colorGroup().dark() ); + pw.drawLine( 0, 0, width() - 1, 0 ); + pw.drawLine( 0, 0, 0, height() - 1 ); + pw.drawLine( width() - 2, height() - 2, width() - 2, 1 ); + pw.drawLine( width() - 2, height() - 2, 1, height() - 2 ); + pw.end(); + bitBlt( this, 0, 0, &pixmap, 0, 0, width(), height() ); +} // VDocumentPreview::paintEvent + +VDocumentTab::VDocumentTab( KarbonView* view, QWidget* parent ) + : QWidget( parent, "DocumentTab" ), m_view( view ) +{ + QFrame* frame; + QGridLayout* layout = new QGridLayout( this ); + layout->setMargin( 3 ); + layout->setSpacing( 2 ); + layout->addMultiCellWidget( m_documentPreview = new VDocumentPreview( m_view, this ), 0, 7, 2, 2 ); + layout->addWidget( new QLabel( i18n( "document width", "Width:" ), this ), 0, 0 ); + layout->addWidget( new QLabel( i18n( "Height:" ), this ), 1, 0 ); + layout->addMultiCellWidget( frame = new QFrame( this ), 2, 2, 0, 1 ); + frame->setFrameShape( QFrame::HLine ); + layout->addWidget( new QLabel( i18n( "Layers:" ), this ), 3, 0 ); + layout->addWidget( new QLabel( i18n( "Format:" ), this ), 4, 0 ); + layout->addMultiCellWidget( frame = new QFrame( this ), 5, 5, 0, 1 ); + frame->setFrameShape( QFrame::HLine ); + //layout->addMultiCellWidget( new QLabel( i18n( "Zoom factor:" ), this ), 6, 6, 0, 1 ); + layout->addWidget( m_width = new QLabel( this ), 0, 1 ); + layout->addWidget( m_height = new QLabel( this ), 1, 1 ); + layout->addWidget( m_layers = new QLabel( this ), 3, 1 ); + layout->addWidget( m_format = new QLabel( this ), 4, 1 ); + layout->setRowStretch( 7, 1 ); + layout->setColStretch( 0, 0 ); + layout->setColStretch( 1, 0 ); + layout->setColStretch( 2, 2 ); + //layout->addWidget( + + m_width->setAlignment( AlignRight ); + m_height->setAlignment( AlignRight ); + m_layers->setAlignment( AlignRight ); + m_format->setAlignment( AlignRight ); + + connect( view->part()->commandHistory(), SIGNAL( commandAdded( VCommand* ) ), this, SLOT( slotCommandAdded( VCommand* ) ) ); + connect( view->part()->commandHistory(), SIGNAL( commandExecuted() ), this, SLOT( slotCommandExecuted() ) ); + connect( view, SIGNAL( pageLayoutChanged() ), this, SLOT( slotCommandExecuted() ) ); + connect( view->canvasWidget(), SIGNAL( viewportChanged() ), this, SLOT( slotViewportChanged() ) ); + + updateDocumentInfo(); +} // VDocumentTab::VDocumentTab + +VDocumentTab::~VDocumentTab() +{ +} // VDocumentTab::~VDocumentTab + +void +VDocumentTab::updateDocumentInfo() +{ + m_width->setText( KoUnit::toUserStringValue( m_view->part()->document().width(), m_view->part()->unit() ) + m_view->part()->unitName() ); + m_height->setText( KoUnit::toUserStringValue( m_view->part()->document().height(), m_view->part()->unit() ) + m_view->part()->unitName() ); + m_layers->setText( QString::number( m_view->part()->document().layers().count() ) ); +} // VDocumentTab::updateDocumentInfo + +void +VDocumentTab::slotCommandAdded( VCommand * ) +{ + m_documentPreview->reset(); + m_documentPreview->update(); +} + +void +VDocumentTab::slotZoomChanged( double ) +{ + m_documentPreview->update(); +} + +void +VDocumentTab::slotViewportChanged() +{ + m_documentPreview->update(); + updateDocumentInfo(); +} + +void +VDocumentTab::slotCommandExecuted() +{ + m_documentPreview->reset(); + m_documentPreview->update(); +} + +/************************************************************************* + * Layers tab * + *************************************************************************/ + +VObjectListViewItem::VObjectListViewItem( QListViewItem* parent, VObject* object, VDocument *doc, uint key, QPtrDict<VObjectListViewItem> *map ) + : QListViewItem( parent, 0L ), m_object( object ), m_document( doc ), m_key( key ), m_map( map ) +{ + update(); + // add itself to object list item map + m_map->insert( object, this ); +} + +VObjectListViewItem::~VObjectListViewItem() +{ + // remove itself from object list item map + m_map->take( m_object ); +} + +QString +VObjectListViewItem::key( int, bool ) const +{ + return QString( "%1" ).arg( m_key ); +} + +void +VObjectListViewItem::update() +{ + // text description + VSelectionDescription selectionDesc; + selectionDesc.visit( *m_object ); + setText( 0, QString( "%1" ).arg( selectionDesc.shortDescription() ) ); + + // draw thumb preview (16x16) + QPixmap preview; + preview.resize( 16, 16 ); + VKoPainter p( &preview, 16, 16, false ); + // Y mirroring + QWMatrix mat; + mat.scale( 1, -1 ); + KoRect bbox = m_object->boundingBox(); + mat.translate( 0, -16 ); + double factor = 16. / kMax( bbox.width(), bbox.height() ); + mat.translate( -bbox.x() * factor, -bbox.y() * factor ); + p.setWorldMatrix( mat ); + + // TODO: When the document will support page size, change the following line. + p.setZoomFactor( factor ); + m_object->draw( &p ); + p.setZoomFactor( 1 ); + p.setWorldMatrix( QWMatrix() ); + p.setPen( Qt::black ); + p.setBrush( Qt::NoBrush ); + p.drawRect( KoRect( 0, 0, 16, 16 ) ); + p.end(); + + // set thumb preview, lock and visible pixmaps + setPixmap( 0, preview ); + QString s = ( m_object->state() == VObject::normal_locked || m_object->state() == VObject::hidden_locked ) ? "locked" : "unlocked"; + setPixmap( 1, *KarbonFactory::rServer()->cachePixmap( s, KIcon::Small ) ); + s = ( m_object->state() == VObject::hidden || m_object->state() == VObject::hidden_locked ) ? "14_layer_novisible" : "14_layer_visible"; + setPixmap( 2, *KarbonFactory::rServer()->cachePixmap( s, KIcon::Small ) ); +} + +int +VObjectListViewItem::compare( QListViewItem *i, int /*col*/, bool /*ascending*/ ) const +{ + VObjectListViewItem *objectItem = dynamic_cast<VObjectListViewItem*>(i); + if( ! objectItem ) return 0; + return m_key < objectItem->m_key ? -1 : 1; +} + +VLayerListViewItem::VLayerListViewItem( QListView* parent, VLayer* layer, VDocument *doc, QPtrDict<VLayerListViewItem> *map ) + : QCheckListItem( parent, 0L, CheckBox ), m_layer( layer ), m_document( doc), m_map( map ) +{ + update(); + // add itself to layer list item map + m_map->insert( layer, this ); +} // VLayerListViewItem::VLayerListViewItem + +VLayerListViewItem::~VLayerListViewItem() +{ + // remove itself from layer list item map + m_map->take( m_layer ); +} + +void +VLayerListViewItem::update() +{ + // draw thumb preview (16x16) + QPixmap preview; + preview.resize( 16, 16 ); + VKoPainter p( &preview, 16, 16, false ); + // Y mirroring + QWMatrix mat; + mat.scale( 1, -1 ); + mat.translate( 0, -16 ); + p.setWorldMatrix( mat ); + + // TODO: When the document will support page size, change the following line. + p.setZoomFactor( 16. / 800. ); + m_layer->draw( &p ); + p.setZoomFactor( 1 ); + p.setWorldMatrix( QWMatrix() ); + p.setPen( Qt::black ); + p.setBrush( Qt::NoBrush ); + p.drawRect( KoRect( 0, 0, 16, 16 ) ); + p.end(); + + // text description + setOn( m_layer->selected() ); + setText( 0, m_layer->name() ); + + // set thumb preview, lock and visible pixmaps + setPixmap( 0, preview ); + QString s = ( m_layer->state() == VObject::normal_locked || m_layer->state() == VObject::hidden_locked ) ? "locked" : "unlocked"; + setPixmap( 1, *KarbonFactory::rServer()->cachePixmap( s, KIcon::Small ) ); + s = ( m_layer->state() == VObject::normal || m_layer->state() == VObject::normal_locked ) ? "14_layer_visible" : "14_layer_novisible"; + setPixmap( 2, *KarbonFactory::rServer()->cachePixmap( s, KIcon::Small ) ); +} // VLayerListViewItem::update + +void +VLayerListViewItem::stateChange( bool on ) +{ + m_layer->setSelected( on ); +} // VLayerListViewItem::stateChange + +int +VLayerListViewItem::pos() +{ + VLayerListViewItem* item; + if( !( item = (VLayerListViewItem*)itemAbove() ) ) + return 0; + else + return 1 + item->pos(); +} // VLayerListViewItem::pos + +QString +VLayerListViewItem::key( int, bool ) const +{ + return QString( "%1" ).arg( m_key ); +} + +int +VLayerListViewItem::compare( QListViewItem *i, int /*col*/, bool /*ascending*/ ) const +{ + VLayerListViewItem *layerItem = dynamic_cast<VLayerListViewItem*>(i); + if( ! layerItem ) return 0; + return m_key < layerItem->m_key ? -1 : 1; +} + +VLayersTab::VLayersTab( KarbonView* view, QWidget* parent ) + : QWidget( parent, "LayersTab" ), m_view( view ), m_document( &view->part()->document() ) +{ + + QToolButton* button; + QVBoxLayout* layout = new QVBoxLayout( this, 1 ); + layout->addWidget( m_layersListView = new QListView( this ), 1 ); + m_buttonGroup = new QHButtonGroup( this ); + m_buttonGroup->setInsideMargin( 3 ); + button = new QToolButton( m_buttonGroup ); + button->setIconSet( SmallIcon( "14_layer_newlayer" ) ); + button->setTextLabel( i18n( "New" ) ); + m_buttonGroup->insert( button ); + button = new QToolButton( m_buttonGroup ); + button->setIconSet( SmallIcon( "14_layer_raiselayer" ) ); + button->setTextLabel( i18n( "Raise" ) ); + m_buttonGroup->insert( button ); + button = new QToolButton( m_buttonGroup ); + button->setIconSet( SmallIcon( "14_layer_lowerlayer" ) ); + button->setTextLabel( i18n( "Lower" ) ); + m_buttonGroup->insert( button ); + button = new QToolButton( m_buttonGroup ); + button->setIconSet( SmallIcon( "14_layer_deletelayer" ) ); + button->setTextLabel( i18n( "Delete" ) ); + m_buttonGroup->insert( button ); + layout->addWidget( m_buttonGroup, 0); + layout->setSpacing( 0 ); + layout->setMargin( 3 ); + + m_layersListView->setAllColumnsShowFocus( true ); + m_layersListView->addColumn( i18n( "Item" ), 120 ); + m_layersListView->addColumn( i18n( "L" ), 20 ); + m_layersListView->addColumn( i18n( "V" ), 20 ); + m_layersListView->setColumnWidthMode( 0, QListView::Maximum ); + m_layersListView->setColumnAlignment( 1, Qt::AlignCenter ); + m_layersListView->setColumnAlignment( 2, Qt::AlignCenter ); + m_layersListView->setResizeMode( QListView::NoColumn ); + m_layersListView->setSorting( 0, false ); + m_layersListView->setRootIsDecorated( true ); + m_layersListView->setSelectionMode( QListView::Extended ); + + connect( m_layersListView, SIGNAL( clicked( QListViewItem*, const QPoint&, int ) ), this, SLOT( itemClicked( QListViewItem*, const QPoint&, int ) ) ); + connect( m_layersListView, SIGNAL( rightButtonClicked( QListViewItem*, const QPoint&, int ) ), this, SLOT( renameItem( QListViewItem*, const QPoint&, int ) ) ); + connect( m_layersListView, SIGNAL( selectionChanged() ), this, SLOT( selectionChangedFromList() ) ); + connect( m_view, SIGNAL( selectionChange() ), this, SLOT( selectionChangedFromTool() ) ); + connect( m_buttonGroup, SIGNAL( clicked( int ) ), this, SLOT( slotButtonClicked( int ) ) ); + connect( view->part()->commandHistory(), SIGNAL( commandExecuted( VCommand*) ), this, SLOT( slotCommandExecuted( VCommand* ) ) ); + + layout->activate(); + updateLayers(); +} // VLayersTab::VLayersTab + +VLayersTab::~VLayersTab() +{ +} // VLayersTab::~VLayersTab + +void +VLayersTab::slotButtonClicked( int ID ) +{ + switch( ID ) + { + case 0: + addLayer(); break; + case 1: + raiseItem(); break; + case 2: + lowerItem(); break; + case 3: + deleteItem(); break; + } +} // VLayersTab::slotButtonClicked + +void +VLayersTab::resetSelection() +{ + QListViewItemIterator it( m_layersListView ); + + // iterates over all list items and deselects them manually + // to avoid the list views selectionChanged signal + for(; it.current(); ++it ) + { + it.current()->setSelected( false ); + it.current()->repaint(); + } +} + +void +VLayersTab::selectActiveLayer() +{ + if( ! m_layers[ m_document->activeLayer() ] ) + { + QPtrVector<VLayer> vector; + m_document->layers().toVector( &vector ); + // find another layer to set active + for( int i = vector.count() - 1; i >= 0; i-- ) + if ( vector[i]->state() != VObject::deleted ) + { + m_document->setActiveLayer( vector[i] ); + break; + } + } + + // deselect all other layers + QPtrDictIterator<VLayerListViewItem> it( m_layers ); + for(; it.current(); ++it ) + { + it.current()->setSelected( false ); + it.current()->repaint(); + } + + VLayerListViewItem *layerItem = m_layers[ m_document->activeLayer() ]; + if( layerItem ) + { + layerItem->setSelected( true ); + layerItem->repaint(); + kdDebug(38000) << "selecting active layer: " << layerItem->text() << endl; + } +} + +void +VLayersTab::selectionChangedFromTool() +{ + resetSelection(); + removeDeletedObjectsFromList(); + + // TODO : use some kind of mapping... + VObjectListIterator itr = m_document->selection()->objects(); + for( ; itr.current(); ++itr ) + if( itr.current()->state() != VObject::deleted ) + { + VObject *obj = itr.current(); + + VObjectListViewItem *item = m_objects[ obj ]; + if( ! item ) + { + VLayerListViewItem *layerItem = m_layers[ obj->parent() ]; + if( layerItem ) + updateObjects( layerItem->layer(), layerItem ); + else + { + VObjectListViewItem *objectItem = m_objects[ obj->parent() ]; + if( objectItem ) + updateObjects( objectItem->object(), objectItem ); + else + continue; + } + item = m_objects[ obj ]; + } + if( ! item ) continue; + + item->setSelected( true ); + item->update(); + } + selectActiveLayer(); +} + +void +VLayersTab::updateChildItems( QListViewItem *item ) +{ + QListViewItemIterator it( item ); + + // iterator points to item, so make the next item current first + for( ++it; it.current(); ++it ) + { + VObjectListViewItem *objectItem = dynamic_cast<VObjectListViewItem *>( it.current() ); + if( ! objectItem ) continue; + + if( dynamic_cast<VGroup*>( objectItem->object() ) ) + updateChildItems( objectItem ); + + objectItem->update(); + objectItem->repaint(); + } +} + +void +VLayersTab::toggleState( VObject *obj, int col ) +{ + switch( col ) + { + case 1: // toggle visibility + if( obj->state() == VObject::hidden_locked ) + obj->setState( VObject::hidden ); + else if( obj->state() == VObject::normal_locked ) + obj->setState( VObject::selected ); + else if( obj->state() == VObject::normal || obj->state() >= VObject::selected ) + obj->setState( VObject::normal_locked ); + else if( obj->state() == VObject::hidden ) + obj->setState( VObject::hidden_locked ); + break; + case 2: // toggle locking + if( obj->state() == VObject::hidden_locked ) + obj->setState( VObject::normal_locked ); + else if( obj->state() == VObject::normal_locked ) + obj->setState( VObject::hidden_locked ); + else if( obj->state() == VObject::normal || obj->state() >= VObject::selected ) + obj->setState( VObject::hidden ); + else if( obj->state() == VObject::hidden ) + obj->setState( VObject::selected ); + break; + default: return; + } + + if( obj->state() < VObject::selected ) + m_document->selection()->take( *obj ); + else + m_document->selection()->append( obj ); +} + +void +VLayersTab::itemClicked( QListViewItem* item, const QPoint &, int col ) +{ + if( item ) + { + VLayerListViewItem *layerItem = dynamic_cast<VLayerListViewItem *>( item ); + if( layerItem ) + { + if( col == 0 ) + { + m_document->setActiveLayer( layerItem->layer() ); + selectActiveLayer(); + } + if( col > 0 ) + { + toggleState( layerItem->layer(), col ); + + layerItem->update(); + layerItem->repaint(); + + updateChildItems( layerItem ); + + m_view->part()->repaintAllViews(); + } + } + else + { + VObjectListViewItem *objectItem = dynamic_cast< VObjectListViewItem *>( item ); + + if( col == 0 ) + { + VObject *obj = objectItem->object(); + if( obj->state() == VObject::normal ) + obj->setState( VObject::selected ); + } + if( col > 0 ) + { + toggleState( objectItem->object(), col ); + + if( objectItem->object()->state() == VObject::selected ) + objectItem->setSelected( true ); + else + objectItem->setSelected( false ); + + objectItem->update(); + objectItem->repaint(); + + if( dynamic_cast<VGroup*>( objectItem->object() ) ) + updateChildItems( objectItem ); + + m_view->part()->repaintAllViews(); + } + } + } +} // VLayersTab::itemClicked + +void +VLayersTab::selectionChangedFromList() +{ + m_document->selection()->clear(); + + QListViewItemIterator it( m_layersListView ); + + // iterate over all list items and add their corresponding object + // to the documents selection if the list item is selected and not hidden or locked or both + for(; it.current(); ++it ) + { + VObjectListViewItem *objectItem = dynamic_cast<VObjectListViewItem *>( it.current() ); + if( ! objectItem ) continue; + + VObject::VState state = objectItem->object()->state(); + + if( state == VObject::deleted ) + { + delete objectItem; + continue; + } + + if( objectItem->isSelected() && (state != VObject::hidden) && (state != VObject::normal_locked ) + && (state != VObject::hidden_locked) ) + { + m_document->selection()->append( objectItem->object() ); + objectItem->repaint(); + } + } + + m_view->selectionChanged(); + m_view->part()->repaintAllViews(); +} + +void +VLayersTab::renameItem( QListViewItem* item, const QPoint&, int col ) +{ + if ( ( item ) && col == 0 ) + { + bool ok = true; + VLayerListViewItem* layerItem = dynamic_cast<VLayerListViewItem *>( item ); + if( !layerItem ) + { + VObjectListViewItem *objectItem = dynamic_cast< VObjectListViewItem *>( item ); + VObject *obj = objectItem->object(); + QString name = KInputDialog::getText( i18n( "Current Object" ), i18n( "Change the name of the object:" ), + obj->name(), &ok, this ); + if( ok ) + { + m_document->setObjectName( obj, name ); + objectItem->update(); + } + } + else + { + QString name = KInputDialog::getText( i18n( "Rename Layer" ), i18n( "Change the name of the current layer:" ), + layerItem->layer()->name(), &ok, this ); + if( ok ) + { + layerItem->layer()->setName( name ); + layerItem->update(); + } + } + } +} // VLayersTab::renameItem + +void +VLayersTab::addLayer() +{ + bool ok = true; + QString name = KInputDialog::getText( i18n( "New Layer" ), i18n( "Enter the name of the new layer:" ), + i18n( "New layer" ), &ok, this ); + if( ok ) + { + VLayer* layer = new VLayer( m_document ); + layer->setName( name ); + VLayerCmd* cmd = new VLayerCmd( m_document, i18n( "Add Layer" ), + layer, VLayerCmd::addLayer ); + m_view->part()->addCommand( cmd, true ); + updateLayers(); + } +} // VLayersTab::addLayer + +void +VLayersTab::raiseItem() +{ + VCommand *cmd = 0L; + //QListViewItem *newselection = 0L; + QListViewItemIterator it( m_layersListView ); + + if( m_document->selection()->objects().count() ) + { + cmd = new VZOrderCmd( m_document, VZOrderCmd::up ); + m_view->part()->addCommand( cmd, true ); + } + else + { + for(; it.current(); ++it ) + { + if( ! it.current()->isSelected() ) continue; + + VLayerListViewItem* layerItem = dynamic_cast<VLayerListViewItem *>( it.current() ); + if( layerItem ) + { + VLayer *layer = layerItem->layer(); + if( layer && m_document->canRaiseLayer( layer ) ) + { + cmd = new VLayerCmd( m_document, i18n( "Raise Layer" ), + layerItem->layer(), VLayerCmd::raiseLayer ); + m_view->part()->addCommand( cmd, true ); + } + } + } + } + + if( cmd ) updatePreviews(); +} // VLayersTab::raiseItem + +void +VLayersTab::lowerItem() +{ + VCommand *cmd = 0L; + QListViewItemIterator it( m_layersListView ); + + if( m_document->selection()->objects().count() ) + { + cmd = new VZOrderCmd( m_document, VZOrderCmd::down ); + m_view->part()->addCommand( cmd, true ); + } + else + { + for(; it.current(); ++it ) + { + if( ! it.current()->isSelected() ) continue; + + VLayerListViewItem* layerItem = dynamic_cast<VLayerListViewItem *>( it.current() ); + if( layerItem ) + { + VLayer *layer = layerItem->layer(); + if( layer && m_document->canLowerLayer( layer ) ) + { + cmd = new VLayerCmd( m_document, i18n( "Lower Layer" ), layer, VLayerCmd::lowerLayer ); + m_view->part()->addCommand( cmd, true ); + } + } + } + } + + if( cmd ) updatePreviews(); +} // VLayersTab::lowerItem + +void +VLayersTab::deleteItem() +{ + VCommand *cmd = 0L; + QListViewItemIterator it( m_layersListView ); + + QPtrList<QListViewItem> deleteItems; + deleteItems.setAutoDelete( false ); + + // collect all selected items because they get deselected + // when the first item is removed + for(; it.current(); ++it ) + { + if( ! it.current()->isSelected() ) continue; + deleteItems.append( it.current() ); + } + + for( ;deleteItems.first(); ) + { + VLayerListViewItem* layerItem = dynamic_cast< VLayerListViewItem *>( deleteItems.current() ); + if( layerItem ) + { + VLayer *layer = layerItem->layer(); + if( layer && m_layers.count() > 1 ) + { + cmd = new VLayerCmd( m_document, i18n( "Delete Layer" ), layer, VLayerCmd::deleteLayer ); + + VObjectListIterator itr = layer->objects(); + // iterate over this layers child objects and remove them from the internal + // object list and the list of the to be deleted items + for( ; itr.current(); ++itr ) + { + VObjectListViewItem *objectItem = m_objects.take( itr.current() ); + deleteItems.remove( objectItem ); + } + + delete layerItem; + + m_view->part()->addCommand( cmd ); + + selectActiveLayer(); + } + } + else + { + VObjectListViewItem* item = dynamic_cast< VObjectListViewItem *>( deleteItems.current() ); + if( item ) + { + cmd = new VDeleteCmd( m_document, item->object() ); + + delete item; + + m_view->part()->addCommand( cmd ); + } + } + // remove first item, next item becomes current + deleteItems.removeFirst(); + } + if( cmd ) + { + updatePreviews(); + m_view->part()->repaintAllViews(); + } +} // VLayersTab::deleteItem + +void +VLayersTab::updatePreviews() +{ + // TODO: Optimization: call update() on each view item... + updateLayers(); +} // VLayersTab::updatePreviews + +void +VLayersTab::updateLayers() +{ + removeDeletedObjectsFromList(); + + QPtrVector<VLayer> vector; + m_document->layers().toVector( &vector ); + VLayerListViewItem* item = 0L; + for( int i = vector.count() - 1; i >= 0; i-- ) + { + if ( vector[i]->state() != VObject::deleted ) + { + if( !m_layers[ vector[i] ] ) + { + item = new VLayerListViewItem( m_layersListView, vector[i], m_document, &m_layers ); + item->setOpen( true ); + } + else + item = m_layers[ vector[i] ]; + + item->setKey(i); + + updateObjects( vector[i], item ); + } + } + + selectActiveLayer(); + m_layersListView->sort(); +} // VLayersTab::updateLayers + +void +VLayersTab::updateObjects( VObject *object, QListViewItem *item ) +{ + VObjectListIterator itr = dynamic_cast<VGroup *>( object )->objects(); + + for( uint objcount = 1; itr.current(); ++itr, objcount++ ) + if( itr.current()->state() != VObject::deleted ) + { + VObjectListViewItem *objectItem = m_objects[ itr.current() ]; + if( ! objectItem ) + { + // object not found -> insert + objectItem = new VObjectListViewItem( item, itr.current(), m_document, objcount, &m_objects ); + objectItem->update(); + } + else if( objectItem->parent() != item ) + { + // object found, but has false parent -> reparent + objectItem->parent()->takeItem( objectItem ); + item->insertItem( objectItem ); + } + + objectItem->setKey( objcount ); + + if( dynamic_cast<VGroup *>( itr.current() ) ) + updateObjects( itr.current(), objectItem ); + } + + item->sort(); +} + +void +VLayersTab::removeDeletedObjectsFromList() +{ + QPtrDictIterator<VObjectListViewItem> it( m_objects ); + + // iterate over all object items and delete the following items: + // - items representing deleted objects + // - items with objects objects that changed parents + // BEWARE: when deleting an item, the iterator is automatically incremented + for(; it.current(); ) + { + VLayerListViewItem *layerItem = dynamic_cast<VLayerListViewItem*>( it.current()->parent() ); + if( layerItem ) + { + VGroup *group = dynamic_cast<VGroup*>( layerItem->layer() ); + // check if object of item is still child of object of parent item + if( group && ! group->objects().contains( it.current()->object() ) ) + { + layerItem->takeItem( it.current() ); + delete it.current(); + continue; + } + } + else + { + VObjectListViewItem *objectItem = dynamic_cast<VObjectListViewItem*>( it.current()->parent() ); + if( objectItem ) + { + VGroup *group = dynamic_cast<VGroup*>( objectItem->object() ); + // check if object of item is still child of object of parent item + if( group && ! group->objects().contains( it.current()->object() ) ) + { + objectItem->takeItem( it.current() ); + delete it.current(); + continue; + } + } + else + { + delete it.current(); + continue; + } + } + + if( it.current()->object()->state() == VObject::deleted ) + { + delete it.current(); + continue; + } + + ++it; + } + + QPtrDictIterator<VLayerListViewItem> itr( m_layers ); + + // iterate over all layer items and delete the following items: + // - items representing deleted layers + // BEWARE: when deleting an item, the iterator is automatically incremented + for(; itr.current(); ) + { + if( itr.current()->layer()->state() == VObject::deleted ) + { + m_layersListView->takeItem( itr.current() ); + delete itr.current(); + continue; + } + ++itr; + } +} + + +void +VLayersTab::slotCommandExecuted( VCommand* command ) +{ + // sync listview on changing layers or deleting/undeleting or grouping/ungrouping objects + if( dynamic_cast<VLayerCmd*>( command ) + || dynamic_cast<VDeleteCmd*>( command ) + || dynamic_cast<VGroupCmd*>( command ) + || dynamic_cast<VUnGroupCmd*>( command ) + || dynamic_cast<VZOrderCmd*>( command ) ) + updateLayers(); +} + +/************************************************************************* + * History tab * + *************************************************************************/ + +VHistoryGroupItem::VHistoryGroupItem( VHistoryItem* item, QListView* parent, QListViewItem* after ) + : QListViewItem( parent, after ) +{ + setPixmap( 0, *item->pixmap( 0 ) ); + setText( 0, item->text( 0 ) ); + parent->takeItem( item ); + insertItem( item ); + m_key = item->key( 0, true ); +} // VHistoryItem::VHistoryItem + +VHistoryGroupItem::~VHistoryGroupItem() +{ +} // VHistoryGroupItem::~VHistoryGroupItem + +void +VHistoryGroupItem::paintCell( QPainter* p, const QColorGroup& cg, int column, int width, int align ) +{ + int e = 0; + int n = 0; + VHistoryItem* item = (VHistoryItem*)firstChild(); + while ( item ) + { + if ( item->command()->success() ) + e++; + else + n++; + item = (VHistoryItem*)item->nextSibling(); + } + if ( e > 0 ) + { + p->fillRect( 0, 0, width, height(), cg.base() ); + if ( n > 0 ) + p->fillRect( 0, 0, width, height(), QBrush( cg.base().dark( 140 ), QBrush::BDiagPattern ) ); + } + else + p->fillRect( 0, 0, width, height(), cg.base().dark( 140 ) ); + + const QPixmap* pixmap = this->pixmap( column ); + int xstart; + if ( pixmap ) + { + int pw = pixmap->width(); + int ph = pixmap->height(); + p->drawPixmap( ( height() - pw ) / 2, ( height() - ph ) / 2, *pixmap ); + xstart = height(); + } + else + xstart = 4; + p->setPen( cg.text() ); + p->drawText( xstart, 0, width - xstart, height(), align | Qt::AlignVCenter, text( column ) ); +} // VHistoryGroupItem::paintCell + +void +VHistoryGroupItem::paintFocus( QPainter*, const QColorGroup&, const QRect& ) +{ + // Do not paint any focus rectangle + // It makes the list and the selected item look messy + +} // VHistoryGroupItem::paintFocus + +VHistoryItem::VHistoryItem( VCommand* command, QListView* parent, QListViewItem* after ) + : QListViewItem( parent, after ), m_command( command ) +{ + init(); +} // VHistoryItem::VHistoryItem + +VHistoryItem::VHistoryItem( VCommand* command, VHistoryGroupItem* parent, QListViewItem* after ) + : QListViewItem( parent, after ), m_command( command ) +{ + init(); +} // VHistoryItem::VHistoryItem + +void +VHistoryItem::init() +{ + kdDebug(38000) << "In VHistoryItem::init() : " << m_command->name() << endl; + char buffer[70]; + sprintf( buffer, "%064ld", ++g_lastKey ); + m_key = buffer; + setPixmap( 0, QPixmap( KGlobal::iconLoader()->iconPath( m_command->icon(), KIcon::Small ) ) ); + setText( 0, m_command->name() ); +} // VHistoryITem::init + +VHistoryItem::~VHistoryItem() +{ +} // VHistoryItem::~VHistoryItem + +void +VHistoryItem::paintCell( QPainter* p, const QColorGroup& cg, int column, int width, int align ) +{ + p->fillRect( 0, 0, width, height(), ( m_command->success() ? cg.base() : cg.base().dark( 140 ) ) ); + + const QPixmap* pixmap = this->pixmap( column ); + int xstart; + if ( pixmap ) + { + int pw = pixmap->width(); + int ph = pixmap->height(); + p->drawPixmap( ( height() - pw ) / 2, ( height() - ph ) / 2, *pixmap ); + xstart = height(); + } + else + xstart = 4; + p->setPen( cg.text() ); + p->drawText( xstart, 0, width - xstart, height(), align | Qt::AlignVCenter, text( column ) ); +} // VHistoryItem::paintCell + +void +VHistoryItem::paintFocus( QPainter*, const QColorGroup&, const QRect& ) +{ + // Do not paint any focus rectangle + // It makes the list and the selected item look messy + +} // VHistoryItem::paintFocus + +VHistoryTab::VHistoryTab( KarbonPart* part, QWidget* parent ) + : QWidget( parent ), m_part( part ) +{ + QVBoxLayout* layout = new QVBoxLayout( this ); + layout->setMargin( 3 ); + layout->setSpacing( 2 ); + layout->add( m_history = new QListView( this ) ); + m_history->setVScrollBarMode( QListView::AlwaysOn ); + m_history->setSelectionMode( QListView::NoSelection ); + m_history->addColumn( i18n( "Commands" ) ); + m_history->setResizeMode( QListView::AllColumns ); + m_history->setRootIsDecorated( true ); + layout->add( m_groupCommands = new QCheckBox( i18n( "Group commands" ), this ) ); + + m_history->setSorting( 0, true ); + VHistoryGroupItem* group = 0; + VHistoryItem* last = 0; + QPtrVector<VCommand> cmds; + part->commandHistory()->commands()->toVector( &cmds ); + int c = cmds.count(); + for ( int i = 0; i < c; i++ ) + { + if ( ( i > 0 ) && ( cmds[ i ]->name() == cmds[ i - 1 ]->name() ) ) + if ( group ) + { + QListViewItem* prev = group->firstChild(); + while ( prev && prev->nextSibling() ) + prev = prev->nextSibling(); + new VHistoryItem( cmds[ i ], group, prev ); + } + else + { + group = new VHistoryGroupItem( last, m_history, last ); + new VHistoryItem( cmds[ i ], group, last ); + } + else + { + last = new VHistoryItem( cmds[ i ], m_history, last ); + group = 0; + } + } + m_history->sort(); + + connect( m_history, SIGNAL( mouseButtonClicked( int, QListViewItem*, const QPoint&, int ) ), this, SLOT( commandClicked( int, QListViewItem*, const QPoint&, int ) ) ); + connect( m_groupCommands, SIGNAL( stateChanged( int ) ), this, SLOT( groupingChanged( int ) ) ); + connect( part->commandHistory(), SIGNAL( historyCleared() ), this, SLOT( historyCleared() ) ); + connect( part->commandHistory(), SIGNAL( commandAdded( VCommand* ) ), this, SLOT( slotCommandAdded( VCommand* ) ) ); + connect( part->commandHistory(), SIGNAL( commandExecuted( VCommand* ) ), this, SLOT( commandExecuted( VCommand* ) ) ); + connect( part->commandHistory(), SIGNAL( firstCommandRemoved() ), this, SLOT( removeFirstCommand() ) ); + connect( part->commandHistory(), SIGNAL( lastCommandRemoved() ), this, SLOT( removeLastCommand() ) ); + connect( this, SIGNAL( undoCommand( VCommand* ) ), part->commandHistory(), SLOT( undo( VCommand* ) ) ); + connect( this, SIGNAL( redoCommand( VCommand* ) ), part->commandHistory(), SLOT( redo( VCommand* ) ) ); + connect( this, SIGNAL( undoCommandsTo( VCommand* ) ), part->commandHistory(), SLOT( undoAllTo( VCommand* ) ) ); + connect( this, SIGNAL( redoCommandsTo( VCommand* ) ), part->commandHistory(), SLOT( redoAllTo( VCommand* ) ) ); +} // VHistoryTab::VHistoryTab + +VHistoryTab::~VHistoryTab() +{ +} // VHistoryTab::~VHistoryTab + +bool +VHistoryTab::groupingEnabled() +{ + return m_groupCommands->isChecked(); +} // VHistoryTab::groupingEnabled + +void +VHistoryTab::historyCleared() +{ + m_history->clear(); +} // VHistoryTab::historyCleared + +void +VHistoryTab::commandExecuted( VCommand* command ) +{ + QListViewItem* item = m_history->firstChild(); + bool found = false; + while ( !found && item ) + { + if ( item->rtti() == 1001 ) + { + QListViewItem* child = item->firstChild(); + while ( !found && child ) + { + found = ( ( (VHistoryItem*)child )->command() == command ); + if ( !found ) + child = child->nextSibling(); + else + item = child; + } + } + found = ( item && ( (VHistoryItem*)item )->command() == command ); + if ( !found ) + item = item->nextSibling(); + } + if ( found ) + { + m_history->repaintItem( item ); + if ( item->parent() ) + m_history->repaintItem( item->parent() ); + m_history->ensureItemVisible( item ); + } +} // VHistoryTab::commandExecuted + +void +VHistoryTab::slotCommandAdded( VCommand* command ) +{ + if ( !command ) + return; + + QListViewItem* last = m_history->firstChild(); + while ( last && last->nextSibling() ) + last = last->nextSibling(); + + if( groupingEnabled() ) + { + if( ( last ) && last->text( 0 ) == command->name() ) + { + if( last->rtti() == 1002 ) + { + QListViewItem* prevSibling; + if( m_history->childCount() > 1 ) + { + prevSibling = m_history->firstChild(); + while ( prevSibling->nextSibling() != last ) + prevSibling = prevSibling->nextSibling(); + } + else + prevSibling = m_history->firstChild(); + last = new VHistoryGroupItem( (VHistoryItem*)last, m_history, prevSibling ); + } + QListViewItem* prev = last->firstChild(); + while ( prev && prev->nextSibling() ) + prev = prev->nextSibling(); + m_history->setCurrentItem( new VHistoryItem( command, (VHistoryGroupItem*)last, prev ) ); + } + else + m_history->setCurrentItem( new VHistoryItem( command, m_history, last ) ); + } + else + m_history->setCurrentItem( new VHistoryItem( command, m_history, last ) ); + + m_history->sort(); + m_history->ensureItemVisible( m_history->currentItem() ); + m_history->update(); +} // VHistoryTab::slotCommandAdded + +void +VHistoryTab::removeFirstCommand() +{ + if ( m_history->childCount() > 0 ) + if ( m_history->firstChild()->rtti() == 1002 ) + delete m_history->firstChild(); + else + { + VHistoryGroupItem* group = (VHistoryGroupItem*)m_history->firstChild(); + delete group->firstChild(); + if ( group->childCount() == 1 ) + { + new VHistoryItem( ( (VHistoryItem*)group->firstChild() )->command(), m_history, 0 ); + delete group; + } + } +} // VHistoryTab::removeFirstCommand + +void +VHistoryTab::removeLastCommand() +{ + if ( m_history->childCount() > 0 ) + { + QListViewItem* last = m_history->firstChild(); + while ( last && last->nextSibling() ) + last = last->nextSibling(); + if ( last->rtti() == 1002 ) + delete last; + else + { + VHistoryGroupItem* group = (VHistoryGroupItem*)last; + last = group->firstChild(); + while ( last && last->nextSibling() ) + last = last->nextSibling(); + delete last; + if ( group->childCount() == 1 ) + { + new VHistoryItem( ( (VHistoryItem*)group->firstChild() )->command(), m_history, group ); + delete group; + } + } + } +} // VHistoryTab::removeLastCommand + +void +VHistoryTab::commandClicked( int button, QListViewItem* item, const QPoint&, int ) +{ + if ( !item || item->rtti() == 1001 ) + return; + + VCommand* cmd = ( (VHistoryItem*)item )->command(); + if ( cmd->success() ) + if ( button == 1 ) + emit undoCommandsTo( ( (VHistoryItem*)item )->command() ); + else + emit undoCommand( ( (VHistoryItem*)item )->command() ); + else + if ( button == 1 ) + emit redoCommandsTo( ( (VHistoryItem*)item )->command() ); + else + emit redoCommand( ( (VHistoryItem*)item )->command() ); +} // VHistoryTab::commandClicked + +void +VHistoryTab::groupingChanged( int ) +{ + if ( m_groupCommands->isChecked() && m_history->childCount() > 1 ) + { + QListViewItem* s2last = 0; + QListViewItem* last = m_history->firstChild(); + QListViewItem* item = last->nextSibling(); + while ( item ) + if ( last->text( 0 ) == item->text( 0 ) ) + { + if ( last->rtti() == 1002 ) + last = new VHistoryGroupItem( (VHistoryItem*)last, m_history, s2last ); + m_history->takeItem( item ); + last->insertItem( item ); + item = last->nextSibling(); + } + else + { + s2last = last; + last = item; + item = last->nextSibling(); + } + } + else + { + QListViewItem* item = m_history->firstChild(); + while ( item ) + if ( item->rtti() == 1001 ) + { + QListViewItem* child; + while ( ( child = item->firstChild() ) ) + { + item->takeItem( child ); + m_history->insertItem( child ); + } + child = item; + item = item->nextSibling(); + delete child; + } + else + item = item->nextSibling(); + } + m_history->sort(); + m_history->update(); +} // VHistoryTab::groupingChanged + +#include "vdocumentdocker.moc" diff --git a/karbon/dockers/vdocumentdocker.h b/karbon/dockers/vdocumentdocker.h new file mode 100644 index 00000000..278f56ba --- /dev/null +++ b/karbon/dockers/vdocumentdocker.h @@ -0,0 +1,256 @@ +/* This file is part of the KDE project + Copyright (C) 2001, 2002, 2003 The Karbon Developers + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + 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. +*/ + +#ifndef __VDOCUMENTDOCKER_H__ +#define __VDOCUMENTDOCKER_H__ + +#include <qlistview.h> +#include <qptrdict.h> + +class QHButtonGroup; +class QPoint; +class QLabel; +class QPixmap; +class QCheckBox; + +class VDocument; +class VLayer; +class KarbonView; + +/************************************************************************* + * Document Tab * + *************************************************************************/ + +class VDocumentPreview : public QWidget +{ + Q_OBJECT + + public: + VDocumentPreview( KarbonView* view, QWidget* parent = 0 ); + ~VDocumentPreview(); + + void reset(); + + protected: + void paintEvent( QPaintEvent* e ); + virtual bool eventFilter( QObject* object, QEvent* event ); + + private: + VDocument *m_document; + KarbonView *m_view; + KoPoint m_firstPoint; + KoPoint m_lastPoint; + bool m_dragging; + QPixmap *m_docpixmap; +}; // VDocumentPreview + +class VDocumentTab : public QWidget +{ + Q_OBJECT + + public: + VDocumentTab( KarbonView* view, QWidget* parent ); + ~VDocumentTab(); + + public slots: + void updateDocumentInfo(); + void slotCommandAdded( VCommand* command ); + void slotZoomChanged( double ); + void slotViewportChanged(); + void slotCommandExecuted(); + + private: + VDocumentPreview* m_documentPreview; + QLabel* m_height; + QLabel* m_width; + QLabel* m_layers; + QLabel* m_format; + + KarbonView* m_view; +}; // VDocumentTab + +/************************************************************************* + * Layers Tab * + *************************************************************************/ + +class VLayerListViewItem : public QCheckListItem +{ +public: + VLayerListViewItem( QListView* parent, VLayer* layer, VDocument *doc, QPtrDict<VLayerListViewItem> *map ); + virtual ~VLayerListViewItem(); + + VLayer* layer() { return m_layer; } + int pos(); + void update(); + virtual QString key( int column, bool ascending ) const; + virtual int compare( QListViewItem *i, int col, bool ascending ) const; + void setKey( uint key ) { m_key = key; } + +protected: + virtual void stateChange( bool on ); + +private: + VLayer *m_layer; + VDocument *m_document; + uint m_key; + QPtrDict<VLayerListViewItem> *m_map; +}; // VLayerListViewItem + +class VObjectListViewItem : public QListViewItem +{ +public: + VObjectListViewItem( QListViewItem* parent, VObject* object, VDocument *doc, uint key, QPtrDict<VObjectListViewItem> *map ); + virtual ~VObjectListViewItem(); + + VObject* object() { return m_object; } + void update(); + virtual QString key( int column, bool ascending ) const; + virtual int compare( QListViewItem *i, int col, bool ascending ) const; + void setKey( uint key ) { m_key = key; } +private: + VObject *m_object; + VDocument *m_document; + uint m_key; + QPtrDict<VObjectListViewItem> *m_map; +}; + +class VLayersTab : public QWidget +{ +Q_OBJECT + +public: + VLayersTab( KarbonView* view, QWidget* parent = 0 ); + ~VLayersTab(); + +public slots: + void updatePreviews(); + void updateLayers(); + + void itemClicked( QListViewItem* item, const QPoint&, int col ); + void selectionChangedFromList(); + void selectionChangedFromTool(); + void renameItem( QListViewItem* item, const QPoint&, int col ); + void addLayer(); + void raiseItem(); + void lowerItem(); + void deleteItem(); + void slotCommandExecuted( VCommand* command ); + +private slots: + void slotButtonClicked( int ID ); + void removeDeletedObjectsFromList(); + void updateChildItems( QListViewItem *item ); + void toggleState( VObject *obj, int col ); + +protected: + VLayerListViewItem* listItem( int pos ); + void updateObjects( VObject *object, QListViewItem *item ); + void resetSelection(); + void selectActiveLayer(); + +private: + QListView *m_layersListView; + QHButtonGroup *m_buttonGroup; + KarbonView *m_view; + VDocument *m_document; + QPtrDict<VLayerListViewItem> m_layers; + QPtrDict<VObjectListViewItem> m_objects; +}; // VLayersTab + +/************************************************************************* + * History Tab * + *************************************************************************/ + +class VHistoryItem; + +class VHistoryGroupItem : public QListViewItem +{ + public: + VHistoryGroupItem( VHistoryItem* item, QListView* parent, QListViewItem* after ); + ~VHistoryGroupItem(); + + void paintCell( QPainter* p, const QColorGroup& cg, int column, int width, int align ); + void paintFocus( QPainter*, const QColorGroup&, const QRect& ); + + virtual QString key( int, bool ) const { return m_key; } + virtual int rtti() const { return 1001; } + + private: + QString m_key; +}; // VHistoryGroupItem + +class VHistoryItem : public QListViewItem +{ + public: + VHistoryItem( VCommand* command, QListView* parent, QListViewItem* after ); + VHistoryItem( VCommand* command, VHistoryGroupItem* parent, QListViewItem* after ); + ~VHistoryItem(); + + VCommand* command() { return m_command; } + + void paintCell( QPainter* p, const QColorGroup& cg, int column, int width, int align ); + void paintFocus( QPainter*, const QColorGroup&, const QRect& ); + + virtual QString key( int, bool ) const { return m_key; } + virtual int rtti() const { return 1002; } + + private: + void init(); + + QString m_key; + VCommand* m_command; +}; // VHistoryItem + +class VHistoryTab : public QWidget +{ + Q_OBJECT + + public: + VHistoryTab( KarbonPart* part, QWidget* parent ); + ~VHistoryTab(); + + bool groupingEnabled(); + + public slots: + void historyCleared(); + void commandExecuted( VCommand* command ); + void slotCommandAdded( VCommand* command ); + void removeFirstCommand(); + void removeLastCommand(); + + void commandClicked( int button, QListViewItem* item, const QPoint& point, int col ); + void groupingChanged( int ); + + signals: + void undoCommand( VCommand* command ); + void redoCommand( VCommand* command ); + void undoCommandsTo( VCommand* command ); + void redoCommandsTo( VCommand* command ); + + private: + QListView* m_history; + QListViewItem* m_lastCommand; + QCheckBox* m_groupCommands; + long m_lastCommandIndex; + + KarbonPart* m_part; +}; // VHistoryTab + +#endif + diff --git a/karbon/dockers/vstrokedocker.cc b/karbon/dockers/vstrokedocker.cc new file mode 100644 index 00000000..200c9dc9 --- /dev/null +++ b/karbon/dockers/vstrokedocker.cc @@ -0,0 +1,211 @@ +/* This file is part of the KDE project + Made by Tomislav Lukman (tomislav.lukman@ck.tel.hr) + Copyright (C) 2002, The Karbon Developers + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + 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. +*/ + +#include <qhbuttongroup.h> +#include <qlabel.h> +#include <qlayout.h> +#include <qpushbutton.h> +#include <qwidget.h> +#include <qtooltip.h> + +#include <kiconloader.h> +#include <klocale.h> +#include <KoMainWindow.h> + +#include "KoUnitWidgets.h" + +#include "karbon_part.h" +#include "karbon_view.h" +#include "vstroke.h" +#include "vselection.h" +#include "vstrokecmd.h" + +#include "vstrokedocker.h" + +VStrokeDocker::VStrokeDocker( KarbonPart* part, KarbonView* parent, const char* /*name*/ ) + : QWidget(), m_part ( part ), m_view( parent ) +{ + setCaption( i18n( "Stroke Properties" ) ); + + QPushButton *button; + + QGridLayout *mainLayout = new QGridLayout( this, 4, 2 ); + + QLabel* widthLabel = new QLabel( i18n ( "stroke width", "Width:" ), this ); + mainLayout->addWidget( widthLabel, 0, 0 ); + // set min/max/step and value in points, then set actual unit + m_setLineWidth = new KoUnitDoubleSpinBox( this, 0.0, 1000.0, 0.5, 1.0, KoUnit::U_PT, 2 ); + m_setLineWidth->setUnit( part->unit() ); + QToolTip::add( m_setLineWidth, i18n( "Set line width of actual selection" ) ); + mainLayout->addWidget ( m_setLineWidth, 0, 1 ); + connect( m_setLineWidth, SIGNAL( valueChanged( double ) ), this, SLOT( widthChanged() ) ); + + QLabel* capLabel = new QLabel( i18n ( "Cap:" ), this ); + mainLayout->addWidget( capLabel, 1, 0 ); + m_capGroup = new QHButtonGroup( this ); + m_capGroup->setFrameShape( QFrame::NoFrame ); + m_capGroup->setInsideMargin( 1 ); + m_capGroup->setExclusive( true ); + button = new QPushButton( "", m_capGroup ); + button->setPixmap( SmallIcon( "cap_butt" ) ); + button->setToggleButton( true ); + QToolTip::add( button, i18n( "Butt cap" ) ); + m_capGroup->insert( button ); + button = new QPushButton( "", m_capGroup ); + button->setPixmap( SmallIcon( "cap_round" ) ); + button->setToggleButton( true ); + QToolTip::add( button, i18n( "Round cap" ) ); + m_capGroup->insert( button ); + button = new QPushButton( "", m_capGroup ); + button->setPixmap( SmallIcon( "cap_square" ) ); + button->setToggleButton( true ); + QToolTip::add( button, i18n( "Square cap" ) ); + m_capGroup->insert( button ); + mainLayout->addWidget( m_capGroup, 1, 1 ); + connect( m_capGroup, SIGNAL( clicked( int ) ), this, SLOT( slotCapChanged( int ) ) ); + + QLabel* joinLabel = new QLabel( i18n ( "Join:" ), this ); + mainLayout->addWidget( joinLabel, 2, 0 ); + + m_joinGroup = new QHButtonGroup( this ); + m_joinGroup->setFrameShape( QFrame::NoFrame ); + m_joinGroup->setInsideMargin( 1 ); + m_joinGroup->setExclusive( true ); + button = new QPushButton( "", m_joinGroup ); + button->setPixmap( SmallIcon( "join_miter" ) ); + button->setToggleButton( true ); + QToolTip::add( button, i18n( "Miter join" ) ); + m_joinGroup->insert( button ); + button = new QPushButton( "", m_joinGroup ); + button->setPixmap( SmallIcon( "join_round" ) ); + button->setToggleButton( true ); + QToolTip::add( button, i18n( "Round join" ) ); + m_joinGroup->insert( button ); + button = new QPushButton( "", m_joinGroup ); + button->setPixmap( SmallIcon( "join_bevel" ) ); + button->setToggleButton( true ); + QToolTip::add( button, i18n( "Bevel join" ) ); + m_joinGroup->insert( button ); + mainLayout->addWidget( m_joinGroup, 2, 1 ); + connect( m_joinGroup, SIGNAL( clicked( int ) ), this, SLOT( slotJoinChanged( int ) ) ); + + mainLayout->setRowStretch( 3, 1 ); + mainLayout->setColStretch( 1, 1 ); + mainLayout->activate(); + + updateDocker(); +} + +void VStrokeDocker::updateCanvas() +{ + if( m_part && m_part->document().selection()->objects().count() > 0 ) + m_part->addCommand( new VStrokeCmd( &m_part->document(), &m_stroke ), true ); +} + +void VStrokeDocker::slotCapChanged( int ID ) +{ + switch( ID ) + { + case 1: + m_stroke.setLineCap( VStroke::capRound ); break; + case 2: + m_stroke.setLineCap( VStroke::capSquare ); break; + default: + m_stroke.setLineCap( VStroke::capButt ); + } + updateCanvas(); +} + +void VStrokeDocker::slotJoinChanged( int ID ) +{ + switch( ID ) + { + case 1: + m_stroke.setLineJoin( VStroke::joinRound ); break; + case 2: + m_stroke.setLineJoin( VStroke::joinBevel ); break; + default: + m_stroke.setLineJoin( VStroke::joinMiter ); + } + updateCanvas(); +} + +void VStrokeDocker::updateDocker() +{ + disconnect( m_setLineWidth, SIGNAL( valueChanged( double ) ), this, SLOT( widthChanged() ) ); + disconnect( m_capGroup, SIGNAL( clicked( int ) ), this, SLOT( slotCapChanged( int ) ) ); + disconnect( m_joinGroup, SIGNAL( clicked( int ) ), this, SLOT( slotJoinChanged( int ) ) ); + + switch( m_stroke.lineCap() ) + { + case VStroke::capRound: + m_capGroup->setButton( 1 ); break; + case VStroke::capSquare: + m_capGroup->setButton( 2 ); break; + default: + m_capGroup->setButton( 0 ); + } + + switch( m_stroke.lineJoin() ) + { + case VStroke::joinRound: + m_joinGroup->setButton( 1 ); break; + case VStroke::joinBevel: + m_joinGroup->setButton( 2 ); break; + default: + m_joinGroup->setButton( 0 ); + } + + m_setLineWidth->changeValue( m_stroke.lineWidth() ); + + connect( m_setLineWidth, SIGNAL( valueChanged( double ) ), this, SLOT( widthChanged() ) ); + connect( m_capGroup, SIGNAL( clicked( int ) ), this, SLOT( slotCapChanged( int ) ) ); + connect( m_joinGroup, SIGNAL( clicked( int ) ), this, SLOT( slotJoinChanged( int ) ) ); +} + +void VStrokeDocker::widthChanged() +{ + m_stroke.setLineWidth( m_setLineWidth->value() ); + updateCanvas(); +} + +void VStrokeDocker::setStroke( const VStroke &stroke ) +{ + if( &stroke ) + m_stroke = stroke; + else + m_stroke = VStroke(); + updateDocker(); +} + +void VStrokeDocker::setUnit( KoUnit::Unit unit ) +{ + disconnect( m_setLineWidth, SIGNAL( valueChanged( double ) ), this, SLOT( widthChanged() ) ); + disconnect( m_capGroup, SIGNAL( clicked( int ) ), this, SLOT( slotCapChanged( int ) ) ); + disconnect( m_joinGroup, SIGNAL( clicked( int ) ), this, SLOT( slotJoinChanged( int ) ) ); + + m_setLineWidth->setUnit( unit ); + + connect( m_setLineWidth, SIGNAL( valueChanged( double ) ), this, SLOT( widthChanged() ) ); + connect( m_capGroup, SIGNAL( clicked( int ) ), this, SLOT( slotCapChanged( int ) ) ); + connect( m_joinGroup, SIGNAL( clicked( int ) ), this, SLOT( slotJoinChanged( int ) ) ); +} +#include "vstrokedocker.moc" + diff --git a/karbon/dockers/vstrokedocker.h b/karbon/dockers/vstrokedocker.h new file mode 100644 index 00000000..77d536b9 --- /dev/null +++ b/karbon/dockers/vstrokedocker.h @@ -0,0 +1,63 @@ +/* This file is part of the KDE project + Made by Tomislav Lukman (tomislav.lukman@ck.tel.hr) + Copyright (C) 2002, The Karbon Developers + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + 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. +*/ + +#ifndef __VSTROKEDOCKER_H__ +#define __VSTROKEDOCKER_H__ + +class QHButtonGroup; +class QWidget; + +class KoUnitDoubleSpinBox; + +class KoMainWindow; +class KarbonView; +class KarbonPart; + +class VStrokeDocker : public QWidget +{ + Q_OBJECT + +public: + VStrokeDocker( KarbonPart* part, KarbonView* parent = 0L, const char* name = 0L ); + +public slots: + virtual void setStroke( const VStroke & ); + virtual void setUnit( KoUnit::Unit unit ); + +private: + QHButtonGroup *m_capGroup; + QHButtonGroup *m_joinGroup; + KarbonPart *m_part; + KarbonView *m_view; + KoUnitDoubleSpinBox *m_setLineWidth; + +private slots: + void slotCapChanged( int ID ); + void slotJoinChanged( int ID ); + void updateCanvas(); + void updateDocker(); + void widthChanged(); + +protected: + VStroke m_stroke; +}; + +#endif + diff --git a/karbon/dockers/vstyledocker.cc b/karbon/dockers/vstyledocker.cc new file mode 100644 index 00000000..9a7ce083 --- /dev/null +++ b/karbon/dockers/vstyledocker.cc @@ -0,0 +1,303 @@ +/* This file is part of the KDE project + Made by Tomislav Lukman (tomislav.lukman@ck.tel.hr) + Copyright (C) 2002, 2003 The Karbon Developers + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + 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. +*/ + +#include <qlabel.h> +#include <qlayout.h> +#include <qtabwidget.h> +#include <qsize.h> +#include <qhbuttongroup.h> +#include <qtoolbutton.h> + +#include <klocale.h> +#include <kiconloader.h> +#include <KoMainWindow.h> +#include <KoFilterManager.h> +#include <kfiledialog.h> + +#include "karbon_part.h" +#include "karbon_view.h" +#include "karbon_factory.h" +#include "karbon_resourceserver.h" +#include "karbon_drag.h" +#include "vselection.h" +#include "vlayer.h" +#include "vfill.h" +#include "vfillcmd.h" +#include "vtransformcmd.h" + +#include "vstyledocker.h" + +#include <unistd.h> + +ClipartChooser::ClipartChooser( QSize iconSize, QWidget *parent, const char *name ) + : KoIconChooser( iconSize, parent, name ) +{ + setDragEnabled( true ); +} + +void +ClipartChooser::startDrag() +{ + KoIconChooser::startDrag(); + KarbonDrag* kd = new KarbonDrag( this ); + VObjectList objects; + VClipartIconItem *selectedClipart = (VClipartIconItem *)currentItem(); + double s = kMax( selectedClipart->originalWidth(), selectedClipart->originalHeight() ); + VObject *clipart = selectedClipart->clipart()->clone(); + + QWMatrix mat( s, 0, 0, -s, -( s / 2 ), ( s / 2 ) ); + + VTransformCmd trafo( 0L, mat ); + trafo.visit( *clipart ); + + objects.append( clipart ); + kd->setObjectList( objects ); + kd->dragCopy(); +} + +VStyleDocker::VStyleDocker( KarbonPart* part, KarbonView* parent, const char* /*name*/ ) + : QWidget(), m_part ( part ), m_view( parent ) +{ + setCaption( i18n( "Resources" ) ); + + mTabWidget = new QTabWidget( this ); + + //Pattern + KoPatternChooser *pPatternChooser = new KoPatternChooser( KarbonFactory::rServer()->patterns(), mTabWidget ); + pPatternChooser->setCaption( i18n( "Patterns" ) ); + + connect( pPatternChooser, SIGNAL(selected( KoIconItem * ) ), this, SLOT( slotItemSelected( KoIconItem * ))); + connect( KarbonFactory::rServer(), SIGNAL( patternAdded( KoIconItem * )), pPatternChooser, SLOT( addPattern( KoIconItem * ))); + connect( KarbonFactory::rServer(), SIGNAL( patternRemoved( KoIconItem * )), pPatternChooser, SLOT( removePattern( KoIconItem * ))); + mTabWidget->addTab( pPatternChooser, i18n( "Patterns" ) ); + + //Clipart + ClipartWidget *pClipartWidget = new ClipartWidget( KarbonFactory::rServer()->cliparts(), part, mTabWidget ); + mTabWidget->addTab( pClipartWidget, i18n( "Clipart" ) ); + + QVBoxLayout *mainWidgetLayout = new QVBoxLayout( this, 2 ); + mainWidgetLayout->addWidget( mTabWidget ); + mainWidgetLayout->activate(); + setMinimumHeight( 174 ); + setMinimumWidth( 194 ); +} + +VStyleDocker::~VStyleDocker() +{ +} + +void VStyleDocker::slotItemSelected( KoIconItem *item ) +{ + VPattern *pattern = (VPattern *)item; + if( !pattern ) return; + kdDebug(38000) << "loading pattern : " << pattern->tilename().latin1() << endl; + if( m_part && m_part->document().selection() ) + { + VFill fill; + fill.pattern() = *pattern;//.load( pattern->tilename() ); + //fill.setColor( *m_color ); + fill.setType( VFill::patt ); + m_part->addCommand( new VFillCmd( &m_part->document(), fill ), true ); + } +} + +void +VStyleDocker::mouseReleaseEvent( QMouseEvent * ) +{ +} + +ClipartWidget::ClipartWidget( QPtrList<VClipartIconItem>* clipartItems, KarbonPart *part, QWidget* parent ) + : QWidget( parent ), m_part( part ) +{ + KIconLoader il; + + QVBoxLayout* layout = new QVBoxLayout( this ); + layout->addWidget( m_clipartChooser = new ClipartChooser( QSize( 32, 32 ), this ) ); + layout->addWidget( m_buttonGroup = new QHButtonGroup( this ) ); + QToolButton* m_addClipartButton; + m_buttonGroup->insert( m_addClipartButton = new QToolButton( m_buttonGroup ) ); + m_buttonGroup->insert( m_importClipartButton = new QToolButton( m_buttonGroup ) ); + m_buttonGroup->insert( m_deleteClipartButton = new QToolButton( m_buttonGroup ) ); + m_addClipartButton->setIconSet( SmallIcon( "14_layer_newlayer" ) ); + m_addClipartButton->setTextLabel( i18n( "Add" ) ); + m_importClipartButton->setIconSet( SmallIcon( "fileimport" ) ); + m_importClipartButton->setTextLabel( i18n( "Import" ) ); + m_deleteClipartButton->setIconSet( SmallIcon( "14_layer_deletelayer" ) ); + m_deleteClipartButton->setTextLabel( i18n( "Delete" ) ); + + m_buttonGroup->setInsideMargin( 3 ); + + //setFrameStyle( Box | Sunken ); + layout->setMargin( 3 ); + + connect( m_buttonGroup, SIGNAL( clicked( int ) ), this, SLOT( slotButtonClicked( int ) ) ); + //connect( m_deleteClipartButton, SIGNAL( clicked() ), this, SLOT( deleteClipart() ) ); + connect( m_clipartChooser, SIGNAL( selected( KoIconItem* ) ), this, SLOT( clipartSelected( KoIconItem* ) ) ); + + m_clipartChooser->setAutoDelete( false ); + VClipartIconItem* item = 0L; + + for( item = clipartItems->first(); item; item = clipartItems->next() ) + m_clipartChooser->addItem( item ); + + m_clipartItem = ( clipartItems->first() ) ? clipartItems->first()->clone() : 0; + if( !m_clipartItem ) + m_deleteClipartButton->setEnabled( false ); +} + +ClipartWidget::~ClipartWidget() +{ + delete m_clipartItem; +} + +VClipartIconItem* ClipartWidget::selectedClipart() +{ + return m_clipartItem; +} + +void +ClipartWidget::clipartSelected( KoIconItem* item ) +{ + if( item ) + { + delete m_clipartItem; + VClipartIconItem* clipartItem = ( VClipartIconItem* ) item; + m_deleteClipartButton->setEnabled( clipartItem->canDelete() ); + m_selectedItem = clipartItem; + m_clipartItem = clipartItem->clone(); + } +} + +void +ClipartWidget::addClipart() +{ + VObject* clipart = 0L; + VSelection* selection = m_part->document().selection(); + + if( selection->objects().count() == 1 ) + { + clipart = selection->objects().getFirst()->clone(); + clipart->setParent( 0L ); + } + + if( selection->objects().count() > 1 ) + { + QPtrVector<VObject> objects; + selection->objects().toVector( &objects ); + VGroup* group = new VGroup( 0L ); + + for( unsigned int i = 0; i < objects.count(); i++ ) + { + VObject *obj = objects[ i ]->clone(); + obj->setParent( 0L ); + group->append( obj ); + } + + clipart = group; + } + + if( clipart ) + { + KoRect clipartBox = clipart->boundingBox(); + double scaleFactor = 1. / kMax( clipartBox.width(), clipartBox.height() ); + QWMatrix trMatrix( scaleFactor, 0, 0, scaleFactor, -clipartBox.x() * scaleFactor, -clipartBox.y() * scaleFactor ); + + VTransformCmd trafo( 0L, trMatrix ); + trafo.visit( *clipart ); + + // center the clipart + trMatrix.reset(); + double size = kMax( clipart->boundingBox().width(), clipart->boundingBox().height() ); + trMatrix.translate( ( size - clipart->boundingBox().width() ) / 2, ( size - clipart->boundingBox().height() ) / 2 ); + + trafo.setMatrix( trMatrix ); + trafo.visit( *clipart ); + + // remove Y-mirroring + trMatrix.reset(); + trMatrix.scale( 1, -1 ); + trMatrix.translate( 0, -1 ); + + trafo.setMatrix( trMatrix ); + trafo.visit( *clipart ); + + m_clipartChooser->addItem( KarbonFactory::rServer()->addClipart( clipart, clipartBox.width(), clipartBox.height() ) ); + } + + m_clipartChooser->updateContents(); +} + +void +ClipartWidget::importClipart() +{ + QStringList filter; + filter << "application/x-karbon" << "image/svg+xml" << "image/x-wmf" << "image/x-eps" << "application/postscript"; + KFileDialog *dialog = new KFileDialog( "foo", QString::null, 0L, "Choose Graphic to Add", true); + dialog->setMimeFilter( filter, "application/x-karbon" ); + if( dialog->exec()!=QDialog::Accepted ) + { + delete dialog; + return; + } + QString fname = dialog->selectedFile(); + delete dialog; + if( m_part->nativeFormatMimeType() == dialog->currentMimeFilter().latin1() ) + m_part->mergeNativeFormat( fname ); + else + { + KoFilterManager man( m_part ); + KoFilter::ConversionStatus status; + QString importedFile = man.import( fname, status ); + if( status == KoFilter::OK ) + m_part->mergeNativeFormat( importedFile ); + if( !importedFile.isEmpty() ) + unlink( QFile::encodeName( importedFile ) ); + if( status != KoFilter::OK ) + return; + } + m_part->document().selection()->clear(); + m_part->document().selection()->append( m_part->document().activeLayer()->objects() ); + addClipart(); + m_part->document().selection()->clear(); + m_part->document().removeLayer( m_part->document().activeLayer() ); +} + +void +ClipartWidget::deleteClipart() +{ + VClipartIconItem* clipartItem = m_clipartItem; + KarbonFactory::rServer()->removeClipart( clipartItem ); + m_clipartChooser->removeItem( m_selectedItem ); + m_clipartChooser->updateContents(); +} + +void +ClipartWidget::slotButtonClicked( int id ) +{ + switch( id ) + { + case 0: addClipart(); break; + case 1: importClipart(); break; + case 2: deleteClipart(); + } +} + +#include "vstyledocker.moc" + diff --git a/karbon/dockers/vstyledocker.h b/karbon/dockers/vstyledocker.h new file mode 100644 index 00000000..b1187735 --- /dev/null +++ b/karbon/dockers/vstyledocker.h @@ -0,0 +1,89 @@ +/* This file is part of the KDE project + Made by Tomislav Lukman (tomislav.lukman@ck.tel.hr) + Copyright (C) 2002, The Karbon Developers + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + 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. +*/ + +#ifndef __VSTYLEDOCKER_H__ +#define __VSTYLEDOCKER_H__ + +#include <koIconChooser.h> +#include <qwidget.h> + +class QTabWidget; +class KarbonView; +class KarbonPart; +class QHButtonGroup; +class QToolButton; + +class VClipartIconItem; + +class ClipartChooser : public KoIconChooser +{ +public: + ClipartChooser( QSize iconSize, QWidget *parent = 0L, const char *name = 0L ); + virtual void startDrag(); +}; + +class ClipartWidget : public QWidget +{ + Q_OBJECT + +public: + ClipartWidget( QPtrList<VClipartIconItem>* clipartItems, KarbonPart *part, QWidget* parent = 0L ); + ~ClipartWidget(); + + VClipartIconItem* selectedClipart(); + +public slots: + void addClipart(); + void importClipart(); + void deleteClipart(); + void clipartSelected( KoIconItem* item ); + + void slotButtonClicked( int id ); + +private: + ClipartChooser* m_clipartChooser; + QHButtonGroup* m_buttonGroup; + QToolButton* m_importClipartButton; + QToolButton* m_deleteClipartButton; + KarbonPart* m_part; + VClipartIconItem* m_clipartItem; + VClipartIconItem* m_selectedItem; +}; + +class VStyleDocker : public QWidget +{ + Q_OBJECT + +public: + VStyleDocker( KarbonPart* part, KarbonView* parent = 0L, const char* name = 0L ); + virtual ~VStyleDocker(); + +public slots: + void slotItemSelected( KoIconItem * ); + +private: + virtual void mouseReleaseEvent( QMouseEvent *e ); + QTabWidget *mTabWidget; + KarbonPart *m_part; + KarbonView *m_view; +}; + +#endif + diff --git a/karbon/dockers/vtransformdocker.cc b/karbon/dockers/vtransformdocker.cc new file mode 100644 index 00000000..56b07161 --- /dev/null +++ b/karbon/dockers/vtransformdocker.cc @@ -0,0 +1,265 @@ +/* This file is part of the KDE project + Made by Tomislav Lukman (tomislav.lukman@ck.tel.hr) + Copyright (C) 2002, The Karbon Developers + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + 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. +*/ + +#include <qlabel.h> +#include <qlayout.h> +#include <qwidget.h> +#include <qwmatrix.h> +#include <qtooltip.h> + +#include <klocale.h> +#include <KoMainWindow.h> +#include <KoRect.h> +#include <KoUnitWidgets.h> + +#include "karbon_part.h" +#include "karbon_view.h" + +#include "vselection.h" +#include "vtransformcmd.h" + +#include "vtransformdocker.h" + +VTransformDocker::VTransformDocker( KarbonPart* part, KarbonView* parent, const char* /*name*/ ) + : QWidget(), m_part ( part ), m_view( parent ) +{ + setCaption( i18n( "Transform" ) ); + + QGridLayout *mainLayout = new QGridLayout( this, 5, 5 ); + + //X: (TODO: Set 5000 limit to real Karbon14 limit) + QLabel* xLabel = new QLabel( i18n ( "X:" ), this ); + mainLayout->addWidget( xLabel, 0, 0 ); + m_x = new KoUnitDoubleSpinBox( this, -5000.0, 5000.0, 1.0, 10.0, m_part->unit(), 1 ); + mainLayout->addWidget( m_x, 0, 1 ); + QToolTip::add( m_x, i18n("Set x-position of actual selection") ); + + //Y: (TODO: Set 5000 limit to real Karbon14 limit) + QLabel* yLabel = new QLabel( i18n ( "Y:" ), this ); + mainLayout->addWidget( yLabel, 0, 2 ); + m_y = new KoUnitDoubleSpinBox( this, -5000.0, 5000.0, 1.0, 10.0, m_part->unit(), 1 ); + mainLayout->addWidget( m_y, 0, 3 ); + QToolTip::add( m_y, i18n("Set y-position of actual selection") ); + + //Width: (TODO: Set 5000 limit to real Karbon14 limit) + QLabel* wLabel = new QLabel( i18n ( "W:" ), this ); + mainLayout->addWidget( wLabel, 1, 0 ); + m_width = new KoUnitDoubleSpinBox( this, 0.0, 5000.0, 1.0, 10.0, m_part->unit(), 1 ); + mainLayout->addWidget( m_width, 1, 1 ); + QToolTip::add( m_width, i18n("Set width of actual selection") ); + + //Height: (TODO: Set 5000 limit to real Karbon14 limit) + QLabel* hLabel = new QLabel( i18n ( "H:" ), this ); + mainLayout->addWidget( hLabel, 1, 2 ); + m_height = new KoUnitDoubleSpinBox( this, 0.0, 5000.0, 1.0, 10.0, m_part->unit(), 1 ); + mainLayout->addWidget( m_height, 1, 3 ); + QToolTip::add( m_height, i18n("Set height of actual selection") ); + + //TODO: Add Rotation, Shear + //ROTATE: (TODO: Set 5000 limit to real Karbon14 limit) + QLabel* rLabel = new QLabel( i18n ( "R:" ), this ); + mainLayout->addWidget( rLabel, 3, 0 ); + m_rotate = new KDoubleSpinBox( -360.0, 360.0, 1.0, 10.0, 1, this ); + mainLayout->addWidget( m_rotate, 3, 1 ); + QToolTip::add( m_rotate, i18n("Rotate actual selection") ); + + //X-Shear: (TODO: Set 5000 limit to real Karbon14 limit) + QLabel* sxLabel = new QLabel( i18n ( "SX:" ), this ); + mainLayout->addWidget( sxLabel, 2, 0 ); + m_shearX = new KoUnitDoubleSpinBox( this, -5000.0, 5000.0, 1.0, 10.0, m_part->unit(), 1 ); + mainLayout->addWidget( m_shearX, 2, 1 ); + QToolTip::add( m_shearX, i18n("Shear actual selection in x-direction") ); + + //Y-Shear: (TODO: Set 5000 limit to real Karbon14 limit) + QLabel* syLabel = new QLabel( i18n ( "SY:" ), this ); + mainLayout->addWidget( syLabel, 2, 2 ); + m_shearY = new KoUnitDoubleSpinBox( this, -5000.0, 5000.0, 1.0, 10.0, m_part->unit(), 1 ); + mainLayout->addWidget( m_shearY, 2, 3 ); + QToolTip::add( m_shearY, i18n("Shear actual selection in y-direction") ); + + mainLayout->setRowStretch( 4, 1 ); + mainLayout->setColStretch( 1, 1 ); + mainLayout->setColStretch( 3, 1 ); + + update(); +} + +void +VTransformDocker::enableSignals( bool enable ) +{ + if( enable ) + { + connect( m_x, SIGNAL( valueChanged( double ) ), this, SLOT( translate() ) ); + connect( m_y, SIGNAL( valueChanged( double ) ), this, SLOT( translate() ) ); + connect( m_width, SIGNAL( valueChanged( double ) ), this, SLOT( scale() ) ); + connect( m_height, SIGNAL( valueChanged( double ) ), this, SLOT( scale() ) ); + connect( m_shearX, SIGNAL( valueChanged( double ) ), this, SLOT( shearX() ) ); + connect( m_shearY, SIGNAL( valueChanged( double ) ), this, SLOT( shearY() ) ); + connect( m_rotate, SIGNAL( valueChanged( double ) ), this, SLOT( rotate() ) ); + } + else + { + disconnect( m_x, SIGNAL( valueChanged( double ) ), this, SLOT( translate() ) ); + disconnect( m_y, SIGNAL( valueChanged( double ) ), this, SLOT( translate() ) ); + disconnect( m_width, SIGNAL( valueChanged( double ) ), this, SLOT( scale() ) ); + disconnect( m_height, SIGNAL( valueChanged( double ) ), this, SLOT( scale() ) ); + disconnect( m_shearX, SIGNAL( valueChanged( double ) ), this, SLOT( shearX() ) ); + disconnect( m_shearY, SIGNAL( valueChanged( double ) ), this, SLOT( shearY() ) ); + disconnect( m_rotate, SIGNAL( valueChanged( double ) ), this, SLOT( rotate() ) ); + } +} + +void +VTransformDocker::update() +{ + enableSignals( false ); + + int objcount = m_view->part()->document().selection()->objects().count(); + if ( objcount>0 ) + { + setEnabled( true ); + KoRect rect = m_view->part()->document().selection()->boundingBox(); + + m_x->changeValue( rect.x() ); + m_y->changeValue( rect.y() ); + m_width->changeValue( rect.width() ); + m_height->changeValue( rect.height() ); + } + else + { + m_x->changeValue(0.0); + m_y->changeValue(0.0); + m_width->changeValue(0.0); + m_height->changeValue(0.0); + setEnabled( false ); + } + + m_shearX->changeValue(0.0); + m_shearY->changeValue(0.0); + m_rotate->setValue(0.0); + + enableSignals( true ); +} + +void +VTransformDocker::translate() +{ + //FIXME: Needs an appropriate transform command which takes absolute values of object size + double newX = m_x->value(); + double newY = m_y->value(); + + KoRect rect = m_view->part()->document().selection()->boundingBox(); + + if( rect.x() != newX || rect.y() != newY ) + { + VTranslateCmd *cmd = new VTranslateCmd( &m_view->part()->document(), newX-rect.x(), newY-rect.y(), false ); + m_view->part()->addCommand( cmd ); + } + m_part->repaintAllViews( true ); +} + +void +VTransformDocker::scale() +{ + //FIXME: Needs an appropriate transform command which takes absolute values of object size + double newW = m_width->value(); + double newH = m_height->value(); + + KoRect rect = m_view->part()->document().selection()->boundingBox(); + + if( rect.width() != newW || rect.height() != newH ) + { + + VScaleCmd *cmd = new VScaleCmd( &m_view->part()->document(), rect.topLeft(), newW/rect.width(), newH/rect.height(), false ); + m_view->part()->addCommand( cmd ); + } + m_part->repaintAllViews( true ); +} + +void +VTransformDocker::setUnit( KoUnit::Unit unit ) +{ + enableSignals( false ); + + m_x->setUnit( unit ); + m_y->setUnit( unit ); + m_width->setUnit( unit ); + m_height->setUnit( unit ); + m_shearX->setUnit( unit ); + m_shearY->setUnit( unit ); + + enableSignals( true ); +} + +void +VTransformDocker::shearX() +{ + double shear = m_shearX->value(); + + if( shear != 0.0 ) + { + KoRect rect = m_view->part()->document().selection()->boundingBox(); + shear /= double(rect.width()*0.5); + VShearCmd *cmd = new VShearCmd( &m_view->part()->document(), rect.center(), shear, 0 ); + m_view->part()->addCommand( cmd ); + m_part->repaintAllViews( true ); + disconnect( m_shearX, SIGNAL( valueChanged( double ) ), this, SLOT( shearX() ) ); + m_shearX->changeValue(0.0); + connect( m_shearX, SIGNAL( valueChanged( double ) ), this, SLOT( shearX() ) ); + } +} + +void +VTransformDocker::shearY() +{ + double shear = m_shearY->value(); + + if( shear != 0.0 ) + { + KoRect rect = m_view->part()->document().selection()->boundingBox(); + shear /= double(rect.height()*0.5); + VShearCmd *cmd = new VShearCmd( &m_view->part()->document(), rect.center(), 0, shear ); + m_view->part()->addCommand( cmd ); + m_part->repaintAllViews( true ); + disconnect( m_shearY, SIGNAL( valueChanged( double ) ), this, SLOT( shearY() ) ); + m_shearY->changeValue(0.0); + connect( m_shearY, SIGNAL( valueChanged( double ) ), this, SLOT( shearY() ) ); + } +} + +void +VTransformDocker::rotate() +{ + double angle = m_rotate->value(); + + if( angle != 0.0 ) + { + KoPoint center = m_view->part()->document().selection()->boundingBox().center(); + VRotateCmd *cmd = new VRotateCmd( &m_view->part()->document(), center, angle ); + m_view->part()->addCommand( cmd ); + m_part->repaintAllViews( true ); + disconnect( m_rotate, SIGNAL( valueChanged( double ) ), this, SLOT( rotate() ) ); + m_rotate->setValue(0.0); + connect( m_rotate, SIGNAL( valueChanged( double ) ), this, SLOT( rotate() ) ); + } +} + +#include "vtransformdocker.moc" + diff --git a/karbon/dockers/vtransformdocker.h b/karbon/dockers/vtransformdocker.h new file mode 100644 index 00000000..3ba161d4 --- /dev/null +++ b/karbon/dockers/vtransformdocker.h @@ -0,0 +1,60 @@ +/* This file is part of the KDE project + Made by Tomislav Lukman (tomislav.lukman@ck.tel.hr) + Copyright (C) 2002, The Karbon Developers + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + 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. +*/ + +#ifndef __VTRANSFORMDOCKER_H__ +#define __VTRANSFORMDOCKER_H__ + +class KarbonPart; +class KarbonView; +class KoUnitDoubleSpinBox; + +class VTransformDocker : public QWidget +{ + Q_OBJECT + +public: + VTransformDocker( KarbonPart* part, KarbonView* parent = 0L, const char* name = 0L ); + +public slots: + void update(); + virtual void setUnit( KoUnit::Unit unit ); + +private slots: + void translate(); + void scale(); + void enableSignals( bool enable ); + void shearX(); + void shearY(); + void rotate(); + +private: + KarbonPart *m_part; + KarbonView *m_view; + KoUnitDoubleSpinBox *m_x; + KoUnitDoubleSpinBox *m_y; + KoUnitDoubleSpinBox *m_width; + KoUnitDoubleSpinBox *m_height; + KDoubleSpinBox *m_rotate; + KoUnitDoubleSpinBox *m_shearX; + KoUnitDoubleSpinBox *m_shearY; +}; + +#endif + |