1 /* This file is part of the KDE project
2
3 Copyright (C) 2006-2009 Thorsten Zachmann <zachmann@kde.org>
4 Copyright (C) 2007 Thomas Zander <zander@kde.org>
5 Copyright (C) 2009 Inge Wallin <inge@lysator.liu.se>
6 Copyright (C) 2010 Boudewijn Rempt <boud@kogmbh.com>
7
8 This library is free software; you can redistribute it and/or
9 modify it under the terms of the GNU Library General Public
10 License as published by the Free Software Foundation; either
11 version 2 of the License, or (at your option) any later version.
12
13 This library is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 Library General Public License for more details.
17
18 You should have received a copy of the GNU Library General Public License
19 along with this library; see the file COPYING.LIB. If not, write to
20 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
21 * Boston, MA 02110-1301, USA.
22 */
23
24 #include "KoPAView.h"
25
26 #include <QGridLayout>
27 #include <QApplication>
28 #include <QClipboard>
29 #include <QLabel>
30 #include <QTabBar>
31
32 #include <KoIcon.h>
33 #include <KoShapeRegistry.h>
34 #include <KoShapeFactoryBase.h>
35 #include <KoProperties.h>
36 #include <KoCanvasControllerWidget.h>
37 #include <KoCanvasResourceManager.h>
38 #include <KoColorBackground.h>
39 #include <KoFind.h>
40 #include <KoTextDocumentLayout.h>
41 #include <KoToolManager.h>
42 #include <KoToolProxy.h>
43 #include <KoZoomHandler.h>
44 #include <KoStandardAction.h>
45 #include <KoModeBoxFactory.h>
46 #include <KoToolBoxFactory.h>
47 #include <KoShapeController.h>
48 #include <KoShapeManager.h>
49 #include <KoZoomAction.h>
50 #include <KoZoomController.h>
51 #include <KoInlineTextObjectManager.h>
52 #include <KoSelection.h>
53 #include <KoGridData.h>
54 #include <KoGuidesData.h>
55 #include <KoMainWindow.h>
56 #include <KoDockerManager.h>
57 #include <KoShapeLayer.h>
58 #include <KoRuler.h>
59 #include <KoRulerController.h>
60 #include <KoDrag.h>
61 #include <KoCutController.h>
62 #include <KoCopyController.h>
63 #include <KoUnit.h>
64
65 #include "KoPADocumentStructureDocker.h"
66 #include "KoShapeTraversal.h"
67 #include "KoPACanvas.h"
68 #include "KoPADocument.h"
69 #include "KoPAPage.h"
70 #include "KoPAMasterPage.h"
71 #include "KoPAViewModeNormal.h"
72 #include "KoPAOdfPageSaveHelper.h"
73 #include "KoPAPastePage.h"
74 #include "KoPAPrintJob.h"
75 #include "commands/KoPAPageInsertCommand.h"
76 #include "commands/KoPAChangeMasterPageCommand.h"
77 #include "dialogs/KoPAMasterPageDialog.h"
78 #include "dialogs/KoPAPageLayoutDialog.h"
79 #include "dialogs/KoPAConfigureDialog.h"
80 #include "widgets/KoPageNavigator.h"
81
82 #include <PageAppDebug.h>
83 #include <klocalizedstring.h>
84 #include <ktoggleaction.h>
85 #include <kactionmenu.h>
86 #include <kactioncollection.h>
87 #include <kmessagebox.h>
88 #include <KoNetAccess.h>
89
90 #include <QFileDialog>
91 #include <QAction>
92 #include <QStatusBar>
93 #include <QTemporaryFile>
94 #include <QUrl>
95
96
97 class Q_DECL_HIDDEN KoPAView::Private
98 {
99 public:
Private(KoPADocument * document)100 Private( KoPADocument *document )
101 : doc( document )
102 , canvas( 0 )
103 , activePage( 0 )
104 {}
105
~Private()106 ~Private()
107 {}
108
109 // These were originally private in the .h file
110 KoPADocumentStructureDocker *documentStructureDocker;
111
112 KoCanvasController *canvasController;
113 KoZoomController *zoomController;
114 KoCopyController *copyController;
115 KoCutController *cutController;
116
117 QAction *editPaste;
118 QAction *deleteSelectionAction;
119
120 KToggleAction *actionViewSnapToGrid;
121 KToggleAction *actionViewShowMasterPages;
122
123 QAction *actionInsertPage;
124 QAction *actionCopyPage;
125 QAction *actionDeletePage;
126
127 QAction *actionMasterPage;
128 QAction *actionPageLayout;
129
130 QAction *actionConfigure;
131
132 KoRuler *horizontalRuler;
133 KoRuler *verticalRuler;
134 KToggleAction *viewRulers;
135
136 KoZoomAction *zoomAction;
137
138 KToggleAction *showPageMargins;
139
140 KoFind *find;
141
142 KoPAViewMode *viewModeNormal;
143
144 // This tab bar hidden by default. It could be used to alternate between view modes
145 QTabBar *tabBar;
146
147 QGridLayout *tabBarLayout;
148 QWidget *insideWidget;
149
150 // status bar
151 KoPageNavigator *pageNavigator;
152 QLabel *status; ///< ordinary status
153 QWidget *zoomActionWidget;
154
155 // These used to be protected.
156 KoPADocument *doc;
157 KoPACanvas *canvas;
158 KoPAPageBase *activePage;
159 };
160
161
162
KoPAView(KoPart * part,KoPADocument * document,KoPAFlags withModeBox,QWidget * parent)163 KoPAView::KoPAView(KoPart *part, KoPADocument *document, KoPAFlags withModeBox, QWidget *parent)
164 : KoView(part, document, parent)
165 , d( new Private(document))
166 {
167 initGUI(withModeBox);
168 initActions();
169
170 if ( d->doc->pageCount() > 0 )
171 doUpdateActivePage( d->doc->pageByIndex( 0, false ) );
172
173 setAcceptDrops(true);
174 }
175
~KoPAView()176 KoPAView::~KoPAView()
177 {
178 KoToolManager::instance()->removeCanvasController( d->canvasController );
179
180 removeStatusBarItem(d->status);
181 removeStatusBarItem(d->zoomActionWidget);
182
183 delete d->canvasController;
184 delete d->zoomController;
185 delete d->viewModeNormal;
186
187 delete d;
188 }
189
addImages(const QVector<QImage> & imageList,const QPoint & insertAt)190 void KoPAView::addImages(const QVector<QImage> &imageList, const QPoint &insertAt)
191 {
192 // get position from event and convert to document coordinates
193 QPointF pos = zoomHandler()->viewToDocument(insertAt)
194 + kopaCanvas()->documentOffset() - kopaCanvas()->documentOrigin();
195
196 // create a factory
197 KoShapeFactoryBase *factory = KoShapeRegistry::instance()->value("PictureShape");
198 if (!factory) {
199 warnPageApp << "No picture shape found, cannot drop images.";
200 return;
201 }
202
203 foreach(const QImage &image, imageList) {
204
205 KoProperties params;
206 QVariant v;
207 v.setValue<QImage>(image);
208 params.setProperty("qimage", v);
209
210 KoShape *shape = factory->createShape(¶ms, d->doc->resourceManager());
211
212 if (!shape) {
213 warnPageApp << "Could not create a shape from the image";
214 return;
215 }
216 shape->setPosition(pos);
217 pos += QPointF(25,25); // increase the position for each shape we insert so the
218 // user can see them all.
219 KUndo2Command *cmd = kopaCanvas()->shapeController()->addShapeDirect(shape);
220 if (cmd) {
221 KoSelection *selection = kopaCanvas()->shapeManager()->selection();
222 selection->deselectAll();
223 selection->select(shape);
224 }
225 kopaCanvas()->addCommand(cmd);
226 }
227 }
228
229
initGUI(KoPAFlags flags)230 void KoPAView::initGUI(KoPAFlags flags)
231 {
232 d->tabBarLayout = new QGridLayout(this);
233 d->tabBarLayout->setMargin(0);
234 d->tabBarLayout->setSpacing(0);
235 d->insideWidget = new QWidget();
236 QGridLayout *gridLayout = new QGridLayout(d->insideWidget);
237 gridLayout->setMargin(0);
238 gridLayout->setSpacing(0);
239 setLayout(d->tabBarLayout);
240
241 d->canvas = new KoPACanvas( this, d->doc, this );
242 KoCanvasControllerWidget *canvasController = new KoCanvasControllerWidget( actionCollection(), this );
243
244 if (mainWindow()) {
245 // this needs to be done before KoCanvasControllerWidget::setCanvas is called
246 KoPADocumentStructureDockerFactory structureDockerFactory(KoDocumentSectionView::ThumbnailMode, d->doc->pageType());
247 d->documentStructureDocker = qobject_cast<KoPADocumentStructureDocker*>(mainWindow()->createDockWidget(&structureDockerFactory));
248 connect(d->documentStructureDocker, SIGNAL(pageChanged(KoPAPageBase*)), proxyObject, SLOT(updateActivePage(KoPAPageBase*)));
249 connect(d->documentStructureDocker, SIGNAL(dockerReset()), this, SLOT(reinitDocumentDocker()));
250 }
251
252 d->canvasController = canvasController;
253 d->canvasController->setCanvas( d->canvas );
254 KoToolManager::instance()->addController( d->canvasController );
255 KoToolManager::instance()->registerTools( actionCollection(), d->canvasController );
256
257 d->zoomController = new KoZoomController( d->canvasController, zoomHandler(), actionCollection());
258 connect( d->zoomController, SIGNAL(zoomChanged(KoZoomMode::Mode,qreal)),
259 this, SLOT(slotZoomChanged(KoZoomMode::Mode,qreal)) );
260
261 d->zoomAction = d->zoomController->zoomAction();
262
263 // page/slide navigator
264 d->pageNavigator = new KoPageNavigator(this);
265 addStatusBarItem(d->pageNavigator, 0);
266
267 // set up status bar message
268 d->status = new QLabel(QString(), this);
269 d->status->setAlignment( Qt::AlignLeft | Qt::AlignVCenter );
270 d->status->setMinimumWidth( 300 );
271 addStatusBarItem( d->status, 1 );
272 connect( KoToolManager::instance(), SIGNAL(changedStatusText(QString)),
273 d->status, SLOT(setText(QString)) );
274 d->zoomActionWidget = d->zoomAction->createWidget( statusBar() );
275 addStatusBarItem( d->zoomActionWidget, 0 );
276
277 d->zoomController->setZoomMode( KoZoomMode::ZOOM_PAGE );
278
279 d->viewModeNormal = new KoPAViewModeNormal( this, d->canvas );
280 setViewMode(d->viewModeNormal);
281
282 // The rulers
283 d->horizontalRuler = new KoRuler(this, Qt::Horizontal, viewConverter( d->canvas ));
284 d->horizontalRuler->setShowMousePosition(true);
285 d->horizontalRuler->setUnit(d->doc->unit());
286 d->verticalRuler = new KoRuler(this, Qt::Vertical, viewConverter( d->canvas ));
287 d->verticalRuler->setUnit(d->doc->unit());
288 d->verticalRuler->setShowMousePosition(true);
289
290 new KoRulerController(d->horizontalRuler, d->canvas->resourceManager());
291
292 connect(d->doc, SIGNAL(unitChanged(KoUnit)), this, SLOT(updateUnit(KoUnit)));
293 //Layout a tab bar
294 d->tabBar = new QTabBar();
295 d->tabBarLayout->addWidget(d->insideWidget, 1, 1);
296 setTabBarPosition(Qt::Horizontal);
297
298 gridLayout->addWidget(d->horizontalRuler->tabChooser(), 0, 0);
299 gridLayout->addWidget(d->horizontalRuler, 0, 1);
300 gridLayout->addWidget(d->verticalRuler, 1, 0);
301 gridLayout->addWidget(canvasController, 1, 1);
302
303 //tab bar is hidden by default a method is provided to access to the tab bar
304 d->tabBar->hide();
305
306 connect(d->canvasController->proxyObject, SIGNAL(canvasOffsetXChanged(int)),
307 this, SLOT(pageOffsetChanged()));
308 connect(d->canvasController->proxyObject, SIGNAL(canvasOffsetYChanged(int)),
309 this, SLOT(pageOffsetChanged()));
310 connect(d->canvasController->proxyObject, SIGNAL(sizeChanged(QSize)),
311 this, SLOT(pageOffsetChanged()));
312 connect(d->canvasController->proxyObject, SIGNAL(canvasMousePositionChanged(QPoint)),
313 this, SLOT(updateMousePosition(QPoint)));
314 d->verticalRuler->createGuideToolConnection(d->canvas);
315 d->horizontalRuler->createGuideToolConnection(d->canvas);
316
317 KoMainWindow *mw = mainWindow();
318 if (flags & KoPAView::ModeBox) {
319 if (mw) {
320 KoModeBoxFactory modeBoxFactory(canvasController, qApp->applicationName(), i18n("Tools"));
321 QDockWidget* modeBox = mw->createDockWidget(&modeBoxFactory);
322 mw->dockerManager()->removeToolOptionsDocker();
323 dynamic_cast<KoCanvasObserverBase*>(modeBox)->setObservedCanvas(d->canvas);
324 }
325 } else {
326 if (mw) {
327 KoToolBoxFactory toolBoxFactory;
328 mw->createDockWidget( &toolBoxFactory );
329 connect(canvasController, SIGNAL(toolOptionWidgetsChanged(QList<QPointer<QWidget>>)),
330 mw->dockerManager(), SLOT(newOptionWidgets(QList<QPointer<QWidget>>)));
331 }
332 }
333
334 connect(shapeManager(), SIGNAL(selectionChanged()), this, SLOT(selectionChanged()));
335 connect(shapeManager(), SIGNAL(contentChanged()), this, SLOT(updateCanvasSize()));
336 connect(d->doc, SIGNAL(shapeAdded(KoShape*)), this, SLOT(updateCanvasSize()));
337 connect(d->doc, SIGNAL(shapeRemoved(KoShape*)), this, SLOT(updateCanvasSize()));
338 connect(d->doc, SIGNAL(update(KoPAPageBase*)), this, SLOT(pageUpdated(KoPAPageBase*)));
339 connect(d->canvas, SIGNAL(documentSize(QSize)), d->canvasController->proxyObject, SLOT(updateDocumentSize(QSize)));
340 connect(d->canvasController->proxyObject, SIGNAL(moveDocumentOffset(QPoint)), d->canvas, SLOT(slotSetDocumentOffset(QPoint)));
341 connect(d->canvasController->proxyObject, SIGNAL(sizeChanged(QSize)), this, SLOT(updateCanvasSize()));
342
343 if (mw) {
344 KoToolManager::instance()->requestToolActivation( d->canvasController );
345 }
346 }
347
initActions()348 void KoPAView::initActions()
349 {
350 QAction *action = actionCollection()->addAction( KStandardAction::Cut, "edit_cut", 0, 0);
351 d->cutController = new KoCutController(kopaCanvas(), action);
352 action = actionCollection()->addAction( KStandardAction::Copy, "edit_copy", 0, 0 );
353 d->copyController = new KoCopyController(kopaCanvas(), action);
354 d->editPaste = actionCollection()->addAction( KStandardAction::Paste, "edit_paste", proxyObject, SLOT(editPaste()) );
355 connect(QApplication::clipboard(), SIGNAL(dataChanged()), this, SLOT(clipboardDataChanged()));
356 connect(d->canvas->toolProxy(), SIGNAL(toolChanged(QString)), this, SLOT(clipboardDataChanged()));
357 clipboardDataChanged();
358 actionCollection()->addAction(KStandardAction::SelectAll, "edit_select_all", this, SLOT(editSelectAll()));
359 actionCollection()->addAction(KStandardAction::Deselect, "edit_deselect_all", this, SLOT(editDeselectAll()));
360
361 d->deleteSelectionAction = new QAction(koIcon("edit-delete"), i18n("D&elete"), this);
362 actionCollection()->addAction("edit_delete", d->deleteSelectionAction );
363 d->deleteSelectionAction->setShortcut(QKeySequence("Del"));
364 d->deleteSelectionAction->setEnabled(false);
365 connect(d->deleteSelectionAction, SIGNAL(triggered()), this, SLOT(editDeleteSelection()));
366 connect(d->canvas->toolProxy(), SIGNAL(selectionChanged(bool)),
367 d->deleteSelectionAction, SLOT(setEnabled(bool)));
368
369 KToggleAction *showGrid= d->doc->gridData().gridToggleAction(d->canvas);
370 actionCollection()->addAction("view_grid", showGrid );
371
372 d->actionViewSnapToGrid = new KToggleAction(i18n("Snap to Grid"), this);
373 d->actionViewSnapToGrid->setChecked(d->doc->gridData().snapToGrid());
374 actionCollection()->addAction("view_snaptogrid", d->actionViewSnapToGrid);
375 connect( d->actionViewSnapToGrid, SIGNAL(triggered(bool)), this, SLOT(viewSnapToGrid(bool)));
376
377 KToggleAction *actionViewShowGuides = KoStandardAction::showGuides(this, SLOT(viewGuides(bool)), this);
378 actionViewShowGuides->setChecked( d->doc->guidesData().showGuideLines() );
379 actionCollection()->addAction(KoStandardAction::name(KoStandardAction::ShowGuides),
380 actionViewShowGuides );
381
382 d->actionViewShowMasterPages = new KToggleAction(i18n( "Show Master Pages" ), this );
383 actionCollection()->addAction( "view_masterpages", d->actionViewShowMasterPages );
384 connect( d->actionViewShowMasterPages, SIGNAL(triggered(bool)), this, SLOT(setMasterMode(bool)) );
385
386 d->viewRulers = new KToggleAction(i18n("Show Rulers"), this);
387 actionCollection()->addAction("view_rulers", d->viewRulers );
388 d->viewRulers->setToolTip(i18n("Show/hide the view's rulers"));
389 connect(d->viewRulers, SIGNAL(triggered(bool)), proxyObject, SLOT(setShowRulers(bool)));
390 setShowRulers(d->doc->rulersVisible());
391
392 d->showPageMargins = new KToggleAction(i18n("Show Page Margins"), this);
393 actionCollection()->addAction("view_page_margins", d->showPageMargins);
394 d->showPageMargins->setToolTip(i18n("Show/hide the page margins"));
395 connect(d->showPageMargins, SIGNAL(toggled(bool)), SLOT(setShowPageMargins(bool)));
396 setShowPageMargins(d->doc->showPageMargins());
397
398 d->actionInsertPage = new QAction(koIcon("document-new"), i18n("Insert Page"), this);
399 actionCollection()->addAction( "page_insertpage", d->actionInsertPage );
400 d->actionInsertPage->setToolTip( i18n( "Insert a new page after the current one" ) );
401 d->actionInsertPage->setWhatsThis( i18n( "Insert a new page after the current one" ) );
402 connect( d->actionInsertPage, SIGNAL(triggered()), proxyObject, SLOT(insertPage()) );
403
404 d->actionCopyPage = new QAction( i18n( "Copy Page" ), this );
405 actionCollection()->addAction( "page_copypage", d->actionCopyPage );
406 d->actionCopyPage->setToolTip( i18n( "Copy the current page" ) );
407 d->actionCopyPage->setWhatsThis( i18n( "Copy the current page" ) );
408 connect( d->actionCopyPage, SIGNAL(triggered()), this, SLOT(copyPage()) );
409
410 d->actionDeletePage = new QAction( i18n( "Delete Page" ), this );
411 d->actionDeletePage->setEnabled( d->doc->pageCount() > 1 );
412 actionCollection()->addAction( "page_deletepage", d->actionDeletePage );
413 d->actionDeletePage->setToolTip( i18n( "Delete the current page" ) );
414 d->actionDeletePage->setWhatsThis( i18n( "Delete the current page" ) );
415 connect( d->actionDeletePage, SIGNAL(triggered()), this, SLOT(deletePage()) );
416
417 d->actionMasterPage = new QAction(i18n("Master Page..."), this);
418 actionCollection()->addAction("format_masterpage", d->actionMasterPage);
419 connect(d->actionMasterPage, SIGNAL(triggered()), this, SLOT(formatMasterPage()));
420
421 d->actionPageLayout = new QAction( i18n( "Page Layout..." ), this );
422 actionCollection()->addAction( "format_pagelayout", d->actionPageLayout );
423 connect( d->actionPageLayout, SIGNAL(triggered()), this, SLOT(formatPageLayout()) );
424
425 actionCollection()->addAction(KStandardAction::Prior, "page_previous", this, SLOT(goToPreviousPage()));
426 actionCollection()->addAction(KStandardAction::Next, "page_next", this, SLOT(goToNextPage()));
427 actionCollection()->addAction(KStandardAction::FirstPage, "page_first", this, SLOT(goToFirstPage()));
428 actionCollection()->addAction(KStandardAction::LastPage, "page_last", this, SLOT(goToLastPage()));
429 d->pageNavigator->initActions();
430
431 KActionMenu *actionMenu = new KActionMenu(i18n("Variable"), this);
432 foreach(QAction *action, d->doc->inlineTextObjectManager()->createInsertVariableActions(d->canvas))
433 actionMenu->addAction(action);
434 actionCollection()->addAction("insert_variable", actionMenu);
435
436 QAction * am = new QAction(i18n("Import Document..."), this);
437 actionCollection()->addAction("import_document", am);
438 connect(am, SIGNAL(triggered()), this, SLOT(importDocument()));
439
440 d->actionConfigure = new QAction(koIcon("configure"), i18n("Configure..."), this);
441 actionCollection()->addAction("configure", d->actionConfigure);
442 connect(d->actionConfigure, SIGNAL(triggered()), this, SLOT(configure()));
443 // not sure why this isn't done through KStandardAction, but since it isn't
444 // we ought to set the MenuRole manually so the item ends up in the appropriate
445 // menu on OS X:
446 d->actionConfigure->setMenuRole(QAction::PreferencesRole);
447
448 d->find = new KoFind( this, d->canvas->resourceManager(), actionCollection() );
449 connect( d->find, SIGNAL(findDocumentSetNext(QTextDocument*)),
450 this, SLOT(findDocumentSetNext(QTextDocument*)) );
451 connect( d->find, SIGNAL(findDocumentSetPrevious(QTextDocument*)),
452 this, SLOT(findDocumentSetPrevious(QTextDocument*)) );
453
454 actionCollection()->action( "object_group" )->setShortcut( QKeySequence( "Ctrl+G" ) );
455 actionCollection()->action( "object_ungroup" )->setShortcut( QKeySequence( "Ctrl+Shift+G" ) );
456
457 connect(d->doc, &KoPADocument::actionsPossible, this, &KoPAView::setActionEnabled);
458 }
459
canvasController() const460 KoCanvasController *KoPAView::canvasController() const
461 {
462 return d->canvasController;
463 }
464
kopaCanvas() const465 KoPACanvasBase * KoPAView::kopaCanvas() const
466 {
467 return d->canvas;
468 }
469
kopaDocument() const470 KoPADocument * KoPAView::kopaDocument() const
471 {
472 return d->doc;
473 }
474
activePage() const475 KoPAPageBase* KoPAView::activePage() const
476 {
477 return d->activePage;
478 }
479
updateReadWrite(bool readwrite)480 void KoPAView::updateReadWrite( bool readwrite )
481 {
482 Q_UNUSED(readwrite);
483 }
484
horizontalRuler()485 KoRuler* KoPAView::horizontalRuler()
486 {
487 return d->horizontalRuler;
488 }
489
verticalRuler()490 KoRuler* KoPAView::verticalRuler()
491 {
492 return d->verticalRuler;
493 }
494
setShowPageMargins(bool state)495 void KoPAView::setShowPageMargins(bool state)
496 {
497 d->showPageMargins->setChecked(state);
498 d->canvas->setShowPageMargins(state);
499 d->doc->setShowPageMargins(state);
500 }
501
zoomController() const502 KoZoomController* KoPAView::zoomController() const
503 {
504 return d->zoomController;
505 }
506
copyController() const507 KoCopyController* KoPAView::copyController() const
508 {
509 return d->copyController;
510 }
511
cutController() const512 KoCutController* KoPAView::cutController() const
513 {
514 return d->cutController;
515 }
516
deleteSelectionAction() const517 QAction * KoPAView::deleteSelectionAction() const
518 {
519 return d->deleteSelectionAction;
520 }
521
importDocument()522 void KoPAView::importDocument()
523 {
524 QFileDialog *dialog = new QFileDialog( /* QT5TODO: QUrl("kfiledialog:///OpenDialog"),*/ this );
525 dialog->setObjectName( "file dialog" );
526 dialog->setFileMode( QFileDialog::AnyFile );
527 if ( d->doc->pageType() == KoPageApp::Slide ) {
528 dialog->setWindowTitle(i18n("Import Slideshow"));
529 }
530 else {
531 dialog->setWindowTitle(i18n("Import Document"));
532 }
533
534 // TODO make it possible to select also other supported types (than the default format) here.
535 // this needs to go via the filters to get the file in the correct format.
536 // For now we only support the native mime types
537 QStringList mimeFilter;
538
539 mimeFilter << KoOdf::mimeType( d->doc->documentType() ) << KoOdf::templateMimeType( d->doc->documentType() );
540
541 dialog->setMimeTypeFilters( mimeFilter );
542 if (dialog->exec() == QDialog::Accepted) {
543 QUrl url(dialog->selectedUrls().first());
544 QString tmpFile;
545 if ( KIO::NetAccess::download( url, tmpFile, 0 ) ) {
546 QFile file( tmpFile );
547 file.open( QIODevice::ReadOnly );
548 QByteArray ba;
549 ba = file.readAll();
550
551 // set the correct mime type as otherwise it does not find the correct tag when loading
552 QMimeData data;
553 data.setData( KoOdf::mimeType( d->doc->documentType() ), ba);
554 KoPAPastePage paste( d->doc,d->activePage );
555 if ( ! paste.paste( d->doc->documentType(), &data ) ) {
556 KMessageBox::error(0, i18n("Could not import\n%1", url.url(QUrl::PreferLocalFile)));
557 }
558 }
559 else {
560 KMessageBox::error(0, i18n("Could not import\n%1", url.url(QUrl::PreferLocalFile)));
561 }
562 }
563 delete dialog;
564 }
565
viewSnapToGrid(bool snap)566 void KoPAView::viewSnapToGrid(bool snap)
567 {
568 d->doc->gridData().setSnapToGrid(snap);
569 d->actionViewSnapToGrid->setChecked(snap);
570 }
571
viewGuides(bool show)572 void KoPAView::viewGuides(bool show)
573 {
574 d->doc->guidesData().setShowGuideLines(show);
575 d->canvas->update();
576 }
577
editPaste()578 void KoPAView::editPaste()
579 {
580 if ( !d->canvas->toolProxy()->paste() ) {
581 pagePaste();
582 }
583 }
584
pagePaste()585 void KoPAView::pagePaste()
586 {
587 const QMimeData * data = QApplication::clipboard()->mimeData();
588
589 KoOdf::DocumentType documentTypes[] = { KoOdf::Graphics, KoOdf::Presentation };
590
591 for ( unsigned int i = 0; i < sizeof( documentTypes ) / sizeof( KoOdf::DocumentType ); ++i )
592 {
593 if ( data->hasFormat( KoOdf::mimeType( documentTypes[i] ) ) ) {
594 KoPAPastePage paste( d->doc, d->activePage );
595 paste.paste( documentTypes[i], data );
596 break;
597 }
598 }
599 }
600
editDeleteSelection()601 void KoPAView::editDeleteSelection()
602 {
603 d->canvas->toolProxy()->deleteSelection();
604 }
605
editSelectAll()606 void KoPAView::editSelectAll()
607 {
608 KoSelection* selection = kopaCanvas()->shapeManager()->selection();
609 if( !selection )
610 return;
611 if (!this->isVisible()) {
612 emit selectAllRequested();
613 return;
614 }
615
616 QList<KoShape*> shapes = activePage()->shapes();
617
618 foreach( KoShape *shape, shapes ) {
619 KoShapeLayer *layer = dynamic_cast<KoShapeLayer *>( shape );
620
621 if ( layer ) {
622 QList<KoShape*> layerShapes( layer->shapes() );
623 foreach( KoShape *layerShape, layerShapes ) {
624 selection->select( layerShape );
625 layerShape->update();
626 }
627 }
628 }
629
630 selectionChanged();
631 }
632
editDeselectAll()633 void KoPAView::editDeselectAll()
634 {
635 if (!this->isVisible()) {
636 emit deselectAllRequested();
637 return;
638 }
639
640 KoSelection* selection = kopaCanvas()->shapeManager()->selection();
641 if( selection )
642 selection->deselectAll();
643
644 selectionChanged();
645 d->canvas->update();
646 }
647
formatMasterPage()648 void KoPAView::formatMasterPage()
649 {
650 KoPAPage *page = dynamic_cast<KoPAPage *>(d->activePage);
651 Q_ASSERT(page);
652 KoPAMasterPageDialog *dialog = new KoPAMasterPageDialog(d->doc, page->masterPage(), d->canvas);
653
654 if (dialog->exec() == QDialog::Accepted) {
655 KoPAMasterPage *masterPage = dialog->selectedMasterPage();
656 KoPAPage *page = dynamic_cast<KoPAPage *>(d->activePage);
657 if (page) {
658 KoPAChangeMasterPageCommand * command = new KoPAChangeMasterPageCommand( d->doc, page, masterPage );
659 d->canvas->addCommand( command );
660 }
661 }
662
663 delete dialog;
664 }
665
formatPageLayout()666 void KoPAView::formatPageLayout()
667 {
668 const KoPageLayout &pageLayout = viewMode()->activePageLayout();
669
670 KoPAPageLayoutDialog dialog( d->doc, pageLayout, d->canvas );
671
672 if ( dialog.exec() == QDialog::Accepted ) {
673 KUndo2Command *command = new KUndo2Command( kundo2_i18n( "Change page layout" ) );
674 viewMode()->changePageLayout( dialog.pageLayout(), dialog.applyToDocument(), command );
675
676 d->canvas->addCommand( command );
677 }
678
679 }
680
slotZoomChanged(KoZoomMode::Mode mode,qreal zoom)681 void KoPAView::slotZoomChanged( KoZoomMode::Mode mode, qreal zoom )
682 {
683 Q_UNUSED(zoom);
684 if (d->activePage) {
685 if (mode == KoZoomMode::ZOOM_PAGE) {
686 const KoPageLayout &layout = viewMode()->activePageLayout();
687 QRectF pageRect( 0, 0, layout.width, layout.height );
688 d->canvasController->ensureVisible(d->canvas->viewConverter()->documentToView(pageRect));
689 } else if (mode == KoZoomMode::ZOOM_WIDTH) {
690 // horizontally center the page
691 const KoPageLayout &layout = viewMode()->activePageLayout();
692 QRectF pageRect( 0, 0, layout.width, layout.height );
693 QRect viewRect = d->canvas->viewConverter()->documentToView(pageRect).toRect();
694 viewRect.translate(d->canvas->documentOrigin());
695 QRect currentVisible(qMax(0, -d->canvasController->canvasOffsetX()), qMax(0, -d->canvasController->canvasOffsetY()), d->canvasController->visibleWidth(), d->canvasController->visibleHeight());
696 int horizontalMove = viewRect.center().x() - currentVisible.center().x();
697 d->canvasController->pan(QPoint(horizontalMove, 0));
698 }
699 updateCanvasSize(true);
700 }
701 }
702
configure()703 void KoPAView::configure()
704 {
705 openConfiguration();
706 // TODO update canvas
707 }
708
openConfiguration()709 void KoPAView::openConfiguration()
710 {
711 QPointer<KoPAConfigureDialog> dialog(new KoPAConfigureDialog(this));
712 dialog->exec();
713 delete dialog;
714 }
715
setMasterMode(bool master)716 void KoPAView::setMasterMode( bool master )
717 {
718 viewMode()->setMasterMode( master );
719 if (mainWindow()) {
720 d->documentStructureDocker->setMasterMode(master);
721 }
722 d->actionMasterPage->setEnabled(!master);
723
724 QList<KoPAPageBase*> pages = d->doc->pages( master );
725 d->actionDeletePage->setEnabled( pages.size() > 1 );
726 }
727
shapeManager() const728 KoShapeManager* KoPAView::shapeManager() const
729 {
730 return d->canvas->shapeManager();
731 }
732
733
masterShapeManager() const734 KoShapeManager* KoPAView::masterShapeManager() const
735 {
736 return d->canvas->masterShapeManager();
737 }
738
reinitDocumentDocker()739 void KoPAView::reinitDocumentDocker()
740 {
741 if (mainWindow()) {
742 d->documentStructureDocker->setActivePage( d->activePage );
743 }
744 }
745
pageUpdated(KoPAPageBase * page)746 void KoPAView::pageUpdated(KoPAPageBase* page)
747 {
748 // if the page was updated its content e.g. master page has been changed. Therefore we need to
749 // set the page again to set the shapes of the new master page and get a repaint. Without this
750 // changing the master page does not update the page.
751 if (d->activePage == page) {
752 doUpdateActivePage(page);
753 }
754 }
755
updateCanvasSize(bool forceUpdate)756 void KoPAView::updateCanvasSize(bool forceUpdate)
757 {
758 const KoPageLayout &layout = viewMode()->activePageLayout();
759 QPoint scrollValue(d->canvasController->scrollBarValue());
760
761 QSizeF pageSize(layout.width, layout.height);
762 QSizeF viewportSize = d->canvasController->viewportSize();
763
764 //calculate size of union page + viewport
765 QSizeF documentMinSize(qMax(zoomHandler()->unzoomItX(viewportSize.width()), layout.width),
766 qMax(zoomHandler()->unzoomItY(viewportSize.height()), layout.height));
767
768 // create a rect out of it with origin in tp left of page
769 QRectF documentRect(QPointF((documentMinSize.width() - layout.width) * -0.5,
770 (documentMinSize.height() - layout.height) * -0.5),
771 documentMinSize);
772
773 // Now make a union with the bounding rect of all shapes
774 // Fetch boundingRect like this as a viewmode might have set other shapes than the page
775 foreach (KoShape *layer, d->canvas->shapeManager()->shapes()) {
776 if (! dynamic_cast<KoShapeLayer *>(layer)) {
777 documentRect = documentRect.united(layer->boundingRect());
778 }
779 }
780
781 QPointF offset = -documentRect.topLeft();
782 QPoint scrollChange = d->canvas->documentOrigin() - zoomHandler()->documentToView(offset).toPoint();
783
784 if (forceUpdate || scrollChange != QPoint(0, 0)
785 || d->zoomController->documentSize() != documentRect.size()
786 || d->zoomController->pageSize() != pageSize) {
787 d->horizontalRuler->setRulerLength(layout.width);
788 d->verticalRuler->setRulerLength(layout.height);
789 d->horizontalRuler->setActiveRange(layout.leftMargin, layout.width - layout.rightMargin);
790 d->verticalRuler->setActiveRange(layout.topMargin, layout.height - layout.bottomMargin);
791 QSizeF documentSize(documentRect.size());
792 d->canvas->setDocumentOrigin(offset);
793 d->zoomController->setDocumentSize(documentSize);
794
795 d->canvas->resourceManager()->setResource(KoCanvasResourceManager::PageSize, pageSize);
796
797 d->canvas->update();
798 QSize documentPxSize(zoomHandler()->zoomItX(documentRect.width()), zoomHandler()->zoomItY(documentRect.height()));
799 d->canvasController->proxyObject->updateDocumentSize(documentPxSize);
800 // 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
801 d->zoomController->setPageSize(pageSize);
802 }
803 }
804
doUpdateActivePage(KoPAPageBase * page)805 void KoPAView::doUpdateActivePage( KoPAPageBase * page )
806 {
807 bool pageChanged = page != d->activePage;
808 setActivePage( page );
809
810 updateCanvasSize(true);
811
812 updatePageNavigationActions();
813
814 if ( pageChanged ) {
815 proxyObject->emitActivePageChanged();
816 }
817
818 pageOffsetChanged();
819 }
820
setActivePage(KoPAPageBase * page)821 void KoPAView::setActivePage( KoPAPageBase* page )
822 {
823 if ( !page )
824 return;
825
826 bool pageChanged = page != d->activePage;
827
828 shapeManager()->removeAdditional( d->activePage );
829 d->activePage = page;
830 shapeManager()->addAdditional( d->activePage );
831 QList<KoShape*> shapes = page->shapes();
832 shapeManager()->setShapes(shapes, KoShapeManager::AddWithoutRepaint);
833 //Make the top most layer active
834 if ( !shapes.isEmpty() ) {
835 KoShapeLayer* layer = dynamic_cast<KoShapeLayer*>( shapes.last() );
836 shapeManager()->selection()->setActiveLayer( layer );
837 }
838
839 // if the page is not a master page itself set shapes of the master page
840 KoPAPage * paPage = dynamic_cast<KoPAPage *>( page );
841 if ( paPage ) {
842 KoPAMasterPage * masterPage = paPage->masterPage();
843 QList<KoShape*> masterShapes = masterPage->shapes();
844 masterShapeManager()->setShapes(masterShapes, KoShapeManager::AddWithoutRepaint);
845 //Make the top most layer active
846 if ( !masterShapes.isEmpty() ) {
847 KoShapeLayer* layer = dynamic_cast<KoShapeLayer*>( masterShapes.last() );
848 masterShapeManager()->selection()->setActiveLayer( layer );
849 }
850 }
851 else {
852 // if the page is a master page no shapes are in the masterShapeManager
853 masterShapeManager()->setShapes( QList<KoShape*>() );
854 }
855
856 if ( mainWindow() && pageChanged ) {
857 d->documentStructureDocker->setActivePage(d->activePage);
858 proxyObject->emitActivePageChanged();
859 }
860
861 // Set the current page number in the canvas resource provider
862 d->canvas->resourceManager()->setResource( KoCanvasResourceManager::CurrentPage, d->doc->pageIndex(d->activePage)+1 );
863 }
864
navigatePage(KoPageApp::PageNavigation pageNavigation)865 void KoPAView::navigatePage( KoPageApp::PageNavigation pageNavigation )
866 {
867 KoPAPageBase * newPage = d->doc->pageByNavigation( d->activePage, pageNavigation );
868
869 if ( newPage != d->activePage ) {
870 proxyObject->updateActivePage( newPage );
871 }
872 }
873
createPrintJob()874 KoPrintJob * KoPAView::createPrintJob()
875 {
876 return new KoPAPrintJob(this);
877 }
878
pageOffsetChanged()879 void KoPAView::pageOffsetChanged()
880 {
881 QPoint documentOrigin(d->canvas->documentOrigin());
882 d->horizontalRuler->setOffset(d->canvasController->canvasOffsetX() + documentOrigin.x());
883 d->verticalRuler->setOffset(d->canvasController->canvasOffsetY() + documentOrigin.y());
884 }
885
updateMousePosition(const QPoint & position)886 void KoPAView::updateMousePosition(const QPoint& position)
887 {
888 const QPoint canvasOffset( d->canvasController->canvasOffsetX(), d->canvasController->canvasOffsetY() );
889 const QPoint viewPos = position - d->canvas->documentOrigin() - canvasOffset;
890
891 d->horizontalRuler->updateMouseCoordinate(viewPos.x());
892 d->verticalRuler->updateMouseCoordinate(viewPos.y());
893
894 // Update the selection borders in the rulers while moving with the mouse
895 if(d->canvas->shapeManager()->selection() && (d->canvas->shapeManager()->selection()->count() > 0)) {
896 QRectF boundingRect = d->canvas->shapeManager()->selection()->boundingRect();
897 d->horizontalRuler->updateSelectionBorders(boundingRect.x(), boundingRect.right());
898 d->verticalRuler->updateSelectionBorders(boundingRect.y(), boundingRect.bottom());
899 }
900 }
901
selectionChanged()902 void KoPAView::selectionChanged()
903 {
904 // Show the borders of the selection in the rulers
905 if(d->canvas->shapeManager()->selection() && (d->canvas->shapeManager()->selection()->count() > 0)) {
906 QRectF boundingRect = d->canvas->shapeManager()->selection()->boundingRect();
907 d->horizontalRuler->setShowSelectionBorders(true);
908 d->verticalRuler->setShowSelectionBorders(true);
909 d->horizontalRuler->updateSelectionBorders(boundingRect.x(), boundingRect.right());
910 d->verticalRuler->updateSelectionBorders(boundingRect.y(), boundingRect.bottom());
911 } else {
912 d->horizontalRuler->setShowSelectionBorders(false);
913 d->verticalRuler->setShowSelectionBorders(false);
914 }
915 }
916
setShowRulers(bool show)917 void KoPAView::setShowRulers(bool show)
918 {
919 d->horizontalRuler->setVisible(show);
920 d->verticalRuler->setVisible(show);
921
922 d->viewRulers->setChecked(show);
923 d->doc->setRulersVisible(show);
924 }
925
insertPage()926 void KoPAView::insertPage()
927 {
928 KoPAPageBase * page = 0;
929 if ( viewMode()->masterMode() ) {
930 KoPAMasterPage * masterPage = d->doc->newMasterPage();
931 masterPage->setBackground(QSharedPointer<KoColorBackground>(new KoColorBackground(Qt::white)));
932 // use the layout of the current active page for the new page
933 KoPageLayout & layout = masterPage->pageLayout();
934 KoPAMasterPage * activeMasterPage = dynamic_cast<KoPAMasterPage *>( d->activePage );
935 if ( activeMasterPage ) {
936 layout = activeMasterPage->pageLayout();
937 }
938 page = masterPage;
939 }
940 else {
941 KoPAPage * activePage = static_cast<KoPAPage*>( d->activePage );
942 KoPAMasterPage * masterPage = activePage->masterPage();
943 page = d->doc->newPage( masterPage );
944 }
945
946 KoPAPageInsertCommand * command = new KoPAPageInsertCommand( d->doc, page, d->activePage );
947 d->canvas->addCommand( command );
948
949 doUpdateActivePage(page);
950 }
951
copyPage()952 void KoPAView::copyPage()
953 {
954 QList<KoPAPageBase *> pages;
955 pages.append( d->activePage );
956 KoPAOdfPageSaveHelper saveHelper( d->doc, pages );
957 KoDrag drag;
958 drag.setOdf( KoOdf::mimeType( d->doc->documentType() ), saveHelper );
959 drag.addToClipboard();
960 }
961
deletePage()962 void KoPAView::deletePage()
963 {
964 if ( !isMasterUsed( d->activePage ) ) {
965 d->doc->removePage( d->activePage );
966 }
967 }
968
setActionEnabled(int actions,bool enable)969 void KoPAView::setActionEnabled( int actions, bool enable )
970 {
971 if ( actions & ActionInsertPage )
972 {
973 d->actionInsertPage->setEnabled( enable );
974 }
975 if ( actions & ActionCopyPage )
976 {
977 d->actionCopyPage->setEnabled( enable );
978 }
979 if ( actions & ActionDeletePage )
980 {
981 d->actionDeletePage->setEnabled( enable );
982 }
983 if ( actions & ActionViewShowMasterPages )
984 {
985 d->actionViewShowMasterPages->setEnabled( enable );
986 }
987 if ( actions & ActionFormatMasterPage )
988 {
989 d->actionMasterPage->setEnabled( enable );
990 }
991 }
992
setViewMode(KoPAViewMode * mode)993 void KoPAView::setViewMode(KoPAViewMode* mode)
994 {
995 KoPAViewMode* previousViewMode = viewMode();
996 KoPAViewBase::setViewMode(mode);
997
998 if (previousViewMode && mode != previousViewMode) {
999 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
pageThumbnail(KoPAPageBase * page,const QSize & size)1006 QPixmap KoPAView::pageThumbnail(KoPAPageBase* page, const QSize& size)
1007 {
1008 return d->doc->pageThumbnail(page, size);
1009 }
1010
exportPageThumbnail(KoPAPageBase * page,const QUrl & url,const QSize & size,const char * format,int quality)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
documentStructureDocker() const1052 KoPADocumentStructureDocker* KoPAView::documentStructureDocker() const
1053 {
1054 return d->documentStructureDocker;
1055 }
1056
clipboardDataChanged()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
goToPreviousPage()1082 void KoPAView::goToPreviousPage()
1083 {
1084 navigatePage( KoPageApp::PagePrevious );
1085 }
1086
goToNextPage()1087 void KoPAView::goToNextPage()
1088 {
1089 navigatePage( KoPageApp::PageNext );
1090 }
1091
goToFirstPage()1092 void KoPAView::goToFirstPage()
1093 {
1094 navigatePage( KoPageApp::PageFirst );
1095 }
1096
goToLastPage()1097 void KoPAView::goToLastPage()
1098 {
1099 navigatePage( KoPageApp::PageLast );
1100 }
1101
findDocumentSetNext(QTextDocument * document)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
findDocumentSetPrevious(QTextDocument * document)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
updatePageNavigationActions()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
isMasterUsed(KoPAPageBase * page)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
centerPage()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
tabBar() const1256 QTabBar *KoPAView::tabBar() const
1257 {
1258 return d->tabBar;
1259 }
1260
replaceCentralWidget(QWidget * newWidget)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
restoreCentralWidget()1272 void KoPAView::restoreCentralWidget()
1273 {
1274 //hide custom central widget
1275 hideCustomCentralWidget();
1276 //show standard central widget
1277 d->insideWidget->show();
1278 }
1279
hideCustomCentralWidget()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
setTabBarPosition(Qt::Orientation orientation)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
updateUnit(const KoUnit & unit)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 }
1314