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( "document width", "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     if( m_document->selection()->objects().count() )
00808     {
00809         cmd = new VZOrderCmd( m_document, VZOrderCmd::up );
00810         m_view->part()->addCommand( cmd, true );
00811     }
00812     else
00813     {
00814         for(; it.current(); ++it )
00815         {
00816             if( ! it.current()->isSelected() ) continue;
00817     
00818             VLayerListViewItem* layerItem = dynamic_cast<VLayerListViewItem *>( it.current() );
00819             if( layerItem )
00820             {
00821                 VLayer *layer = layerItem->layer();
00822                 if( layer && m_document->canRaiseLayer( layer ) )
00823                 {
00824                     cmd = new VLayerCmd( m_document, i18n( "Raise Layer" ),
00825                                     layerItem->layer(), VLayerCmd::raiseLayer );
00826                     m_view->part()->addCommand( cmd, true );
00827                 }
00828             }
00829         }
00830     }
00831 
00832     if( cmd ) updatePreviews();
00833 } // VLayersTab::raiseItem
00834 
00835 void
00836 VLayersTab::lowerItem()
00837 {
00838     VCommand *cmd = 0L;
00839     QListViewItemIterator it( m_layersListView );
00840 
00841     if( m_document->selection()->objects().count() )
00842     {
00843         cmd = new VZOrderCmd( m_document, VZOrderCmd::down );
00844         m_view->part()->addCommand( cmd, true );
00845     }
00846     else
00847     {
00848         for(; it.current(); ++it )
00849         {
00850             if( ! it.current()->isSelected() ) continue;
00851             
00852             VLayerListViewItem* layerItem = dynamic_cast<VLayerListViewItem *>( it.current() );
00853             if( layerItem )
00854             {
00855                 VLayer *layer = layerItem->layer();
00856                 if( layer && m_document->canLowerLayer( layer ) )
00857                 {
00858                     cmd = new VLayerCmd( m_document, i18n( "Lower Layer" ), layer, VLayerCmd::lowerLayer );
00859                     m_view->part()->addCommand( cmd, true );
00860                 }
00861             }
00862         }
00863     }
00864 
00865     if( cmd ) updatePreviews();
00866 } // VLayersTab::lowerItem
00867 
00868 void
00869 VLayersTab::deleteItem()
00870 {
00871     VCommand *cmd = 0L;
00872     QListViewItemIterator it( m_layersListView );
00873 
00874     QPtrList<QListViewItem> deleteItems;
00875     deleteItems.setAutoDelete( false );
00876 
00877     // collect all selected items because they get deselected
00878     // when the first item is removed
00879     for(; it.current(); ++it )
00880     {
00881         if( ! it.current()->isSelected() ) continue;
00882             deleteItems.append( it.current() );
00883     }
00884     
00885     for( ;deleteItems.first(); )
00886     {
00887         VLayerListViewItem* layerItem = dynamic_cast< VLayerListViewItem *>( deleteItems.current() );
00888         if( layerItem )
00889         {
00890             VLayer *layer = layerItem->layer();
00891             if( layer && m_layers.count() > 1 )
00892             {
00893                 cmd = new VLayerCmd( m_document, i18n( "Delete Layer" ), layer, VLayerCmd::deleteLayer );
00894 
00895                 VObjectListIterator itr = layer->objects();
00896                 // iterate over this layers child objects and remove them from the internal 
00897                 // object list and the list of the to be deleted items
00898                 for( ; itr.current(); ++itr )
00899                 {
00900                     VObjectListViewItem *objectItem = m_objects.take( itr.current() );
00901                     deleteItems.remove( objectItem );
00902                 }
00903                 
00904                 delete layerItem;
00905 
00906                 m_view->part()->addCommand( cmd );
00907                 
00908                 selectActiveLayer();
00909             }
00910         }
00911         else
00912         {
00913             VObjectListViewItem* item = dynamic_cast< VObjectListViewItem *>( deleteItems.current() );
00914             if( item )
00915             {
00916                 cmd = new VDeleteCmd( m_document, item->object() );
00917                 
00918                 delete item;
00919 
00920                 m_view->part()->addCommand( cmd );
00921             }
00922         }
00923         // remove first item, next item becomes current
00924         deleteItems.removeFirst();
00925     }
00926     if( cmd ) 
00927     {
00928         updatePreviews();
00929         m_view->part()->repaintAllViews();
00930     }
00931 } // VLayersTab::deleteItem
00932 
00933 void
00934 VLayersTab::updatePreviews()
00935 {
00936     // TODO: Optimization: call update() on each view item...
00937     updateLayers();
00938 } // VLayersTab::updatePreviews
00939 
00940 void
00941 VLayersTab::updateLayers()
00942 {
00943     removeDeletedObjectsFromList(); 
00944 
00945     QPtrVector<VLayer> vector;
00946     m_document->layers().toVector( &vector );
00947     VLayerListViewItem* item = 0L;
00948     for( int i = vector.count() - 1; i >= 0; i-- )
00949     {
00950         if ( vector[i]->state() != VObject::deleted )
00951         {
00952             if( !m_layers[ vector[i] ] )
00953             {
00954                 item = new VLayerListViewItem( m_layersListView, vector[i], m_document, &m_layers );
00955                 item->setOpen( true );
00956             }
00957             else 
00958                 item = m_layers[ vector[i] ];
00959 
00960             item->setKey(i);
00961 
00962             updateObjects( vector[i], item );
00963         }
00964     }
00965 
00966     selectActiveLayer();
00967     m_layersListView->sort();
00968 } // VLayersTab::updateLayers
00969 
00970 void
00971 VLayersTab::updateObjects( VObject *object, QListViewItem *item )
00972 {
00973     VObjectListIterator itr = dynamic_cast<VGroup *>( object )->objects();
00974 
00975     for( uint objcount = 1; itr.current(); ++itr, objcount++ )
00976         if( itr.current()->state() != VObject::deleted )
00977         {
00978             VObjectListViewItem *objectItem = m_objects[ itr.current() ];
00979             if( ! objectItem )
00980             {
00981                 // object not found -> insert
00982                 objectItem = new VObjectListViewItem( item, itr.current(), m_document, objcount, &m_objects );
00983                 objectItem->update();
00984             }
00985             else if( objectItem->parent() != item )
00986             {
00987                 // object found, but has false parent -> reparent
00988                 objectItem->parent()->takeItem( objectItem );
00989                 item->insertItem( objectItem );
00990             }
00991 
00992             objectItem->setKey( objcount );
00993 
00994             if( dynamic_cast<VGroup *>( itr.current() ) )
00995                 updateObjects( itr.current(), objectItem );
00996         }
00997 
00998     item->sort();
00999 }
01000 
01001 void
01002 VLayersTab::removeDeletedObjectsFromList()
01003 {
01004     QPtrDictIterator<VObjectListViewItem> it( m_objects );
01005 
01006     // iterate over all object items and delete the following items:
01007     // - items representing deleted objects
01008     // - items with objects objects that changed parents
01009     // BEWARE: when deleting an item, the iterator is automatically incremented
01010     for(; it.current(); )
01011     {
01012         VLayerListViewItem *layerItem = dynamic_cast<VLayerListViewItem*>( it.current()->parent() );
01013         if( layerItem )
01014         {
01015             VGroup *group = dynamic_cast<VGroup*>( layerItem->layer() );
01016             // check if object of item is still child of object of parent item
01017             if( group && ! group->objects().contains( it.current()->object() ) )
01018             {
01019                 layerItem->takeItem( it.current() );
01020                 delete it.current();
01021                 continue;
01022             }
01023         }
01024         else
01025         {
01026             VObjectListViewItem *objectItem = dynamic_cast<VObjectListViewItem*>( it.current()->parent() );
01027             if( objectItem ) 
01028             {
01029                 VGroup *group = dynamic_cast<VGroup*>( objectItem->object() );
01030                 // check if object of item is still child of object of parent item
01031                 if( group && ! group->objects().contains( it.current()->object() ) )
01032                 {
01033                     objectItem->takeItem( it.current() );
01034                     delete it.current();
01035                     continue;
01036                 }
01037             }
01038             else
01039             {
01040                 delete it.current();
01041                 continue;
01042             }
01043         }
01044 
01045         if( it.current()->object()->state() == VObject::deleted )
01046         {
01047             delete it.current();
01048             continue;
01049         }
01050 
01051         ++it;
01052     }
01053 
01054     QPtrDictIterator<VLayerListViewItem> itr( m_layers );
01055 
01056     // iterate over all layer items and delete the following items:
01057     // - items representing deleted layers
01058     // BEWARE: when deleting an item, the iterator is automatically incremented
01059     for(; itr.current(); )
01060     {
01061         if( itr.current()->layer()->state() == VObject::deleted )
01062         {
01063             m_layersListView->takeItem( itr.current() );
01064             delete itr.current();
01065             continue;
01066         }
01067         ++itr;
01068     }
01069 }
01070 
01071 
01072 void 
01073 VLayersTab::slotCommandExecuted( VCommand* command )
01074 {
01075     // sync listview on changing layers or deleting/undeleting or grouping/ungrouping objects
01076     if( dynamic_cast<VLayerCmd*>( command ) 
01077     || dynamic_cast<VDeleteCmd*>( command ) 
01078     || dynamic_cast<VGroupCmd*>( command ) 
01079     || dynamic_cast<VUnGroupCmd*>( command ) 
01080     || dynamic_cast<VZOrderCmd*>( command ) )
01081         updateLayers();
01082 }
01083 
01084 /*************************************************************************
01085  *  History tab                                                          *
01086  *************************************************************************/
01087 
01088 VHistoryGroupItem::VHistoryGroupItem( VHistoryItem* item, QListView* parent, QListViewItem* after )
01089         : QListViewItem( parent, after )
01090 {
01091     setPixmap( 0, *item->pixmap( 0 ) );
01092     setText( 0, item->text( 0 ) );
01093     parent->takeItem( item );
01094     insertItem( item );
01095     m_key = item->key( 0, true );
01096 } // VHistoryItem::VHistoryItem
01097 
01098 VHistoryGroupItem::~VHistoryGroupItem()
01099 {
01100 } // VHistoryGroupItem::~VHistoryGroupItem
01101 
01102 void
01103 VHistoryGroupItem::paintCell( QPainter* p, const QColorGroup& cg, int column, int width, int align )
01104 {
01105     int e = 0;
01106     int n = 0;
01107     VHistoryItem* item = (VHistoryItem*)firstChild();
01108     while ( item )
01109     {
01110         if ( item->command()->success() )
01111             e++;
01112         else
01113             n++;
01114         item = (VHistoryItem*)item->nextSibling();
01115     }
01116     if ( e > 0 )
01117     {
01118         p->fillRect( 0, 0, width, height(), cg.base() );
01119         if ( n > 0 )
01120             p->fillRect( 0, 0, width, height(), QBrush( cg.base().dark( 140 ), QBrush::BDiagPattern ) );
01121     }
01122     else
01123         p->fillRect( 0, 0, width, height(), cg.base().dark( 140 ) );
01124 
01125     const QPixmap* pixmap = this->pixmap( column );
01126     int xstart;
01127     if ( pixmap )
01128     {
01129         int pw = pixmap->width();
01130         int ph = pixmap->height();
01131         p->drawPixmap( ( height() - pw ) / 2, ( height() - ph ) / 2, *pixmap );
01132         xstart = height();
01133     }
01134     else
01135         xstart = 4;
01136     p->setPen( cg.text() );
01137     p->drawText( xstart, 0, width - xstart, height(), align | Qt::AlignVCenter, text( column ) );
01138 } // VHistoryGroupItem::paintCell
01139 
01140 void
01141 VHistoryGroupItem::paintFocus( QPainter*, const QColorGroup&, const QRect& )
01142 {
01143     // Do not paint any focus rectangle
01144     // It makes the list and the selected item look messy
01145 
01146 } // VHistoryGroupItem::paintFocus
01147 
01148 VHistoryItem::VHistoryItem( VCommand* command, QListView* parent, QListViewItem* after )
01149         : QListViewItem( parent, after ), m_command( command )
01150 {
01151     init();
01152 } // VHistoryItem::VHistoryItem
01153 
01154 VHistoryItem::VHistoryItem( VCommand* command, VHistoryGroupItem* parent, QListViewItem* after )
01155         : QListViewItem( parent, after ), m_command( command )
01156 {
01157     init();
01158 } // VHistoryItem::VHistoryItem
01159 
01160 void
01161 VHistoryItem::init()
01162 {
01163     kdDebug(38000) << "In VHistoryItem::init() : " << m_command->name() << endl;
01164     char buffer[70];
01165     sprintf( buffer, "%064ld", ++g_lastKey );
01166     m_key = buffer;
01167     setPixmap( 0, QPixmap( KGlobal::iconLoader()->iconPath( m_command->icon(), KIcon::Small ) ) );
01168     setText( 0, m_command->name() );
01169 } // VHistoryITem::init
01170 
01171 VHistoryItem::~VHistoryItem()
01172 {
01173 } // VHistoryItem::~VHistoryItem
01174 
01175 void
01176 VHistoryItem::paintCell( QPainter* p, const QColorGroup& cg, int column, int width, int align )
01177 {
01178     p->fillRect( 0, 0, width, height(), ( m_command->success() ? cg.base() : cg.base().dark( 140 ) ) );
01179 
01180     const QPixmap* pixmap = this->pixmap( column );
01181     int xstart;
01182     if ( pixmap )
01183     {
01184         int pw = pixmap->width();
01185         int ph = pixmap->height();
01186         p->drawPixmap( ( height() - pw ) / 2, ( height() - ph ) / 2, *pixmap );
01187         xstart = height();
01188     }
01189     else
01190         xstart = 4;
01191     p->setPen( cg.text() );
01192     p->drawText( xstart, 0, width - xstart, height(), align | Qt::AlignVCenter, text( column ) );
01193 } // VHistoryItem::paintCell
01194 
01195 void
01196 VHistoryItem::paintFocus( QPainter*, const QColorGroup&, const QRect& )
01197 {
01198     // Do not paint any focus rectangle
01199     // It makes the list and the selected item look messy
01200 
01201 } // VHistoryItem::paintFocus
01202 
01203 VHistoryTab::VHistoryTab( KarbonPart* part, QWidget* parent )
01204         : QWidget( parent ), m_part( part )
01205 {
01206     QVBoxLayout* layout = new QVBoxLayout( this );
01207     layout->setMargin( 3 );
01208     layout->setSpacing( 2 );
01209     layout->add( m_history = new QListView( this ) );
01210     m_history->setVScrollBarMode( QListView::AlwaysOn );
01211     m_history->setSelectionMode( QListView::NoSelection );
01212     m_history->addColumn( i18n( "Commands" ) );
01213     m_history->setResizeMode( QListView::AllColumns );
01214     m_history->setRootIsDecorated( true );
01215     layout->add( m_groupCommands = new QCheckBox( i18n( "Group commands" ), this ) );
01216 
01217     m_history->setSorting( 0, true );
01218     VHistoryGroupItem* group = 0;
01219     VHistoryItem* last = 0;
01220     QPtrVector<VCommand> cmds;
01221     part->commandHistory()->commands()->toVector( &cmds );
01222     int c = cmds.count();
01223     for ( int i = 0; i < c; i++ )
01224     {
01225         if ( ( i > 0 ) && ( cmds[ i ]->name() == cmds[ i - 1 ]->name() ) )
01226             if ( group )
01227             {
01228                 QListViewItem* prev = group->firstChild();
01229                 while ( prev && prev->nextSibling() )
01230                     prev = prev->nextSibling();
01231                 new VHistoryItem( cmds[ i ], group, prev );
01232             }
01233             else
01234             {
01235                 group = new VHistoryGroupItem( last, m_history, last );
01236                 new VHistoryItem( cmds[ i ], group, last );
01237             }
01238         else
01239         {
01240             last = new VHistoryItem( cmds[ i ], m_history, last );
01241             group = 0;
01242         }
01243     }
01244     m_history->sort();
01245 
01246     connect( m_history, SIGNAL( mouseButtonClicked( int, QListViewItem*, const QPoint&, int ) ), this, SLOT( commandClicked( int, QListViewItem*, const QPoint&, int ) ) );
01247     connect( m_groupCommands, SIGNAL( stateChanged( int ) ), this, SLOT( groupingChanged( int ) ) );
01248     connect( part->commandHistory(), SIGNAL( historyCleared() ), this, SLOT( historyCleared() ) );
01249     connect( part->commandHistory(), SIGNAL( commandAdded( VCommand* ) ), this, SLOT( slotCommandAdded( VCommand* ) ) );
01250     connect( part->commandHistory(), SIGNAL( commandExecuted( VCommand* ) ), this, SLOT( commandExecuted( VCommand* ) ) );
01251     connect( part->commandHistory(), SIGNAL( firstCommandRemoved() ), this, SLOT( removeFirstCommand() ) );
01252     connect( part->commandHistory(), SIGNAL( lastCommandRemoved() ), this, SLOT( removeLastCommand() ) );
01253     connect( this, SIGNAL( undoCommand( VCommand* ) ), part->commandHistory(), SLOT( undo( VCommand* ) ) );
01254     connect( this, SIGNAL( redoCommand( VCommand* ) ), part->commandHistory(), SLOT( redo( VCommand* ) ) );
01255     connect( this, SIGNAL( undoCommandsTo( VCommand* ) ), part->commandHistory(), SLOT( undoAllTo( VCommand* ) ) );
01256     connect( this, SIGNAL( redoCommandsTo( VCommand* ) ), part->commandHistory(), SLOT( redoAllTo( VCommand* ) ) );
01257 } // VHistoryTab::VHistoryTab
01258 
01259 VHistoryTab::~VHistoryTab()
01260 {
01261 } // VHistoryTab::~VHistoryTab
01262 
01263 bool
01264 VHistoryTab::groupingEnabled()
01265 {
01266     return m_groupCommands->isChecked();
01267 } // VHistoryTab::groupingEnabled
01268 
01269 void
01270 VHistoryTab::historyCleared()
01271 {
01272     m_history->clear();
01273 } // VHistoryTab::historyCleared
01274 
01275 void
01276 VHistoryTab::commandExecuted( VCommand* command )
01277 {
01278     QListViewItem* item = m_history->firstChild();
01279     bool found = false;
01280     while ( !found && item )
01281     {
01282         if ( item->rtti() == 1001 )
01283         {
01284             QListViewItem* child = item->firstChild();
01285             while ( !found && child )
01286             {
01287                 found = ( ( (VHistoryItem*)child )->command() == command );
01288                 if ( !found )
01289                     child = child->nextSibling();
01290                 else
01291                     item = child;
01292             }
01293         }
01294         found = ( item && ( (VHistoryItem*)item )->command() == command );
01295         if ( !found )
01296             item = item->nextSibling();
01297     }
01298     if ( found )
01299     {
01300         m_history->repaintItem( item );
01301         if ( item->parent() )
01302             m_history->repaintItem( item->parent() );
01303         m_history->ensureItemVisible( item );
01304     }
01305 } // VHistoryTab::commandExecuted
01306 
01307 void
01308 VHistoryTab::slotCommandAdded( VCommand* command )
01309 {
01310     if ( !command )
01311         return;
01312 
01313     QListViewItem* last = m_history->firstChild();
01314     while ( last && last->nextSibling() )
01315         last = last->nextSibling();
01316 
01317     if( groupingEnabled() )
01318     {
01319         if( ( last ) && last->text( 0 ) == command->name() )
01320         {
01321             if( last->rtti() == 1002 )
01322             {
01323                 QListViewItem* prevSibling;
01324                 if( m_history->childCount() > 1 )
01325                 {
01326                     prevSibling = m_history->firstChild();
01327                     while ( prevSibling->nextSibling() != last )
01328                         prevSibling = prevSibling->nextSibling();
01329                 }
01330                 else
01331                     prevSibling = m_history->firstChild();
01332                 last = new VHistoryGroupItem( (VHistoryItem*)last, m_history, prevSibling );
01333             }
01334             QListViewItem* prev = last->firstChild();
01335             while ( prev && prev->nextSibling() )
01336                 prev = prev->nextSibling();
01337             m_history->setCurrentItem( new VHistoryItem( command, (VHistoryGroupItem*)last, prev ) );
01338         }
01339         else
01340             m_history->setCurrentItem( new VHistoryItem( command, m_history, last ) );
01341     }
01342     else
01343         m_history->setCurrentItem( new VHistoryItem( command, m_history, last ) );
01344 
01345     m_history->sort();
01346     m_history->ensureItemVisible( m_history->currentItem() );
01347     m_history->update();
01348 } // VHistoryTab::slotCommandAdded
01349 
01350 void
01351 VHistoryTab::removeFirstCommand()
01352 {
01353     if ( m_history->childCount() > 0 )
01354         if ( m_history->firstChild()->rtti() == 1002 )
01355             delete m_history->firstChild();
01356         else
01357         {
01358             VHistoryGroupItem* group = (VHistoryGroupItem*)m_history->firstChild();
01359             delete group->firstChild();
01360             if ( group->childCount() == 1 )
01361             {
01362                 new VHistoryItem( ( (VHistoryItem*)group->firstChild() )->command(), m_history, 0 );
01363                 delete group;
01364             }
01365         }
01366 } // VHistoryTab::removeFirstCommand
01367 
01368 void
01369 VHistoryTab::removeLastCommand()
01370 {
01371     if ( m_history->childCount() > 0 )
01372     {
01373         QListViewItem* last = m_history->firstChild();
01374         while ( last && last->nextSibling() )
01375             last = last->nextSibling();
01376         if ( last->rtti() == 1002 )
01377             delete last;
01378         else
01379         {
01380             VHistoryGroupItem* group = (VHistoryGroupItem*)last;
01381             last = group->firstChild();
01382             while ( last && last->nextSibling() )
01383                 last = last->nextSibling();
01384             delete last;
01385             if ( group->childCount() == 1 )
01386             {
01387                 new VHistoryItem( ( (VHistoryItem*)group->firstChild() )->command(), m_history, group );
01388                 delete group;
01389             }
01390         }
01391     }
01392 } // VHistoryTab::removeLastCommand
01393 
01394 void
01395 VHistoryTab::commandClicked( int button, QListViewItem* item, const QPoint&, int )
01396 {
01397     if ( !item || item->rtti() == 1001 )
01398         return;
01399 
01400     VCommand* cmd = ( (VHistoryItem*)item )->command();
01401     if ( cmd->success() )
01402         if ( button == 1 )
01403             emit undoCommandsTo( ( (VHistoryItem*)item )->command() );
01404         else
01405             emit undoCommand( ( (VHistoryItem*)item )->command() );
01406     else
01407         if ( button == 1 )
01408             emit redoCommandsTo( ( (VHistoryItem*)item )->command() );
01409         else
01410             emit redoCommand( ( (VHistoryItem*)item )->command() );
01411 } // VHistoryTab::commandClicked
01412 
01413 void
01414 VHistoryTab::groupingChanged( int )
01415 {
01416     if ( m_groupCommands->isChecked() && m_history->childCount() > 1 )
01417     {
01418         QListViewItem* s2last = 0;
01419         QListViewItem* last = m_history->firstChild();
01420         QListViewItem* item = last->nextSibling();
01421         while ( item )
01422             if ( last->text( 0 ) == item->text( 0 ) )
01423             {
01424                 if ( last->rtti() == 1002 )
01425                     last = new VHistoryGroupItem( (VHistoryItem*)last, m_history, s2last );
01426                 m_history->takeItem( item );
01427                 last->insertItem( item );
01428                 item = last->nextSibling();
01429             }
01430             else
01431             {
01432                 s2last = last;
01433                 last = item;
01434                 item = last->nextSibling();
01435             }
01436     }
01437     else
01438     {
01439         QListViewItem* item = m_history->firstChild();
01440         while ( item )
01441             if ( item->rtti() == 1001 )
01442             {
01443                 QListViewItem* child;
01444                 while ( ( child = item->firstChild() ) )
01445                 {
01446                     item->takeItem( child );
01447                     m_history->insertItem( child );
01448                 }
01449                 child = item;
01450                 item = item->nextSibling();
01451                 delete child;
01452             }
01453             else
01454                 item = item->nextSibling();
01455     }
01456     m_history->sort();
01457     m_history->update();
01458 } // VHistoryTab::groupingChanged
01459 
01460 #include "vdocumentdocker.moc"
KDE Home | KDE Accessibility Home | Description of Access Keys