Warning, file /office/calligra/libs/pageapp/KoPAView.cpp was not indexed or was modified since last indexation (in which case cross-reference links may be missing, inaccurate or erroneous).

0001 /* This file is part of the KDE project
0002 
0003    Copyright (C) 2006-2009 Thorsten Zachmann <zachmann@kde.org>
0004    Copyright (C) 2007 Thomas Zander <zander@kde.org>
0005    Copyright (C) 2009 Inge Wallin   <inge@lysator.liu.se>
0006    Copyright (C) 2010 Boudewijn Rempt <boud@kogmbh.com>
0007 
0008    This library is free software; you can redistribute it and/or
0009    modify it under the terms of the GNU Library General Public
0010    License as published by the Free Software Foundation; either
0011    version 2 of the License, or (at your option) any later version.
0012 
0013    This library is distributed in the hope that it will be useful,
0014    but WITHOUT ANY WARRANTY; without even the implied warranty of
0015    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
0016    Library General Public License for more details.
0017 
0018    You should have received a copy of the GNU Library General Public License
0019    along with this library; see the file COPYING.LIB.  If not, write to
0020    the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
0021  * Boston, MA 02110-1301, USA.
0022 */
0023 
0024 #include "KoPAView.h"
0025 
0026 #include <QGridLayout>
0027 #include <QApplication>
0028 #include <QClipboard>
0029 #include <QLabel>
0030 #include <QTabBar>
0031 
0032 #include <KoIcon.h>
0033 #include <KoShapeRegistry.h>
0034 #include <KoShapeFactoryBase.h>
0035 #include <KoProperties.h>
0036 #include <KoCanvasControllerWidget.h>
0037 #include <KoCanvasResourceManager.h>
0038 #include <KoColorBackground.h>
0039 #include <KoFind.h>
0040 #include <KoTextDocumentLayout.h>
0041 #include <KoToolManager.h>
0042 #include <KoToolProxy.h>
0043 #include <KoZoomHandler.h>
0044 #include <KoStandardAction.h>
0045 #include <KoModeBoxFactory.h>
0046 #include <KoToolBoxFactory.h>
0047 #include <KoShapeController.h>
0048 #include <KoShapeManager.h>
0049 #include <KoZoomAction.h>
0050 #include <KoZoomController.h>
0051 #include <KoInlineTextObjectManager.h>
0052 #include <KoSelection.h>
0053 #include <KoGridData.h>
0054 #include <KoGuidesData.h>
0055 #include <KoMainWindow.h>
0056 #include <KoDockerManager.h>
0057 #include <KoShapeLayer.h>
0058 #include <KoRuler.h>
0059 #include <KoRulerController.h>
0060 #include <KoDrag.h>
0061 #include <KoCutController.h>
0062 #include <KoCopyController.h>
0063 #include <KoUnit.h>
0064 
0065 #include "KoPADocumentStructureDocker.h"
0066 #include "KoShapeTraversal.h"
0067 #include "KoPACanvas.h"
0068 #include "KoPADocument.h"
0069 #include "KoPAPage.h"
0070 #include "KoPAMasterPage.h"
0071 #include "KoPAViewModeNormal.h"
0072 #include "KoPAOdfPageSaveHelper.h"
0073 #include "KoPAPastePage.h"
0074 #include "KoPAPrintJob.h"
0075 #include "commands/KoPAPageInsertCommand.h"
0076 #include "commands/KoPAChangeMasterPageCommand.h"
0077 #include "dialogs/KoPAMasterPageDialog.h"
0078 #include "dialogs/KoPAPageLayoutDialog.h"
0079 #include "dialogs/KoPAConfigureDialog.h"
0080 #include "widgets/KoPageNavigator.h"
0081 
0082 #include <PageAppDebug.h>
0083 #include <klocalizedstring.h>
0084 #include <ktoggleaction.h>
0085 #include <kactionmenu.h>
0086 #include <kactioncollection.h>
0087 #include <kmessagebox.h>
0088 #include <KoNetAccess.h>
0089 
0090 #include <QFileDialog>
0091 #include <QAction>
0092 #include <QStatusBar>
0093 #include <QTemporaryFile>
0094 #include <QUrl>
0095 
0096 
0097 class Q_DECL_HIDDEN KoPAView::Private
0098 {
0099 public:
0100     Private( KoPADocument *document )
0101     : doc( document )
0102     , canvas( 0 )
0103     , activePage( 0 )
0104     {}
0105 
0106     ~Private()
0107     {}
0108 
0109     // These were originally private in the .h file
0110     KoPADocumentStructureDocker *documentStructureDocker;
0111 
0112     KoCanvasController *canvasController;
0113     KoZoomController *zoomController;
0114     KoCopyController *copyController;
0115     KoCutController *cutController;
0116 
0117     QAction *editPaste;
0118     QAction *deleteSelectionAction;
0119 
0120     KToggleAction *actionViewSnapToGrid;
0121     KToggleAction *actionViewShowMasterPages;
0122 
0123     QAction *actionInsertPage;
0124     QAction *actionCopyPage;
0125     QAction *actionDeletePage;
0126 
0127     QAction *actionMasterPage;
0128     QAction *actionPageLayout;
0129 
0130     QAction *actionConfigure;
0131 
0132     KoRuler *horizontalRuler;
0133     KoRuler *verticalRuler;
0134     KToggleAction *viewRulers;
0135 
0136     KoZoomAction  *zoomAction;
0137 
0138     KToggleAction *showPageMargins;
0139 
0140     KoFind *find;
0141 
0142     KoPAViewMode *viewModeNormal;
0143 
0144     // This tab bar hidden by default. It could be used to alternate between view modes
0145     QTabBar *tabBar;
0146 
0147     QGridLayout *tabBarLayout;
0148     QWidget *insideWidget;
0149 
0150     // status bar
0151     KoPageNavigator *pageNavigator;
0152     QLabel *status;       ///< ordinary status
0153     QWidget *zoomActionWidget;
0154 
0155     // These used to be protected.
0156     KoPADocument *doc;
0157     KoPACanvas *canvas;
0158     KoPAPageBase *activePage;
0159 };
0160 
0161 
0162 
0163 KoPAView::KoPAView(KoPart *part, KoPADocument *document, KoPAFlags withModeBox, QWidget *parent)
0164 : KoView(part, document, parent)
0165 , d( new Private(document))
0166 {
0167     initGUI(withModeBox);
0168     initActions();
0169 
0170     if ( d->doc->pageCount() > 0 )
0171         doUpdateActivePage( d->doc->pageByIndex( 0, false ) );
0172 
0173     setAcceptDrops(true);
0174 }
0175 
0176 KoPAView::~KoPAView()
0177 {
0178     KoToolManager::instance()->removeCanvasController( d->canvasController );
0179 
0180     removeStatusBarItem(d->status);
0181     removeStatusBarItem(d->zoomActionWidget);
0182 
0183     delete d->canvasController;
0184     delete d->zoomController;
0185     delete d->viewModeNormal;
0186 
0187     delete d;
0188 }
0189 
0190 void KoPAView::addImages(const QVector<QImage> &imageList, const QPoint &insertAt)
0191 {
0192     // get position from event and convert to document coordinates
0193     QPointF pos = zoomHandler()->viewToDocument(insertAt)
0194             + kopaCanvas()->documentOffset() - kopaCanvas()->documentOrigin();
0195 
0196     // create a factory
0197     KoShapeFactoryBase *factory = KoShapeRegistry::instance()->value("PictureShape");
0198     if (!factory) {
0199         warnPageApp << "No picture shape found, cannot drop images.";
0200         return;
0201     }
0202 
0203     foreach(const QImage &image, imageList) {
0204 
0205         KoProperties params;
0206         QVariant v;
0207         v.setValue<QImage>(image);
0208         params.setProperty("qimage", v);
0209 
0210         KoShape *shape = factory->createShape(&params, d->doc->resourceManager());
0211 
0212         if (!shape) {
0213             warnPageApp << "Could not create a shape from the image";
0214             return;
0215         }
0216         shape->setPosition(pos);
0217         pos += QPointF(25,25); // increase the position for each shape we insert so the
0218                                // user can see them all.
0219         KUndo2Command *cmd = kopaCanvas()->shapeController()->addShapeDirect(shape);
0220         if (cmd) {
0221             KoSelection *selection = kopaCanvas()->shapeManager()->selection();
0222             selection->deselectAll();
0223             selection->select(shape);
0224         }
0225         kopaCanvas()->addCommand(cmd);
0226     }
0227 }
0228 
0229 
0230 void KoPAView::initGUI(KoPAFlags flags)
0231 {
0232     d->tabBarLayout = new QGridLayout(this);
0233     d->tabBarLayout->setMargin(0);
0234     d->tabBarLayout->setSpacing(0);
0235     d->insideWidget = new QWidget();
0236     QGridLayout *gridLayout = new QGridLayout(d->insideWidget);
0237     gridLayout->setMargin(0);
0238     gridLayout->setSpacing(0);
0239     setLayout(d->tabBarLayout);
0240 
0241     d->canvas = new KoPACanvas( this, d->doc, this );
0242     KoCanvasControllerWidget *canvasController = new KoCanvasControllerWidget( actionCollection(), this );
0243 
0244     if (mainWindow()) {
0245         // this needs to be done before KoCanvasControllerWidget::setCanvas is called
0246         KoPADocumentStructureDockerFactory structureDockerFactory(KoDocumentSectionView::ThumbnailMode, d->doc->pageType());
0247         d->documentStructureDocker = qobject_cast<KoPADocumentStructureDocker*>(mainWindow()->createDockWidget(&structureDockerFactory));
0248         connect(d->documentStructureDocker, SIGNAL(pageChanged(KoPAPageBase*)), proxyObject, SLOT(updateActivePage(KoPAPageBase*)));
0249         connect(d->documentStructureDocker, SIGNAL(dockerReset()), this, SLOT(reinitDocumentDocker()));
0250     }
0251 
0252     d->canvasController = canvasController;
0253     d->canvasController->setCanvas( d->canvas );
0254     KoToolManager::instance()->addController( d->canvasController );
0255     KoToolManager::instance()->registerTools( actionCollection(), d->canvasController );
0256 
0257     d->zoomController = new KoZoomController( d->canvasController, zoomHandler(), actionCollection());
0258     connect( d->zoomController, SIGNAL(zoomChanged(KoZoomMode::Mode,qreal)),
0259              this, SLOT(slotZoomChanged(KoZoomMode::Mode,qreal)) );
0260 
0261     d->zoomAction = d->zoomController->zoomAction();
0262 
0263     // page/slide navigator
0264     d->pageNavigator = new KoPageNavigator(this);
0265     addStatusBarItem(d->pageNavigator, 0);
0266 
0267     // set up status bar message
0268     d->status = new QLabel(QString(), this);
0269     d->status->setAlignment( Qt::AlignLeft | Qt::AlignVCenter );
0270     d->status->setMinimumWidth( 300 );
0271     addStatusBarItem( d->status, 1 );
0272     connect( KoToolManager::instance(), SIGNAL(changedStatusText(QString)),
0273              d->status, SLOT(setText(QString)) );
0274     d->zoomActionWidget = d->zoomAction->createWidget(  statusBar() );
0275     addStatusBarItem( d->zoomActionWidget, 0 );
0276 
0277     d->zoomController->setZoomMode( KoZoomMode::ZOOM_PAGE );
0278 
0279     d->viewModeNormal = new KoPAViewModeNormal( this, d->canvas );
0280     setViewMode(d->viewModeNormal);
0281 
0282     // The rulers
0283     d->horizontalRuler = new KoRuler(this, Qt::Horizontal, viewConverter( d->canvas ));
0284     d->horizontalRuler->setShowMousePosition(true);
0285     d->horizontalRuler->setUnit(d->doc->unit());
0286     d->verticalRuler = new KoRuler(this, Qt::Vertical, viewConverter( d->canvas ));
0287     d->verticalRuler->setUnit(d->doc->unit());
0288     d->verticalRuler->setShowMousePosition(true);
0289 
0290     new KoRulerController(d->horizontalRuler, d->canvas->resourceManager());
0291 
0292     connect(d->doc, SIGNAL(unitChanged(KoUnit)), this, SLOT(updateUnit(KoUnit)));
0293     //Layout a tab bar
0294     d->tabBar = new QTabBar();
0295     d->tabBarLayout->addWidget(d->insideWidget, 1, 1);
0296     setTabBarPosition(Qt::Horizontal);
0297 
0298     gridLayout->addWidget(d->horizontalRuler->tabChooser(), 0, 0);
0299     gridLayout->addWidget(d->horizontalRuler, 0, 1);
0300     gridLayout->addWidget(d->verticalRuler, 1, 0);
0301     gridLayout->addWidget(canvasController, 1, 1);
0302 
0303     //tab bar is hidden by default a method is provided to access to the tab bar
0304     d->tabBar->hide();
0305 
0306     connect(d->canvasController->proxyObject, SIGNAL(canvasOffsetXChanged(int)),
0307             this, SLOT(pageOffsetChanged()));
0308     connect(d->canvasController->proxyObject, SIGNAL(canvasOffsetYChanged(int)),
0309             this, SLOT(pageOffsetChanged()));
0310     connect(d->canvasController->proxyObject, SIGNAL(sizeChanged(QSize)),
0311             this, SLOT(pageOffsetChanged()));
0312     connect(d->canvasController->proxyObject, SIGNAL(canvasMousePositionChanged(QPoint)),
0313             this, SLOT(updateMousePosition(QPoint)));
0314     d->verticalRuler->createGuideToolConnection(d->canvas);
0315     d->horizontalRuler->createGuideToolConnection(d->canvas);
0316 
0317     KoMainWindow *mw = mainWindow();
0318     if (flags & KoPAView::ModeBox) {
0319         if (mw) {
0320             KoModeBoxFactory modeBoxFactory(canvasController, qApp->applicationName(), i18n("Tools"));
0321             QDockWidget* modeBox = mw->createDockWidget(&modeBoxFactory);
0322             mw->dockerManager()->removeToolOptionsDocker();
0323             dynamic_cast<KoCanvasObserverBase*>(modeBox)->setObservedCanvas(d->canvas);
0324         }
0325     } else {
0326         if (mw) {
0327             KoToolBoxFactory toolBoxFactory;
0328             mw->createDockWidget( &toolBoxFactory );
0329             connect(canvasController, SIGNAL(toolOptionWidgetsChanged(QList<QPointer<QWidget>>)),
0330             mw->dockerManager(), SLOT(newOptionWidgets(QList<QPointer<QWidget>>)));
0331         }
0332     }
0333 
0334     connect(shapeManager(), SIGNAL(selectionChanged()), this, SLOT(selectionChanged()));
0335     connect(shapeManager(), SIGNAL(contentChanged()), this, SLOT(updateCanvasSize()));
0336     connect(d->doc, SIGNAL(shapeAdded(KoShape*)), this, SLOT(updateCanvasSize()));
0337     connect(d->doc, SIGNAL(shapeRemoved(KoShape*)), this, SLOT(updateCanvasSize()));
0338     connect(d->doc, SIGNAL(update(KoPAPageBase*)), this, SLOT(pageUpdated(KoPAPageBase*)));
0339     connect(d->canvas, SIGNAL(documentSize(QSize)), d->canvasController->proxyObject, SLOT(updateDocumentSize(QSize)));
0340     connect(d->canvasController->proxyObject, SIGNAL(moveDocumentOffset(QPoint)), d->canvas, SLOT(slotSetDocumentOffset(QPoint)));
0341     connect(d->canvasController->proxyObject, SIGNAL(sizeChanged(QSize)), this, SLOT(updateCanvasSize()));
0342 
0343     if (mw) {
0344         KoToolManager::instance()->requestToolActivation( d->canvasController );
0345     }
0346 }
0347 
0348 void KoPAView::initActions()
0349 {
0350     QAction *action = actionCollection()->addAction( KStandardAction::Cut, "edit_cut", 0, 0);
0351     d->cutController = new KoCutController(kopaCanvas(), action);
0352     action = actionCollection()->addAction( KStandardAction::Copy, "edit_copy", 0, 0 );
0353     d->copyController = new KoCopyController(kopaCanvas(), action);
0354     d->editPaste = actionCollection()->addAction( KStandardAction::Paste, "edit_paste", proxyObject, SLOT(editPaste()) );
0355     connect(QApplication::clipboard(), SIGNAL(dataChanged()), this, SLOT(clipboardDataChanged()));
0356     connect(d->canvas->toolProxy(), SIGNAL(toolChanged(QString)), this, SLOT(clipboardDataChanged()));
0357     clipboardDataChanged();
0358     actionCollection()->addAction(KStandardAction::SelectAll,  "edit_select_all", this, SLOT(editSelectAll()));
0359     actionCollection()->addAction(KStandardAction::Deselect,  "edit_deselect_all", this, SLOT(editDeselectAll()));
0360 
0361     d->deleteSelectionAction = new QAction(koIcon("edit-delete"), i18n("D&elete"), this);
0362     actionCollection()->addAction("edit_delete", d->deleteSelectionAction );
0363     d->deleteSelectionAction->setShortcut(QKeySequence("Del"));
0364     d->deleteSelectionAction->setEnabled(false);
0365     connect(d->deleteSelectionAction, SIGNAL(triggered()), this, SLOT(editDeleteSelection()));
0366     connect(d->canvas->toolProxy(),    SIGNAL(selectionChanged(bool)),
0367             d->deleteSelectionAction, SLOT(setEnabled(bool)));
0368 
0369     KToggleAction *showGrid= d->doc->gridData().gridToggleAction(d->canvas);
0370     actionCollection()->addAction("view_grid", showGrid );
0371 
0372     d->actionViewSnapToGrid = new KToggleAction(i18n("Snap to Grid"), this);
0373     d->actionViewSnapToGrid->setChecked(d->doc->gridData().snapToGrid());
0374     actionCollection()->addAction("view_snaptogrid", d->actionViewSnapToGrid);
0375     connect( d->actionViewSnapToGrid, SIGNAL(triggered(bool)), this, SLOT(viewSnapToGrid(bool)));
0376 
0377     KToggleAction *actionViewShowGuides = KoStandardAction::showGuides(this, SLOT(viewGuides(bool)), this);
0378     actionViewShowGuides->setChecked( d->doc->guidesData().showGuideLines() );
0379     actionCollection()->addAction(KoStandardAction::name(KoStandardAction::ShowGuides),
0380             actionViewShowGuides );
0381 
0382     d->actionViewShowMasterPages = new KToggleAction(i18n( "Show Master Pages" ), this );
0383     actionCollection()->addAction( "view_masterpages", d->actionViewShowMasterPages );
0384     connect( d->actionViewShowMasterPages, SIGNAL(triggered(bool)), this, SLOT(setMasterMode(bool)) );
0385 
0386     d->viewRulers  = new KToggleAction(i18n("Show Rulers"), this);
0387     actionCollection()->addAction("view_rulers", d->viewRulers );
0388     d->viewRulers->setToolTip(i18n("Show/hide the view's rulers"));
0389     connect(d->viewRulers, SIGNAL(triggered(bool)), proxyObject, SLOT(setShowRulers(bool)));
0390     setShowRulers(d->doc->rulersVisible());
0391 
0392     d->showPageMargins  = new KToggleAction(i18n("Show Page Margins"), this);
0393     actionCollection()->addAction("view_page_margins", d->showPageMargins);
0394     d->showPageMargins->setToolTip(i18n("Show/hide the page margins"));
0395     connect(d->showPageMargins, SIGNAL(toggled(bool)), SLOT(setShowPageMargins(bool)));
0396     setShowPageMargins(d->doc->showPageMargins());
0397 
0398     d->actionInsertPage = new QAction(koIcon("document-new"), i18n("Insert Page"), this);
0399     actionCollection()->addAction( "page_insertpage", d->actionInsertPage );
0400     d->actionInsertPage->setToolTip( i18n( "Insert a new page after the current one" ) );
0401     d->actionInsertPage->setWhatsThis( i18n( "Insert a new page after the current one" ) );
0402     connect( d->actionInsertPage, SIGNAL(triggered()), proxyObject, SLOT(insertPage()) );
0403 
0404     d->actionCopyPage = new QAction( i18n( "Copy Page" ), this );
0405     actionCollection()->addAction( "page_copypage", d->actionCopyPage );
0406     d->actionCopyPage->setToolTip( i18n( "Copy the current page" ) );
0407     d->actionCopyPage->setWhatsThis( i18n( "Copy the current page" ) );
0408     connect( d->actionCopyPage, SIGNAL(triggered()), this, SLOT(copyPage()) );
0409 
0410     d->actionDeletePage = new QAction( i18n( "Delete Page" ), this );
0411     d->actionDeletePage->setEnabled( d->doc->pageCount() > 1 );
0412     actionCollection()->addAction( "page_deletepage", d->actionDeletePage );
0413     d->actionDeletePage->setToolTip( i18n( "Delete the current page" ) );
0414     d->actionDeletePage->setWhatsThis( i18n( "Delete the current page" ) );
0415     connect( d->actionDeletePage, SIGNAL(triggered()), this, SLOT(deletePage()) );
0416 
0417     d->actionMasterPage = new QAction(i18n("Master Page..."), this);
0418     actionCollection()->addAction("format_masterpage", d->actionMasterPage);
0419     connect(d->actionMasterPage, SIGNAL(triggered()), this, SLOT(formatMasterPage()));
0420 
0421     d->actionPageLayout = new QAction( i18n( "Page Layout..." ), this );
0422     actionCollection()->addAction( "format_pagelayout", d->actionPageLayout );
0423     connect( d->actionPageLayout, SIGNAL(triggered()), this, SLOT(formatPageLayout()) );
0424 
0425     actionCollection()->addAction(KStandardAction::Prior,  "page_previous", this, SLOT(goToPreviousPage()));
0426     actionCollection()->addAction(KStandardAction::Next,  "page_next", this, SLOT(goToNextPage()));
0427     actionCollection()->addAction(KStandardAction::FirstPage,  "page_first", this, SLOT(goToFirstPage()));
0428     actionCollection()->addAction(KStandardAction::LastPage,  "page_last", this, SLOT(goToLastPage()));
0429     d->pageNavigator->initActions();
0430 
0431     KActionMenu *actionMenu = new KActionMenu(i18n("Variable"), this);
0432     foreach(QAction *action, d->doc->inlineTextObjectManager()->createInsertVariableActions(d->canvas))
0433         actionMenu->addAction(action);
0434     actionCollection()->addAction("insert_variable", actionMenu);
0435 
0436     QAction * am = new QAction(i18n("Import Document..."), this);
0437     actionCollection()->addAction("import_document", am);
0438     connect(am, SIGNAL(triggered()), this, SLOT(importDocument()));
0439 
0440     d->actionConfigure = new QAction(koIcon("configure"), i18n("Configure..."), this);
0441     actionCollection()->addAction("configure", d->actionConfigure);
0442     connect(d->actionConfigure, SIGNAL(triggered()), this, SLOT(configure()));
0443     // not sure why this isn't done through KStandardAction, but since it isn't
0444     // we ought to set the MenuRole manually so the item ends up in the appropriate
0445     // menu on OS X:
0446     d->actionConfigure->setMenuRole(QAction::PreferencesRole);
0447 
0448     d->find = new KoFind( this, d->canvas->resourceManager(), actionCollection() );
0449     connect( d->find, SIGNAL(findDocumentSetNext(QTextDocument*)),
0450              this,    SLOT(findDocumentSetNext(QTextDocument*)) );
0451     connect( d->find, SIGNAL(findDocumentSetPrevious(QTextDocument*)),
0452              this,    SLOT(findDocumentSetPrevious(QTextDocument*)) );
0453 
0454     actionCollection()->action( "object_group" )->setShortcut( QKeySequence( "Ctrl+G" ) );
0455     actionCollection()->action( "object_ungroup" )->setShortcut( QKeySequence( "Ctrl+Shift+G" ) );
0456 
0457     connect(d->doc, &KoPADocument::actionsPossible, this, &KoPAView::setActionEnabled);
0458 }
0459 
0460 KoCanvasController *KoPAView::canvasController() const
0461 {
0462     return d->canvasController;
0463 }
0464 
0465 KoPACanvasBase * KoPAView::kopaCanvas() const
0466 {
0467     return d->canvas;
0468 }
0469 
0470 KoPADocument * KoPAView::kopaDocument() const
0471 {
0472     return d->doc;
0473 }
0474 
0475 KoPAPageBase* KoPAView::activePage() const
0476 {
0477     return d->activePage;
0478 }
0479 
0480 void KoPAView::updateReadWrite( bool readwrite )
0481 {
0482     Q_UNUSED(readwrite);
0483 }
0484 
0485 KoRuler* KoPAView::horizontalRuler()
0486 {
0487     return d->horizontalRuler;
0488 }
0489 
0490 KoRuler* KoPAView::verticalRuler()
0491 {
0492     return d->verticalRuler;
0493 }
0494 
0495 void KoPAView::setShowPageMargins(bool state)
0496 {
0497     d->showPageMargins->setChecked(state);
0498     d->canvas->setShowPageMargins(state);
0499     d->doc->setShowPageMargins(state);
0500 }
0501 
0502 KoZoomController* KoPAView::zoomController() const
0503 {
0504     return d->zoomController;
0505 }
0506 
0507 KoCopyController* KoPAView::copyController() const
0508 {
0509     return d->copyController;
0510 }
0511 
0512 KoCutController* KoPAView::cutController() const
0513 {
0514     return d->cutController;
0515 }
0516 
0517 QAction * KoPAView::deleteSelectionAction() const
0518 {
0519     return d->deleteSelectionAction;
0520 }
0521 
0522 void KoPAView::importDocument()
0523 {
0524     QFileDialog *dialog = new QFileDialog( /* QT5TODO: QUrl("kfiledialog:///OpenDialog"),*/ this );
0525     dialog->setObjectName( "file dialog" );
0526     dialog->setFileMode( QFileDialog::AnyFile );
0527     if ( d->doc->pageType() == KoPageApp::Slide ) {
0528         dialog->setWindowTitle(i18n("Import Slideshow"));
0529     }
0530     else {
0531         dialog->setWindowTitle(i18n("Import Document"));
0532     }
0533 
0534     // TODO make it possible to select also other supported types (than the default format) here.
0535     // this needs to go via the filters to get the file in the correct format.
0536     // For now we only support the native mime types
0537     QStringList mimeFilter;
0538 
0539     mimeFilter << KoOdf::mimeType( d->doc->documentType() ) << KoOdf::templateMimeType( d->doc->documentType() );
0540 
0541     dialog->setMimeTypeFilters( mimeFilter );
0542     if (dialog->exec() == QDialog::Accepted) {
0543         QUrl url(dialog->selectedUrls().first());
0544         QString tmpFile;
0545         if ( KIO::NetAccess::download( url, tmpFile, 0 ) ) {
0546             QFile file( tmpFile );
0547             file.open( QIODevice::ReadOnly );
0548             QByteArray ba;
0549             ba = file.readAll();
0550 
0551             // set the correct mime type as otherwise it does not find the correct tag when loading
0552             QMimeData data;
0553             data.setData( KoOdf::mimeType( d->doc->documentType() ), ba);
0554             KoPAPastePage paste( d->doc,d->activePage );
0555             if ( ! paste.paste( d->doc->documentType(), &data ) ) {
0556                 KMessageBox::error(0, i18n("Could not import\n%1", url.url(QUrl::PreferLocalFile)));
0557             }
0558         }
0559         else {
0560             KMessageBox::error(0, i18n("Could not import\n%1", url.url(QUrl::PreferLocalFile)));
0561         }
0562     }
0563     delete dialog;
0564 }
0565 
0566 void KoPAView::viewSnapToGrid(bool snap)
0567 {
0568     d->doc->gridData().setSnapToGrid(snap);
0569     d->actionViewSnapToGrid->setChecked(snap);
0570 }
0571 
0572 void KoPAView::viewGuides(bool show)
0573 {
0574     d->doc->guidesData().setShowGuideLines(show);
0575     d->canvas->update();
0576 }
0577 
0578 void KoPAView::editPaste()
0579 {
0580     if ( !d->canvas->toolProxy()->paste() ) {
0581         pagePaste();
0582     }
0583 }
0584 
0585 void KoPAView::pagePaste()
0586 {
0587     const QMimeData * data = QApplication::clipboard()->mimeData();
0588 
0589     KoOdf::DocumentType documentTypes[] = { KoOdf::Graphics, KoOdf::Presentation };
0590 
0591     for ( unsigned int i = 0; i < sizeof( documentTypes ) / sizeof( KoOdf::DocumentType ); ++i )
0592     {
0593         if ( data->hasFormat( KoOdf::mimeType( documentTypes[i] ) ) ) {
0594             KoPAPastePage paste( d->doc, d->activePage );
0595             paste.paste( documentTypes[i], data );
0596             break;
0597         }
0598     }
0599 }
0600 
0601 void KoPAView::editDeleteSelection()
0602 {
0603     d->canvas->toolProxy()->deleteSelection();
0604 }
0605 
0606 void KoPAView::editSelectAll()
0607 {
0608     KoSelection* selection = kopaCanvas()->shapeManager()->selection();
0609     if( !selection )
0610         return;
0611     if (!this->isVisible()) {
0612         emit selectAllRequested();
0613         return;
0614     }
0615 
0616     QList<KoShape*> shapes = activePage()->shapes();
0617 
0618     foreach( KoShape *shape, shapes ) {
0619         KoShapeLayer *layer = dynamic_cast<KoShapeLayer *>( shape );
0620 
0621         if ( layer ) {
0622             QList<KoShape*> layerShapes( layer->shapes() );
0623             foreach( KoShape *layerShape, layerShapes ) {
0624                 selection->select( layerShape );
0625                 layerShape->update();
0626             }
0627         }
0628     }
0629 
0630     selectionChanged();
0631 }
0632 
0633 void KoPAView::editDeselectAll()
0634 {
0635     if (!this->isVisible()) {
0636         emit deselectAllRequested();
0637         return;
0638     }
0639 
0640     KoSelection* selection = kopaCanvas()->shapeManager()->selection();
0641     if( selection )
0642         selection->deselectAll();
0643 
0644     selectionChanged();
0645     d->canvas->update();
0646 }
0647 
0648 void KoPAView::formatMasterPage()
0649 {
0650     KoPAPage *page = dynamic_cast<KoPAPage *>(d->activePage);
0651     Q_ASSERT(page);
0652     KoPAMasterPageDialog *dialog = new KoPAMasterPageDialog(d->doc, page->masterPage(), d->canvas);
0653 
0654     if (dialog->exec() == QDialog::Accepted) {
0655         KoPAMasterPage *masterPage = dialog->selectedMasterPage();
0656         KoPAPage *page = dynamic_cast<KoPAPage *>(d->activePage);
0657         if (page) {
0658             KoPAChangeMasterPageCommand * command = new KoPAChangeMasterPageCommand( d->doc, page, masterPage );
0659             d->canvas->addCommand( command );
0660         }
0661     }
0662 
0663     delete dialog;
0664 }
0665 
0666 void KoPAView::formatPageLayout()
0667 {
0668     const KoPageLayout &pageLayout = viewMode()->activePageLayout();
0669 
0670     KoPAPageLayoutDialog dialog( d->doc, pageLayout, d->canvas );
0671 
0672     if ( dialog.exec() == QDialog::Accepted ) {
0673         KUndo2Command *command = new KUndo2Command( kundo2_i18n( "Change page layout" ) );
0674         viewMode()->changePageLayout( dialog.pageLayout(), dialog.applyToDocument(), command );
0675 
0676         d->canvas->addCommand( command );
0677     }
0678 
0679 }
0680 
0681 void KoPAView::slotZoomChanged( KoZoomMode::Mode mode, qreal zoom )
0682 {
0683     Q_UNUSED(zoom);
0684     if (d->activePage) {
0685         if (mode == KoZoomMode::ZOOM_PAGE) {
0686             const KoPageLayout &layout = viewMode()->activePageLayout();
0687             QRectF pageRect( 0, 0, layout.width, layout.height );
0688             d->canvasController->ensureVisible(d->canvas->viewConverter()->documentToView(pageRect));
0689         } else if (mode == KoZoomMode::ZOOM_WIDTH) {
0690             // horizontally center the page
0691             const KoPageLayout &layout = viewMode()->activePageLayout();
0692             QRectF pageRect( 0, 0, layout.width, layout.height );
0693             QRect viewRect = d->canvas->viewConverter()->documentToView(pageRect).toRect();
0694             viewRect.translate(d->canvas->documentOrigin());
0695             QRect currentVisible(qMax(0, -d->canvasController->canvasOffsetX()), qMax(0, -d->canvasController->canvasOffsetY()), d->canvasController->visibleWidth(), d->canvasController->visibleHeight());
0696             int horizontalMove = viewRect.center().x() - currentVisible.center().x();
0697             d->canvasController->pan(QPoint(horizontalMove, 0));
0698         }
0699         updateCanvasSize(true);
0700     }
0701 }
0702 
0703 void KoPAView::configure()
0704 {
0705     openConfiguration();
0706     // TODO update canvas
0707 }
0708 
0709 void KoPAView::openConfiguration()
0710 {
0711     QPointer<KoPAConfigureDialog> dialog(new KoPAConfigureDialog(this));
0712     dialog->exec();
0713     delete dialog;
0714 }
0715 
0716 void KoPAView::setMasterMode( bool master )
0717 {
0718     viewMode()->setMasterMode( master );
0719     if (mainWindow()) {
0720         d->documentStructureDocker->setMasterMode(master);
0721     }
0722     d->actionMasterPage->setEnabled(!master);
0723 
0724     QList<KoPAPageBase*> pages = d->doc->pages( master );
0725     d->actionDeletePage->setEnabled( pages.size() > 1 );
0726 }
0727 
0728 KoShapeManager* KoPAView::shapeManager() const
0729 {
0730     return d->canvas->shapeManager();
0731 }
0732 
0733 
0734 KoShapeManager* KoPAView::masterShapeManager() const
0735 {
0736     return d->canvas->masterShapeManager();
0737 }
0738 
0739 void KoPAView::reinitDocumentDocker()
0740 {
0741     if (mainWindow()) {
0742         d->documentStructureDocker->setActivePage( d->activePage );
0743     }
0744 }
0745 
0746 void KoPAView::pageUpdated(KoPAPageBase* page)
0747 {
0748     // if the page was updated its content e.g. master page has been changed. Therefore we need to
0749     // set the page again to set the shapes of the new master page and get a repaint. Without this
0750     // changing the master page does not update the page.
0751     if (d->activePage == page) {
0752         doUpdateActivePage(page);
0753     }
0754 }
0755 
0756 void KoPAView::updateCanvasSize(bool forceUpdate)
0757 {
0758     const KoPageLayout &layout = viewMode()->activePageLayout();
0759     QPoint scrollValue(d->canvasController->scrollBarValue());
0760 
0761     QSizeF pageSize(layout.width, layout.height);
0762     QSizeF viewportSize = d->canvasController->viewportSize();
0763 
0764     //calculate size of union page + viewport
0765     QSizeF documentMinSize(qMax(zoomHandler()->unzoomItX(viewportSize.width()), layout.width),
0766                         qMax(zoomHandler()->unzoomItY(viewportSize.height()), layout.height));
0767 
0768     // create a rect out of it with origin in tp left of page
0769     QRectF documentRect(QPointF((documentMinSize.width() - layout.width) * -0.5,
0770                                (documentMinSize.height() - layout.height) * -0.5),
0771                        documentMinSize);
0772 
0773     // Now make a union with the bounding rect of all shapes
0774     // Fetch boundingRect like this as a viewmode might have set other shapes than the page
0775     foreach (KoShape *layer, d->canvas->shapeManager()->shapes()) {
0776         if (! dynamic_cast<KoShapeLayer *>(layer)) {
0777             documentRect = documentRect.united(layer->boundingRect());
0778         }
0779     }
0780 
0781     QPointF offset = -documentRect.topLeft();
0782     QPoint scrollChange = d->canvas->documentOrigin() - zoomHandler()->documentToView(offset).toPoint();
0783 
0784     if (forceUpdate || scrollChange != QPoint(0, 0)
0785                     || d->zoomController->documentSize() != documentRect.size()
0786                     || d->zoomController->pageSize() != pageSize) {
0787         d->horizontalRuler->setRulerLength(layout.width);
0788         d->verticalRuler->setRulerLength(layout.height);
0789         d->horizontalRuler->setActiveRange(layout.leftMargin, layout.width - layout.rightMargin);
0790         d->verticalRuler->setActiveRange(layout.topMargin, layout.height - layout.bottomMargin);
0791         QSizeF documentSize(documentRect.size());
0792         d->canvas->setDocumentOrigin(offset);
0793         d->zoomController->setDocumentSize(documentSize);
0794 
0795         d->canvas->resourceManager()->setResource(KoCanvasResourceManager::PageSize, pageSize);
0796 
0797         d->canvas->update();
0798         QSize documentPxSize(zoomHandler()->zoomItX(documentRect.width()), zoomHandler()->zoomItY(documentRect.height()));
0799         d->canvasController->proxyObject->updateDocumentSize(documentPxSize);
0800         // this can trigger a change of the zoom level in "fit to mode" and therefore this needs to be at the end as it calls this function again
0801         d->zoomController->setPageSize(pageSize);
0802     }
0803 }
0804 
0805 void KoPAView::doUpdateActivePage( KoPAPageBase * page )
0806 {
0807     bool pageChanged = page != d->activePage;
0808     setActivePage( page );
0809 
0810     updateCanvasSize(true);
0811 
0812     updatePageNavigationActions();
0813 
0814     if ( pageChanged ) {
0815         proxyObject->emitActivePageChanged();
0816     }
0817 
0818     pageOffsetChanged();
0819 }
0820 
0821 void KoPAView::setActivePage( KoPAPageBase* page )
0822 {
0823     if ( !page )
0824         return;
0825 
0826     bool pageChanged = page != d->activePage;
0827 
0828     shapeManager()->removeAdditional( d->activePage );
0829     d->activePage = page;
0830     shapeManager()->addAdditional( d->activePage );
0831     QList<KoShape*> shapes = page->shapes();
0832     shapeManager()->setShapes(shapes, KoShapeManager::AddWithoutRepaint);
0833     //Make the top most layer active
0834     if ( !shapes.isEmpty() ) {
0835         KoShapeLayer* layer = dynamic_cast<KoShapeLayer*>( shapes.last() );
0836         shapeManager()->selection()->setActiveLayer( layer );
0837     }
0838 
0839     // if the page is not a master page itself set shapes of the master page
0840     KoPAPage * paPage = dynamic_cast<KoPAPage *>( page );
0841     if ( paPage ) {
0842         KoPAMasterPage * masterPage = paPage->masterPage();
0843         QList<KoShape*> masterShapes = masterPage->shapes();
0844         masterShapeManager()->setShapes(masterShapes, KoShapeManager::AddWithoutRepaint);
0845         //Make the top most layer active
0846         if ( !masterShapes.isEmpty() ) {
0847             KoShapeLayer* layer = dynamic_cast<KoShapeLayer*>( masterShapes.last() );
0848             masterShapeManager()->selection()->setActiveLayer( layer );
0849         }
0850     }
0851     else {
0852         // if the page is a master page no shapes are in the masterShapeManager
0853         masterShapeManager()->setShapes( QList<KoShape*>() );
0854     }
0855 
0856     if ( mainWindow() && pageChanged ) {
0857         d->documentStructureDocker->setActivePage(d->activePage);
0858         proxyObject->emitActivePageChanged();
0859     }
0860 
0861     // Set the current page number in the canvas resource provider
0862     d->canvas->resourceManager()->setResource( KoCanvasResourceManager::CurrentPage, d->doc->pageIndex(d->activePage)+1 );
0863 }
0864 
0865 void KoPAView::navigatePage( KoPageApp::PageNavigation pageNavigation )
0866 {
0867     KoPAPageBase * newPage = d->doc->pageByNavigation( d->activePage, pageNavigation );
0868 
0869     if ( newPage != d->activePage ) {
0870         proxyObject->updateActivePage( newPage );
0871     }
0872 }
0873 
0874 KoPrintJob * KoPAView::createPrintJob()
0875 {
0876     return new KoPAPrintJob(this);
0877 }
0878 
0879 void KoPAView::pageOffsetChanged()
0880 {
0881     QPoint documentOrigin(d->canvas->documentOrigin());
0882     d->horizontalRuler->setOffset(d->canvasController->canvasOffsetX() + documentOrigin.x());
0883     d->verticalRuler->setOffset(d->canvasController->canvasOffsetY() + documentOrigin.y());
0884 }
0885 
0886 void KoPAView::updateMousePosition(const QPoint& position)
0887 {
0888     const QPoint canvasOffset( d->canvasController->canvasOffsetX(), d->canvasController->canvasOffsetY() );
0889     const QPoint viewPos = position - d->canvas->documentOrigin() - canvasOffset;
0890 
0891     d->horizontalRuler->updateMouseCoordinate(viewPos.x());
0892     d->verticalRuler->updateMouseCoordinate(viewPos.y());
0893 
0894     // Update the selection borders in the rulers while moving with the mouse
0895     if(d->canvas->shapeManager()->selection() && (d->canvas->shapeManager()->selection()->count() > 0)) {
0896         QRectF boundingRect = d->canvas->shapeManager()->selection()->boundingRect();
0897         d->horizontalRuler->updateSelectionBorders(boundingRect.x(), boundingRect.right());
0898         d->verticalRuler->updateSelectionBorders(boundingRect.y(), boundingRect.bottom());
0899     }
0900 }
0901 
0902 void KoPAView::selectionChanged()
0903 {
0904     // Show the borders of the selection in the rulers
0905     if(d->canvas->shapeManager()->selection() && (d->canvas->shapeManager()->selection()->count() > 0)) {
0906         QRectF boundingRect = d->canvas->shapeManager()->selection()->boundingRect();
0907         d->horizontalRuler->setShowSelectionBorders(true);
0908         d->verticalRuler->setShowSelectionBorders(true);
0909         d->horizontalRuler->updateSelectionBorders(boundingRect.x(), boundingRect.right());
0910         d->verticalRuler->updateSelectionBorders(boundingRect.y(), boundingRect.bottom());
0911     } else {
0912         d->horizontalRuler->setShowSelectionBorders(false);
0913         d->verticalRuler->setShowSelectionBorders(false);
0914     }
0915 }
0916 
0917 void KoPAView::setShowRulers(bool show)
0918 {
0919     d->horizontalRuler->setVisible(show);
0920     d->verticalRuler->setVisible(show);
0921 
0922     d->viewRulers->setChecked(show);
0923     d->doc->setRulersVisible(show);
0924 }
0925 
0926 void KoPAView::insertPage()
0927 {
0928     KoPAPageBase * page = 0;
0929     if ( viewMode()->masterMode() ) {
0930         KoPAMasterPage * masterPage = d->doc->newMasterPage();
0931         masterPage->setBackground(QSharedPointer<KoColorBackground>(new KoColorBackground(Qt::white)));
0932         // use the layout of the current active page for the new page
0933         KoPageLayout & layout = masterPage->pageLayout();
0934         KoPAMasterPage * activeMasterPage = dynamic_cast<KoPAMasterPage *>( d->activePage );
0935         if ( activeMasterPage ) {
0936             layout = activeMasterPage->pageLayout();
0937         }
0938         page = masterPage;
0939     }
0940     else {
0941         KoPAPage * activePage = static_cast<KoPAPage*>( d->activePage );
0942         KoPAMasterPage * masterPage = activePage->masterPage();
0943         page = d->doc->newPage( masterPage );
0944     }
0945 
0946     KoPAPageInsertCommand * command = new KoPAPageInsertCommand( d->doc, page, d->activePage );
0947     d->canvas->addCommand( command );
0948 
0949     doUpdateActivePage(page);
0950 }
0951 
0952 void KoPAView::copyPage()
0953 {
0954     QList<KoPAPageBase *> pages;
0955     pages.append( d->activePage );
0956     KoPAOdfPageSaveHelper saveHelper( d->doc, pages );
0957     KoDrag drag;
0958     drag.setOdf( KoOdf::mimeType( d->doc->documentType() ), saveHelper );
0959     drag.addToClipboard();
0960 }
0961 
0962 void KoPAView::deletePage()
0963 {
0964     if ( !isMasterUsed( d->activePage ) ) {
0965         d->doc->removePage( d->activePage );
0966     }
0967 }
0968 
0969 void KoPAView::setActionEnabled( int actions, bool enable )
0970 {
0971     if ( actions & ActionInsertPage )
0972     {
0973         d->actionInsertPage->setEnabled( enable );
0974     }
0975     if ( actions & ActionCopyPage )
0976     {
0977         d->actionCopyPage->setEnabled( enable );
0978     }
0979     if ( actions & ActionDeletePage )
0980     {
0981         d->actionDeletePage->setEnabled( enable );
0982     }
0983     if ( actions & ActionViewShowMasterPages )
0984     {
0985         d->actionViewShowMasterPages->setEnabled( enable );
0986     }
0987     if ( actions & ActionFormatMasterPage )
0988     {
0989         d->actionMasterPage->setEnabled( enable );
0990     }
0991 }
0992 
0993 void KoPAView::setViewMode(KoPAViewMode* mode)
0994 {
0995     KoPAViewMode* previousViewMode = viewMode();
0996     KoPAViewBase::setViewMode(mode);
0997 
0998     if (previousViewMode && mode != previousViewMode) {
0999         disconnect(d->doc, SIGNAL(shapeAdded(KoShape*)), previousViewMode, SLOT(addShape(KoShape*)));
1000         disconnect(d->doc, SIGNAL(shapeRemoved(KoShape*)), previousViewMode, SLOT(removeShape(KoShape*)));
1001     }
1002     connect(d->doc, SIGNAL(shapeAdded(KoShape*)), mode, SLOT(addShape(KoShape*)));
1003     connect(d->doc, SIGNAL(shapeRemoved(KoShape*)), mode, SLOT(removeShape(KoShape*)));
1004 }
1005 
1006 QPixmap KoPAView::pageThumbnail(KoPAPageBase* page, const QSize& size)
1007 {
1008     return d->doc->pageThumbnail(page, size);
1009 }
1010 
1011 bool KoPAView::exportPageThumbnail( KoPAPageBase * page, const QUrl &url, const QSize& size,
1012                                     const char * format, int quality )
1013 {
1014     bool res = false;
1015     QPixmap pix = d->doc->pageThumbnail( page, size );
1016     if ( !pix.isNull() ) {
1017         // Depending on the desired target size due to rounding
1018         // errors during zoom the resulting pixmap *might* be
1019         // 1 pixel or 2 pixels wider/higher than desired: we just
1020         // remove the additional columns/rows.  This can be done
1021         // since Stage is leaving a minimal border below/at
1022         // the right of the image anyway.
1023         if ( size != pix.size() ) {
1024             pix = pix.copy( 0, 0, size.width(), size.height() );
1025         }
1026         // save the pixmap to the desired file
1027         QUrl fileUrl( url );
1028         if ( fileUrl.scheme().isEmpty() ) {
1029             fileUrl.setScheme( "file" );
1030         }
1031         const bool bLocalFile = fileUrl.isLocalFile();
1032         QTemporaryFile* tmpFile = bLocalFile ? 0 : new QTemporaryFile();
1033         if( bLocalFile || tmpFile->open() ) {
1034             QFile file( bLocalFile ? fileUrl.path() : tmpFile->fileName() );
1035             if ( file.open( QIODevice::ReadWrite ) ) {
1036                 res = pix.save( &file, format, quality );
1037                 file.close();
1038             }
1039             if ( !bLocalFile ) {
1040                 if ( res ) {
1041                     res = KIO::NetAccess::upload( tmpFile->fileName(), fileUrl, this );
1042                 }
1043             }
1044         }
1045         if ( !bLocalFile ) {
1046             delete tmpFile;
1047         }
1048    }
1049    return res;
1050 }
1051 
1052 KoPADocumentStructureDocker* KoPAView::documentStructureDocker() const
1053 {
1054     return d->documentStructureDocker;
1055 }
1056 
1057 void KoPAView::clipboardDataChanged()
1058 {
1059     const QMimeData* data = QApplication::clipboard()->mimeData();
1060     bool paste = false;
1061 
1062     if (data)
1063     {
1064         // TODO see if we can use the KoPasteController instead of having to add this feature in each calligra app.
1065         QStringList mimeTypes = d->canvas->toolProxy()->supportedPasteMimeTypes();
1066         mimeTypes << KoOdf::mimeType( KoOdf::Graphics );
1067         mimeTypes << KoOdf::mimeType( KoOdf::Presentation );
1068 
1069         foreach(const QString & mimeType, mimeTypes)
1070         {
1071             if ( data->hasFormat( mimeType ) ) {
1072                 paste = true;
1073                 break;
1074             }
1075         }
1076 
1077     }
1078 
1079     d->editPaste->setEnabled(paste);
1080 }
1081 
1082 void KoPAView::goToPreviousPage()
1083 {
1084     navigatePage( KoPageApp::PagePrevious );
1085 }
1086 
1087 void KoPAView::goToNextPage()
1088 {
1089     navigatePage( KoPageApp::PageNext );
1090 }
1091 
1092 void KoPAView::goToFirstPage()
1093 {
1094     navigatePage( KoPageApp::PageFirst );
1095 }
1096 
1097 void KoPAView::goToLastPage()
1098 {
1099     navigatePage( KoPageApp::PageLast );
1100 }
1101 
1102 void KoPAView::findDocumentSetNext( QTextDocument * document )
1103 {
1104     KoPAPageBase * page = 0;
1105     KoShape * startShape = 0;
1106     KoTextDocumentLayout *lay = document ? qobject_cast<KoTextDocumentLayout*>(document->documentLayout()) : 0;
1107     if ( lay != 0 ) {
1108         startShape = lay->shapes().value( 0 );
1109         Q_ASSERT( startShape->shapeId() == "TextShapeID" );
1110         page = d->doc->pageByShape( startShape );
1111         if ( d->doc->pageIndex( page ) == -1 ) {
1112             page = 0;
1113         }
1114     }
1115 
1116     if ( page == 0 ) {
1117         page = d->activePage;
1118         startShape = page;
1119     }
1120 
1121     KoShape * shape = startShape;
1122 
1123     do {
1124         // find next text shape
1125         shape = KoShapeTraversal::nextShape( shape, "TextShapeID" );
1126         // get next text shape
1127         if ( shape != 0 ) {
1128             if ( page != d->activePage ) {
1129                 setActivePage( page );
1130                 d->canvas->update();
1131             }
1132             KoSelection* selection = kopaCanvas()->shapeManager()->selection();
1133             selection->deselectAll();
1134             selection->select( shape );
1135             // TODO can this be done nicer? is there a way to get the shape id and the tool id from the shape?
1136             KoToolManager::instance()->switchToolRequested( "TextToolFactory_ID" );
1137             break;
1138         }
1139         else {
1140             //if none is found go to next page and try again
1141             if ( d->doc->pageIndex( page ) < d->doc->pages().size() - 1 ) {
1142                 // TODO use also master slides
1143                 page = d->doc->pageByNavigation( page, KoPageApp::PageNext );
1144             }
1145             else {
1146                 page = d->doc->pageByNavigation( page, KoPageApp::PageFirst );
1147             }
1148             shape = page;
1149         }
1150         // do until you find the same start shape or you are on the same page again only if there was none
1151     } while ( page != startShape );
1152 }
1153 
1154 void KoPAView::findDocumentSetPrevious( QTextDocument * document )
1155 {
1156     KoPAPageBase * page = 0;
1157     KoShape * startShape = 0;
1158     KoTextDocumentLayout *lay = document ? qobject_cast<KoTextDocumentLayout*>(document->documentLayout()) : 0;
1159     if ( lay != 0 ) {
1160         startShape = lay->shapes().value( 0 );
1161         Q_ASSERT( startShape->shapeId() == "TextShapeID" );
1162         page = d->doc->pageByShape( startShape );
1163         if ( d->doc->pageIndex( page ) == -1 ) {
1164             page = 0;
1165         }
1166     }
1167 
1168     bool check = false;
1169     if ( page == 0 ) {
1170         page = d->activePage;
1171         startShape = KoShapeTraversal::last( page );
1172         check = true;
1173     }
1174 
1175     KoShape * shape = startShape;
1176 
1177     do {
1178         if ( !check || shape->shapeId() != "TextShapeID" ) {
1179             shape = KoShapeTraversal::previousShape( shape, "TextShapeID" );
1180         }
1181         // get next text shape
1182         if ( shape != 0 ) {
1183             if ( page != d->activePage ) {
1184                 setActivePage( page );
1185                 d->canvas->update();
1186             }
1187             KoSelection* selection = kopaCanvas()->shapeManager()->selection();
1188             selection->deselectAll();
1189             selection->select( shape );
1190             // TODO can this be done nicer? is there a way to get the shape id and the tool id from the shape?
1191             KoToolManager::instance()->switchToolRequested( "TextToolFactory_ID" );
1192             break;
1193         }
1194         else {
1195             //if none is found go to next page and try again
1196             if ( d->doc->pageIndex( page ) > 0 ) {
1197                 // TODO use also master slides
1198                 page = d->doc->pageByNavigation( page, KoPageApp::PagePrevious );
1199             }
1200             else {
1201                 page = d->doc->pageByNavigation( page, KoPageApp::PageLast );
1202             }
1203             shape = KoShapeTraversal::last( page );
1204             check = true;
1205         }
1206         // do until you find the same start shape or you are on the same page again only if there was none
1207     } while ( shape != startShape );
1208 }
1209 
1210 void KoPAView::updatePageNavigationActions()
1211 {
1212     int index = d->doc->pageIndex(activePage());
1213     int pageCount = d->doc->pages(viewMode()->masterMode()).count();
1214 
1215     actionCollection()->action("page_previous")->setEnabled(index > 0);
1216     actionCollection()->action("page_first")->setEnabled(index > 0);
1217     actionCollection()->action("page_next")->setEnabled(index < pageCount - 1);
1218     actionCollection()->action("page_last")->setEnabled(index < pageCount - 1);
1219 }
1220 
1221 bool KoPAView::isMasterUsed( KoPAPageBase * page )
1222 {
1223     KoPAMasterPage * master = dynamic_cast<KoPAMasterPage *>( page );
1224 
1225     bool used = false;
1226 
1227     if ( master ) {
1228         QList<KoPAPageBase*> pages = d->doc->pages();
1229         foreach( KoPAPageBase * page, pages ) {
1230             KoPAPage * p = dynamic_cast<KoPAPage *>( page );
1231             Q_ASSERT( p );
1232             if ( p && p->masterPage() == master ) {
1233                 used = true;
1234                 break;
1235             }
1236         }
1237     }
1238 
1239     return used;
1240 }
1241 
1242 void KoPAView::centerPage()
1243 {
1244     KoPageLayout &layout = d->activePage->pageLayout();
1245     QSizeF pageSize( layout.width, layout.height );
1246 
1247     QPoint documentCenter =
1248         zoomHandler()->documentToView(QPoint(pageSize.width(),
1249                                               pageSize.height())).toPoint();
1250 
1251     d->canvasController->setPreferredCenter(documentCenter);
1252     d->canvasController->recenterPreferred();
1253 
1254 }
1255 
1256 QTabBar *KoPAView::tabBar() const
1257 {
1258     return d->tabBar;
1259 }
1260 
1261 void KoPAView::replaceCentralWidget(QWidget *newWidget)
1262 {
1263     // hide standard central widget
1264     d->insideWidget->hide();
1265     // If there is already a custom central widget, it's hided and removed from the layout
1266     hideCustomCentralWidget();
1267     // layout and show new custom widget
1268     d->tabBarLayout->addWidget(newWidget, 2, 1);
1269     newWidget->show();
1270 }
1271 
1272 void KoPAView::restoreCentralWidget()
1273 {
1274     //hide custom central widget
1275     hideCustomCentralWidget();
1276     //show standard central widget
1277     d->insideWidget->show();
1278 }
1279 
1280 void KoPAView::hideCustomCentralWidget()
1281 {
1282     if (d->tabBarLayout->itemAtPosition(2, 1)) {
1283         if (d->tabBarLayout->itemAtPosition(2, 1)->widget()) {
1284             d->tabBarLayout->itemAtPosition(2, 1)->widget()->hide();
1285         }
1286         d->tabBarLayout->removeItem(d->tabBarLayout->itemAtPosition(2, 1));
1287     }
1288 }
1289 
1290 void KoPAView::setTabBarPosition(Qt::Orientation orientation)
1291 {
1292     switch (orientation) {
1293     case Qt::Horizontal:
1294         d->tabBarLayout->removeWidget(d->tabBar);
1295         d->tabBar->setShape(QTabBar::RoundedNorth);
1296         d->tabBarLayout->addWidget(d->tabBar, 0, 1);
1297         break;
1298     case Qt::Vertical:
1299         d->tabBarLayout->removeWidget(d->tabBar);
1300         d->tabBar->setShape(QTabBar::RoundedWest);
1301         d->tabBarLayout->addWidget(d->tabBar, 1, 0, 2, 1, Qt::AlignTop);
1302         break;
1303     default:
1304         break;
1305     }
1306 }
1307 
1308 void KoPAView::updateUnit(const KoUnit &unit)
1309 {
1310     d->horizontalRuler->setUnit(unit);
1311     d->verticalRuler->setUnit(unit);
1312     d->canvas->resourceManager()->setResource(KoCanvasResourceManager::Unit, unit);
1313 }