// -*- Mode: c++; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 4; -*- /* This file is part of the KDE project Copyright (C) 1998, 1999 Reginald Stadlbauer Copyright (C) 2001 Lukas Tinkl Copyright (C) 2002 Ariya Hidayat Copyright (C) 2005 Laurent Montel Copyright (C) 2005 Thorsten Zachmann This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include "KPrSideBar.h" #include "KPrView.h" #include "KPrDocument.h" #include "KPrCanvas.h" #include "KPrPage.h" #include "KPrObject.h" #include #include "KPrCommand.h" #include #include "KPrFreehandObject.h" #include "KPrBezierCurveObject.h" #include "KPrTextObject.h" #include "KPrPolylineObject.h" #include "KPrClosedLineObject.h" #include "KPrGroupObject.h" TQValidator::State KPrRenamePageValidator::validate( TQString & input, int& ) const { TQString str = input.stripWhiteSpace(); if ( str.isEmpty() ) // we want to allow empty titles. Empty == automatic. return Acceptable; if ( mStringList.find( str ) == mStringList.end() ) return Acceptable; else return Intermediate; } class ThumbToolTip : public TQToolTip { public: ThumbToolTip( KPrThumbBar *parent ) : TQToolTip( parent->viewport() ) , m_thumbBar( parent ) {} protected: void maybeTip(const TQPoint &pos) { TQString title; TQRect r( m_thumbBar->tip( pos, title ) ); if (!r.isValid()) return; tip(r, title); } private: KPrThumbBar *m_thumbBar; }; class OutlineSlideItem: public KListViewItem { public: OutlineSlideItem( KListView * parent, KPrPage* page, bool _masterPage ); OutlineSlideItem( KListView * parent, OutlineSlideItem *after, KPrPage* page, bool _masterPage ); KPrPage* page() const { return m_page; } void setPage( KPrPage* p ); void update(); void updateTitle(); private: KPrPage* m_page; bool m_masterPage; }; class OutlineObjectItem: public KListViewItem { public: OutlineObjectItem( OutlineSlideItem * parent, KPrObject* object, const TQString& name = TQString() ); KPrObject* object() const { return m_object; } void setObject( KPrObject* o ); private: KPrObject* m_object; }; class ThumbItem : public TQIconViewItem { public: ThumbItem( TQIconView *parent, const TQString & text, const TQPixmap & icon ) : TQIconViewItem( parent, text, icon ) { uptodate = true; } ThumbItem( TQIconView *parent, TQIconViewItem *after, const TQString & text, const TQPixmap & icon ) : TQIconViewItem( parent, after, text, icon ) { uptodate = true; } virtual bool isUptodate() { return uptodate; }; virtual void setUptodate( bool _uptodate) { uptodate = _uptodate; }; private: bool uptodate; }; KPrSideBar::KPrSideBar(TQWidget *parent, KPrDocument *d, KPrView *v) :TQTabWidget(parent), m_doc(d), m_view(v) { setTabPosition(TQTabWidget::Top); setTabShape(TQTabWidget::Triangular); m_outline = new KPrOutline(this, m_doc, m_view); addTab(m_outline, i18n("Structure of the presentation", "Outline")); m_thb = new KPrThumbBar(this, m_doc, m_view); addTab(m_thb,i18n("Preview")); //TODO find a better way connect(m_outline, TQT_SIGNAL(showPage(int)), this, TQT_SIGNAL(showPage(int))); connect(m_thb, TQT_SIGNAL(showPage(int)), this, TQT_SIGNAL(showPage(int))); connect(m_outline, TQT_SIGNAL(movePage(int,int)), this, TQT_SIGNAL(movePage(int,int))); connect(m_outline, TQT_SIGNAL(selectPage(int,bool)), this, TQT_SIGNAL(selectPage(int,bool))); connect(this, TQT_SIGNAL(currentChanged(TQWidget *)), this, TQT_SLOT(currentChanged(TQWidget *))); } void KPrSideBar::currentChanged(TQWidget *tab) { if (tab == m_thb) { if (!m_thb->uptodate && m_thb->isVisible()) m_thb->rebuildItems(); else m_thb->refreshItems(); } } void KPrSideBar::addItem( int pos ) { m_outline->addItem( pos ); m_thb->addItem( pos ); } void KPrSideBar::moveItem( int oldPos, int newPos ) { m_outline->moveItem( oldPos, newPos ); m_thb->moveItem( oldPos, newPos ); } void KPrSideBar::removeItem( int pos ) { m_outline->removeItem( pos ); m_thb->removeItem( pos ); } void KPrSideBar::updateItem( KPrPage *page ) { bool sticky = false; int pos = 0; if ( page == m_doc->masterPage() ) { pos = -1; sticky = true; } else { pos = m_doc->pageList().findRef( page ); } m_outline->updateItem( pos, sticky ); m_thb->updateItem( pos, sticky ); } void KPrSideBar::setViewMasterPage( bool _masterPage ) { m_outline->setViewMasterPage( _masterPage ); m_thb->setViewMasterPage( _masterPage ); m_outline->rebuildItems(); m_thb->rebuildItems(); } KPrSideBarBase::KPrSideBarBase(KPrDocument *_doc, KPrView *_view) : m_doc( _doc ), m_view( _view ), m_viewMasterPage( false ) { } void KPrSideBarBase::setViewMasterPage( bool _b ) { m_viewMasterPage = _b; } KPrThumbBar::KPrThumbBar(TQWidget *parent, KPrDocument *d, KPrView *v) :KIconView(parent), KPrSideBarBase( d,v) { uptodate = false; m_offsetX = 0; m_offsetY = 0; setArrangement(TQIconView::LeftToRight); setAutoArrange(true); setSorting(false); setItemsMovable(false); setResizeMode(TQIconView::Adjust); m_thumbTip = new ThumbToolTip(this); connect(this, TQT_SIGNAL(currentChanged(TQIconViewItem *)), this, TQT_SLOT(itemClicked(TQIconViewItem *))); connect(this, TQT_SIGNAL(contentsMoving(int, int)), this, TQT_SLOT(slotContentsMoving(int, int))); } KPrThumbBar::~KPrThumbBar() { delete m_thumbTip; } void KPrThumbBar::setCurrentPage( int pg ) { for ( TQIconViewItem *it = firstItem(); it; it = it->nextItem() ) { if ( it->text().toInt() - 1 == pg ) { blockSignals( true ); setCurrentItem( it ); setSelected( it, FALSE ); // to avoid the blue "selected"-mark ensureItemVisible(it); refreshItems(); blockSignals( false ); return; } } } TQRect KPrThumbBar::tip(const TQPoint &pos, TQString &title) { TQIconViewItem *item = findItem(viewportToContents(pos)); if (!item) return TQRect(0, 0, -1, -1); int pagenr = item->index(); title = m_doc->pageList().at(pagenr)->pageTitle(); TQRect r = item->pixmapRect(FALSE); r = TQRect(contentsToViewport(TQPoint(r.x(), r.y())), TQSize(r.width(), r.height())); return r; } void KPrThumbBar::rebuildItems() { kdDebug()<<" void KPrThumbBar::rebuildItems() beofre \n"; if( !isVisible()) return; kdDebug(33001) << "KPrThumbBar::rebuildItems" << endl; TQApplication::setOverrideCursor( TQt::waitCursor ); clear(); if ( m_viewMasterPage ) { } else { for ( unsigned int i = 0; i < m_doc->getPageNums(); i++ ) { // calculate the size of the thumb TQRect rect = m_doc->pageList().at(i)->getZoomPageRect( ); int w = rect.width(); int h = rect.height(); if ( w > h ) { w = 130; float diff = (float)rect.width() / (float)w; h = (int) (rect.height() / diff); if ( h > 120 ) { h = 120; float diff = (float)rect.height() / (float)h; w = (int) (rect.width() / diff); } } else if ( w < h ) { h = 130; float diff = (float)rect.height() / (float)h; w = (int) (rect.width() / diff); if ( w > 120 ) { w = 120; float diff = (float)rect.width() / (float)w; h = (int) (rect.height() / diff); } } else if ( w == h ) { w = 130; h = 130; } // draw an empty thumb TQPixmap pix(w, h); pix.fill( TQt::white ); TQPainter p(&pix); p.setPen(TQt::black); p.drawRect(pix.rect()); ThumbItem *item = new ThumbItem(static_cast(this), TQString::number(i+1), pix); item->setUptodate( false ); item->setDragEnabled(false); //no dragging for now } TQTimer::singleShot( 10, this, TQT_SLOT( slotRefreshItems() ) ); } uptodate = true; TQApplication::restoreOverrideCursor(); } void KPrThumbBar::refreshItems(bool offset) { TQRect vRect = visibleRect(); if ( offset ) vRect.moveBy( m_offsetX, m_offsetY ); else vRect.moveBy( contentsX(), contentsY() ); TQIconViewItem *it = findFirstVisibleItem( vRect ); while ( it ) { kdDebug(33001) << "visible page = " << it->text().toInt() << endl; if ( ! dynamic_cast(it)->isUptodate( ) ){ //todo refresh picture it->setPixmap( getSlideThumb( it->text().toInt() - 1 ) ); static_cast(it)->setUptodate( true ); } if ( it == findLastVisibleItem( vRect ) ) break; it = it->nextItem(); } m_offsetX = 0; m_offsetY = 0; } void KPrThumbBar::updateItem( int pagenr /* 0-based */, bool sticky ) { if ( m_viewMasterPage ) return; if ( !uptodate ) return; int pagecnt = 0; // calculate rect of visible objects TQRect vRect = visibleRect(); vRect.moveBy( contentsX(), contentsY() ); // Find icon TQIconViewItem *it = firstItem(); do { if ( it == findFirstVisibleItem( vRect ) ) { do { if ( sticky || it->text().toInt() == pagenr + 1 ) { it->setPixmap(getSlideThumb( pagecnt )); static_cast(it)->setUptodate( true ); if ( !sticky ) return; } if ( it == findLastVisibleItem( vRect ) ) break; pagecnt++; it = it->nextItem(); } while ( true ); } else if ( sticky || it->text().toInt() == pagenr + 1 ) { static_cast(it)->setUptodate( false ); if ( !sticky ) return; } pagecnt++; it = it->nextItem(); } while ( it ); if ( ! sticky ) kdWarning(33001) << "Item for page " << pagenr << " not found" << endl; } // add a thumb item without recreating all thumbs void KPrThumbBar::addItem( int pos ) { kdDebug(33001)<< "KPrThumbBar::addItem" << endl; int page = 0; for ( TQIconViewItem *it = firstItem(); it; it = it->nextItem() ) { // find page which should move // do stuff because a item can not be insert at the beginning if ( pos == 0 && page == pos ){ ThumbItem *item = new ThumbItem(static_cast(this), it, TQString::number(2), getSlideThumb(1)); item->setDragEnabled(false); //no dragging for now it->setPixmap(getSlideThumb( 0 )); // move on to next item as we have inserted one it = it->nextItem(); } else if ( (page + 1) == pos ) { ThumbItem *item = new ThumbItem(static_cast(this), it, TQString::number(pos+1), getSlideThumb(pos)); item->setDragEnabled(false); //no dragging for now it = it->nextItem(); } // update page numbers if ( page >= pos ) it->setText( TQString::number(page+2) ); page++; } } // moves a item without recreating all pages void KPrThumbBar::moveItem( int oldPos, int newPos ) { kdDebug(33001)<< "KPrThumbBar::moveItem " << oldPos << " to " << newPos << endl; int page = 0; TQIconViewItem *after = 0; TQIconViewItem *take = 0; for ( TQIconViewItem *it = firstItem(); it; it = it->nextItem() ) { // find page which should move if ( page == oldPos ) take = it; // find position where page should be insert // as a page can not be insert at the beginning get the first one // the page to get depends on if a page is moved forward / backwards if ( page == newPos ) after = page == 0 ? it : newPos > oldPos ? it : it->prevItem(); page++; } if ( ! take ) return; // workaround for a bug in qt 3.1.1 insertItem dose not work. // TODO remove workaround when qt 3.1.2 comes out tz //takeItem( take ); //insertItem( take, after); ThumbItem *item = new ThumbItem( static_cast(this), after, TQString::number( newPos ), *(take->pixmap()) ); item->setDragEnabled(false); //no dragging for now delete take; // update the thumbs if new pos was 0 // because it was insert after the first one if ( newPos == 0 ) { //todo do not recreate the pics after->setPixmap(getSlideThumb( 0 )); //take->setPixmap(getSlideThumb( 1 )); item->setPixmap(getSlideThumb( 1 )); } //write the new page numbers int lowPage = oldPos > newPos ? newPos : oldPos; int highPage = oldPos < newPos ? newPos : oldPos; page = 0; for ( TQIconViewItem *it = firstItem(); it; it = it->nextItem() ) { if ( page >= lowPage && page <= highPage) it->setText( TQString::number(page+1) ); page++; } } void KPrThumbBar::removeItem( int pos ) { kdDebug(33001)<< "KPrThumbBar::removeItem" << endl; int page = 0; bool change = false; TQIconViewItem *itemToDelete = 0; for ( TQIconViewItem *it = firstItem(); it; it = it->nextItem() ) { if ( page == pos ) { itemToDelete = it; if ( it->nextItem() ) it = it->nextItem(); change = true; } if ( change ) it->setText( TQString::number( page + 1 ) ); page++; } delete itemToDelete; } TQPixmap KPrThumbBar::getSlideThumb(int slideNr) const { //kdDebug(33001) << "KPrThumbBar::getSlideThumb: " << slideNr << endl; TQPixmap pix( 10, 10 ); m_view->getCanvas()->drawPageInPix( pix, slideNr, 60 ); int w = pix.width(); int h = pix.height(); if ( w > h ) { w = 130; h = 120; } else if ( w < h ) { w = 120; h = 130; } else if ( w == h ) { w = 130; h = 130; } const TQImage img(pix.convertToImage().smoothScale( w, h, TQ_ScaleMin )); pix.convertFromImage(img); // draw a frame around the thumb to show its size TQPainter p(&pix); p.setPen(TQt::black); p.drawRect(pix.rect()); return pix; } void KPrThumbBar::itemClicked(TQIconViewItem *i) { if ( !i ) return; emit showPage( i->index() ); } void KPrThumbBar::slotContentsMoving(int x, int y) { m_offsetX = x; m_offsetY = y; kdDebug(33001) << "offset x,y = " << x << ", " << y << endl; refreshItems( true ); } void KPrThumbBar::slotRefreshItems() { refreshItems(); } OutlineSlideItem::OutlineSlideItem( KListView* parent, KPrPage* _page, bool _masterPage ) : KListViewItem( parent ), m_page( _page ), m_masterPage( _masterPage ) { setDragEnabled(true); setPage( _page ); setPixmap( 0, KPBarIcon( "slide" ) ); } OutlineSlideItem::OutlineSlideItem( KListView* parent, OutlineSlideItem * after, KPrPage* _page, bool _masterPage ) : KListViewItem( parent, after ), m_page( _page ), m_masterPage( _masterPage ) { setDragEnabled(true); setPage( _page ); setPixmap( 0, KPBarIcon( "slide" ) ); } void OutlineSlideItem::setPage( KPrPage* p ) { if( !p ) return; m_page = p; update(); } void OutlineSlideItem::update() { if( !m_page ) return; KPrDocument *doc = m_page->kPresenterDoc(); updateTitle(); // add all objects OutlineObjectItem *ooi = 0; while ( ( ooi = dynamic_cast( this->firstChild() ) ) ) delete ooi; // keep selected object ooi = 0; TQPtrListIterator it( m_page->objectList() ); if ( !m_masterPage ) { for ( ; it.current(); ++it ) { OutlineObjectItem *item = new OutlineObjectItem( this, it.current() ); item->setDragEnabled( false ); if ( it.current()->isSelected() ) ooi = item; } } else { KPrObject* header = 0; KPrObject* footer = 0; // add sticky objects, exclude header and footer it = doc->masterPage()->objectList(); for ( ; it.current() ; ++it ) { KPrObject* object = it.current(); if( m_page->hasHeader() && doc->isHeader( object ) ) header = object; else if( m_page->hasFooter() && doc->isFooter( object ) ) footer = object; else if( !doc->isHeader( object ) && !doc->isFooter( object ) ) { OutlineObjectItem *item = new OutlineObjectItem( this, object ); if ( object->isSelected() ) ooi = item; } } // add header and footer (if any) if ( footer ) { OutlineObjectItem *item = new OutlineObjectItem( this, footer, i18n("Footer") ); if ( footer->isSelected() ) ooi = item; } if ( header ) { OutlineObjectItem *item = new OutlineObjectItem( this, header, i18n("Header") ); if ( header->isSelected() ) ooi = item; } } // select selected object the page is necessary that a // sticky object is selected on the active page if ( ooi && doc->activePage() == m_page ) (ooi->listView())->setSelected( ooi, true ); } void OutlineSlideItem::updateTitle() { TQString title = m_page->pageTitle(); if ( ! m_page->isSlideSelected() ) title = i18n( "(%1)" ).tqarg( title ); setText( 0, title ); } OutlineObjectItem::OutlineObjectItem( OutlineSlideItem* parent, KPrObject* _object, const TQString& name ) : KListViewItem( parent ), m_object( _object ) { setObject( m_object ); setDragEnabled( false ); TQString objectName = name.isEmpty() ? m_object->getObjectName() : name; //if( sticky ) objectName += i18n(" (Sticky)" ); setText( 0, objectName ); } void OutlineObjectItem::setObject( KPrObject* object ) { if( !object ) return; m_object = object; switch ( m_object->getType() ) { case OT_PICTURE: setPixmap( 0, KPBarIcon( "frame_image" ) ); break; case OT_LINE: setPixmap( 0, KPBarIcon( "mini_line" ) ); break; case OT_RECT: setPixmap( 0, KPBarIcon( "mini_rect" ) ); break; case OT_ELLIPSE: setPixmap( 0, KPBarIcon( "mini_circle" ) ); break; case OT_TEXT: setPixmap( 0, KPBarIcon( "frame_text" ) ); break; case OT_AUTOFORM: setPixmap( 0, KPBarIcon( "mini_autoform" ) ); break; case OT_CLIPART: setPixmap( 0, KPBarIcon( "mini_clipart" ) ); break; case OT_PIE: setPixmap( 0, KPBarIcon( "mini_pie" ) ); break; case OT_PART: setPixmap( 0, KPBarIcon( "frame_query" ) ); break; case OT_FREEHAND: setPixmap( 0, KPBarIcon( "freehand" ) ); break; case OT_POLYLINE: setPixmap( 0, KPBarIcon( "polyline" ) ); break; case OT_TQUADRICBEZIERCURVE: setPixmap( 0, KPBarIcon( "quadricbeziercurve" ) ); break; case OT_CUBICBEZIERCURVE: setPixmap( 0, KPBarIcon( "cubicbeziercurve" ) ); break; case OT_POLYGON: setPixmap( 0, KPBarIcon( "mini_polygon" ) ); break; case OT_CLOSED_LINE: { TQString name = m_object->getTypeString(); if ( name == i18n( "Closed Freehand" ) ) setPixmap( 0, KPBarIcon( "closed_freehand" ) ); else if ( name == i18n( "Closed Polyline" ) ) setPixmap( 0, KPBarIcon( "closed_polyline" ) ); else if ( name == i18n( "Closed Quadric Bezier Curve" ) ) setPixmap( 0, KPBarIcon( "closed_quadricbeziercurve" ) ); else if ( name == i18n( "Closed Cubic Bezier Curve" ) ) setPixmap( 0, KPBarIcon( "closed_cubicbeziercurve" ) ); } break; case OT_GROUP: setPixmap( 0, KPBarIcon( "group" ) ); break; default: break; } } KPrOutline::KPrOutline( TQWidget *parent, KPrDocument *d, KPrView *v ) : KListView( parent ), KPrSideBarBase( d, v) { rebuildItems(); setSorting( -1 ); header()->hide(); addColumn( i18n( "Slide" ) ); tqsetSizePolicy( TQSizePolicy( TQSizePolicy::Minimum, TQSizePolicy::Expanding ) ); connect( this, TQT_SIGNAL( currentChanged( TQListViewItem * ) ), this, TQT_SLOT( itemClicked( TQListViewItem * ) ) ); connect( this, TQT_SIGNAL( rightButtonPressed( TQListViewItem *, const TQPoint &, int ) ), this, TQT_SLOT( rightButtonPressed( TQListViewItem *, const TQPoint &, int ) ) ); connect( this, TQT_SIGNAL( contextMenu( KListView*, TQListViewItem*, const TQPoint& ) ), this, TQT_SLOT( slotContextMenu( KListView*, TQListViewItem*, const TQPoint&) ) ); connect( this, TQT_SIGNAL( doubleClicked ( TQListViewItem * )), this, TQT_SLOT(renamePageTitle())); connect( this, TQT_SIGNAL( dropped( TQDropEvent*, TQListViewItem*, TQListViewItem* ) ), this, TQT_SLOT( slotDropped( TQDropEvent*, TQListViewItem*, TQListViewItem* ) )); setItemsMovable( false ); setDragEnabled( true ); setAcceptDrops( true ); setDropVisualizer( true ); setFullWidth( true ); this->setRootIsDecorated( true ); } KPrOutline::~KPrOutline() { } void KPrOutline::rebuildItems() { clear(); if ( m_viewMasterPage ) { KPrPage *page=m_doc->masterPage(); new OutlineSlideItem( this, page, true ); } else { // Rebuild all the items for ( int i = m_doc->getPageNums() - 1; i >= 0; --i ) { KPrPage *page=m_doc->pageList().at( i ); new OutlineSlideItem( this, page, false ); } } } // given the page number (0-based), find associated slide item // returns 0 upon stupid things (e.g. invalid page number) OutlineSlideItem* KPrOutline::slideItem( int pageNumber ) { TQListViewItem* item = firstChild(); for( int index = 0; item; ++index, item = item->nextSibling() ) { if( index == pageNumber ) return dynamic_cast( item ); } return 0; } // update the KPrOutline item, the title may have changed void KPrOutline::updateItem( int pagenr /* 0-based */, bool sticky ) { if ( ! sticky ) { OutlineSlideItem *item = slideItem( pagenr ); if( item ) { blockSignals(true); item->update(); blockSignals(false); } } else { blockSignals(true); for( TQListViewItem *item = this->firstChild(); item; item = item->nextSibling() ) dynamic_cast(item)->update(); blockSignals(false); } } void KPrOutline::addItem( int pos ) { kdDebug(33001)<< "KPrOutline::addItem" << endl; KPrPage *page=m_doc->pageList().at( pos ); OutlineSlideItem *item; if ( pos == 0 ) { item = new OutlineSlideItem( this, page,m_viewMasterPage ); } else { OutlineSlideItem *after = slideItem( pos - 1 ); item = new OutlineSlideItem( this, after, page,m_viewMasterPage ); } item = dynamic_cast( item->nextSibling() ); // update title for( ; item; item = dynamic_cast( item->nextSibling() ) ) item->updateTitle(); } // move an KPrOutline Item so that not the hole list has to be recreated void KPrOutline::moveItem( int oldPos, int newPos ) { kdDebug(33001)<< "KPrOutline::moveItem " << oldPos << " to " << newPos << endl; int lowPage = oldPos > newPos ? newPos : oldPos; int highPage = oldPos < newPos ? newPos : oldPos; OutlineSlideItem *item = dynamic_cast( firstChild() ); TQListViewItem *itemToMove = 0; TQListViewItem *itemAfter = 0; // moving backwards if ( newPos < oldPos ) newPos--; for ( int index = 0; item; ++index, item = dynamic_cast( item->nextSibling() ) ) { if ( index == oldPos ) itemToMove = item; if ( index == newPos ) itemAfter = item; if ( index >= lowPage && index <= highPage ) item->updateTitle(); } KListView::moveItem( itemToMove, 0, itemAfter ); } void KPrOutline::removeItem( int pos ) { kdDebug(33001)<< "KPrOutline::removeItem" << endl; OutlineSlideItem* item = slideItem( pos ); if( !item ) return; OutlineSlideItem* temp = dynamic_cast(item->nextSibling()); delete item; for ( item = temp; item; item = dynamic_cast( item->nextSibling() ) ) item->updateTitle(); } void KPrOutline::itemClicked( TQListViewItem *item ) { if( !item ) return; // check if we need to show chosen slide OutlineSlideItem* slideItem = dynamic_cast(item); if( slideItem ) { KPrPage* page = slideItem->page(); if( !page ) return; if ( !m_viewMasterPage ) emit showPage( m_doc->pageList().findRef( page ) ); } // check if we need to show chosen object OutlineObjectItem* objectItem = dynamic_cast(item); if( objectItem ) { KPrObject *object = objectItem->object(); if( !object ) return; // ensure the owner slide is shown first OutlineSlideItem* slideItem = dynamic_cast(objectItem->parent()); if( slideItem && m_doc->activePage() != slideItem->page() ) { KPrPage* page = slideItem->page(); if( !page ) return; if ( !m_viewMasterPage ) emit showPage( m_doc->pageList().findRef( page ) ); } // select the object, make sure it's visible m_doc->deSelectAllObj(); m_view->getCanvas()->selectObj( object ); m_view->showObjectRect( object ); m_doc->tqrepaint( false ); } } /** * The listview no longer moves the item by itself. It just calls m_doc->movePage * which then moves the item. At the moment the method only works as long as * only one object is moves. * When an item is about to move (using drag-and-drop), it makes shure that * it's not moved right after an object. */ void KPrOutline::slotDropped( TQDropEvent * /* e */, TQListViewItem *parent, TQListViewItem *target ) { kdDebug(33001) << "slotDropped" << endl; /* slide doesn't have parent (always 0) * Only slides can move at the moment, objects can't. */ if ( parent ) return; // This code is taken from KListView for (TQListViewItem *i = firstChild(), *iNext = 0; i != 0; i = iNext) { iNext = i->itemBelow(); if ( !i->isSelected() ) continue; // don't drop an item after itself, or else // it moves to the top of the list if ( i == target ) continue; i->setSelected( false ); // don't move the item as it is allready moveItem(i, parent, target ); // Only one item can be moved break; } } // We have to overwrite this method as it checks if an item is movable // and we have disabled it. bool KPrOutline::acceptDrag( TQDropEvent* e ) const { return acceptDrops() && (e->source()==viewport()); } void KPrOutline::setCurrentPage( int pg ) { OutlineSlideItem *item = slideItem( pg ); if( item && ( item!=currentItem()->parent() ) ) { blockSignals( true ); setCurrentItem( item ); setSelected( item, true ); ensureItemVisible( item ); blockSignals( false ); } } void KPrOutline::contentsDropEvent( TQDropEvent *e ) { disconnect( this, TQT_SIGNAL( currentChanged( TQListViewItem * ) ), this, TQT_SLOT( itemClicked( TQListViewItem * ) ) ); KListView::contentsDropEvent( e ); connect( this, TQT_SIGNAL( currentChanged( TQListViewItem * ) ), this, TQT_SLOT( itemClicked( TQListViewItem * ) ) ); } void KPrOutline::moveItem( TQListViewItem *i, TQListViewItem *, TQListViewItem *newAfter ) { OutlineSlideItem* srcItem = dynamic_cast( i ); if ( !srcItem ) return; int num = m_doc->pageList().findRef( srcItem->page() ); int numNow = 0; if ( newAfter ) { OutlineSlideItem* dstItem = dynamic_cast( newAfter ); if( !dstItem ) return; numNow = m_doc->pageList().findRef( dstItem->page() ); if ( numNow < num ) numNow++; } if ( num!=numNow ) m_doc->movePage( num, numNow ); } void KPrOutline::rightButtonPressed( TQListViewItem *, const TQPoint &pnt, int ) { if ( !m_doc->isReadWrite() || m_viewMasterPage ) return; TQListViewItem *item = TQListView::selectedItem(); if( !item ) return; OutlineSlideItem* slideItem = dynamic_cast(item); if( slideItem ) { m_view->openPopupMenuSideBar(pnt); } else { OutlineObjectItem* objectItem = dynamic_cast(item); if( objectItem ) { KPrObject * kpobject = objectItem->object(); if( !kpobject ) { return; } KPrCanvas* canvas = static_cast(m_view->canvas()); canvas->deSelectAllObj(); canvas->selectObj( kpobject ); canvas->objectPopup( kpobject, pnt ); } } } void KPrOutline::slotContextMenu( KListView*, TQListViewItem* item, const TQPoint& p ) { rightButtonPressed( item, p, 0 ); } void KPrOutline::renamePageTitle() { TQListViewItem *item = TQListView::selectedItem(); if( !item || m_viewMasterPage) return; OutlineSlideItem* slideItem = dynamic_cast(item); if( !slideItem ) return; KPrPage* page = slideItem->page(); if( !page ) return; bool ok = false; TQString activeTitle = item->text( 0 ); TQStringList page_titles; KPrPage *it; for ( it = m_doc->pageList().first(); it; it = m_doc->pageList().next() ) if ( it->pageTitle() != activeTitle ) page_titles.append( it->pageTitle() ); KPrRenamePageValidator validator( page_titles ); TQString newTitle = KInputDialog::getText( i18n("Rename Slide"), i18n("Slide title:"), activeTitle, &ok, this, 0, &validator ); // Have a different name ? if ( ok ) { // User pushed an OK button. if ( newTitle != activeTitle ) { // Title changed. KPrChangeTitlePageNameCommand *cmd=new KPrChangeTitlePageNameCommand( i18n("Rename Slide"), m_doc, activeTitle, newTitle.stripWhiteSpace(), page ); cmd->execute(); m_doc->addCommand(cmd); } } } TQDragObject* KPrOutline::dragObject() { if( !selectedItem()->dragEnabled() ) { return 0; } return KListView::dragObject(); } #include "KPrSideBar.moc"