karbon

vdocumentdocker.cc

00001 /* This file is part of the KDE project
00002    Copyright (C) 2001, 2002, 2003 The Karbon Developers
00003 
00004    This library is free software; you can redistribute it and/or
00005    modify it under the terms of the GNU Library General Public
00006    License as published by the Free Software Foundation; either
00007    version 2 of the License, or (at your option) any later version.
00008 
00009    This library is distributed in the hope that it will be useful,
00010    but WITHOUT ANY WARRANTY; without even the implied warranty of
00011    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00012    Library General Public License for more details.
00013 
00014    You should have received a copy of the GNU Library General Public License
00015    along with this library; see the file COPYING.LIB.  If not, write to
00016    the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
00017  * Boston, MA 02110-1301, USA.
00018 */
00019 
00020 #include <qhbuttongroup.h>
00021 #include <qinputdialog.h>
00022 #include <qlayout.h>
00023 #include <qcheckbox.h>
00024 #include <qlistview.h>
00025 #include <qptrvector.h>
00026 #include <qtoolbutton.h>
00027 #include <qpainter.h>
00028 #include <qtabwidget.h>
00029 #include <qlabel.h>
00030 #include <qcursor.h>
00031 
00032 #include <klocale.h>
00033 #include <kglobal.h>
00034 #include <KoMainWindow.h>
00035 #include <kdebug.h>
00036 #include <kiconloader.h>
00037 #include <klineeditdlg.h>
00038 #include <kinputdialog.h>
00039 
00040 #include "karbon_part.h"
00041 #include "karbon_view.h"
00042 #include "karbon_factory.h"
00043 #include "karbon_resourceserver.h"
00044 #include "vdocument.h"
00045 #include "vkopainter.h"
00046 #include "vlayer.h"
00047 #include "vlayercmd.h"
00048 #include "vdeletecmd.h"
00049 #include "vzordercmd.h"
00050 #include "vgroupcmd.h"
00051 #include "vungroupcmd.h"
00052 #include "vselection.h"
00053 #include "vstroke.h"
00054 #include "vcanvas.h"
00055 #include "vdocumentdocker.h"
00056 #include <visitors/vselectiondesc.h>
00057 
00058 static long g_lastKey = 0;
00059 
00060 /*************************************************************************
00061  *  Document tab                                                         *
00062  *************************************************************************/
00063 
00064 VDocumentPreview::VDocumentPreview( KarbonView* view, QWidget* parent )
00065         : QWidget( parent, "DocumentPreview" ), m_document( &view->part()->document() ), m_view( view )
00066 {
00067     update();
00068     installEventFilter( this );
00069     setBackgroundMode( Qt::NoBackground );
00070     setMouseTracking( true );
00071     m_dragging = false;
00072     m_docpixmap = 0L;
00073 } // VDocumentPreview::VDocumentPreview
00074 
00075 VDocumentPreview::~VDocumentPreview()
00076 {
00077     delete m_docpixmap;
00078 } // VDocumentPreview::~VDocumentPreview
00079 
00080 void
00081 VDocumentPreview::reset()
00082 {
00083     delete m_docpixmap;
00084     m_docpixmap = 0L;
00085 }
00086 
00087 bool
00088 VDocumentPreview::eventFilter( QObject* object, QEvent* event )
00089 {
00090     double scaleFactor;
00091     double xoffset = 0.;
00092     double yoffset = 0.;
00093     if ( ( height() - 4 ) / m_document->height() > ( width() - 4 ) / m_document->width() )
00094     {
00095         scaleFactor = ( width() - 4 ) / m_document->width();
00096         yoffset = ( ( height() - 4 ) / scaleFactor - m_document->height() ) / 2;
00097     }
00098     else
00099     {
00100         scaleFactor = ( height() - 4 ) / m_document->height();
00101         xoffset = ( ( width() - 4 ) / scaleFactor - m_document->width() ) / 2;
00102     }
00103     KoRect rect = m_view->canvasWidget()->boundingBox();
00104 
00105     QMouseEvent* mouseEvent = static_cast<QMouseEvent*>( event );
00106     if( event->type() == QEvent::MouseButtonPress )
00107     {
00108         m_firstPoint.setX( mouseEvent->pos().x() );
00109         m_firstPoint.setY( mouseEvent->pos().y() );
00110         m_lastPoint = m_firstPoint;
00111         KoPoint p3( m_firstPoint.x() / scaleFactor - xoffset,
00112                     ( height() - m_firstPoint.y() ) / scaleFactor - yoffset );
00113         m_dragging = rect.contains( p3 );
00114     }
00115     else if( event->type() == QEvent::MouseButtonRelease )
00116     {
00117         if( m_dragging )
00118         {
00119             m_lastPoint.setX( mouseEvent->pos().x() );
00120             m_lastPoint.setY( mouseEvent->pos().y() );
00121             double dx = m_lastPoint.x() - m_firstPoint.x();
00122             double dy = m_lastPoint.y() - m_firstPoint.y();
00123             scaleFactor /= m_view->zoom();
00124             m_view->canvasWidget()->scrollBy( int( dx / scaleFactor ), int( dy / scaleFactor ) );
00125             m_firstPoint = m_lastPoint;
00126             m_dragging = false;
00127             update();
00128         }
00129     }
00130     else if( event->type() == QEvent::MouseMove )
00131     {
00132         if( m_dragging )
00133         {
00134             m_lastPoint.setX( mouseEvent->pos().x() );
00135             m_lastPoint.setY( mouseEvent->pos().y() );
00136             update();
00137             /*double dx = m_lastPoint.x() - m_firstPoint.x();
00138             double dy = m_lastPoint.y() - m_firstPoint.y();
00139             scaleFactor /= m_view->zoom();
00140             m_view->canvasWidget()->scrollBy( int( dx / scaleFactor ), int( dy / scaleFactor ) );
00141             m_firstPoint = m_lastPoint;*/
00142         }
00143         else
00144         {
00145             KoPoint p3( mouseEvent->pos().x() / scaleFactor - xoffset,
00146                         ( height() - mouseEvent->pos().y() ) / scaleFactor - yoffset );
00147             setCursor( rect.contains( p3 ) ? QCursor::SizeAllCursor : QCursor( Qt::arrowCursor ) );
00148         }
00149     }
00150 
00151     return QWidget::eventFilter( object, event );
00152 }
00153 
00154 void
00155 VDocumentPreview::paintEvent( QPaintEvent* )
00156 {
00157     // TODO : use NotROP, otherwise too slow
00158     QPixmap pixmap( width(), height() );
00159     double xoffset = 0.;
00160     double yoffset = 0.;
00161     double scaleFactor;
00162     if ( ( height() - 4 ) / m_document->height() > ( width() - 4 ) / m_document->width() )
00163     {
00164         scaleFactor = ( width() - 4 ) / m_document->width();
00165         yoffset = ( ( height() - 4 ) / scaleFactor - m_document->height() ) / 2;
00166     }
00167     else
00168     {
00169         scaleFactor = ( height() - 4 ) / m_document->height();
00170         xoffset = ( ( width() - 4 ) / scaleFactor - m_document->width() ) / 2;
00171     }
00172     xoffset += 2 / scaleFactor;
00173     yoffset += 2 / scaleFactor;
00174     if( !m_docpixmap || m_docpixmap->width() != width() || m_docpixmap->height() != height() )
00175     {
00176         delete m_docpixmap;
00177         m_docpixmap = new QPixmap( width(), height() );
00178         VKoPainter p( m_docpixmap, width(), height() );
00179         p.clear( QColor( 195, 194, 193 ) );
00180         p.setWorldMatrix( QWMatrix( 1, 0, 0, -1, xoffset * scaleFactor, height() - yoffset * scaleFactor ) );
00181         p.setZoomFactor( scaleFactor );
00182         KoRect rect( -xoffset, -yoffset, m_document->width() + xoffset, m_document->height() + yoffset );
00183         // draw doc outline
00184         VColor c( Qt::black );
00185         VStroke stroke( c, 0L, 1.0 / scaleFactor );
00186         p.setPen( stroke );
00187         p.setBrush( Qt::white );
00188         p.drawRect( KoRect( 2, 2, m_document->width() - 2, m_document->height() - 2 ) );
00189         m_document->draw( &p, &rect );
00190         p.end();
00191     }
00192     bitBlt( &pixmap, 0, 0, m_docpixmap, 0, 0, width(), height() );
00193 
00194     // draw viewport rect
00195     {
00196         QPainter p( &pixmap );
00197         p.setWorldMatrix( QWMatrix( scaleFactor, 0, 0, -scaleFactor, xoffset * scaleFactor, height() - yoffset * scaleFactor ) );
00198         p.setPen( Qt::red );
00199         double dx = ( m_lastPoint.x() - m_firstPoint.x() ) * m_view->zoom();
00200         double dy = ( m_lastPoint.y() - m_firstPoint.y() ) * m_view->zoom();
00201         KoPoint p1( dx / scaleFactor, dy / scaleFactor );
00202         p1 = m_view->canvasWidget()->toContents( p1 );
00203         KoPoint p2( dx / scaleFactor + m_view->canvasWidget()->width(), dy / scaleFactor + m_view->canvasWidget()->height() );
00204         p2 = m_view->canvasWidget()->toContents( p2 );
00205         p.drawRect( int( p1.x() ), int( p1.y() ), int( p2.x() - p1.x() ), int( p2.y() - p1.y() ) );
00206     }
00207 
00208     QPainter pw( &pixmap );
00209     pw.setPen( colorGroup().light() );
00210     pw.drawLine( 1, 1, 1, height() - 2 );
00211     pw.drawLine( 1, 1, width() - 2, 1 );
00212     pw.drawLine( width() - 1, height() - 1, 0, height() - 1 );
00213     pw.drawLine( width() - 1, height() - 1, width() - 1, 0 );
00214     pw.setPen( colorGroup().dark() );
00215     pw.drawLine( 0, 0, width() - 1, 0 );
00216     pw.drawLine( 0, 0, 0, height() - 1 );
00217     pw.drawLine( width() - 2, height() - 2, width() - 2, 1 );
00218     pw.drawLine( width() - 2, height() - 2, 1, height() - 2 );
00219     pw.end();
00220     bitBlt( this, 0, 0, &pixmap, 0, 0, width(), height() );
00221 } // VDocumentPreview::paintEvent
00222 
00223 VDocumentTab::VDocumentTab( KarbonView* view, QWidget* parent )
00224         : QWidget( parent, "DocumentTab" ), m_view( view )
00225 {
00226     QFrame* frame;
00227     QGridLayout* layout = new QGridLayout( this );
00228     layout->setMargin( 3 );
00229     layout->setSpacing( 2 );
00230     layout->addMultiCellWidget( m_documentPreview = new VDocumentPreview( m_view, this ), 0, 7, 2, 2 );
00231     layout->addWidget( new QLabel( i18n( "Width:" ), this ), 0, 0 );
00232     layout->addWidget( new QLabel( i18n( "Height:" ), this ), 1, 0 );
00233     layout->addMultiCellWidget( frame = new QFrame( this ), 2, 2, 0, 1 );
00234     frame->setFrameShape( QFrame::HLine );
00235     layout->addWidget( new QLabel( i18n( "Layers:" ), this ), 3, 0 );
00236     layout->addWidget( new QLabel( i18n( "Format:" ), this ), 4, 0 );
00237     layout->addMultiCellWidget( frame = new QFrame( this ), 5, 5, 0, 1 );
00238     frame->setFrameShape( QFrame::HLine );
00239     //layout->addMultiCellWidget( new QLabel( i18n( "Zoom factor:" ), this ), 6, 6, 0, 1 );
00240     layout->addWidget( m_width = new QLabel( this ), 0, 1 );
00241     layout->addWidget( m_height = new QLabel( this ), 1, 1 );
00242     layout->addWidget( m_layers = new QLabel( this ), 3, 1 );
00243     layout->addWidget( m_format = new QLabel( this ), 4, 1 );
00244     layout->setRowStretch( 7, 1 );
00245     layout->setColStretch( 0, 0 );
00246     layout->setColStretch( 1, 0 );
00247     layout->setColStretch( 2, 2 );
00248     //layout->addWidget(
00249 
00250     m_width->setAlignment( AlignRight );
00251     m_height->setAlignment( AlignRight );
00252     m_layers->setAlignment( AlignRight );
00253     m_format->setAlignment( AlignRight );
00254 
00255     connect( view->part()->commandHistory(), SIGNAL( commandAdded( VCommand* ) ), this, SLOT( slotCommandAdded( VCommand* ) ) );
00256     connect( view->part()->commandHistory(), SIGNAL( commandExecuted() ), this, SLOT( slotCommandExecuted() ) );
00257     connect( view, SIGNAL( pageLayoutChanged() ), this, SLOT( slotCommandExecuted() ) );
00258     connect( view->canvasWidget(), SIGNAL( viewportChanged() ), this, SLOT( slotViewportChanged() ) );
00259 
00260     updateDocumentInfo();
00261 } // VDocumentTab::VDocumentTab
00262 
00263 VDocumentTab::~VDocumentTab()
00264 {
00265 } // VDocumentTab::~VDocumentTab
00266 
00267 void
00268 VDocumentTab::updateDocumentInfo()
00269 {
00270     m_width->setText( KoUnit::toUserStringValue( m_view->part()->document().width(), m_view->part()->unit() ) + m_view->part()->unitName() );
00271     m_height->setText( KoUnit::toUserStringValue( m_view->part()->document().height(), m_view->part()->unit() ) + m_view->part()->unitName() );
00272     m_layers->setText( QString::number( m_view->part()->document().layers().count() ) );
00273 } // VDocumentTab::updateDocumentInfo
00274 
00275 void
00276 VDocumentTab::slotCommandAdded( VCommand * )
00277 {
00278     m_documentPreview->reset();
00279     m_documentPreview->update();
00280 }
00281 
00282 void
00283 VDocumentTab::slotZoomChanged( double )
00284 {
00285     m_documentPreview->update();
00286 }
00287 
00288 void
00289 VDocumentTab::slotViewportChanged()
00290 {
00291     m_documentPreview->update();
00292     updateDocumentInfo();
00293 }
00294 
00295 void
00296 VDocumentTab::slotCommandExecuted()
00297 {
00298     m_documentPreview->reset();
00299     m_documentPreview->update();
00300 }
00301 
00302 /*************************************************************************
00303  *  Layers tab                                                           *
00304  *************************************************************************/
00305 
00306 VObjectListViewItem::VObjectListViewItem( QListViewItem* parent, VObject* object, VDocument *doc, uint key, QPtrDict<VObjectListViewItem> *map )
00307     : QListViewItem( parent, 0L ), m_object( object ), m_document( doc ), m_key( key ), m_map( map )
00308 {
00309     update();
00310     // add itself to object list item map
00311     m_map->insert( object, this );
00312 }
00313 
00314 VObjectListViewItem::~VObjectListViewItem() 
00315 {
00316     // remove itself from object list item map
00317     m_map->take( m_object );
00318 }
00319 
00320 QString
00321 VObjectListViewItem::key( int, bool ) const
00322 {
00323     return QString( "%1" ).arg( m_key );
00324 }
00325 
00326 void
00327 VObjectListViewItem::update()
00328 {
00329     // text description
00330     VSelectionDescription selectionDesc;
00331     selectionDesc.visit( *m_object );
00332     setText( 0, QString( "%1" ).arg( selectionDesc.shortDescription() ) );
00333 
00334     // draw thumb preview (16x16)
00335     QPixmap preview;
00336     preview.resize( 16, 16 );
00337     VKoPainter p( &preview, 16, 16, false );
00338     // Y mirroring
00339     QWMatrix mat;
00340     mat.scale( 1, -1 );
00341     KoRect bbox = m_object->boundingBox();
00342     mat.translate( 0, -16 );
00343     double factor = 16. / kMax( bbox.width(), bbox.height() );
00344     mat.translate( -bbox.x() * factor, -bbox.y() * factor );
00345     p.setWorldMatrix( mat );
00346 
00347     // TODO: When the document will support page size, change the following line.
00348     p.setZoomFactor( factor );
00349     m_object->draw( &p );
00350     p.setZoomFactor( 1 );
00351     p.setWorldMatrix( QWMatrix() );
00352     p.setPen( Qt::black );
00353     p.setBrush( Qt::NoBrush );
00354     p.drawRect( KoRect( 0, 0, 16, 16 ) );
00355     p.end();
00356 
00357     // set thumb preview, lock and visible pixmaps
00358     setPixmap( 0, preview );
00359     QString s = ( m_object->state() == VObject::normal_locked || m_object->state() == VObject::hidden_locked ) ? "locked" : "unlocked";
00360     setPixmap( 1, *KarbonFactory::rServer()->cachePixmap( s, KIcon::Small ) );
00361     s = ( m_object->state() == VObject::hidden || m_object->state() == VObject::hidden_locked ) ? "14_layer_novisible" : "14_layer_visible";
00362     setPixmap( 2, *KarbonFactory::rServer()->cachePixmap( s, KIcon::Small ) );
00363 }
00364 
00365 int 
00366 VObjectListViewItem::compare( QListViewItem *i, int /*col*/, bool /*ascending*/ ) const
00367 {
00368     VObjectListViewItem *objectItem = dynamic_cast<VObjectListViewItem*>(i);
00369     if( ! objectItem ) return 0;
00370     return m_key < objectItem->m_key ? -1 : 1;
00371 }
00372 
00373 VLayerListViewItem::VLayerListViewItem( QListView* parent, VLayer* layer, VDocument *doc, QPtrDict<VLayerListViewItem> *map )
00374     : QCheckListItem( parent, 0L, CheckBox ), m_layer( layer ), m_document( doc), m_map( map )
00375 {
00376     update();
00377     // add itself to layer list item map
00378     m_map->insert( layer, this );
00379 } // VLayerListViewItem::VLayerListViewItem
00380 
00381 VLayerListViewItem::~VLayerListViewItem()
00382 {
00383     // remove itself from layer list item map
00384     m_map->take( m_layer );
00385 }
00386 
00387 void
00388 VLayerListViewItem::update()
00389 {
00390     // draw thumb preview (16x16)
00391     QPixmap preview;
00392     preview.resize( 16, 16 );
00393     VKoPainter p( &preview, 16, 16, false );
00394     // Y mirroring
00395     QWMatrix mat;
00396     mat.scale( 1, -1 );
00397     mat.translate( 0,  -16 );
00398     p.setWorldMatrix( mat );
00399 
00400     // TODO: When the document will support page size, change the following line.
00401     p.setZoomFactor( 16. / 800. );
00402     m_layer->draw( &p );
00403     p.setZoomFactor( 1 );
00404     p.setWorldMatrix( QWMatrix() );
00405     p.setPen( Qt::black );
00406     p.setBrush( Qt::NoBrush );
00407     p.drawRect( KoRect( 0, 0, 16, 16 ) );
00408     p.end();
00409 
00410     // text description
00411     setOn( m_layer->selected() );
00412     setText( 0, m_layer->name() );
00413 
00414     // set thumb preview, lock and visible pixmaps
00415     setPixmap( 0, preview );
00416     QString s = ( m_layer->state() == VObject::normal_locked || m_layer->state() == VObject::hidden_locked ) ? "locked" : "unlocked";
00417     setPixmap( 1, *KarbonFactory::rServer()->cachePixmap( s, KIcon::Small ) );
00418     s = ( m_layer->state() == VObject::normal || m_layer->state() == VObject::normal_locked ) ? "14_layer_visible" : "14_layer_novisible";
00419     setPixmap( 2, *KarbonFactory::rServer()->cachePixmap( s, KIcon::Small ) );
00420 } // VLayerListViewItem::update
00421 
00422 void
00423 VLayerListViewItem::stateChange( bool on )
00424 {
00425     m_layer->setSelected( on );
00426 } // VLayerListViewItem::stateChange
00427 
00428 int
00429 VLayerListViewItem::pos()
00430 {
00431     VLayerListViewItem* item;
00432     if( !( item = (VLayerListViewItem*)itemAbove() ) )
00433         return 0;
00434     else
00435         return 1 + item->pos();
00436 } // VLayerListViewItem::pos
00437 
00438 QString
00439 VLayerListViewItem::key( int, bool ) const
00440 {
00441     return QString( "%1" ).arg( m_key );
00442 }
00443 
00444 int 
00445 VLayerListViewItem::compare( QListViewItem *i, int /*col*/, bool /*ascending*/ ) const
00446 {
00447     VLayerListViewItem *layerItem = dynamic_cast<VLayerListViewItem*>(i);
00448     if( ! layerItem ) return 0;
00449     return m_key < layerItem->m_key ? -1 : 1;
00450 }
00451 
00452 VLayersTab::VLayersTab( KarbonView* view, QWidget* parent )
00453         : QWidget( parent, "LayersTab" ), m_view( view ), m_document( &view->part()->document() )
00454 {
00455 
00456     QToolButton* button;
00457     QVBoxLayout* layout = new QVBoxLayout( this, 1 );
00458     layout->addWidget( m_layersListView = new QListView( this ), 1 );
00459     m_buttonGroup = new QHButtonGroup( this );
00460     m_buttonGroup->setInsideMargin( 3 );
00461     button = new QToolButton( m_buttonGroup );
00462     button->setIconSet( SmallIcon( "14_layer_newlayer" ) );
00463     button->setTextLabel( i18n( "New" ) );
00464     m_buttonGroup->insert( button );
00465     button = new QToolButton( m_buttonGroup );
00466     button->setIconSet( SmallIcon( "14_layer_raiselayer" ) );
00467     button->setTextLabel( i18n( "Raise" ) );
00468     m_buttonGroup->insert( button );
00469     button = new QToolButton( m_buttonGroup );
00470     button->setIconSet( SmallIcon( "14_layer_lowerlayer" ) );
00471     button->setTextLabel( i18n( "Lower" ) );
00472     m_buttonGroup->insert( button );
00473     button = new QToolButton( m_buttonGroup );
00474     button->setIconSet( SmallIcon( "14_layer_deletelayer" ) );
00475     button->setTextLabel( i18n( "Delete" ) );
00476     m_buttonGroup->insert( button );
00477     layout->addWidget( m_buttonGroup, 0);
00478     layout->setSpacing( 0 );
00479     layout->setMargin( 3 );
00480 
00481     m_layersListView->setAllColumnsShowFocus( true );
00482     m_layersListView->addColumn( i18n( "Item" ), 120 );
00483     m_layersListView->addColumn( i18n( "L" ), 20 );
00484     m_layersListView->addColumn( i18n( "V" ), 20 );
00485     m_layersListView->setColumnWidthMode( 0, QListView::Maximum );
00486     m_layersListView->setColumnAlignment( 1, Qt::AlignCenter );
00487     m_layersListView->setColumnAlignment( 2, Qt::AlignCenter );
00488     m_layersListView->setResizeMode( QListView::NoColumn );
00489     m_layersListView->setSorting( 0, false );
00490     m_layersListView->setRootIsDecorated( true );
00491     m_layersListView->setSelectionMode( QListView::Extended );
00492 
00493     connect( m_layersListView, SIGNAL( clicked( QListViewItem*, const QPoint&, int ) ), this, SLOT( itemClicked( QListViewItem*, const QPoint&, int ) ) );
00494     connect( m_layersListView, SIGNAL( rightButtonClicked( QListViewItem*, const QPoint&, int ) ), this, SLOT( renameItem( QListViewItem*, const QPoint&, int ) ) );
00495     connect( m_layersListView, SIGNAL( selectionChanged() ), this, SLOT( selectionChangedFromList() ) );
00496     connect( m_view, SIGNAL( selectionChange() ), this, SLOT( selectionChangedFromTool() ) );
00497     connect( m_buttonGroup, SIGNAL( clicked( int ) ), this, SLOT( slotButtonClicked( int ) ) );
00498     connect( view->part()->commandHistory(), SIGNAL( commandExecuted( VCommand*) ), this, SLOT( slotCommandExecuted( VCommand* ) ) );
00499 
00500     layout->activate();
00501     updateLayers();
00502 } // VLayersTab::VLayersTab
00503 
00504 VLayersTab::~VLayersTab()
00505 {
00506 } // VLayersTab::~VLayersTab
00507 
00508 void
00509 VLayersTab::slotButtonClicked( int ID )
00510 {
00511     switch( ID )
00512     {
00513         case 0:
00514             addLayer(); break;
00515         case 1:
00516             raiseItem(); break;
00517         case 2:
00518             lowerItem(); break;
00519         case 3:
00520             deleteItem(); break;
00521     }
00522 } // VLayersTab::slotButtonClicked
00523 
00524 void 
00525 VLayersTab::resetSelection()
00526 {
00527     QListViewItemIterator it( m_layersListView );
00528 
00529     // iterates over all list items and deselects them manually
00530     // to avoid the list views selectionChanged signal
00531     for(; it.current(); ++it )
00532     {
00533         it.current()->setSelected( false );
00534         it.current()->repaint();
00535     }
00536 }
00537 
00538 void 
00539 VLayersTab::selectActiveLayer()
00540 {
00541     if( ! m_layers[ m_document->activeLayer() ] )
00542     {
00543         QPtrVector<VLayer> vector;
00544         m_document->layers().toVector( &vector );
00545         // find another layer to set active
00546         for( int i = vector.count() - 1; i >= 0; i-- )
00547             if ( vector[i]->state() != VObject::deleted )
00548             {
00549                 m_document->setActiveLayer( vector[i] );
00550                 break;
00551             }
00552     }
00553 
00554     // deselect all other layers
00555     QPtrDictIterator<VLayerListViewItem> it( m_layers );
00556     for(; it.current(); ++it )
00557     {
00558         it.current()->setSelected( false );
00559         it.current()->repaint();
00560     }
00561 
00562     VLayerListViewItem *layerItem = m_layers[ m_document->activeLayer() ];
00563     if( layerItem )
00564     {
00565         layerItem->setSelected( true );
00566         layerItem->repaint();
00567         kdDebug(38000) << "selecting active layer: " << layerItem->text() << endl;
00568     }
00569 }
00570 
00571 void
00572 VLayersTab::selectionChangedFromTool()
00573 {
00574     resetSelection();
00575     removeDeletedObjectsFromList();
00576 
00577     // TODO : use some kind of mapping...
00578     VObjectListIterator itr = m_document->selection()->objects();
00579     for( ; itr.current(); ++itr )
00580         if( itr.current()->state() != VObject::deleted )
00581         {
00582             VObject *obj = itr.current();
00583 
00584             VObjectListViewItem *item = m_objects[ obj ];
00585             if( ! item ) 
00586             {
00587                 VLayerListViewItem *layerItem = m_layers[ obj->parent() ];
00588                 if( layerItem )
00589                     updateObjects( layerItem->layer(), layerItem );
00590                 else
00591                 {
00592                     VObjectListViewItem *objectItem = m_objects[ obj->parent() ];
00593                     if( objectItem )
00594                         updateObjects( objectItem->object(), objectItem );
00595                     else
00596                         continue;
00597                 }
00598                 item = m_objects[ obj ];
00599             }
00600             if( ! item ) continue;
00601 
00602             item->setSelected( true );
00603             item->update();
00604         }
00605     selectActiveLayer();    
00606 }
00607 
00608 void 
00609 VLayersTab::updateChildItems( QListViewItem *item )
00610 {
00611     QListViewItemIterator it( item );
00612 
00613     // iterator points to item, so make the next item current first
00614     for( ++it; it.current(); ++it )
00615     {
00616         VObjectListViewItem *objectItem = dynamic_cast<VObjectListViewItem *>( it.current() );
00617         if( ! objectItem ) continue;
00618         
00619         if( dynamic_cast<VGroup*>( objectItem->object() ) )
00620             updateChildItems( objectItem );
00621 
00622         objectItem->update();
00623         objectItem->repaint();
00624     }
00625 }
00626 
00627 void 
00628 VLayersTab::toggleState( VObject *obj, int col )
00629 {
00630     switch( col )
00631     {
00632         case 1: // toggle visibility
00633             if( obj->state() == VObject::hidden_locked )
00634                 obj->setState( VObject::hidden );
00635             else if( obj->state() == VObject::normal_locked )
00636                 obj->setState( VObject::selected );
00637             else if( obj->state() == VObject::normal || obj->state() >= VObject::selected )
00638                 obj->setState( VObject::normal_locked );
00639             else if( obj->state() == VObject::hidden )
00640                 obj->setState( VObject::hidden_locked );
00641         break;
00642         case 2: // toggle locking
00643             if( obj->state() == VObject::hidden_locked )
00644                 obj->setState( VObject::normal_locked );
00645             else if( obj->state() == VObject::normal_locked )
00646                 obj->setState( VObject::hidden_locked );
00647             else if( obj->state() == VObject::normal || obj->state() >= VObject::selected )
00648                 obj->setState( VObject::hidden );
00649             else if( obj->state() == VObject::hidden )
00650                 obj->setState( VObject::selected );
00651         break;
00652         default: return;
00653     }
00654 
00655     if( obj->state() < VObject::selected )
00656         m_document->selection()->take( *obj );
00657     else
00658         m_document->selection()->append( obj );
00659 }
00660 
00661 void
00662 VLayersTab::itemClicked( QListViewItem* item, const QPoint &, int col )
00663 {
00664     if( item )
00665     {
00666         VLayerListViewItem *layerItem = dynamic_cast<VLayerListViewItem *>( item );
00667         if( layerItem )
00668         {
00669             if( col == 0 )
00670             {
00671                 m_document->setActiveLayer( layerItem->layer() );
00672                 selectActiveLayer();
00673             }
00674             if( col > 0 )
00675             {
00676                 toggleState( layerItem->layer(), col );
00677 
00678                 layerItem->update();
00679                 layerItem->repaint();
00680 
00681                 updateChildItems( layerItem );
00682 
00683                 m_view->part()->repaintAllViews();
00684             }
00685         }
00686         else
00687         {
00688             VObjectListViewItem *objectItem = dynamic_cast< VObjectListViewItem *>( item );
00689 
00690             if( col == 0 )
00691             {
00692                 VObject *obj = objectItem->object();
00693                 if( obj->state() == VObject::normal )
00694                     obj->setState( VObject::selected );
00695             }
00696             if( col > 0 ) 
00697             {
00698                 toggleState( objectItem->object(), col );
00699                 
00700                 if( objectItem->object()->state() == VObject::selected )
00701                     objectItem->setSelected( true );
00702                 else
00703                     objectItem->setSelected( false );
00704 
00705                 objectItem->update();
00706                 objectItem->repaint();
00707 
00708                 if( dynamic_cast<VGroup*>( objectItem->object() ) )
00709                     updateChildItems( objectItem );
00710 
00711                 m_view->part()->repaintAllViews();
00712             }
00713         }
00714     }
00715 } // VLayersTab::itemClicked
00716 
00717 void
00718 VLayersTab::selectionChangedFromList()
00719 {
00720     m_document->selection()->clear();
00721 
00722     QListViewItemIterator it( m_layersListView );
00723 
00724     // iterate over all list items and add their corresponding object 
00725     // to the documents selection if the list item is selected and not hidden or locked or both
00726     for(; it.current(); ++it )
00727     {
00728         VObjectListViewItem *objectItem = dynamic_cast<VObjectListViewItem *>( it.current() );
00729         if( ! objectItem ) continue;
00730 
00731         VObject::VState state = objectItem->object()->state();
00732         
00733         if( state == VObject::deleted ) 
00734         {
00735             delete objectItem;
00736             continue;
00737         }
00738 
00739         if( objectItem->isSelected() && (state != VObject::hidden) && (state != VObject::normal_locked ) 
00740         && (state != VObject::hidden_locked) )
00741         {
00742             m_document->selection()->append( objectItem->object() );
00743             objectItem->repaint();
00744         }
00745     }
00746     
00747     m_view->selectionChanged();
00748     m_view->part()->repaintAllViews();
00749 }
00750 
00751 void
00752 VLayersTab::renameItem( QListViewItem* item, const QPoint&, int col )
00753 {
00754     if ( ( item ) && col == 0 )
00755     {
00756         bool ok = true;
00757         VLayerListViewItem* layerItem = dynamic_cast<VLayerListViewItem *>( item );
00758         if( !layerItem )
00759         {
00760             VObjectListViewItem *objectItem = dynamic_cast< VObjectListViewItem *>( item );
00761             VObject *obj = objectItem->object();
00762             QString name = KInputDialog::getText( i18n( "Current Object" ), i18n( "Change the name of the object:" ),
00763                                                   obj->name(), &ok, this );
00764             if( ok )
00765             {
00766                 m_document->setObjectName( obj, name );
00767                 objectItem->update();
00768             }
00769         }
00770         else
00771         {
00772             QString name = KInputDialog::getText( i18n( "Rename Layer" ), i18n( "Change the name of the current layer:" ),
00773                                                   layerItem->layer()->name(), &ok, this );
00774             if( ok )
00775             {
00776                 layerItem->layer()->setName( name );
00777                 layerItem->update();
00778             }
00779         }
00780     }
00781 } // VLayersTab::renameItem
00782 
00783 void
00784 VLayersTab::addLayer()
00785 {
00786     bool ok = true;
00787     QString name = KInputDialog::getText( i18n( "New Layer" ), i18n( "Enter the name of the new layer:" ),
00788                                           i18n( "New layer" ), &ok, this );
00789     if( ok )
00790     {
00791         VLayer* layer = new VLayer( m_document );
00792         layer->setName( name );
00793         VLayerCmd* cmd = new VLayerCmd( m_document, i18n( "Add Layer" ),
00794                 layer, VLayerCmd::addLayer );
00795         m_view->part()->addCommand( cmd, true );
00796         updateLayers();
00797     }
00798 } // VLayersTab::addLayer
00799 
00800 void
00801 VLayersTab::raiseItem()
00802 {
00803     VCommand *cmd = 0L;
00804     //QListViewItem *newselection = 0L;
00805     QListViewItemIterator it( m_layersListView );
00806 
00807     for(; it.current(); ++it )
00808     {
00809         if( ! it.current()->isSelected() ) continue;
00810 
00811         VLayerListViewItem* layerItem = dynamic_cast<VLayerListViewItem *>( it.current() );
00812         if( layerItem )
00813         {
00814             VLayer *layer = layerItem->layer();
00815             if( layer && m_document->canRaiseLayer( layer ) )
00816             {
00817                 cmd = new VLayerCmd( m_document, i18n( "Raise Layer" ),
00818                                 layerItem->layer(), VLayerCmd::raiseLayer );
00819                 //newselection = layerItem;
00820             }
00821         }
00822         else
00823         {
00824             VObjectListViewItem* item = dynamic_cast< VObjectListViewItem *>( it.current() );
00825             if( item )
00826             {
00827                 cmd = new VZOrderCmd( m_document, item->object(), VZOrderCmd::up );
00828                 //newselection = item;
00829             }
00830         }
00831         if( cmd )
00832         {
00833             m_view->part()->addCommand( cmd, true );
00834             //if( newselection )
00835             //  m_layersListView->setSelected( newselection, true );
00836         }
00837     }
00838     if( cmd ) updatePreviews();
00839 } // VLayersTab::raiseItem
00840 
00841 void
00842 VLayersTab::lowerItem()
00843 {
00844     VCommand *cmd = 0L;
00845     QListViewItemIterator it( m_layersListView );
00846 
00847     for(; it.current(); ++it )
00848     {
00849         if( ! it.current()->isSelected() ) continue;
00850         
00851         VLayerListViewItem* layerItem = dynamic_cast<VLayerListViewItem *>( it.current() );
00852         if( layerItem )
00853         {
00854             VLayer *layer = layerItem->layer();
00855             if( layer && m_document->canLowerLayer( layer ) )
00856                 cmd = new VLayerCmd( m_document, i18n( "Lower Layer" ), layer, VLayerCmd::lowerLayer );
00857         }
00858         else
00859         {
00860             VObjectListViewItem* item = dynamic_cast< VObjectListViewItem *>( it.current() );
00861             if( item )
00862                 cmd = new VZOrderCmd( m_document, item->object(), VZOrderCmd::down );
00863         }
00864         if( cmd )
00865         {
00866             m_view->part()->addCommand( cmd, true );
00867         }
00868     }
00869     if( cmd ) updatePreviews();
00870 } // VLayersTab::lowerItem
00871 
00872 void
00873 VLayersTab::deleteItem()
00874 {
00875     VCommand *cmd = 0L;
00876     QListViewItemIterator it( m_layersListView );
00877 
00878     QPtrList<QListViewItem> deleteItems;
00879     deleteItems.setAutoDelete( false );
00880 
00881     // collect all selected items because they get deselected
00882     // when the first item is removed
00883     for(; it.current(); ++it )
00884     {
00885         if( ! it.current()->isSelected() ) continue;
00886             deleteItems.append( it.current() );
00887     }
00888     
00889     for( ;deleteItems.first(); )
00890     {
00891         VLayerListViewItem* layerItem = dynamic_cast< VLayerListViewItem *>( deleteItems.current() );
00892         if( layerItem )
00893         {
00894             VLayer *layer = layerItem->layer();
00895             if( layer && m_layers.count() > 1 )
00896             {
00897                 cmd = new VLayerCmd( m_document, i18n( "Delete Layer" ), layer, VLayerCmd::deleteLayer );
00898 
00899                 VObjectListIterator itr = layer->objects();
00900                 // iterate over this layers child objects and remove them from the internal 
00901                 // object list and the list of the to be deleted items
00902                 for( ; itr.current(); ++itr )
00903                 {
00904                     VObjectListViewItem *objectItem = m_objects.take( itr.current() );
00905                     deleteItems.remove( objectItem );
00906                 }
00907                 
00908                 delete layerItem;
00909 
00910                 m_view->part()->addCommand( cmd );
00911                 
00912                 selectActiveLayer();
00913             }
00914         }
00915         else
00916         {
00917             VObjectListViewItem* item = dynamic_cast< VObjectListViewItem *>( deleteItems.current() );
00918             if( item )
00919             {
00920                 cmd = new VDeleteCmd( m_document, item->object() );
00921                 
00922                 delete item;
00923 
00924                 m_view->part()->addCommand( cmd );
00925             }
00926         }
00927         // remove first item, next item becomes current
00928         deleteItems.removeFirst();
00929     }
00930     if( cmd ) 
00931     {
00932         updatePreviews();
00933         m_view->part()->repaintAllViews();
00934     }
00935 } // VLayersTab::deleteItem
00936 
00937 void
00938 VLayersTab::updatePreviews()
00939 {
00940     // TODO: Optimization: call update() on each view item...
00941     updateLayers();
00942 } // VLayersTab::updatePreviews
00943 
00944 void
00945 VLayersTab::updateLayers()
00946 {
00947     removeDeletedObjectsFromList(); 
00948 
00949     QPtrVector<VLayer> vector;
00950     m_document->layers().toVector( &vector );
00951     VLayerListViewItem* item = 0L;
00952     for( int i = vector.count() - 1; i >= 0; i-- )
00953     {
00954         if ( vector[i]->state() != VObject::deleted )
00955         {
00956             if( !m_layers[ vector[i] ] )
00957             {
00958                 item = new VLayerListViewItem( m_layersListView, vector[i], m_document, &m_layers );
00959                 item->setOpen( true );
00960             }
00961             else 
00962                 item = m_layers[ vector[i] ];
00963 
00964             item->setKey(i);
00965 
00966             updateObjects( vector[i], item );
00967         }
00968     }
00969 
00970     selectActiveLayer();
00971     m_layersListView->sort();
00972 } // VLayersTab::updateLayers
00973 
00974 void
00975 VLayersTab::updateObjects( VObject *object, QListViewItem *item )
00976 {
00977     VObjectListIterator itr = dynamic_cast<VGroup *>( object )->objects();
00978 
00979     for( uint objcount = 1; itr.current(); ++itr, objcount++ )
00980         if( itr.current()->state() != VObject::deleted )
00981         {
00982             VObjectListViewItem *objectItem = m_objects[ itr.current() ];
00983             if( ! objectItem )
00984             {
00985                 // object not found -> insert
00986                 objectItem = new VObjectListViewItem( item, itr.current(), m_document, objcount, &m_objects );
00987                 objectItem->update();
00988             }
00989             else if( objectItem->parent() != item )
00990             {
00991                 // object found, but has false parent -> reparent
00992                 objectItem->parent()->takeItem( objectItem );
00993                 item->insertItem( objectItem );
00994             }
00995 
00996             objectItem->setKey( objcount );
00997 
00998             if( dynamic_cast<VGroup *>( itr.current() ) )
00999                 updateObjects( itr.current(), objectItem );
01000         }
01001 
01002     item->sort();
01003 }
01004 
01005 void
01006 VLayersTab::removeDeletedObjectsFromList()
01007 {
01008     QPtrDictIterator<VObjectListViewItem> it( m_objects );
01009 
01010     // iterate over all object items and delete the following items:
01011     // - items representing deleted objects
01012     // - items with objects objects that changed parents
01013     // BEWARE: when deleting an item, the iterator is automatically incremented
01014     for(; it.current(); )
01015     {
01016         VLayerListViewItem *layerItem = dynamic_cast<VLayerListViewItem*>( it.current()->parent() );
01017         if( layerItem )
01018         {
01019             VGroup *group = dynamic_cast<VGroup*>( layerItem->layer() );
01020             // check if object of item is still child of object of parent item
01021             if( group && ! group->objects().contains( it.current()->object() ) )
01022             {
01023                 layerItem->takeItem( it.current() );
01024                 delete it.current();
01025                 continue;
01026             }
01027         }
01028         else
01029         {
01030             VObjectListViewItem *objectItem = dynamic_cast<VObjectListViewItem*>( it.current()->parent() );
01031             if( objectItem ) 
01032             {
01033                 VGroup *group = dynamic_cast<VGroup*>( objectItem->object() );
01034                 // check if object of item is still child of object of parent item
01035                 if( group && ! group->objects().contains( it.current()->object() ) )
01036                 {
01037                     objectItem->takeItem( it.current() );
01038                     delete it.current();
01039                     continue;
01040                 }
01041             }
01042             else
01043             {
01044                 delete it.current();
01045                 continue;
01046             }
01047         }
01048 
01049         if( it.current()->object()->state() == VObject::deleted )
01050         {
01051             delete it.current();
01052             continue;
01053         }
01054 
01055         ++it;
01056     }
01057 
01058     QPtrDictIterator<VLayerListViewItem> itr( m_layers );
01059 
01060     // iterate over all layer items and delete the following items:
01061     // - items representing deleted layers
01062     // BEWARE: when deleting an item, the iterator is automatically incremented
01063     for(; itr.current(); )
01064     {
01065         if( itr.current()->layer()->state() == VObject::deleted )
01066         {
01067             m_layersListView->takeItem( itr.current() );
01068             delete itr.current();
01069             continue;
01070         }
01071         ++itr;
01072     }
01073 }
01074 
01075 
01076 void 
01077 VLayersTab::slotCommandExecuted( VCommand* command )
01078 {
01079     // sync listview on changing layers or deleting/undeleting or grouping/ungrouping objects
01080     if( dynamic_cast<VLayerCmd*>( command ) 
01081     || dynamic_cast<VDeleteCmd*>( command ) 
01082     || dynamic_cast<VGroupCmd*>( command ) 
01083     || dynamic_cast<VUnGroupCmd*>( command ) 
01084     || dynamic_cast<VZOrderCmd*>( command ) )
01085         updateLayers();
01086 }
01087 
01088 /*************************************************************************
01089  *  History tab                                                          *
01090  *************************************************************************/
01091 
01092 VHistoryGroupItem::VHistoryGroupItem( VHistoryItem* item, QListView* parent, QListViewItem* after )
01093         : QListViewItem( parent, after )
01094 {
01095     setPixmap( 0, *item->pixmap( 0 ) );
01096     setText( 0, item->text( 0 ) );
01097     parent->takeItem( item );
01098     insertItem( item );
01099     m_key = item->key( 0, true );
01100 } // VHistoryItem::VHistoryItem
01101 
01102 VHistoryGroupItem::~VHistoryGroupItem()
01103 {
01104 } // VHistoryGroupItem::~VHistoryGroupItem
01105 
01106 void
01107 VHistoryGroupItem::paintCell( QPainter* p, const QColorGroup& cg, int column, int width, int align )
01108 {
01109     int e = 0;
01110     int n = 0;
01111     VHistoryItem* item = (VHistoryItem*)firstChild();
01112     while ( item )
01113     {
01114         if ( item->command()->success() )
01115             e++;
01116         else
01117             n++;
01118         item = (VHistoryItem*)item->nextSibling();
01119     }
01120     if ( e > 0 )
01121     {
01122         p->fillRect( 0, 0, width, height(), cg.base() );
01123         if ( n > 0 )
01124             p->fillRect( 0, 0, width, height(), QBrush( cg.base().dark( 140 ), QBrush::BDiagPattern ) );
01125     }
01126     else
01127         p->fillRect( 0, 0, width, height(), cg.base().dark( 140 ) );
01128 
01129     const QPixmap* pixmap = this->pixmap( column );
01130     int xstart;
01131     if ( pixmap )
01132     {
01133         int pw = pixmap->width();
01134         int ph = pixmap->height();
01135         p->drawPixmap( ( height() - pw ) / 2, ( height() - ph ) / 2, *pixmap );
01136         xstart = height();
01137     }
01138     else
01139         xstart = 4;
01140     p->setPen( cg.text() );
01141     p->drawText( xstart, 0, width - xstart, height(), align | Qt::AlignVCenter, text( column ) );
01142 } // VHistoryGroupItem::paintCell
01143 
01144 void
01145 VHistoryGroupItem::paintFocus( QPainter*, const QColorGroup&, const QRect& )
01146 {
01147     // Do not paint any focus rectangle
01148     // It makes the list and the selected item look messy
01149 
01150 } // VHistoryGroupItem::paintFocus
01151 
01152 VHistoryItem::VHistoryItem( VCommand* command, QListView* parent, QListViewItem* after )
01153         : QListViewItem( parent, after ), m_command( command )
01154 {
01155     init();
01156 } // VHistoryItem::VHistoryItem
01157 
01158 VHistoryItem::VHistoryItem( VCommand* command, VHistoryGroupItem* parent, QListViewItem* after )
01159         : QListViewItem( parent, after ), m_command( command )
01160 {
01161     init();
01162 } // VHistoryItem::VHistoryItem
01163 
01164 void
01165 VHistoryItem::init()
01166 {
01167     kdDebug(38000) << "In VHistoryItem::init() : " << m_command->name() << endl;
01168     char buffer[70];
01169     sprintf( buffer, "%064ld", ++g_lastKey );
01170     m_key = buffer;
01171     setPixmap( 0, QPixmap( KGlobal::iconLoader()->iconPath( m_command->icon(), KIcon::Small ) ) );
01172     setText( 0, m_command->name() );
01173 } // VHistoryITem::init
01174 
01175 VHistoryItem::~VHistoryItem()
01176 {
01177 } // VHistoryItem::~VHistoryItem
01178 
01179 void
01180 VHistoryItem::paintCell( QPainter* p, const QColorGroup& cg, int column, int width, int align )
01181 {
01182     p->fillRect( 0, 0, width, height(), ( m_command->success() ? cg.base() : cg.base().dark( 140 ) ) );
01183 
01184     const QPixmap* pixmap = this->pixmap( column );
01185     int xstart;
01186     if ( pixmap )
01187     {
01188         int pw = pixmap->width();
01189         int ph = pixmap->height();
01190         p->drawPixmap( ( height() - pw ) / 2, ( height() - ph ) / 2, *pixmap );
01191         xstart = height();
01192     }
01193     else
01194         xstart = 4;
01195     p->setPen( cg.text() );
01196     p->drawText( xstart, 0, width - xstart, height(), align | Qt::AlignVCenter, text( column ) );
01197 } // VHistoryItem::paintCell
01198 
01199 void
01200 VHistoryItem::paintFocus( QPainter*, const QColorGroup&, const QRect& )
01201 {
01202     // Do not paint any focus rectangle
01203     // It makes the list and the selected item look messy
01204 
01205 } // VHistoryItem::paintFocus
01206 
01207 VHistoryTab::VHistoryTab( KarbonPart* part, QWidget* parent )
01208         : QWidget( parent ), m_part( part )
01209 {
01210     QVBoxLayout* layout = new QVBoxLayout( this );
01211     layout->setMargin( 3 );
01212     layout->setSpacing( 2 );
01213     layout->add( m_history = new QListView( this ) );
01214     m_history->setVScrollBarMode( QListView::AlwaysOn );
01215     m_history->setSelectionMode( QListView::NoSelection );
01216     m_history->addColumn( i18n( "Commands" ) );
01217     m_history->setResizeMode( QListView::AllColumns );
01218     m_history->setRootIsDecorated( true );
01219     layout->add( m_groupCommands = new QCheckBox( i18n( "Group commands" ), this ) );
01220 
01221     m_history->setSorting( 0, true );
01222     VHistoryGroupItem* group = 0;
01223     VHistoryItem* last = 0;
01224     QPtrVector<VCommand> cmds;
01225     part->commandHistory()->commands()->toVector( &cmds );
01226     int c = cmds.count();
01227     for ( int i = 0; i < c; i++ )
01228     {
01229         if ( ( i > 0 ) && ( cmds[ i ]->name() == cmds[ i - 1 ]->name() ) )
01230             if ( group )
01231             {
01232                 QListViewItem* prev = group->firstChild();
01233                 while ( prev && prev->nextSibling() )
01234                     prev = prev->nextSibling();
01235                 new VHistoryItem( cmds[ i ], group, prev );
01236             }
01237             else
01238             {
01239                 group = new VHistoryGroupItem( last, m_history, last );
01240                 new VHistoryItem( cmds[ i ], group, last );
01241             }
01242         else
01243         {
01244             last = new VHistoryItem( cmds[ i ], m_history, last );
01245             group = 0;
01246         }
01247     }
01248     m_history->sort();
01249 
01250     connect( m_history, SIGNAL( mouseButtonClicked( int, QListViewItem*, const QPoint&, int ) ), this, SLOT( commandClicked( int, QListViewItem*, const QPoint&, int ) ) );
01251     connect( m_groupCommands, SIGNAL( stateChanged( int ) ), this, SLOT( groupingChanged( int ) ) );
01252     connect( part->commandHistory(), SIGNAL( historyCleared() ), this, SLOT( historyCleared() ) );
01253     connect( part->commandHistory(), SIGNAL( commandAdded( VCommand* ) ), this, SLOT( slotCommandAdded( VCommand* ) ) );
01254     connect( part->commandHistory(), SIGNAL( commandExecuted( VCommand* ) ), this, SLOT( commandExecuted( VCommand* ) ) );
01255     connect( part->commandHistory(), SIGNAL( firstCommandRemoved() ), this, SLOT( removeFirstCommand() ) );
01256     connect( part->commandHistory(), SIGNAL( lastCommandRemoved() ), this, SLOT( removeLastCommand() ) );
01257     connect( this, SIGNAL( undoCommand( VCommand* ) ), part->commandHistory(), SLOT( undo( VCommand* ) ) );
01258     connect( this, SIGNAL( redoCommand( VCommand* ) ), part->commandHistory(), SLOT( redo( VCommand* ) ) );
01259     connect( this, SIGNAL( undoCommandsTo( VCommand* ) ), part->commandHistory(), SLOT( undoAllTo( VCommand* ) ) );
01260     connect( this, SIGNAL( redoCommandsTo( VCommand* ) ), part->commandHistory(), SLOT( redoAllTo( VCommand* ) ) );
01261 } // VHistoryTab::VHistoryTab
01262 
01263 VHistoryTab::~VHistoryTab()
01264 {
01265 } // VHistoryTab::~VHistoryTab
01266 
01267 bool
01268 VHistoryTab::groupingEnabled()
01269 {
01270     return m_groupCommands->isChecked();
01271 } // VHistoryTab::groupingEnabled
01272 
01273 void
01274 VHistoryTab::historyCleared()
01275 {
01276     m_history->clear();
01277 } // VHistoryTab::historyCleared
01278 
01279 void
01280 VHistoryTab::commandExecuted( VCommand* command )
01281 {
01282     QListViewItem* item = m_history->firstChild();
01283     bool found = false;
01284     while ( !found && item )
01285     {
01286         if ( item->rtti() == 1001 )
01287         {
01288             QListViewItem* child = item->firstChild();
01289             while ( !found && child )
01290             {
01291                 found = ( ( (VHistoryItem*)child )->command() == command );
01292                 if ( !found )
01293                     child = child->nextSibling();
01294                 else
01295                     item = child;
01296             }
01297         }
01298         found = ( item && ( (VHistoryItem*)item )->command() == command );
01299         if ( !found )
01300             item = item->nextSibling();
01301     }
01302     if ( found )
01303     {
01304         m_history->repaintItem( item );
01305         if ( item->parent() )
01306             m_history->repaintItem( item->parent() );
01307         m_history->ensureItemVisible( item );
01308     }
01309 } // VHistoryTab::commandExecuted
01310 
01311 void
01312 VHistoryTab::slotCommandAdded( VCommand* command )
01313 {
01314     if ( !command )
01315         return;
01316 
01317     QListViewItem* last = m_history->firstChild();
01318     while ( last && last->nextSibling() )
01319         last = last->nextSibling();
01320 
01321     if( groupingEnabled() )
01322     {
01323         if( ( last ) && last->text( 0 ) == command->name() )
01324         {
01325             if( last->rtti() == 1002 )
01326             {
01327                 QListViewItem* prevSibling;
01328                 if( m_history->childCount() > 1 )
01329                 {
01330                     prevSibling = m_history->firstChild();
01331                     while ( prevSibling->nextSibling() != last )
01332                         prevSibling = prevSibling->nextSibling();
01333                 }
01334                 else
01335                     prevSibling = m_history->firstChild();
01336                 last = new VHistoryGroupItem( (VHistoryItem*)last, m_history, prevSibling );
01337             }
01338             QListViewItem* prev = last->firstChild();
01339             while ( prev && prev->nextSibling() )
01340                 prev = prev->nextSibling();
01341             m_history->setCurrentItem( new VHistoryItem( command, (VHistoryGroupItem*)last, prev ) );
01342         }
01343         else
01344             m_history->setCurrentItem( new VHistoryItem( command, m_history, last ) );
01345     }
01346     else
01347         m_history->setCurrentItem( new VHistoryItem( command, m_history, last ) );
01348 
01349     m_history->sort();
01350     m_history->ensureItemVisible( m_history->currentItem() );
01351     m_history->update();
01352 } // VHistoryTab::slotCommandAdded
01353 
01354 void
01355 VHistoryTab::removeFirstCommand()
01356 {
01357     if ( m_history->childCount() > 0 )
01358         if ( m_history->firstChild()->rtti() == 1002 )
01359             delete m_history->firstChild();
01360         else
01361         {
01362             VHistoryGroupItem* group = (VHistoryGroupItem*)m_history->firstChild();
01363             delete group->firstChild();
01364             if ( group->childCount() == 1 )
01365             {
01366                 new VHistoryItem( ( (VHistoryItem*)group->firstChild() )->command(), m_history, 0 );
01367                 delete group;
01368             }
01369         }
01370 } // VHistoryTab::removeFirstCommand
01371 
01372 void
01373 VHistoryTab::removeLastCommand()
01374 {
01375     if ( m_history->childCount() > 0 )
01376     {
01377         QListViewItem* last = m_history->firstChild();
01378         while ( last && last->nextSibling() )
01379             last = last->nextSibling();
01380         if ( last->rtti() == 1002 )
01381             delete last;
01382         else
01383         {
01384             VHistoryGroupItem* group = (VHistoryGroupItem*)last;
01385             last = group->firstChild();
01386             while ( last && last->nextSibling() )
01387                 last = last->nextSibling();
01388             delete last;
01389             if ( group->childCount() == 1 )
01390             {
01391                 new VHistoryItem( ( (VHistoryItem*)group->firstChild() )->command(), m_history, group );
01392                 delete group;
01393             }
01394         }
01395     }
01396 } // VHistoryTab::removeLastCommand
01397 
01398 void
01399 VHistoryTab::commandClicked( int button, QListViewItem* item, const QPoint&, int )
01400 {
01401     if ( !item || item->rtti() == 1001 )
01402         return;
01403 
01404     VCommand* cmd = ( (VHistoryItem*)item )->command();
01405     if ( cmd->success() )
01406         if ( button == 1 )
01407             emit undoCommandsTo( ( (VHistoryItem*)item )->command() );
01408         else
01409             emit undoCommand( ( (VHistoryItem*)item )->command() );
01410     else
01411         if ( button == 1 )
01412             emit redoCommandsTo( ( (VHistoryItem*)item )->command() );
01413         else
01414             emit redoCommand( ( (VHistoryItem*)item )->command() );
01415 } // VHistoryTab::commandClicked
01416 
01417 void
01418 VHistoryTab::groupingChanged( int )
01419 {
01420     if ( m_groupCommands->isChecked() && m_history->childCount() > 1 )
01421     {
01422         QListViewItem* s2last = 0;
01423         QListViewItem* last = m_history->firstChild();
01424         QListViewItem* item = last->nextSibling();
01425         while ( item )
01426             if ( last->text( 0 ) == item->text( 0 ) )
01427             {
01428                 if ( last->rtti() == 1002 )
01429                     last = new VHistoryGroupItem( (VHistoryItem*)last, m_history, s2last );
01430                 m_history->takeItem( item );
01431                 last->insertItem( item );
01432                 item = last->nextSibling();
01433             }
01434             else
01435             {
01436                 s2last = last;
01437                 last = item;
01438                 item = last->nextSibling();
01439             }
01440     }
01441     else
01442     {
01443         QListViewItem* item = m_history->firstChild();
01444         while ( item )
01445             if ( item->rtti() == 1001 )
01446             {
01447                 QListViewItem* child;
01448                 while ( ( child = item->firstChild() ) )
01449                 {
01450                     item->takeItem( child );
01451                     m_history->insertItem( child );
01452                 }
01453                 child = item;
01454                 item = item->nextSibling();
01455                 delete child;
01456             }
01457             else
01458                 item = item->nextSibling();
01459     }
01460     m_history->sort();
01461     m_history->update();
01462 } // VHistoryTab::groupingChanged
01463 
01464 #include "vdocumentdocker.moc"
KDE Home | KDE Accessibility Home | Description of Access Keys