00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025 #include <qheader.h>
00026 #include <qtimer.h>
00027 #include <qpopupmenu.h>
00028 #include <qimage.h>
00029 #include <qtabwidget.h>
00030 #include <qtooltip.h>
00031
00032 #include <kwordwrap.h>
00033 #include <kmessagebox.h>
00034 #include <klocale.h>
00035 #include <kinputdialog.h>
00036 #include <knotifyclient.h>
00037 #include <kiconview.h>
00038 #include <kdebug.h>
00039
00040 #include "KPrSideBar.h"
00041 #include "KPrView.h"
00042 #include "KPrDocument.h"
00043 #include "KPrCanvas.h"
00044 #include "KPrPage.h"
00045 #include "KPrObject.h"
00046 #include <qapplication.h>
00047 #include "KPrCommand.h"
00048 #include <qvalidator.h>
00049 #include "KPrFreehandObject.h"
00050 #include "KPrBezierCurveObject.h"
00051 #include "KPrTextObject.h"
00052 #include "KPrPolylineObject.h"
00053 #include "KPrClosedLineObject.h"
00054 #include "KPrGroupObject.h"
00055
00056
00057 QValidator::State KPrRenamePageValidator::validate( QString & input, int& ) const
00058 {
00059 QString str = input.stripWhiteSpace();
00060 if ( str.isEmpty() )
00061 return Acceptable;
00062
00063 if ( mStringList.find( str ) == mStringList.end() )
00064 return Acceptable;
00065 else
00066 return Intermediate;
00067 }
00068
00069 class ThumbToolTip : public QToolTip
00070 {
00071 public:
00072 ThumbToolTip( KPrThumbBar *parent )
00073 : QToolTip( parent->viewport() )
00074 , m_thumbBar( parent )
00075 {}
00076
00077 protected:
00078 void maybeTip(const QPoint &pos)
00079 {
00080 QString title;
00081 QRect r( m_thumbBar->tip( pos, title ) );
00082 if (!r.isValid())
00083 return;
00084
00085 tip(r, title);
00086 }
00087 private:
00088 KPrThumbBar *m_thumbBar;
00089 };
00090
00091
00092 class OutlineSlideItem: public KListViewItem
00093 {
00094 public:
00095 OutlineSlideItem( KListView * parent, KPrPage* page, bool _masterPage );
00096 OutlineSlideItem( KListView * parent, OutlineSlideItem *after, KPrPage* page, bool _masterPage );
00097
00098 KPrPage* page() const { return m_page; }
00099
00100 void setPage( KPrPage* p );
00101
00102 void update();
00103 void updateTitle();
00104
00105 private:
00106 KPrPage* m_page;
00107 bool m_masterPage;
00108 };
00109
00110 class OutlineObjectItem: public KListViewItem
00111 {
00112 public:
00113 OutlineObjectItem( OutlineSlideItem * parent, KPrObject* object,
00114 const QString& name = QString::null );
00115
00116 KPrObject* object() const { return m_object; }
00117
00118 void setObject( KPrObject* o );
00119
00120 private:
00121 KPrObject* m_object;
00122 };
00123
00124 class ThumbItem : public QIconViewItem
00125 {
00126 public:
00127 ThumbItem( QIconView *parent, const QString & text, const QPixmap & icon )
00128 : QIconViewItem( parent, text, icon )
00129 { uptodate = true; }
00130 ThumbItem( QIconView *parent, QIconViewItem *after, const QString & text, const QPixmap & icon )
00131 : QIconViewItem( parent, after, text, icon )
00132 { uptodate = true; }
00133
00134 virtual bool isUptodate() { return uptodate; };
00135 virtual void setUptodate( bool _uptodate) { uptodate = _uptodate; };
00136
00137 private:
00138 bool uptodate;
00139 };
00140
00141 KPrSideBar::KPrSideBar(QWidget *parent, KPrDocument *d, KPrView *v)
00142 :QTabWidget(parent), m_doc(d), m_view(v)
00143 {
00144 setTabPosition(QTabWidget::Top);
00145 setTabShape(QTabWidget::Triangular);
00146
00147 m_outline = new KPrOutline(this, m_doc, m_view);
00148 addTab(m_outline, i18n("Structure of the presentation", "Outline"));
00149
00150 m_thb = new KPrThumbBar(this, m_doc, m_view);
00151 addTab(m_thb,i18n("Preview"));
00152
00153
00154
00155 connect(m_outline, SIGNAL(showPage(int)),
00156 this, SIGNAL(showPage(int)));
00157
00158 connect(m_thb, SIGNAL(showPage(int)),
00159 this, SIGNAL(showPage(int)));
00160
00161 connect(m_outline, SIGNAL(movePage(int,int)),
00162 this, SIGNAL(movePage(int,int)));
00163
00164 connect(m_outline, SIGNAL(selectPage(int,bool)),
00165 this, SIGNAL(selectPage(int,bool)));
00166
00167 connect(this, SIGNAL(currentChanged(QWidget *)),
00168 this, SLOT(currentChanged(QWidget *)));
00169
00170 }
00171
00172 void KPrSideBar::currentChanged(QWidget *tab)
00173 {
00174 if (tab == m_thb) {
00175 if (!m_thb->uptodate && m_thb->isVisible())
00176 m_thb->rebuildItems();
00177 else
00178 m_thb->refreshItems();
00179 }
00180 }
00181
00182 void KPrSideBar::addItem( int pos )
00183 {
00184 m_outline->addItem( pos );
00185 m_thb->addItem( pos );
00186 }
00187
00188 void KPrSideBar::moveItem( int oldPos, int newPos )
00189 {
00190 m_outline->moveItem( oldPos, newPos );
00191 m_thb->moveItem( oldPos, newPos );
00192 }
00193
00194 void KPrSideBar::removeItem( int pos )
00195 {
00196 m_outline->removeItem( pos );
00197 m_thb->removeItem( pos );
00198 }
00199
00200 void KPrSideBar::updateItem( KPrPage *page )
00201 {
00202 bool sticky = false;
00203 int pos = 0;
00204 if ( page == m_doc->masterPage() )
00205 {
00206 pos = -1;
00207 sticky = true;
00208 }
00209 else
00210 {
00211 pos = m_doc->pageList().findRef( page );
00212 }
00213
00214 m_outline->updateItem( pos, sticky );
00215 m_thb->updateItem( pos, sticky );
00216 }
00217
00218 void KPrSideBar::setViewMasterPage( bool _masterPage )
00219 {
00220 m_outline->setViewMasterPage( _masterPage );
00221 m_thb->setViewMasterPage( _masterPage );
00222 m_outline->rebuildItems();
00223 m_thb->rebuildItems();
00224 }
00225
00226 KPrSideBarBase::KPrSideBarBase(KPrDocument *_doc, KPrView *_view)
00227 : m_doc( _doc ), m_view( _view ), m_viewMasterPage( false )
00228 {
00229 }
00230
00231 void KPrSideBarBase::setViewMasterPage( bool _b )
00232 {
00233 m_viewMasterPage = _b;
00234 }
00235
00236 KPrThumbBar::KPrThumbBar(QWidget *parent, KPrDocument *d, KPrView *v)
00237 :KIconView(parent), KPrSideBarBase( d,v)
00238 {
00239 uptodate = false;
00240 m_offsetX = 0;
00241 m_offsetY = 0;
00242
00243 setArrangement(QIconView::LeftToRight);
00244 setAutoArrange(true);
00245 setSorting(false);
00246 setItemsMovable(false);
00247 setResizeMode(QIconView::Adjust);
00248
00249 m_thumbTip = new ThumbToolTip(this);
00250
00251 connect(this, SIGNAL(currentChanged(QIconViewItem *)),
00252 this, SLOT(itemClicked(QIconViewItem *)));
00253 connect(this, SIGNAL(contentsMoving(int, int)),
00254 this, SLOT(slotContentsMoving(int, int)));
00255 }
00256
00257 KPrThumbBar::~KPrThumbBar()
00258 {
00259 delete m_thumbTip;
00260 }
00261
00262 void KPrThumbBar::setCurrentPage( int pg )
00263 {
00264 for ( QIconViewItem *it = firstItem(); it; it = it->nextItem() )
00265 {
00266 if ( it->text().toInt() - 1 == pg ) {
00267 blockSignals( true );
00268 setCurrentItem( it );
00269 setSelected( it, FALSE );
00270 ensureItemVisible(it);
00271 refreshItems();
00272 blockSignals( false );
00273 return;
00274 }
00275 }
00276 }
00277
00278 QRect KPrThumbBar::tip(const QPoint &pos, QString &title)
00279 {
00280 QIconViewItem *item = findItem(viewportToContents(pos));
00281 if (!item)
00282 return QRect(0, 0, -1, -1);
00283
00284 int pagenr = item->index();
00285 title = m_doc->pageList().at(pagenr)->pageTitle();
00286
00287 QRect r = item->pixmapRect(FALSE);
00288 r = QRect(contentsToViewport(QPoint(r.x(), r.y())), QSize(r.width(), r.height()));
00289 return r;
00290 }
00291
00292 void KPrThumbBar::rebuildItems()
00293 {
00294 kdDebug()<<" void KPrThumbBar::rebuildItems() beofre \n";
00295 if( !isVisible())
00296 return;
00297 kdDebug(33001) << "KPrThumbBar::rebuildItems" << endl;
00298
00299 QApplication::setOverrideCursor( Qt::waitCursor );
00300
00301 clear();
00302 if ( m_viewMasterPage )
00303 {
00304 }
00305 else
00306 {
00307 for ( unsigned int i = 0; i < m_doc->getPageNums(); i++ ) {
00308
00309 QRect rect = m_doc->pageList().at(i)->getZoomPageRect( );
00310
00311 int w = rect.width();
00312 int h = rect.height();
00313 if ( w > h ) {
00314 w = 130;
00315 float diff = (float)rect.width() / (float)w;
00316 h = (int) (rect.height() / diff);
00317 if ( h > 120 ) {
00318 h = 120;
00319 float diff = (float)rect.height() / (float)h;
00320 w = (int) (rect.width() / diff);
00321 }
00322 }
00323 else if ( w < h ) {
00324 h = 130;
00325 float diff = (float)rect.height() / (float)h;
00326 w = (int) (rect.width() / diff);
00327 if ( w > 120 ) {
00328 w = 120;
00329 float diff = (float)rect.width() / (float)w;
00330 h = (int) (rect.height() / diff);
00331 }
00332 }
00333 else if ( w == h ) {
00334 w = 130;
00335 h = 130;
00336 }
00337
00338
00339 QPixmap pix(w, h);
00340 pix.fill( Qt::white );
00341
00342 QPainter p(&pix);
00343 p.setPen(Qt::black);
00344 p.drawRect(pix.rect());
00345
00346 ThumbItem *item = new ThumbItem(static_cast<QIconView *>(this), QString::number(i+1), pix);
00347 item->setUptodate( false );
00348 item->setDragEnabled(false);
00349 }
00350
00351 QTimer::singleShot( 10, this, SLOT( slotRefreshItems() ) );
00352 }
00353 uptodate = true;
00354
00355 QApplication::restoreOverrideCursor();
00356 }
00357
00358 void KPrThumbBar::refreshItems(bool offset)
00359 {
00360 QRect vRect = visibleRect();
00361 if ( offset )
00362 vRect.moveBy( m_offsetX, m_offsetY );
00363 else
00364 vRect.moveBy( contentsX(), contentsY() );
00365
00366 QIconViewItem *it = findFirstVisibleItem( vRect );
00367 while ( it )
00368 {
00369 kdDebug(33001) << "visible page = " << it->text().toInt() << endl;
00370 if ( ! dynamic_cast<ThumbItem *>(it)->isUptodate( ) ){
00371
00372 it->setPixmap( getSlideThumb( it->text().toInt() - 1 ) );
00373 static_cast<ThumbItem *>(it)->setUptodate( true );
00374 }
00375
00376 if ( it == findLastVisibleItem( vRect ) )
00377 break;
00378 it = it->nextItem();
00379 }
00380
00381 m_offsetX = 0;
00382 m_offsetY = 0;
00383 }
00384
00385 void KPrThumbBar::updateItem( int pagenr , bool sticky )
00386 {
00387 if ( m_viewMasterPage )
00388 return;
00389 if ( !uptodate )
00390 return;
00391 int pagecnt = 0;
00392
00393 QRect vRect = visibleRect();
00394 vRect.moveBy( contentsX(), contentsY() );
00395
00396
00397 QIconViewItem *it = firstItem();
00398 do
00399 {
00400 if ( it == findFirstVisibleItem( vRect ) ) {
00401 do
00402 {
00403 if ( sticky || it->text().toInt() == pagenr + 1 ) {
00404 it->setPixmap(getSlideThumb( pagecnt ));
00405 static_cast<ThumbItem *>(it)->setUptodate( true );
00406
00407 if ( !sticky )
00408 return;
00409 }
00410 if ( it == findLastVisibleItem( vRect ) )
00411 break;
00412 pagecnt++;
00413 it = it->nextItem();
00414 } while ( true );
00415 }
00416 else if ( sticky || it->text().toInt() == pagenr + 1 ) {
00417 static_cast<ThumbItem *>(it)->setUptodate( false );
00418 if ( !sticky )
00419 return;
00420 }
00421 pagecnt++;
00422 it = it->nextItem();
00423 } while ( it );
00424
00425 if ( ! sticky )
00426 kdWarning(33001) << "Item for page " << pagenr << " not found" << endl;
00427 }
00428
00429
00430 void KPrThumbBar::addItem( int pos )
00431 {
00432 kdDebug(33001)<< "KPrThumbBar::addItem" << endl;
00433 int page = 0;
00434 for ( QIconViewItem *it = firstItem(); it; it = it->nextItem() ) {
00435
00436
00437 if ( pos == 0 && page == pos ){
00438 ThumbItem *item = new ThumbItem(static_cast<QIconView *>(this), it, QString::number(2), getSlideThumb(1));
00439 item->setDragEnabled(false);
00440 it->setPixmap(getSlideThumb( 0 ));
00441
00442 it = it->nextItem();
00443 }
00444 else if ( (page + 1) == pos ) {
00445 ThumbItem *item = new ThumbItem(static_cast<QIconView *>(this), it, QString::number(pos+1), getSlideThumb(pos));
00446 item->setDragEnabled(false);
00447 it = it->nextItem();
00448 }
00449
00450 if ( page >= pos )
00451 it->setText( QString::number(page+2) );
00452 page++;
00453 }
00454 }
00455
00456
00457 void KPrThumbBar::moveItem( int oldPos, int newPos )
00458 {
00459 kdDebug(33001)<< "KPrThumbBar::moveItem " << oldPos << " to " << newPos << endl;
00460 int page = 0;
00461 QIconViewItem *after = 0;
00462 QIconViewItem *take = 0;
00463 for ( QIconViewItem *it = firstItem(); it; it = it->nextItem() ) {
00464
00465 if ( page == oldPos )
00466 take = it;
00467
00468
00469
00470 if ( page == newPos )
00471 after = page == 0 ? it : newPos > oldPos ? it : it->prevItem();
00472 page++;
00473 }
00474
00475 if ( ! take )
00476 return;
00477
00478
00479
00480
00481
00482 ThumbItem *item = new ThumbItem( static_cast<QIconView *>(this), after, QString::number( newPos ), *(take->pixmap()) );
00483 item->setDragEnabled(false);
00484 delete take;
00485
00486
00487 if ( newPos == 0 ) {
00488
00489 after->setPixmap(getSlideThumb( 0 ));
00490
00491 item->setPixmap(getSlideThumb( 1 ));
00492 }
00493
00494
00495 int lowPage = oldPos > newPos ? newPos : oldPos;
00496 int highPage = oldPos < newPos ? newPos : oldPos;
00497 page = 0;
00498 for ( QIconViewItem *it = firstItem(); it; it = it->nextItem() ) {
00499 if ( page >= lowPage && page <= highPage)
00500 it->setText( QString::number(page+1) );
00501 page++;
00502 }
00503 }
00504
00505 void KPrThumbBar::removeItem( int pos )
00506 {
00507 kdDebug(33001)<< "KPrThumbBar::removeItem" << endl;
00508 int page = 0;
00509 bool change = false;
00510 QIconViewItem *itemToDelete = 0;
00511
00512 for ( QIconViewItem *it = firstItem(); it; it = it->nextItem() ) {
00513 if ( page == pos ) {
00514 itemToDelete = it;
00515 if ( it->nextItem() )
00516 it = it->nextItem();
00517 change = true;
00518 }
00519 if ( change )
00520 it->setText( QString::number( page + 1 ) );
00521 page++;
00522 }
00523 delete itemToDelete;
00524 }
00525
00526 QPixmap KPrThumbBar::getSlideThumb(int slideNr) const
00527 {
00528
00529 QPixmap pix( 10, 10 );
00530
00531 m_view->getCanvas()->drawPageInPix( pix, slideNr, 60 );
00532
00533 int w = pix.width();
00534 int h = pix.height();
00535
00536 if ( w > h ) {
00537 w = 130;
00538 h = 120;
00539 }
00540 else if ( w < h ) {
00541 w = 120;
00542 h = 130;
00543 }
00544 else if ( w == h ) {
00545 w = 130;
00546 h = 130;
00547 }
00548
00549 const QImage img(pix.convertToImage().smoothScale( w, h, QImage::ScaleMin ));
00550 pix.convertFromImage(img);
00551
00552
00553 QPainter p(&pix);
00554 p.setPen(Qt::black);
00555 p.drawRect(pix.rect());
00556
00557 return pix;
00558 }
00559
00560 void KPrThumbBar::itemClicked(QIconViewItem *i)
00561 {
00562 if ( !i )
00563 return;
00564 emit showPage( i->index() );
00565 }
00566
00567 void KPrThumbBar::slotContentsMoving(int x, int y)
00568 {
00569 m_offsetX = x;
00570 m_offsetY = y;
00571 kdDebug(33001) << "offset x,y = " << x << ", " << y << endl;
00572 refreshItems( true );
00573 }
00574
00575 void KPrThumbBar::slotRefreshItems()
00576 {
00577 refreshItems();
00578 }
00579
00580 OutlineSlideItem::OutlineSlideItem( KListView* parent, KPrPage* _page, bool _masterPage )
00581 : KListViewItem( parent ), m_page( _page ), m_masterPage( _masterPage )
00582 {
00583 setDragEnabled(true);
00584 setPage( _page );
00585 setPixmap( 0, KPBarIcon( "slide" ) );
00586 }
00587
00588 OutlineSlideItem::OutlineSlideItem( KListView* parent, OutlineSlideItem * after, KPrPage* _page, bool _masterPage )
00589 : KListViewItem( parent, after ), m_page( _page ), m_masterPage( _masterPage )
00590 {
00591 setDragEnabled(true);
00592 setPage( _page );
00593 setPixmap( 0, KPBarIcon( "slide" ) );
00594 }
00595
00596 void OutlineSlideItem::setPage( KPrPage* p )
00597 {
00598 if( !p ) return;
00599 m_page = p;
00600 update();
00601 }
00602
00603 void OutlineSlideItem::update()
00604 {
00605 if( !m_page ) return;
00606 KPrDocument *doc = m_page->kPresenterDoc();
00607 updateTitle();
00608
00609
00610 OutlineObjectItem *ooi = 0;
00611 while ( ( ooi = dynamic_cast<OutlineObjectItem*>( this->firstChild() ) ) )
00612 delete ooi;
00613
00614
00615 ooi = 0;
00616
00617 QPtrListIterator<KPrObject> it( m_page->objectList() );
00618
00619 if ( !m_masterPage )
00620 {
00621 for ( ; it.current(); ++it ) {
00622 OutlineObjectItem *item = new OutlineObjectItem( this, it.current() );
00623 item->setDragEnabled( false );
00624 if ( it.current()->isSelected() )
00625 ooi = item;
00626 }
00627 }
00628 else
00629 {
00630 KPrObject* header = 0;
00631 KPrObject* footer = 0;
00632
00633
00634 it = doc->masterPage()->objectList();
00635 for ( ; it.current() ; ++it )
00636 {
00637 KPrObject* object = it.current();
00638
00639 if( m_page->hasHeader() && doc->isHeader( object ) )
00640 header = object;
00641 else if( m_page->hasFooter() && doc->isFooter( object ) )
00642 footer = object;
00643 else if( !doc->isHeader( object ) && !doc->isFooter( object ) ) {
00644 OutlineObjectItem *item = new OutlineObjectItem( this, object );
00645 if ( object->isSelected() )
00646 ooi = item;
00647 }
00648
00649 }
00650
00651
00652 if ( footer ) {
00653 OutlineObjectItem *item = new OutlineObjectItem( this, footer, i18n("Footer") );
00654 if ( footer->isSelected() )
00655 ooi = item;
00656 }
00657
00658 if ( header ) {
00659 OutlineObjectItem *item = new OutlineObjectItem( this, header, i18n("Header") );
00660 if ( header->isSelected() )
00661 ooi = item;
00662 }
00663 }
00664
00665
00666
00667 if ( ooi && doc->activePage() == m_page )
00668 (ooi->listView())->setSelected( ooi, true );
00669 }
00670
00671 void OutlineSlideItem::updateTitle()
00672 {
00673 QString title = m_page->pageTitle();
00674 if ( ! m_page->isSlideSelected() )
00675 title = i18n( "(%1)" ).arg( title );
00676 setText( 0, title );
00677 }
00678
00679 OutlineObjectItem::OutlineObjectItem( OutlineSlideItem* parent, KPrObject* _object,
00680 const QString& name )
00681 : KListViewItem( parent ), m_object( _object )
00682 {
00683 setObject( m_object );
00684 setDragEnabled( false );
00685
00686 QString objectName = name.isEmpty() ? m_object->getObjectName() : name;
00687
00688 setText( 0, objectName );
00689 }
00690
00691 void OutlineObjectItem::setObject( KPrObject* object )
00692 {
00693 if( !object ) return;
00694 m_object = object;
00695
00696 switch ( m_object->getType() ) {
00697 case OT_PICTURE:
00698 setPixmap( 0, KPBarIcon( "frame_image" ) );
00699 break;
00700 case OT_LINE:
00701 setPixmap( 0, KPBarIcon( "mini_line" ) );
00702 break;
00703 case OT_RECT:
00704 setPixmap( 0, KPBarIcon( "mini_rect" ) );
00705 break;
00706 case OT_ELLIPSE:
00707 setPixmap( 0, KPBarIcon( "mini_circle" ) );
00708 break;
00709 case OT_TEXT:
00710 setPixmap( 0, KPBarIcon( "frame_text" ) );
00711 break;
00712 case OT_AUTOFORM:
00713 setPixmap( 0, KPBarIcon( "mini_autoform" ) );
00714 break;
00715 case OT_CLIPART:
00716 setPixmap( 0, KPBarIcon( "mini_clipart" ) );
00717 break;
00718 case OT_PIE:
00719 setPixmap( 0, KPBarIcon( "mini_pie" ) );
00720 break;
00721 case OT_PART:
00722 setPixmap( 0, KPBarIcon( "frame_query" ) );
00723 break;
00724 case OT_FREEHAND:
00725 setPixmap( 0, KPBarIcon( "freehand" ) );
00726 break;
00727 case OT_POLYLINE:
00728 setPixmap( 0, KPBarIcon( "polyline" ) );
00729 break;
00730 case OT_QUADRICBEZIERCURVE:
00731 setPixmap( 0, KPBarIcon( "quadricbeziercurve" ) );
00732 break;
00733 case OT_CUBICBEZIERCURVE:
00734 setPixmap( 0, KPBarIcon( "cubicbeziercurve" ) );
00735 break;
00736 case OT_POLYGON:
00737 setPixmap( 0, KPBarIcon( "mini_polygon" ) );
00738 break;
00739 case OT_CLOSED_LINE: {
00740 QString name = m_object->getTypeString();
00741 if ( name == i18n( "Closed Freehand" ) )
00742 setPixmap( 0, KPBarIcon( "closed_freehand" ) );
00743 else if ( name == i18n( "Closed Polyline" ) )
00744 setPixmap( 0, KPBarIcon( "closed_polyline" ) );
00745 else if ( name == i18n( "Closed Quadric Bezier Curve" ) )
00746 setPixmap( 0, KPBarIcon( "closed_quadricbeziercurve" ) );
00747 else if ( name == i18n( "Closed Cubic Bezier Curve" ) )
00748 setPixmap( 0, KPBarIcon( "closed_cubicbeziercurve" ) );
00749 } break;
00750 case OT_GROUP:
00751 setPixmap( 0, KPBarIcon( "group" ) );
00752 break;
00753 default:
00754 break;
00755 }
00756 }
00757
00758 KPrOutline::KPrOutline( QWidget *parent, KPrDocument *d, KPrView *v )
00759 : KListView( parent ), KPrSideBarBase( d, v)
00760 {
00761 rebuildItems();
00762 setSorting( -1 );
00763 header()->hide();
00764 addColumn( i18n( "Slide" ) );
00765 setSizePolicy( QSizePolicy( QSizePolicy::Minimum, QSizePolicy::Expanding ) );
00766
00767 connect( this, SIGNAL( currentChanged( QListViewItem * ) ), this, SLOT( itemClicked( QListViewItem * ) ) );
00768 connect( this, SIGNAL( rightButtonPressed( QListViewItem *, const QPoint &, int ) ),
00769 this, SLOT( rightButtonPressed( QListViewItem *, const QPoint &, int ) ) );
00770 connect( this, SIGNAL( contextMenu( KListView*, QListViewItem*, const QPoint& ) ),
00771 this, SLOT( slotContextMenu( KListView*, QListViewItem*, const QPoint&) ) );
00772
00773 connect( this, SIGNAL( doubleClicked ( QListViewItem * )),
00774 this, SLOT(renamePageTitle()));
00775 connect( this, SIGNAL( dropped( QDropEvent*, QListViewItem*, QListViewItem* ) ),
00776 this, SLOT( slotDropped( QDropEvent*, QListViewItem*, QListViewItem* ) ));
00777
00778 setItemsMovable( false );
00779 setDragEnabled( true );
00780 setAcceptDrops( true );
00781 setDropVisualizer( true );
00782 setFullWidth( true );
00783 this->setRootIsDecorated( true );
00784 }
00785
00786 KPrOutline::~KPrOutline()
00787 {
00788 }
00789
00790 void KPrOutline::rebuildItems()
00791 {
00792 clear();
00793 if ( m_viewMasterPage )
00794 {
00795 KPrPage *page=m_doc->masterPage();
00796 new OutlineSlideItem( this, page, true );
00797 }
00798 else
00799 {
00800
00801 for ( int i = m_doc->getPageNums() - 1; i >= 0; --i ) {
00802 KPrPage *page=m_doc->pageList().at( i );
00803 new OutlineSlideItem( this, page, false );
00804 }
00805 }
00806 }
00807
00808
00809
00810 OutlineSlideItem* KPrOutline::slideItem( int pageNumber )
00811 {
00812 QListViewItem* item = firstChild();
00813 for( int index = 0; item; ++index, item = item->nextSibling() ) {
00814 if( index == pageNumber )
00815 return dynamic_cast<OutlineSlideItem*>( item );
00816 }
00817
00818 return 0;
00819 }
00820
00821
00822
00823 void KPrOutline::updateItem( int pagenr , bool sticky )
00824 {
00825 if ( ! sticky ) {
00826 OutlineSlideItem *item = slideItem( pagenr );
00827 if( item ) {
00828 blockSignals(true);
00829 item->update();
00830 blockSignals(false);
00831 }
00832 } else {
00833 blockSignals(true);
00834 for( QListViewItem *item = this->firstChild(); item; item = item->nextSibling() )
00835 dynamic_cast<OutlineSlideItem*>(item)->update();
00836 blockSignals(false);
00837 }
00838 }
00839
00840 void KPrOutline::addItem( int pos )
00841 {
00842 kdDebug(33001)<< "KPrOutline::addItem" << endl;
00843
00844 KPrPage *page=m_doc->pageList().at( pos );
00845 OutlineSlideItem *item;
00846 if ( pos == 0 ) {
00847 item = new OutlineSlideItem( this, page,m_viewMasterPage );
00848 }
00849 else {
00850 OutlineSlideItem *after = slideItem( pos - 1 );
00851 item = new OutlineSlideItem( this, after, page,m_viewMasterPage );
00852 }
00853
00854 item = dynamic_cast<OutlineSlideItem*>( item->nextSibling() );
00855
00856 for( ; item; item = dynamic_cast<OutlineSlideItem*>( item->nextSibling() ) )
00857 item->updateTitle();
00858 }
00859
00860
00861 void KPrOutline::moveItem( int oldPos, int newPos )
00862 {
00863 kdDebug(33001)<< "KPrOutline::moveItem " << oldPos << " to " << newPos << endl;
00864
00865 int lowPage = oldPos > newPos ? newPos : oldPos;
00866 int highPage = oldPos < newPos ? newPos : oldPos;
00867
00868 OutlineSlideItem *item = dynamic_cast<OutlineSlideItem*>( firstChild() );
00869 QListViewItem *itemToMove = 0;
00870 QListViewItem *itemAfter = 0;
00871
00872
00873 if ( newPos < oldPos )
00874 newPos--;
00875
00876 for ( int index = 0; item; ++index, item = dynamic_cast<OutlineSlideItem*>( item->nextSibling() ) )
00877 {
00878 if ( index == oldPos )
00879 itemToMove = item;
00880 if ( index == newPos )
00881 itemAfter = item;
00882 if ( index >= lowPage && index <= highPage )
00883 item->updateTitle();
00884 }
00885
00886 KListView::moveItem( itemToMove, 0, itemAfter );
00887 }
00888
00889 void KPrOutline::removeItem( int pos )
00890 {
00891 kdDebug(33001)<< "KPrOutline::removeItem" << endl;
00892
00893 OutlineSlideItem* item = slideItem( pos );
00894 if( !item ) return;
00895 OutlineSlideItem* temp = dynamic_cast<OutlineSlideItem*>(item->nextSibling());
00896
00897 delete item;
00898
00899 for ( item = temp; item; item = dynamic_cast<OutlineSlideItem*>( item->nextSibling() ) )
00900 item->updateTitle();
00901 }
00902
00903 void KPrOutline::itemClicked( QListViewItem *item )
00904 {
00905 if( !item ) return;
00906
00907
00908 OutlineSlideItem* slideItem = dynamic_cast<OutlineSlideItem*>(item);
00909 if( slideItem )
00910 {
00911 KPrPage* page = slideItem->page();
00912 if( !page ) return;
00913 if ( !m_viewMasterPage )
00914 emit showPage( m_doc->pageList().findRef( page ) );
00915 }
00916
00917
00918 OutlineObjectItem* objectItem = dynamic_cast<OutlineObjectItem*>(item);
00919 if( objectItem )
00920 {
00921 KPrObject *object = objectItem->object();
00922 if( !object ) return;
00923
00924
00925 OutlineSlideItem* slideItem = dynamic_cast<OutlineSlideItem*>(objectItem->parent());
00926 if( slideItem && m_doc->activePage() != slideItem->page() )
00927 {
00928 KPrPage* page = slideItem->page();
00929 if( !page ) return;
00930 if ( !m_viewMasterPage )
00931 emit showPage( m_doc->pageList().findRef( page ) );
00932 }
00933
00934
00935 m_doc->deSelectAllObj();
00936 m_view->getCanvas()->selectObj( object );
00937 m_view->showObjectRect( object );
00938 m_doc->repaint( false );
00939 }
00940 }
00941
00949 void KPrOutline::slotDropped( QDropEvent * , QListViewItem *parent, QListViewItem *target )
00950 {
00951 kdDebug(33001) << "slotDropped" << endl;
00952
00953
00954 if ( parent )
00955 return;
00956
00957
00958 for (QListViewItem *i = firstChild(), *iNext = 0; i != 0; i = iNext)
00959 {
00960 iNext = i->itemBelow();
00961 if ( !i->isSelected() )
00962 continue;
00963
00964
00965
00966 if ( i == target )
00967 continue;
00968
00969 i->setSelected( false );
00970
00971
00972 moveItem(i, parent, target );
00973
00974
00975 break;
00976 }
00977 }
00978
00979
00980
00981 bool KPrOutline::acceptDrag( QDropEvent* e ) const
00982 {
00983 return acceptDrops() && (e->source()==viewport());
00984 }
00985
00986
00987 void KPrOutline::setCurrentPage( int pg )
00988 {
00989 OutlineSlideItem *item = slideItem( pg );
00990 if( item && ( item!=currentItem()->parent() ) )
00991 {
00992 blockSignals( true );
00993 setCurrentItem( item );
00994 setSelected( item, true );
00995 ensureItemVisible( item );
00996 blockSignals( false );
00997 }
00998 }
00999
01000 void KPrOutline::contentsDropEvent( QDropEvent *e )
01001 {
01002 disconnect( this, SIGNAL( currentChanged( QListViewItem * ) ), this, SLOT( itemClicked( QListViewItem * ) ) );
01003 KListView::contentsDropEvent( e );
01004 connect( this, SIGNAL( currentChanged( QListViewItem * ) ), this, SLOT( itemClicked( QListViewItem * ) ) );
01005 }
01006
01007 void KPrOutline::moveItem( QListViewItem *i, QListViewItem *, QListViewItem *newAfter )
01008 {
01009 OutlineSlideItem* srcItem = dynamic_cast<OutlineSlideItem*>( i );
01010 if ( !srcItem )
01011 return;
01012
01013 int num = m_doc->pageList().findRef( srcItem->page() );
01014
01015 int numNow = 0;
01016 if ( newAfter )
01017 {
01018 OutlineSlideItem* dstItem = dynamic_cast<OutlineSlideItem*>( newAfter );
01019 if( !dstItem )
01020 return;
01021
01022 numNow = m_doc->pageList().findRef( dstItem->page() );
01023 if ( numNow < num )
01024 numNow++;
01025 }
01026
01027 if ( num!=numNow )
01028 m_doc->movePage( num, numNow );
01029 }
01030
01031 void KPrOutline::rightButtonPressed( QListViewItem *, const QPoint &pnt, int )
01032 {
01033 if ( !m_doc->isReadWrite() || m_viewMasterPage ) return;
01034
01035 QListViewItem *item = QListView::selectedItem();
01036 if( !item ) return;
01037
01038 OutlineSlideItem* slideItem = dynamic_cast<OutlineSlideItem*>(item);
01039
01040 if( slideItem ) {
01041 m_view->openPopupMenuSideBar(pnt);
01042 } else {
01043 OutlineObjectItem* objectItem = dynamic_cast<OutlineObjectItem*>(item);
01044 if( objectItem )
01045 {
01046 KPrObject * kpobject = objectItem->object();
01047
01048 if( !kpobject ) {
01049 return;
01050 }
01051
01052 KPrCanvas* canvas = static_cast<KPrCanvas*>(m_view->canvas());
01053 canvas->deSelectAllObj();
01054 canvas->selectObj( kpobject );
01055
01056 canvas->objectPopup( kpobject, pnt );
01057 }
01058 }
01059 }
01060
01061 void KPrOutline::slotContextMenu( KListView*, QListViewItem* item, const QPoint& p )
01062 {
01063 rightButtonPressed( item, p, 0 );
01064 }
01065
01066 void KPrOutline::renamePageTitle()
01067 {
01068 QListViewItem *item = QListView::selectedItem();
01069 if( !item || m_viewMasterPage) return;
01070
01071 OutlineSlideItem* slideItem = dynamic_cast<OutlineSlideItem*>(item);
01072 if( !slideItem ) return;
01073
01074 KPrPage* page = slideItem->page();
01075 if( !page ) return;
01076
01077 bool ok = false;
01078 QString activeTitle = item->text( 0 );
01079
01080 QStringList page_titles;
01081 KPrPage *it;
01082 for ( it = m_doc->pageList().first(); it; it = m_doc->pageList().next() )
01083 if ( it->pageTitle() != activeTitle )
01084 page_titles.append( it->pageTitle() );
01085
01086 KPrRenamePageValidator validator( page_titles );
01087 QString newTitle = KInputDialog::getText( i18n("Rename Slide"),
01088 i18n("Slide title:"), activeTitle, &ok, this, 0,
01089 &validator );
01090
01091
01092 if ( ok ) {
01093 if ( newTitle != activeTitle ) {
01094 KPrChangeTitlePageNameCommand *cmd=new KPrChangeTitlePageNameCommand( i18n("Rename Slide"),
01095 m_doc, activeTitle, newTitle.stripWhiteSpace(), page );
01096 cmd->execute();
01097 m_doc->addCommand(cmd);
01098 }
01099 }
01100 }
01101
01102 QDragObject* KPrOutline::dragObject()
01103 {
01104 if( !selectedItem()->dragEnabled() ) {
01105 return 0;
01106 }
01107
01108 return KListView::dragObject();
01109 }
01110
01111 #include "KPrSideBar.moc"