File indexing completed on 2024-05-12 16:36:51

0001 /* This file is part of the KDE project
0002 *
0003 * Copyright (C) 2010 Jean-Nicolas Artaud <jeannicolasartaud@gmail.com>
0004 * Copyright (C) 2011 Paul Mendez <paulestebanms@gmail.com>
0005 *
0006 * This library is free software; you can redistribute it and/or
0007 * modify it under the terms of the GNU Library General Public
0008 * License as published by the Free Software Foundation; either
0009 * version 2 of the License, or (at your option) any later version.
0010 *
0011 * This library is distributed in the hope that it will be useful,
0012 * but WITHOUT ANY WARRANTY; without even the implied warranty of
0013 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
0014 * Library General Public License for more details.
0015 *
0016 * You should have received a copy of the GNU Library General Public License
0017 * along with this library; see the file COPYING.LIB.  If not, write to
0018 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
0019 * Boston, MA 02110-1301, USA.
0020 */
0021 
0022 #include "KPrViewModeSlidesSorter.h"
0023 #include "KPrSlidesSorterDocumentModel.h"
0024 #include "KPrFactory.h"
0025 #include "KPrSlidesManagerView.h"
0026 #include "KPrCustomSlideShowsModel.h"
0027 #include "KPrDocument.h"
0028 #include "KPrCustomSlideShows.h"
0029 #include "KPrSlidesSorterItemDelegate.h"
0030 #include "KPrView.h"
0031 #include "StageDebug.h"
0032 
0033 //Qt Headers
0034 #include <QMenu>
0035 #include <QContextMenuEvent>
0036 #include <QGridLayout>
0037 #include <QPushButton>
0038 #include <QSplitter>
0039 #include <QComboBox>
0040 #include <QLabel>
0041 #include <QPropertyAnimation>
0042 #include <QLineEdit>
0043 
0044 //Calligra Headers
0045 #include <KoDocumentResourceManager.h>
0046 #include <KoText.h>
0047 #include <KoZoomController.h>
0048 #include <KoPACanvas.h>
0049 #include <KoPADocument.h>
0050 #include <KoPAPageBase.h>
0051 #include <KoPAView.h>
0052 #include <KoCanvasController.h>
0053 #include <KoCopyController.h>
0054 #include <KoCutController.h>
0055 #include <KoViewItemContextBar.h>
0056 #include <KoComponentData.h>
0057 #include <KoIcon.h>
0058 
0059 // KF5 Headers
0060 #include <klocalizedstring.h>
0061 #include <kconfiggroup.h>
0062 #include <kmessagebox.h>
0063 #include <kactioncollection.h>
0064 
0065 const int DEFAULT_ICON_SIZE = 200;
0066 
0067 KPrViewModeSlidesSorter::KPrViewModeSlidesSorter(KoPAView *view, KoPACanvasBase *canvas)
0068     : KoPAViewMode(view, canvas)
0069     , m_slidesSorterView(new KPrSlidesManagerView())
0070     , m_customSlideShowView(new KPrSlidesManagerView())
0071     , m_slidesSorterModel(new KPrSlidesSorterDocumentModel(this, view->parentWidget()))
0072     , m_centralWidget(new QWidget())
0073     , m_customSlideShowModel(new KPrCustomSlideShowsModel(static_cast<KPrDocument *>(view->kopaDocument()), view->parentWidget()))
0074     , m_iconSize(QSize(200, 200))
0075     , m_editCustomSlideShow(false)
0076 {
0077     setName(i18n("Slides Sorter"));
0078     //Create customSlideShow GUI
0079     QWidget *m_customShowsToolBar = new QWidget();
0080 
0081     QHBoxLayout *toolBarLayout = new QHBoxLayout(m_customShowsToolBar);
0082     toolBarLayout->setMargin(0);
0083     QVBoxLayout *centralWidgetLayout = new QVBoxLayout(m_centralWidget);
0084     centralWidgetLayout->setMargin(0);
0085     centralWidgetLayout->setSpacing(0);
0086 
0087     QLabel *slideShowsLabel = new QLabel(i18n("Slide Show: "));
0088     m_customSlideShowsList = new QComboBox;
0089     m_customSlideShowsList->setEditable(false);
0090     m_customSlideShowsList->setInsertPolicy(QComboBox::NoInsert);
0091     m_customSlideShowsList->setMinimumContentsLength(30);
0092     slideShowsLabel->setBuddy(m_customSlideShowsList);
0093 
0094     m_buttonAddCustomSlideShow = new QToolButton();
0095     m_buttonAddCustomSlideShow->setIcon(koIcon("list-add"));
0096     m_buttonAddCustomSlideShow->setToolTip(i18n("Add a new custom slide show"));
0097 
0098     m_buttonDelCustomSlideShow = new QToolButton();
0099     m_buttonDelCustomSlideShow->setIcon(koIcon("list-remove"));
0100     m_buttonDelCustomSlideShow->setEnabled(false);
0101     m_buttonDelCustomSlideShow->setToolTip(i18n("Delete current custom slide show"));
0102 
0103     m_buttonAddSlideToCurrentShow = new QToolButton();
0104     m_buttonAddSlideToCurrentShow->setIcon(koIcon("arrow-down"));
0105     m_buttonAddSlideToCurrentShow->setToolTip(i18n("Add slides to current custom slide show"));
0106     m_buttonAddSlideToCurrentShow->setEnabled(false);
0107 
0108     m_buttonDelSlideFromCurrentShow = new QToolButton();
0109     m_buttonDelSlideFromCurrentShow->setIcon(koIcon("arrow-up"));
0110     m_buttonDelSlideFromCurrentShow->setToolTip(i18n("Remove slides from current custom slide show"));
0111     m_buttonDelSlideFromCurrentShow->setEnabled(false);
0112 
0113     QSplitter *viewsSplitter = new QSplitter(Qt::Vertical);
0114 
0115     //hide Custom Shows View
0116     m_customSlideShowView->setMaximumHeight(0);
0117 
0118     //Layout Widgets
0119     toolBarLayout->addWidget(slideShowsLabel);
0120     toolBarLayout->addWidget(m_customSlideShowsList);
0121     toolBarLayout->addWidget(m_buttonAddCustomSlideShow);
0122     toolBarLayout->addWidget(m_buttonDelCustomSlideShow);
0123     toolBarLayout->addStretch();
0124     toolBarLayout->addWidget(m_buttonAddSlideToCurrentShow);
0125     toolBarLayout->addWidget(m_buttonDelSlideFromCurrentShow);
0126     viewsSplitter->addWidget(m_slidesSorterView);
0127     viewsSplitter->addWidget(m_customSlideShowView);
0128 
0129     centralWidgetLayout->addWidget(viewsSplitter);
0130     centralWidgetLayout->addWidget(m_customShowsToolBar);
0131 
0132     //initialize widgets
0133     m_centralWidget->hide();
0134     m_slidesSorterView->setIconSize(m_iconSize);
0135     m_slidesSorterView->setAutoScroll(true);
0136     m_customSlideShowView->setIconSize(m_iconSize);
0137     m_customSlideShowView->setAutoScroll(true);
0138 
0139     //Populate ComboBox
0140     customShowChanged(0);
0141     updateCustomSlideShowsList();
0142 
0143     //Setup customSlideShows view
0144     m_customSlideShowView->setModel(m_customSlideShowModel);
0145     m_customSlideShowView->setSelectionBehavior(QAbstractItemView::SelectRows);
0146     m_customSlideShowView->setSelectionMode(QAbstractItemView::ExtendedSelection);
0147     m_customSlideShowView->setDragDropMode(QAbstractItemView::InternalMove);
0148     m_customSlideShowView->setSpacing(10);
0149 
0150     //Setup slides sorter view
0151     m_slidesSorterModel->setDocument(m_view->kopaDocument());
0152     m_slidesSorterView->setModel(m_slidesSorterModel);
0153     m_slidesSorterView->setSelectionBehavior(QAbstractItemView::SelectRows);
0154     m_slidesSorterView->setSelectionMode(QAbstractItemView::ExtendedSelection);
0155     m_slidesSorterView->setDragDropMode(QAbstractItemView::InternalMove);
0156     m_slidesSorterView->setSpacing(10);
0157 
0158     //setup signals
0159     connect(m_slidesSorterView, SIGNAL(requestContextMenu(QContextMenuEvent*)), this, SLOT(slidesSorterContextMenu(QContextMenuEvent*)));
0160     connect(m_customSlideShowView, SIGNAL(requestContextMenu(QContextMenuEvent*)), this, SLOT(customSlideShowsContextMenu(QContextMenuEvent*)));
0161     connect(m_slidesSorterView, SIGNAL(slideDblClick()), this, SLOT(activateNormalViewMode()));
0162     connect(m_buttonAddCustomSlideShow, SIGNAL(clicked()), this, SLOT(addCustomSlideShow()));
0163     connect(m_buttonDelCustomSlideShow, SIGNAL(clicked()), this, SLOT(removeCustomSlideShow()));
0164     connect(m_buttonAddSlideToCurrentShow, SIGNAL(clicked()), this, SLOT(addSlideToCustomShow()));
0165     connect(m_buttonDelSlideFromCurrentShow, SIGNAL(clicked()), this, SLOT(deleteSlidesFromCustomShow()));
0166     connect(m_customSlideShowModel, SIGNAL(customSlideShowsChanged()), this, SLOT(updateCustomSlideShowsList()));
0167     connect(m_customSlideShowModel, SIGNAL(selectPages(int,int)), this, SLOT(selectCustomShowPages(int,int)));
0168 
0169     //setup signals for manage edit actions
0170     connect(view->copyController(), SIGNAL(copyRequested()), this, SLOT(editCopy()));
0171     connect(view->cutController(), SIGNAL(copyRequested()), this, SLOT(editCut()));
0172     connect(view, SIGNAL(selectAllRequested()), m_slidesSorterView, SLOT(selectAll()));
0173     connect(view, SIGNAL(deselectAllRequested()), m_slidesSorterView, SLOT(clearSelection()));
0174     connect(m_slidesSorterView, SIGNAL(selectionCleared()), this, SLOT(disableEditActions()));
0175     connect(m_slidesSorterView, SIGNAL(itemSelected()), this, SLOT(enableEditActions()));
0176     connect(m_slidesSorterView, SIGNAL(focusLost()), SLOT(disableEditActions()));
0177     connect(m_slidesSorterView, SIGNAL(focusGot()), SLOT(manageAddRemoveSlidesButtons()));
0178     connect(m_slidesSorterView, SIGNAL(zoomIn()), m_view->zoomController()->zoomAction(), SLOT(zoomIn()));
0179     connect(m_slidesSorterView, SIGNAL(zoomOut()), m_view->zoomController()->zoomAction(), SLOT(zoomOut()));
0180     connect(m_customSlideShowView, SIGNAL(focusGot()), SLOT(disableEditActions()));
0181     connect(m_customSlideShowView, SIGNAL(focusGot()), SLOT(manageAddRemoveSlidesButtons()));
0182 
0183     //install selection manager for Slides Sorter View and Custom Shows View
0184     m_slidesSorterItemContextBar = new KoViewItemContextBar(m_slidesSorterView);
0185     new KoViewItemContextBar(m_customSlideShowView);
0186     QToolButton *duplicateButton = m_slidesSorterItemContextBar->addContextButton(i18n("Duplicate Slide"),QString("edit-copy"));
0187     QToolButton *deleteButton = m_slidesSorterItemContextBar->addContextButton(i18n("Delete Slide"),QString("edit-delete"));
0188     QToolButton *startPresentation = m_slidesSorterItemContextBar->addContextButton(i18n("Start Slideshow"),QString("view-presentation"));
0189     connect(view->kopaDocument(), SIGNAL(pageRemoved(KoPAPageBase*)), m_slidesSorterItemContextBar, SLOT(update()));
0190 
0191     //setup signals for item context bar buttons
0192     connect(duplicateButton, SIGNAL(clicked()), this, SLOT(contextBarDuplicateSlide()));
0193     connect(deleteButton, SIGNAL(clicked()), this, SLOT(contextBarDeleteSlide()));
0194     connect(startPresentation, SIGNAL(clicked()), this, SLOT(contextBarStartSlideshow()));
0195 
0196     //install delegate for Slides Sorter View
0197     KPrSlidesSorterItemDelegate *slidesSorterDelegate = new KPrSlidesSorterItemDelegate(m_slidesSorterView);
0198     m_slidesSorterView->setItemDelegate(slidesSorterDelegate);
0199 }
0200 
0201 KPrViewModeSlidesSorter::~KPrViewModeSlidesSorter()
0202 {
0203     //save zoom value
0204     saveZoomConfig(zoom());
0205     delete m_centralWidget;
0206 }
0207 
0208 void KPrViewModeSlidesSorter::paint(KoPACanvasBase* /*canvas*/, QPainter& /*painter*/, const QRectF &/*paintRect*/)
0209 {
0210 }
0211 
0212 void KPrViewModeSlidesSorter::paintEvent( KoPACanvas *canvas, QPaintEvent *event )
0213 {
0214     Q_UNUSED(canvas);
0215     Q_UNUSED(event);
0216     Q_ASSERT( m_canvas == canvas );
0217 }
0218 
0219 void KPrViewModeSlidesSorter::tabletEvent(QTabletEvent *event, const QPointF &point)
0220 {
0221     Q_UNUSED(event);
0222     Q_UNUSED(point);
0223 }
0224 
0225 void KPrViewModeSlidesSorter::mousePressEvent(QMouseEvent *event, const QPointF &point)
0226 {
0227     Q_UNUSED(event);
0228     Q_UNUSED(point);
0229 }
0230 
0231 void KPrViewModeSlidesSorter::mouseDoubleClickEvent(QMouseEvent *event, const QPointF &point)
0232 {
0233     Q_UNUSED(event);
0234     Q_UNUSED(point);
0235 }
0236 
0237 void KPrViewModeSlidesSorter::mouseMoveEvent(QMouseEvent *event, const QPointF &point)
0238 {
0239     Q_UNUSED(event);
0240     Q_UNUSED(point);
0241 }
0242 
0243 void KPrViewModeSlidesSorter::mouseReleaseEvent(QMouseEvent *event, const QPointF &point)
0244 {
0245     Q_UNUSED(event);
0246     Q_UNUSED(point);
0247 }
0248 
0249 void KPrViewModeSlidesSorter::shortcutOverrideEvent(QKeyEvent *event)
0250 {
0251     Q_UNUSED(event);
0252 }
0253 
0254 void KPrViewModeSlidesSorter::keyPressEvent(QKeyEvent *event)
0255 {
0256     Q_UNUSED(event);
0257 }
0258 
0259 void KPrViewModeSlidesSorter::keyReleaseEvent(QKeyEvent *event)
0260 {
0261     Q_UNUSED(event);
0262 }
0263 
0264 void KPrViewModeSlidesSorter::wheelEvent(QWheelEvent *event, const QPointF &point)
0265 {
0266     Q_UNUSED(event);
0267     Q_UNUSED(point);
0268 }
0269 
0270 void KPrViewModeSlidesSorter::activate(KoPAViewMode *previousViewMode)
0271 {
0272     Q_UNUSED(previousViewMode);
0273     KoPAView *view = dynamic_cast<KoPAView *>(m_view);
0274     if (view) {
0275         view->replaceCentralWidget(m_centralWidget);
0276     }
0277     m_slidesSorterView->setFocus(Qt::ActiveWindowFocusReason);
0278     updateToActivePageIndex();
0279 
0280     //setup signals
0281     connect(m_slidesSorterView,SIGNAL(indexChanged(QModelIndex)), this, SLOT(itemClicked(QModelIndex)));
0282     connect(m_slidesSorterView, SIGNAL(pressed(QModelIndex)), this, SLOT(itemClicked(QModelIndex)));
0283     connect(m_view->proxyObject, SIGNAL(activePageChanged()), this, SLOT(updateToActivePageIndex()));
0284 
0285     //change zoom saving slot
0286     connect(m_view->zoomController(), SIGNAL(zoomChanged(KoZoomMode::Mode,qreal)), this, SLOT(updateZoom(KoZoomMode::Mode,qreal)));
0287 
0288     KPrView *kPrview = dynamic_cast<KPrView *>(m_view);
0289     if (kPrview) {
0290         disconnect(kPrview->zoomController(), SIGNAL(zoomChanged(KoZoomMode::Mode,qreal)), kPrview, SLOT(zoomChanged(KoZoomMode::Mode,qreal)));
0291         m_view->zoomController()->zoomAction()->setZoomModes(KoZoomMode::ZOOM_CONSTANT);
0292         loadZoomConfig();
0293         disconnect(kPrview->deleteSelectionAction(), SIGNAL(triggered()), kPrview, SLOT(editDeleteSelection()));
0294         connect(kPrview->deleteSelectionAction(), SIGNAL(triggered()), this, SLOT(deleteSlide()));
0295     }
0296     m_view->setActionEnabled(KoPAView::AllActions, false);
0297 }
0298 
0299 void KPrViewModeSlidesSorter::deactivate()
0300 {
0301     // Give the resources back to the canvas
0302     m_canvas->resourceManager()->setResource(KoCanvasResourceManager::ShowTextShapeOutlines, QVariant(false));
0303     // Active the view as a basic but active one
0304     m_view->setActionEnabled(KoPAView::AllActions, true);
0305     m_view->doUpdateActivePage(m_view->activePage());
0306     KoPAView *view = dynamic_cast<KoPAView *>(m_view);
0307     if (view) {
0308         view->restoreCentralWidget();
0309     }
0310 
0311     //save zoom value
0312     saveZoomConfig(zoom());
0313 
0314     //change zoom saving slot and restore normal view zoom values
0315     disconnect(m_view->zoomController(), SIGNAL(zoomChanged(KoZoomMode::Mode,qreal)), this, SLOT(updateZoom(KoZoomMode::Mode,qreal)));
0316     m_view->zoomController()->zoomAction()->setZoomModes(KoZoomMode::ZOOM_PAGE | KoZoomMode::ZOOM_WIDTH);
0317     m_view->setActivePage(m_view->kopaDocument()->pageByIndex(m_slidesSorterView->currentIndex().row(), false));
0318 
0319     KPrView *kPrview = dynamic_cast<KPrView *>(m_view);
0320     if (kPrview) {
0321         kPrview->restoreZoomConfig();
0322         connect(kPrview->zoomController(), SIGNAL(zoomChanged(KoZoomMode::Mode,qreal)), kPrview, SLOT(zoomChanged(KoZoomMode::Mode,qreal)));
0323         connect(kPrview->deleteSelectionAction(), SIGNAL(triggered()), kPrview, SLOT(editDeleteSelection()));
0324         disconnect(kPrview->deleteSelectionAction(), SIGNAL(triggered()), this, SLOT(deleteSlide()));
0325     }
0326     disableEditActions();
0327 }
0328 
0329 void KPrViewModeSlidesSorter::updateActivePage( KoPAPageBase *page )
0330 {
0331     if (m_view->activePage() != page) {
0332         m_view->setActivePage(page);
0333     }
0334     updateToActivePageIndex();
0335 }
0336 
0337 void KPrViewModeSlidesSorter::updateToActivePageIndex()
0338 {
0339     int row = m_view->kopaDocument()->pageIndex(m_view->activePage());
0340     QModelIndex index = m_slidesSorterModel->index(row, 0, QModelIndex());
0341     m_slidesSorterView->setCurrentIndex(index);
0342 }
0343 
0344 void KPrViewModeSlidesSorter::updateActivePageToCurrentIndex()
0345 {
0346     QModelIndex c_index = m_slidesSorterView->currentIndex();
0347     m_view->setActivePage(m_view->kopaDocument()->pageByIndex(c_index.row(), false));
0348 }
0349 
0350 void KPrViewModeSlidesSorter::addShape( KoShape *shape )
0351 {
0352     Q_UNUSED(shape);
0353 }
0354 
0355 void KPrViewModeSlidesSorter::removeShape( KoShape *shape )
0356 {
0357     Q_UNUSED(shape);
0358 }
0359 
0360 QSize KPrViewModeSlidesSorter::iconSize() const
0361 {
0362     return m_iconSize;
0363 }
0364 
0365 void KPrViewModeSlidesSorter::selectSlides(const QList<KoPAPageBase *> &slides)
0366 {
0367     if (slides.isEmpty()) {
0368         return;
0369     }
0370 
0371     m_slidesSorterView->clearSelection();
0372 
0373     foreach (KoPAPageBase *slide, slides) {
0374         int row = m_view->kopaDocument()->pageIndex(slide);
0375         QModelIndex index = m_slidesSorterModel->index(row, 0, QModelIndex());
0376         if (index.isValid()) {
0377             m_slidesSorterView->selectionModel()->select(index, QItemSelectionModel::Select);
0378         }
0379     }
0380 }
0381 
0382 void KPrViewModeSlidesSorter::selectCustomShowPages(int start, int count)
0383 {
0384     if ((start < 0) || (count < 1)) {
0385         return;
0386     }
0387 
0388     m_customSlideShowView->clearSelection();
0389 
0390     for (int i = start; i < (start + count); ++i) {
0391         QModelIndex index = m_customSlideShowModel->index(i, 0, QModelIndex());
0392         if (index.isValid()) {
0393             m_customSlideShowView->selectionModel()->select(index, QItemSelectionModel::Select);
0394         }
0395     }
0396 }
0397 
0398 void KPrViewModeSlidesSorter::activateNormalViewMode()
0399 {
0400     KPrView *view = static_cast<KPrView *>(m_view);
0401     view->showNormal();
0402 }
0403 
0404 void KPrViewModeSlidesSorter::itemClicked(const QModelIndex index)
0405 {
0406     if (!index.isValid()) {
0407         return;
0408     }
0409 
0410     //Avoid deselect slides when dragging
0411     if (m_slidesSorterView->selectionModel()->selectedIndexes().length () > 1) {
0412         return;
0413     }
0414 
0415     KoPAPageBase *page = m_view->kopaDocument()->pageByIndex(index.row(), false);
0416     if (page) {
0417         m_view->setActivePage(page);
0418     }
0419     enableEditActions();
0420 }
0421 
0422 QList<KoPAPageBase *> KPrViewModeSlidesSorter::extractSelectedSlides()
0423 {
0424     QList<KoPAPageBase *> slides;
0425     QModelIndexList selectedItems = m_slidesSorterView->selectionModel()->selectedIndexes();
0426     if (selectedItems.count() == 0) {
0427         return slides;
0428     }
0429 
0430     foreach (const QModelIndex &index, selectedItems) {
0431         KoPAPageBase *page = m_view->kopaDocument()->pageByIndex(index.row (), false);
0432         if (page) {
0433             slides.append(page);
0434         }
0435     }
0436 
0437     //order slides
0438     QMap<int, KoPAPageBase*> map;
0439     foreach (KoPAPageBase *slide, slides)
0440         map.insert(m_view->kopaDocument()->pages(false).indexOf(slide), slide);
0441     slides = map.values();
0442 
0443     return slides;
0444 }
0445 
0446 void KPrViewModeSlidesSorter::deleteSlide()
0447 {
0448     if (m_slidesSorterView->hasFocus()) {
0449         // create a list with all selected slides
0450         QList<KoPAPageBase*> selectedSlides = extractSelectedSlides();
0451         m_slidesSorterModel->removeSlides(selectedSlides);
0452     }
0453     else if (m_customSlideShowView->hasFocus()) {
0454         deleteSlidesFromCustomShow();
0455     }
0456 }
0457 
0458 void KPrViewModeSlidesSorter::addSlide()
0459 {
0460     m_slidesSorterModel->addNewSlide();
0461 }
0462 
0463 void KPrViewModeSlidesSorter::renameCurrentSlide()
0464 {
0465     QModelIndexList selectedItems = m_slidesSorterView->selectionModel()->selectedIndexes();
0466     m_slidesSorterView->edit(selectedItems.first());
0467 }
0468 
0469 void KPrViewModeSlidesSorter::editCut()
0470 {
0471     editCopy();
0472     deleteSlide();
0473 }
0474 
0475 void KPrViewModeSlidesSorter::editCopy()
0476 {
0477     // separate selected layers and selected shapes
0478     QList<KoPAPageBase*> slides = extractSelectedSlides();
0479     m_slidesSorterModel->copySlides(slides);
0480 }
0481 
0482 void KPrViewModeSlidesSorter::editPaste()
0483 {
0484     m_slidesSorterModel->pasteSlides();
0485 }
0486 
0487 void KPrViewModeSlidesSorter::updateZoom(KoZoomMode::Mode mode, qreal zoom)
0488 {
0489     Q_UNUSED(mode);
0490     //at zoom 100%, iconSize is set in 200 x 200
0491     //KPrSlidesSorterDocumentModel uses iconSize function in decorate Role.
0492     //Check if is enough room for context bar
0493     int newIconSize = (zoom*DEFAULT_ICON_SIZE > m_slidesSorterItemContextBar->preferredWidth()) ?
0494                 qRound(zoom*DEFAULT_ICON_SIZE) : m_slidesSorterItemContextBar->preferredWidth();
0495     //Check if slide is not too big
0496     newIconSize = (newIconSize < qMin(m_centralWidget->size().height(), m_centralWidget->size().width())) ?
0497                 newIconSize : qMin(m_centralWidget->size().height(), m_centralWidget->size().width());
0498 
0499     setIconSize(QSize(newIconSize, newIconSize));
0500     m_slidesSorterView->setIconSize(iconSize());
0501     m_customSlideShowModel->setIconSize(iconSize());
0502     m_customSlideShowView->setIconSize(iconSize());
0503     setZoom(qRound(zoom * 100.));
0504 }
0505 
0506 void KPrViewModeSlidesSorter::setIconSize(const QSize &size)
0507 {
0508     if (size != m_iconSize) {
0509         m_iconSize = size;
0510     }
0511 }
0512 
0513 void KPrViewModeSlidesSorter::loadZoomConfig()
0514 {
0515     KSharedConfigPtr config = KPrFactory::componentData().config();
0516     int s_zoom = 100;
0517 
0518     if (config->hasGroup("Interface")) {
0519         const KConfigGroup interface = config->group("Interface");
0520         s_zoom = interface.readEntry("ZoomSlidesSorter", s_zoom);
0521     }
0522     m_view->zoomController()->setZoom(KoZoomMode::ZOOM_CONSTANT, s_zoom/100.);
0523 }
0524 
0525 void KPrViewModeSlidesSorter::saveZoomConfig(int zoom)
0526 {
0527     KSharedConfigPtr config = KPrFactory::componentData().config();
0528     KConfigGroup interface = config->group("Interface");
0529     interface.writeEntry("ZoomSlidesSorter", zoom);
0530 }
0531 
0532 void KPrViewModeSlidesSorter::setZoom(int zoom)
0533 {
0534     m_zoom = zoom;
0535 }
0536 
0537 int KPrViewModeSlidesSorter::zoom()
0538 {
0539     return m_zoom;
0540 }
0541 
0542 void KPrViewModeSlidesSorter::slidesSorterContextMenu(QContextMenuEvent *event)
0543 {
0544     QMenu menu(m_slidesSorterView);
0545     menu.addAction(koIcon("document-new"), i18n("Add a new slide"), this, SLOT(addSlide()));
0546     menu.addAction(koIcon("edit-delete"), i18n("Delete selected slides"), this, SLOT(deleteSlide()));
0547 
0548     QModelIndexList selectedItems = m_slidesSorterView->selectionModel()->selectedIndexes();
0549     if (selectedItems.count() == 1 && selectedItems.first().isValid()) {
0550         menu.addAction(koIcon("edit-rename"), i18n("Rename"), this, SLOT(renameCurrentSlide()));
0551     }
0552 
0553     menu.addSeparator();
0554     menu.addAction(koIcon("edit-cut"), i18n("Cut"), this,  SLOT(editCut()));
0555     menu.addAction(koIcon("edit-copy"), i18n("Copy"), this,  SLOT(editCopy()));
0556     menu.addAction(koIcon("edit-paste"), i18n("Paste"), this, SLOT(editPaste()));
0557     menu.exec(event->globalPos());
0558     enableEditActions();
0559 }
0560 
0561 void KPrViewModeSlidesSorter::customSlideShowsContextMenu(QContextMenuEvent *event)
0562 {
0563     QMenu menu(m_customSlideShowView);
0564     menu.addAction(koIcon("edit-delete"), i18n("Delete selected slides"), this, SLOT(deleteSlidesFromCustomShow()));
0565     menu.exec(event->globalPos());
0566 }
0567 
0568 void KPrViewModeSlidesSorter::enableEditActions()
0569 {
0570     KActionCollection *ac = canvas()->canvasController()->actionCollection();
0571     ac->action("edit_copy")->setEnabled(true);
0572     ac->action("edit_cut")->setEnabled(true);
0573     ac->action("edit_delete")->setEnabled(true);
0574 }
0575 
0576 void KPrViewModeSlidesSorter::disableEditActions()
0577 {
0578     KActionCollection *ac = canvas()->canvasController()->actionCollection();
0579     ac->action("edit_copy")->setEnabled(false);
0580     ac->action("edit_cut")->setEnabled(false);
0581     ac->action("edit_delete")->setEnabled(false);
0582 }
0583 
0584 void KPrViewModeSlidesSorter::customShowChanged(int showNumber)
0585 {
0586     QString name = m_customSlideShowsList->itemText(showNumber);
0587 
0588     bool panelVisible = true;
0589     if (showNumber < 1) {
0590         panelVisible = false;
0591         name.clear();
0592     }
0593 
0594     //Change document current custom slide show
0595     KPrDocument *doc = static_cast<KPrDocument *>(m_view->kopaDocument());
0596     doc->setActiveCustomSlideShow(name);
0597 
0598     //Decide show or hide Custom Slide Shows View
0599     if (panelVisible != m_editCustomSlideShow) {
0600         const bool animate = m_centralWidget->style()->styleHint(QStyle::SH_Widget_Animate);
0601         const int duration = animate ? 250 : 1;
0602         QPropertyAnimation *animation = new QPropertyAnimation(m_customSlideShowView, "maximumHeight");
0603 
0604         if (!panelVisible) {
0605             animation->setDuration(duration);
0606             animation->setStartValue(m_customSlideShowView->maximumHeight());
0607             animation->setEndValue(0);
0608             //Deactivate tool buttons and edition
0609             disableEditCustomShowButtons();
0610             m_slidesSorterView->setAutoScroll(true);
0611         }
0612         else {
0613             animation->setDuration(duration);
0614             animation->setStartValue(0);
0615             animation->setEndValue(m_slidesSorterView->height() / 2);
0616             //Activate tool buttons and edition
0617             enableEditCustomShowButtons();
0618             m_slidesSorterView->setAutoScroll(false);
0619         }
0620         animation->start();
0621     }
0622 
0623     m_editCustomSlideShow = panelVisible;
0624 
0625     //Populate Custom Slide Shows View if visible
0626     if (panelVisible) {
0627         m_customSlideShowModel->setActiveSlideShow(showNumber - 1);
0628     }
0629 }
0630 
0631 void KPrViewModeSlidesSorter::deleteSlidesFromCustomShow()
0632 {
0633     QModelIndexList selectedItems = m_customSlideShowView->selectionModel()->selectedIndexes();
0634     if (selectedItems.count() == 0) {
0635         return;
0636     }
0637     m_customSlideShowModel->removeSlidesByIndexes(selectedItems);
0638 }
0639 
0640 void KPrViewModeSlidesSorter::addSlideToCustomShow()
0641 {
0642     // create a list with all selected slides
0643     QList<KoPAPageBase*> selectedSlides = extractSelectedSlides();
0644     int row = (m_customSlideShowView->currentIndex().row() >= 0) ? m_customSlideShowView->currentIndex().row() + 1 : 0;
0645     m_customSlideShowModel->addSlides(selectedSlides, row);
0646 }
0647 
0648 void KPrViewModeSlidesSorter::addCustomSlideShow()
0649 {
0650     //We create a different default name for every SlideShow:
0651     static int newSlideShowsCount = 1;
0652     while(m_customSlideShowModel->customShowsNamesList().contains(i18n("Slide Show %1", newSlideShowsCount)))
0653     {
0654         ++newSlideShowsCount;
0655     }
0656 
0657     m_customSlideShowModel->addNewCustomShow(i18n("Slide Show %1", newSlideShowsCount));
0658 }
0659 
0660 
0661 void KPrViewModeSlidesSorter::removeCustomSlideShow()
0662 {
0663     m_customSlideShowModel->removeCustomShow(m_customSlideShowsList->currentText());
0664 }
0665 
0666 void KPrViewModeSlidesSorter::updateCustomSlideShowsList()
0667 {
0668     disconnect(m_customSlideShowsList, SIGNAL(currentIndexChanged(int)), this, SLOT(customShowChanged(int)));
0669 
0670     QStringList slideShows;
0671     slideShows << i18n("All slides") << (m_customSlideShowModel->customShowsNamesList());
0672     m_customSlideShowsList->clear();
0673     m_customSlideShowsList->addItems(slideShows);
0674     int index = slideShows.indexOf(m_customSlideShowModel->activeCustomSlideShow());
0675     m_customSlideShowsList->setCurrentIndex(index >= 0 ? index : 0);
0676     customShowChanged(m_customSlideShowsList->currentIndex());
0677 
0678     connect(m_customSlideShowsList, SIGNAL(currentIndexChanged(int)), this, SLOT(customShowChanged(int)));
0679 }
0680 
0681 void KPrViewModeSlidesSorter::renameCustomSlideShow()
0682 {
0683     QString newName = m_customSlideShowsList->currentText();
0684 
0685     if (newName == m_customSlideShowModel->activeCustomSlideShow()) {
0686         return;
0687     }
0688 
0689     // Empty string is not allowed as a name, if the name is empty, revert back to previous name
0690     if (newName.isEmpty()) {
0691         updateCustomSlideShowsList();
0692     }
0693     //If the name is not already in use, use it, otherwise let the user know
0694     else if (!m_customSlideShowModel->customShowsNamesList().contains(newName)) {
0695        m_customSlideShowModel->renameCustomShow(m_customSlideShowModel->activeCustomSlideShow(), newName);
0696        updateCustomSlideShowsList();
0697     }
0698     else {
0699         KMessageBox::sorry(m_customSlideShowView, i18n("There cannot be two slideshows with the same name."), i18n("Error"),
0700                            KMessageBox::Notify);
0701         updateCustomSlideShowsList();
0702     }
0703 }
0704 
0705 void KPrViewModeSlidesSorter::enableEditCustomShowButtons()
0706 {
0707     m_customSlideShowsList->setEditable(true);
0708     connect(m_customSlideShowsList->lineEdit(), SIGNAL(editingFinished()), this, SLOT(renameCustomSlideShow()));
0709     m_buttonDelCustomSlideShow->setEnabled(true);
0710 }
0711 
0712 void KPrViewModeSlidesSorter::disableEditCustomShowButtons()
0713 {
0714     m_customSlideShowsList->setEditable(false);
0715     m_buttonDelCustomSlideShow->setEnabled(false);
0716     m_buttonAddSlideToCurrentShow->setEnabled(false);
0717     m_buttonDelSlideFromCurrentShow->setEnabled(false);
0718 }
0719 
0720 void KPrViewModeSlidesSorter::manageAddRemoveSlidesButtons()
0721 {
0722     m_buttonAddSlideToCurrentShow->setEnabled(m_slidesSorterView->hasFocus() && m_editCustomSlideShow);
0723     m_buttonDelSlideFromCurrentShow->setEnabled(m_customSlideShowView->hasFocus());
0724     KActionCollection *ac = canvas()->canvasController()->actionCollection();
0725     ac->action("edit_delete")->setEnabled(m_customSlideShowView->hasFocus() ||
0726                                           !m_slidesSorterView->selectionModel()->selectedIndexes().isEmpty());
0727 }
0728 
0729 void KPrViewModeSlidesSorter::setActiveCustomSlideShow(int index)
0730 {
0731     disconnect(m_customSlideShowsList, SIGNAL(currentIndexChanged(int)), this, SLOT(customShowChanged(int)));
0732 
0733     m_customSlideShowsList->setCurrentIndex(index >= 0 && index < m_customSlideShowsList->count() ? index : 0);
0734     customShowChanged(m_customSlideShowsList->currentIndex());
0735 
0736     connect(m_customSlideShowsList, SIGNAL(currentIndexChanged(int)), this, SLOT(customShowChanged(int)));
0737 }
0738 
0739 void KPrViewModeSlidesSorter::contextBarDuplicateSlide()
0740 {
0741     QList<KoPAPageBase *> slides;
0742     KoPAPageBase *page = m_view->kopaDocument()->pageByIndex(m_slidesSorterItemContextBar->currentIndex().row (), false);
0743     if (page) {
0744         slides.append(page);
0745         updateActivePage(page);
0746         m_slidesSorterModel->copySlides(slides);
0747         editPaste();
0748     }
0749 }
0750 
0751 void KPrViewModeSlidesSorter::contextBarDeleteSlide()
0752 {
0753     QList<KoPAPageBase *> slides;
0754     if ((m_slidesSorterItemContextBar->currentIndex().row() >= 0) &&
0755             (m_slidesSorterItemContextBar->currentIndex().row() < m_slidesSorterModel->rowCount(QModelIndex()))) {
0756         KoPAPageBase *page = m_view->kopaDocument()->pageByIndex(m_slidesSorterItemContextBar->currentIndex().row(), false);
0757         if (page) {
0758             slides.append(page);
0759             m_slidesSorterModel->removeSlides(slides);
0760         }
0761     }
0762 }
0763 
0764 void KPrViewModeSlidesSorter::contextBarStartSlideshow()
0765 {
0766     KoPAPageBase *page = m_view->kopaDocument()->pageByIndex(m_slidesSorterItemContextBar->currentIndex().row (), false);
0767     updateActivePage(page);
0768     KPrView *kPrview = dynamic_cast<KPrView *>(m_view);
0769     if (kPrview) {
0770        kPrview->startPresentation();
0771     }
0772 }