summaryrefslogtreecommitdiffstats
path: root/karbon/dockers/vdocumentdocker.cc
diff options
context:
space:
mode:
Diffstat (limited to 'karbon/dockers/vdocumentdocker.cc')
-rw-r--r--karbon/dockers/vdocumentdocker.cc1460
1 files changed, 1460 insertions, 0 deletions
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"