1 /* This file is part of the KDE project
2  * Copyright (C) 2001 David Faure <faure@kde.org>
3  * Copyright (C) 2005-2007, 2009, 2010 Thomas Zander <zander@kde.org>
4  * Copyright (C) 2010-2011 Boudewijn Rempt <boud@kogmbh.com>
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Library General Public
8  * License as published by the Free Software Foundation; either
9  * version 2 of the License, or (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  * Library General Public License for more details.
15  *
16  * You should have received a copy of the GNU Library General Public License
17  * along with this library; see the file COPYING.LIB.  If not, write to
18  * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
19  * Boston, MA 02110-1301, USA
20  */
21 
22 // words includes
23 #define  SHOW_ANNOTATIONS 1
24 #include "KWView.h"
25 
26 #include "KWGui.h"
27 #include "KWDocument.h"
28 #include "KWCanvas.h"
29 #include "KWFactory.h"
30 #include "KWStatusBar.h"
31 #include "KWPageManager.h"
32 #include "frames/KWFrame.h"
33 #include "frames/KWCopyShape.h"
34 #include "frames/KWTextFrameSet.h"
35 #include "dialogs/KWFrameDialog.h"
36 #include "dialogs/KWPageSettingsDialog.h"
37 #include "dialogs/KWPrintingDialog.h"
38 #include "dialogs/KWCreateBookmarkDialog.h"
39 #include "dialogs/KWSelectBookmarkDialog.h"
40 #include "dialogs/KWConfigureDialog.h"
41 #include "commands/KWShapeCreateCommand.h"
42 #include "widgets/KoFindToolbar.h"
43 #include "ui_KWInsertImage.h"
44 #include "gemini/ViewModeSwitchEvent.h"
45 #include "WordsDebug.h"
46 
47 // calligra libs includes
48 #include <KoShapeCreateCommand.h>
49 #include <CalligraVersionWrapper.h>
50 #include <KoShapeRegistry.h>
51 #include <KoShapeFactoryBase.h>
52 #include <KoProperties.h>
53 #include <KoCopyController.h>
54 #include <KoTextDocument.h>
55 #include <KoTextShapeData.h>
56 #include <KoCanvasResourceManager.h>
57 #include <KoCutController.h>
58 #include <KoStandardAction.h>
59 #include <KoTemplateCreateDia.h>
60 #include <KoPasteController.h>
61 #include <KoShape.h>
62 #include <KoText.h>
63 #include <KoFind.h>
64 #include <KoShapeContainer.h>
65 #include <KoShapeManager.h>
66 #include <KoSelection.h>
67 #include <KoPointedAt.h>
68 #include <KoTextRangeManager.h>
69 #include <KoAnnotationManager.h>
70 #include <KoAnnotation.h>
71 #include <KoTextEditor.h>
72 #include <KoToolManager.h>
73 #include <KoToolProxy.h>
74 #include <KoGuidesData.h>
75 #include <KoGridData.h>
76 #include <KoShapeAnchor.h>
77 #include <KoShapeGroupCommand.h>
78 #include <KoZoomController.h>
79 #include <KoInlineTextObjectManager.h>
80 #include <KoBookmark.h>
81 #include <KoPathShape.h> // for KoPathShapeId
82 #include <KoCanvasController.h>
83 #include <KoDocumentRdfBase.h>
84 #include <KoDocumentInfo.h>
85 #include <KoAnnotationLayoutManager.h>
86 #include <KoMainWindow.h>
87 #include <KoCanvasControllerWidget.h>
88 #include <KoPart.h>
89 
90 #ifdef SHOULD_BUILD_RDF
91 #include <KoDocumentRdf.h>
92 #include <KoSemanticStylesheetsEditor.h>
93 #endif
94 
95 #include <KoComponentData.h>
96 #include <KoFindText.h>
97 #include <KoTextLayoutRootArea.h>
98 #include <KoIcon.h>
99 
100 // KF5
101 #include <klocalizedstring.h>
102 #include <ktoggleaction.h>
103 #include <kactioncollection.h>
104 #include <kactionmenu.h>
105 #include <kxmlguifactory.h>
106 #include <ktoolbar.h>
107 
108 // Qt
109 #include <QTimer>
110 #include <QScrollBar>
111 #include <QStatusBar>
112 #include <QPushButton>
113 #include <QClipboard>
114 #include <QMenuBar>
115 
116 #include <limits>
117 
KWView(KoPart * part,KWDocument * document,QWidget * parent)118 KWView::KWView(KoPart *part, KWDocument *document, QWidget *parent)
119         : KoView(part, document, parent)
120         , m_canvas(0)
121         , m_textMinX(1)
122         , m_textMaxX(600)
123         , m_minPageNum(1)
124         , m_maxPageNum(1)
125         , m_isFullscreenMode(false)
126 {
127     setAcceptDrops(true);
128 
129     m_document = document;
130     m_snapToGrid = m_document->gridData().snapToGrid();
131     m_gui = new KWGui(QString(), this);
132     m_canvas = m_gui->canvas();
133 
134     setFocusProxy(m_canvas);
135     QVBoxLayout *layout = new QVBoxLayout(this);
136     layout->setMargin(0);
137     layout->addWidget(m_gui);
138 
139     setComponentName(KWFactory::componentData().componentName(), KWFactory::componentData().componentDisplayName());
140     setXMLFile("calligrawords.rc");
141 
142     m_currentPage = m_document->pageManager()->begin();
143 
144     m_document->annotationLayoutManager()->setShapeManager(m_canvas->shapeManager());
145     m_document->annotationLayoutManager()->setCanvasBase(m_canvas);
146     m_document->annotationLayoutManager()->setViewContentWidth(m_canvas->viewMode()->contentsSize().width());
147     connect(m_document->annotationLayoutManager(), SIGNAL(hasAnnotationsChanged(bool)), this, SLOT(hasNotes(bool)));
148     //We need to create associate widget before connect them in actions
149     //Perhaps there is a better place for the WordCount widget creates here
150     //If you know where to move it in a better place, just do it
151     buildAssociatedWidget();
152 
153     setupActions();
154 
155     connect(m_canvas->shapeManager()->selection(), SIGNAL(selectionChanged()), this, SLOT(selectionChanged()));
156 
157     m_find = new KoFindText(this);
158     KoFindToolbar *toolbar = new KoFindToolbar(m_find, actionCollection(), this);
159     toolbar->setVisible(false);
160     connect(m_find, SIGNAL(matchFound(KoFindMatch)), this, SLOT(findMatchFound(KoFindMatch)));
161     connect(m_find, SIGNAL(updateCanvas()), m_canvas, SLOT(update()));
162     // The text documents to search in will potentially change when we add/remove shapes and after load
163     connect(m_document, SIGNAL(shapeAdded(KoShape*,KoShapeManager::Repaint)), this, SLOT(refreshFindTexts()));
164     connect(m_document, SIGNAL(shapeRemoved(KoShape*)), this, SLOT(refreshFindTexts()));
165 
166 
167     refreshFindTexts();
168 
169     layout->addWidget(toolbar);
170 
171     m_zoomController = new KoZoomController(m_gui->canvasController(), &m_zoomHandler, actionCollection(), 0, this);
172     if (statusBar())
173         KWStatusBar::addViewControls(statusBar(), this);
174 
175     // the zoom controller needs to be initialized after the status bar gets initialized as
176     // that resulted in bug 180759
177     QSizeF pageSize = m_currentPage.rect().size();
178     if (m_canvas->showAnnotations()) {
179         pageSize += QSize(KWCanvasBase::AnnotationAreaWidth, 0.0);
180     }
181     m_zoomController->setPageSize(pageSize);
182     m_zoomController->setTextMinMax(m_currentPage.contentRect().left(), m_currentPage.contentRect().right());
183     KoZoomMode::Modes modes = KoZoomMode::ZOOM_WIDTH | KoZoomMode::ZOOM_TEXT;
184     if (m_canvas->viewMode()->hasPages())
185         modes |= KoZoomMode::ZOOM_PAGE;
186     m_zoomController->zoomAction()->setZoomModes(modes);
187     connect(m_canvas, SIGNAL(documentSize(QSizeF)), m_zoomController, SLOT(setDocumentSize(QSizeF)));
188     m_canvas->updateSize(); // to emit the doc size at least once
189     m_zoomController->setZoom(m_document->config().zoomMode(), m_document->config().zoom() / 100.);
190     connect(m_zoomController, SIGNAL(zoomChanged(KoZoomMode::Mode,qreal)), this, SLOT(zoomChanged(KoZoomMode::Mode,qreal)));
191 
192     //Timer start in Fullscreen mode view.
193     m_hideCursorTimer = new QTimer(this);
194     connect(m_hideCursorTimer, SIGNAL(timeout()), this, SLOT(hideCursor()));
195 
196     m_dfmExitButton = new QPushButton(i18n("Exit Fullscreen Mode"));
197     addStatusBarItem(m_dfmExitButton, 0);
198     m_dfmExitButton->setVisible(false);
199     connect(m_dfmExitButton, SIGNAL(clicked()), this, SLOT(exitFullscreenMode()));
200 
201 #ifdef SHOULD_BUILD_RDF
202     if (KoDocumentRdf *rdf = dynamic_cast<KoDocumentRdf*>(m_document->documentRdf())) {
203         connect(rdf, SIGNAL(semanticObjectViewSiteUpdated(hKoRdfBasicSemanticItem,QString)),
204                 this, SLOT(semanticObjectViewSiteUpdated(hKoRdfBasicSemanticItem,QString)));
205     }
206 #endif
207 }
208 
~KWView()209 KWView::~KWView()
210 {
211     KoToolManager::instance()->removeCanvasController(m_gui->canvasController());
212 
213     m_canvas = 0;
214 }
215 
canvasBase() const216 KoCanvasBase *KWView::canvasBase() const
217 {
218     return m_canvas;
219 }
220 
currentPage() const221 const KWPage KWView::currentPage() const
222 {
223     return m_currentPage;
224 }
225 
canvas() const226 QWidget *KWView::canvas() const
227 {
228     return m_canvas;
229 }
230 
updateReadWrite(bool readWrite)231 void KWView::updateReadWrite(bool readWrite)
232 {
233     m_actionFormatFrameSet->setEnabled(readWrite);
234     m_actionViewHeader->setEnabled(readWrite);
235     m_actionViewFooter->setEnabled(readWrite);
236     m_actionViewSnapToGrid->setEnabled(readWrite);
237     QAction *action = actionCollection()->action("insert_framebreak");
238     if (action) action->setEnabled(readWrite);
239     action = actionCollection()->action("insert_variable");
240     if (action) action->setEnabled(readWrite);
241     action = actionCollection()->action("format_page");
242     if (action) action->setEnabled(readWrite);
243     action = actionCollection()->action("anchor");
244     if (action) action->setEnabled(readWrite);
245     action = actionCollection()->action("edit_cut");
246     if (action) action->setEnabled(readWrite);
247     action = actionCollection()->action("edit_copy");
248     if (action) action->setEnabled(readWrite);
249     action = actionCollection()->action("edit_paste");
250     if (action) action->setEnabled(readWrite);
251     action = actionCollection()->action("edit_paste_text");
252     if (action) action->setEnabled(readWrite);
253     action = actionCollection()->action("delete_page");
254     if (action) action->setEnabled(readWrite);
255     action = actionCollection()->action("edit_delete");
256     if (action) action->setEnabled(readWrite);
257     action = actionCollection()->action("create_linked_frame");
258     if (action) action->setEnabled(readWrite);
259     action = actionCollection()->action("create_custom_outline");
260     if (action) action->setEnabled(readWrite);
261 }
262 
buildAssociatedWidget()263 void KWView::buildAssociatedWidget() {
264     wordCount = new KWStatisticsWidget(this,true);
265     wordCount->setLayoutDirection(KWStatisticsWidget::LayoutHorizontal);
266     wordCount->setCanvas(dynamic_cast<KWCanvas*>(this->canvas()));
267     statusBar()->insertWidget(0,wordCount);
268 }
269 
setupActions()270 void KWView::setupActions()
271 {
272     m_actionFormatFrameSet  = new QAction(i18n("Shape Properties..."), this);
273     actionCollection()->addAction("format_frameset", m_actionFormatFrameSet);
274     m_actionFormatFrameSet->setToolTip(i18n("Change how the shape behave"));
275     m_actionFormatFrameSet->setEnabled(false);
276     connect(m_actionFormatFrameSet, SIGNAL(triggered()), this, SLOT(editFrameProperties()));
277 
278     QAction *action = actionCollection()->addAction(KStandardAction::Prior,  "page_previous", this, SLOT(goToPreviousPage()));
279 
280     action = actionCollection()->addAction(KStandardAction::Next,  "page_next", this, SLOT(goToNextPage()));
281 
282     // -------------- File menu
283     m_actionCreateTemplate = new QAction(i18n("Create Template From Document..."), this);
284     m_actionCreateTemplate->setToolTip(i18n("Save this document and use it later as a template"));
285     m_actionCreateTemplate->setWhatsThis(i18n("You can save this document as a template.<br><br>You can use this new template as a starting point for another document."));
286     actionCollection()->addAction("extra_template", m_actionCreateTemplate);
287     connect(m_actionCreateTemplate, SIGNAL(triggered()), this, SLOT(createTemplate()));
288 
289     // -------------- Edit actions
290     action = actionCollection()->addAction(KStandardAction::Cut,  "edit_cut", 0, 0);
291     new KoCutController(canvasBase(), action);
292     action = actionCollection()->addAction(KStandardAction::Copy,  "edit_copy", 0, 0);
293     new KoCopyController(canvasBase(), action);
294     action = actionCollection()->addAction(KStandardAction::Paste,  "edit_paste", 0, 0);
295     new KoPasteController(canvasBase(), action);
296 
297     action = new QAction(koIcon("edit-delete"), i18n("Delete"), this);
298     action->setShortcut(QKeySequence("Del"));
299     connect(action, SIGNAL(triggered()), this, SLOT(editDeleteSelection()));
300     connect(canvasBase()->toolProxy(), SIGNAL(selectionChanged(bool)), action, SLOT(setEnabled(bool)));
301     actionCollection()->addAction("edit_delete", action);
302 
303     // -------------- View menu
304     action = new QAction(i18n("Show Formatting Characters"), this);
305     action->setCheckable(true);
306     actionCollection()->addAction("view_formattingchars", action);
307     connect(action, SIGNAL(toggled(bool)), this, SLOT(setShowFormattingChars(bool)));
308     m_canvas->resourceManager()->setResource(KoCanvasResourceManager::ShowFormattingCharacters, QVariant(false));
309     action->setChecked(m_document->config().showFormattingChars()); // will change resource if true
310     action->setToolTip(i18n("Toggle the display of non-printing characters"));
311     action->setWhatsThis(i18n("Toggle the display of non-printing characters.<br/><br/>When this is enabled, Words shows you tabs, spaces, carriage returns and other non-printing characters."));
312 
313     action = new QAction(i18n("Show Field Shadings"), this);
314     action->setCheckable(true);
315     actionCollection()->addAction("view_fieldshadings", action);
316     connect(action, SIGNAL(toggled(bool)), this, SLOT(setShowInlineObjectVisualization(bool)));
317     m_canvas->resourceManager()->setResource(KoCanvasResourceManager::ShowInlineObjectVisualization, QVariant(false));
318     action->setChecked(m_document->config().showInlineObjectVisualization()); // will change resource if true
319     action->setToolTip(i18n("Toggle the shaded background of fields"));
320     action->setWhatsThis(i18n("Toggle the visualization of fields (variables etc.) by drawing their background in a contrasting color."));
321 
322     action = new QAction(i18n("Show Text Shape Borders"), this);
323     action->setToolTip(i18n("Turns the border display on and off"));
324     action->setCheckable(true);
325     actionCollection()->addAction("view_frameborders", action);
326     connect(action, SIGNAL(toggled(bool)), this, SLOT(toggleViewFrameBorders(bool)));
327     m_canvas->resourceManager()->setResource(KoCanvasResourceManager::ShowTextShapeOutlines, QVariant(false));
328     action->setChecked(m_document->config().viewFrameBorders()); // will change resource if true
329     action->setWhatsThis(i18n("Turns the border display on and off.<br/><br/>The borders are never printed. This option is useful to see how the document will appear on the printed page."));
330 
331     action = new QAction(i18n("Show Table Borders"), this);
332     action->setCheckable(true);
333     actionCollection()->addAction("view_tableborders", action);
334     connect(action, SIGNAL(toggled(bool)), this, SLOT(setShowTableBorders(bool)));
335     m_canvas->resourceManager()->setResource(KoCanvasResourceManager::ShowTableBorders, QVariant(false));
336     action->setChecked(m_document->config().showTableBorders()); // will change resource if true
337     action->setToolTip(i18n("Toggle the display of table borders"));
338     action->setWhatsThis(i18n("Toggle the display of table borders.<br/><br/>When this is enabled, Words shows you any invisible table borders with a thin gray line."));
339 
340     action = new QAction(i18n("Show Section Bounds"), this);
341     action->setCheckable(true);
342     actionCollection()->addAction("view_sectionbounds", action);
343     connect(action, SIGNAL(toggled(bool)), this, SLOT(setShowSectionBounds(bool)));
344     m_canvas->resourceManager()->setResource(KoCanvasResourceManager::ShowSectionBounds, QVariant(false));
345     action->setChecked(m_document->config().showSectionBounds()); // will change resource if true
346     action->setToolTip(i18n("Toggle the display of section bounds"));
347     action->setWhatsThis(i18n("Toggle the display of section bounds.<br/><br/>When this is enabled, any section bounds will be indicated with a thin gray horizontal brackets."));
348 
349     action = new QAction(i18n("Show Rulers"), this);
350     action->setCheckable(true);
351     action->setToolTip(i18n("Shows or hides rulers"));
352     action->setWhatsThis(i18n("The rulers are the white measuring spaces top and left of the "
353                               "document. The rulers show the position and width of pages and of frames and can "
354                               "be used to position tabulators among others.<p>Uncheck this to disable "
355                               "the rulers from being displayed.</p>"));
356     action->setChecked(m_document->config().viewRulers());
357     actionCollection()->addAction("show_ruler", action);
358     connect(action, SIGNAL(toggled(bool)), this, SLOT(showRulers(bool)));
359 
360     action = m_document->gridData().gridToggleAction(m_canvas);
361     actionCollection()->addAction("view_grid", action);
362 
363     m_actionViewSnapToGrid = new KToggleAction(i18n("Snap to Grid"), this);
364     actionCollection()->addAction("view_snaptogrid", m_actionViewSnapToGrid);
365     m_actionViewSnapToGrid->setChecked(m_snapToGrid);
366     connect(m_actionViewSnapToGrid, SIGNAL(triggered()), this, SLOT(toggleSnapToGrid()));
367 
368     KToggleAction *guides = KoStandardAction::showGuides(this, SLOT(setGuideVisibility(bool)), actionCollection());
369     guides->setChecked(m_document->guidesData().showGuideLines());
370 
371     KToggleAction *tAction = new KToggleAction(i18n("Show Status Bar"), this);
372     tAction->setToolTip(i18n("Shows or hides the status bar"));
373     actionCollection()->addAction("showStatusBar", tAction);
374     connect(tAction, SIGNAL(toggled(bool)), this, SLOT(showStatusBar(bool)));
375 
376     mainWindow()->actionCollection()->action("view_fullscreen")->setEnabled(false);
377     tAction = new KToggleAction(i18n("Fullscreen Mode"), this);
378     tAction->setToolTip(i18n("Set view in fullscreen mode"));
379     tAction->setShortcut(QKeySequence(Qt::CTRL + Qt::SHIFT + Qt::Key_F));
380     actionCollection()->addAction("view_fullscreen", tAction);
381     connect(tAction, SIGNAL(toggled(bool)), this, SLOT(setFullscreenMode(bool)));
382 
383 #ifdef SHOULD_BUILD_RDF
384     action = new QAction(i18n("Semantic Stylesheets..."), this);
385     actionCollection()->addAction("edit_semantic_stylesheets", action);
386     action->setToolTip(i18n("Modify and add semantic stylesheets"));
387     action->setWhatsThis(i18n("Stylesheets are used to format the display of information which is stored in RDF."));
388     connect(action, SIGNAL(triggered()), this, SLOT(editSemanticStylesheets()));
389 
390     if (KoDocumentRdf* rdf = dynamic_cast<KoDocumentRdf*>(m_document->documentRdf())) {
391         QAction* createRef = rdf->createInsertSemanticObjectReferenceAction(canvasBase());
392         actionCollection()->addAction("insert_semanticobject_ref", createRef);
393         KActionMenu *subMenu = new KActionMenu(i18n("Create"), this);
394         actionCollection()->addAction("insert_semanticobject_new", subMenu);
395         foreach(QAction *action, rdf->createInsertSemanticObjectNewActions(canvasBase())) {
396             subMenu->addAction(action);
397         }
398     }
399 #endif
400 
401     // -------------- Settings menu
402     action = new QAction(koIcon("configure"), i18n("Configure..."), this);
403     actionCollection()->addAction("configure", action);
404     connect(action, SIGNAL(triggered()), this, SLOT(configure()));
405     // not sure why this isn't done through KStandardAction, but since it isn't
406     // we ought to set the MenuRole manually so the item ends up in the appropriate
407     // menu on OS X:
408     action->setMenuRole(QAction::PreferencesRole);
409 
410     // -------------- Page tool
411     action = new QAction(i18n("Page Layout..."), this);
412     actionCollection()->addAction("format_page", action);
413     action->setToolTip(i18n("Change properties of entire page"));
414     action->setWhatsThis(i18n("Change properties of the entire page.<p>Currently you can change paper size, paper orientation, header and footer sizes, and column settings.</p>"));
415     connect(action, SIGNAL(triggered()), this, SLOT(formatPage()));
416 
417     m_actionViewHeader = new QAction(i18n("Create Header"), this);
418     actionCollection()->addAction("insert_header", m_actionViewHeader);
419     if (m_currentPage.isValid())
420         m_actionViewHeader->setEnabled(m_currentPage.pageStyle().headerPolicy() == Words::HFTypeNone);
421     connect(m_actionViewHeader, SIGNAL(triggered()), this, SLOT(enableHeader()));
422 
423     m_actionViewFooter = new QAction(i18n("Create Footer"), this);
424     actionCollection()->addAction("insert_footer", m_actionViewFooter);
425     if (m_currentPage.isValid())
426         m_actionViewFooter->setEnabled(m_currentPage.pageStyle().footerPolicy() == Words::HFTypeNone);
427     connect(m_actionViewFooter, SIGNAL(triggered()), this, SLOT(enableFooter()));
428 
429     // -------- Show annotations (called Comments in the UI)
430     tAction = new KToggleAction(i18n("Show Comments"), this);
431     tAction->setToolTip(i18n("Shows comments in the document"));
432     tAction->setChecked(m_canvas && m_canvas->showAnnotations());
433     actionCollection()->addAction("view_notes", tAction);
434     connect(tAction, SIGNAL(toggled(bool)), this, SLOT(showNotes(bool)));
435 
436     // -------- Statistics in the status bar
437     KToggleAction *tActionBis = new KToggleAction(i18n("Word Count"), this);
438     tActionBis->setToolTip(i18n("Shows or hides word counting in status bar"));
439     tActionBis->setChecked(kwdocument()->config().statusBarShowWordCount());
440     actionCollection()->addAction("view_wordCount", tActionBis);
441     connect(tActionBis, SIGNAL(toggled(bool)), this, SLOT(showWordCountInStatusBar(bool)));
442     wordCount->setVisible(kwdocument()->config().statusBarShowWordCount());
443 
444     /* ********** From old kwview ****
445     We probably want to have each of these again, so just move them when you want to implement it
446     This saves problems with finding out which we missed near the end.
447 
448     m_actionEditCustomVarsEdit = new QAction(i18n("Custom Variables..."), 0,
449             this, SLOT(editCustomVars()), // TODO: new dialog w add etc.
450             actionCollection(), "custom_vars");
451 
452     m_actionEditCustomVars = new QAction(i18n("Edit Variable..."), 0,
453             this, SLOT(editCustomVariable()),
454             actionCollection(), "edit_customvars");
455 
456     m_actionImportStyle= new QAction(i18n("Import Styles..."), 0,
457             this, SLOT(importStyle()),
458             actionCollection(), "import_style");
459 
460     m_actionConfigureCompletion = new QAction(i18n("Configure Completion..."), 0,
461             this, SLOT(configureCompletion()),
462             actionCollection(), "configure_completion");
463     m_actionConfigureCompletion->setToolTip(i18n("Change the words and options for autocompletion"));
464     m_actionConfigureCompletion->setWhatsThis(i18n("Add words or change the options for autocompletion."));
465 
466     new QAction(i18n("Completion"), KStdAccel::shortcut(KStdAccel::TextCompletion), this, SLOT(slotCompletion()), actionCollection(), "completion");
467     */
468 }
469 
selectedShapes() const470 QList<KoShape *> KWView::selectedShapes() const
471 {
472     return canvasBase()->shapeManager()->selection()->selectedShapes(KoFlake::TopLevelSelection);
473 }
474 
selectedShape() const475 KoShape* KWView::selectedShape() const
476 {
477     KoSelection *selection = canvasBase()->shapeManager()->selection();
478 
479     foreach (KoShape *s, selection->selectedShapes(KoFlake::TopLevelSelection)) {
480         if (s->isGeometryProtected())
481             continue;
482         return s;
483     }
484 
485     return 0;
486 }
487 
488 // -------------------- Actions -----------------------
489 
pasteRequested()490 void KWView::pasteRequested()
491 {
492     QImage img = QApplication::clipboard()->image();
493 
494     if (!img.isNull()) {
495         QVector<QImage> images;
496         images.append(img);
497         addImages(images, canvas()->mapFromGlobal(QCursor::pos()));
498     }
499 }
500 
showNotes(bool show)501 void KWView::showNotes(bool show)
502 {
503     m_canvas->setShowAnnotations(show);
504     m_canvas->updateSize();
505 }
506 
hasNotes(bool has)507 void KWView::hasNotes(bool has)
508 {
509     m_canvas->setShowAnnotations(has);
510     m_canvas->updateSize();
511 
512     KToggleAction *action = (KToggleAction*) actionCollection()->action("view_notes");
513     action->setEnabled(has);
514     action->setChecked(has);
515 }
516 
showWordCountInStatusBar(bool doShow)517 void KWView::showWordCountInStatusBar(bool doShow)
518 {
519     kwdocument()->config().setStatusBarShowWordCount(doShow);
520     wordCount->setVisible(doShow);
521 }
522 
editFrameProperties()523 void KWView::editFrameProperties()
524 {
525     const QList<KoShape *> &shapes = selectedShapes();
526     if (!shapes.isEmpty()) {
527         QPointer<KWFrameDialog> frameDialog = new KWFrameDialog(shapes, m_document, m_canvas);
528         frameDialog->exec();
529         delete frameDialog;
530     }
531 }
532 
createPrintJob()533 KoPrintJob *KWView::createPrintJob()
534 {
535     KWPrintingDialog *dia = new KWPrintingDialog(m_document, m_canvas->shapeManager(), this);
536     dia->printer().setResolution(600);
537     dia->printer().setCreator(QString::fromLatin1("Calligra Words %1").arg(CalligraVersionWrapper::versionString()));
538     dia->printer().setFullPage(true); // ignore printer margins
539     return dia;
540 }
541 
createTemplate()542 void KWView::createTemplate()
543 {
544     KoTemplateCreateDia::createTemplate(koDocument()->documentPart()->templatesResourcePath(), ".ott",
545                                         m_document, this);
546 }
547 
enableHeader()548 void KWView::enableHeader()
549 {
550     if (!m_currentPage.isValid())
551         return;
552     Q_ASSERT(m_currentPage.pageStyle().isValid());
553     m_currentPage.pageStyle().setHeaderPolicy(Words::HFTypeUniform);
554     m_actionViewHeader->setEnabled(false);
555     m_document->relayout();
556 }
557 
enableFooter()558 void KWView::enableFooter()
559 {
560     if (!m_currentPage.isValid())
561         return;
562     Q_ASSERT(m_currentPage.pageStyle().isValid());
563     m_currentPage.pageStyle().setFooterPolicy(Words::HFTypeUniform);
564     m_actionViewFooter->setEnabled(false);
565     m_document->relayout();
566 }
567 
toggleSnapToGrid()568 void KWView::toggleSnapToGrid()
569 {
570     m_snapToGrid = !m_snapToGrid;
571     m_document->gridData().setSnapToGrid(m_snapToGrid); // for persistency
572 }
573 
574 
toggleViewFrameBorders(bool on)575 void KWView::toggleViewFrameBorders(bool on)
576 {
577     m_canvas->resourceManager()->setResource(KoCanvasResourceManager::ShowTextShapeOutlines, on);
578     m_canvas->update();
579     m_document->config().setViewFrameBorders(on);
580 }
581 
setShowInlineObjectVisualization(bool on)582 void KWView::setShowInlineObjectVisualization(bool on)
583 {
584     m_canvas->resourceManager()->setResource(KoCanvasResourceManager::ShowInlineObjectVisualization, QVariant(on));
585     m_canvas->update();
586     m_document->config().setShowInlineObjectVisualization(on);
587 }
588 
setShowFormattingChars(bool on)589 void KWView::setShowFormattingChars(bool on)
590 {
591     m_canvas->resourceManager()->setResource(KoCanvasResourceManager::ShowFormattingCharacters, QVariant(on));
592     m_canvas->update();
593     m_document->config().setShowFormattingChars(on);
594 }
595 
setShowTableBorders(bool on)596 void KWView::setShowTableBorders(bool on)
597 {
598     m_canvas->resourceManager()->setResource(KoCanvasResourceManager::ShowTableBorders, QVariant(on));
599     m_canvas->update();
600     m_document->config().setShowTableBorders(on);
601 }
602 
setShowSectionBounds(bool on)603 void KWView::setShowSectionBounds(bool on)
604 {
605     m_canvas->resourceManager()->setResource(KoCanvasResourceManager::ShowSectionBounds, QVariant(on));
606     m_canvas->update();
607 //     m_document->config().setShowSectionBounds(on);
608 }
609 
formatPage()610 void KWView::formatPage()
611 {
612     if (! m_currentPage.isValid())
613         return;
614     KWPageSettingsDialog *dia = new KWPageSettingsDialog(this, m_document, m_currentPage);
615     if (!m_lastPageSettingsTab.isEmpty()) {
616         KPageWidgetItem *item = dia->pageItem(m_lastPageSettingsTab);
617         if (item)
618             dia->setCurrentPage(item);
619     }
620     connect(dia, SIGNAL(finished(int)), this, SLOT(pageSettingsDialogFinished()));
621     dia->show();
622 }
623 
pageSettingsDialogFinished()624 void KWView::pageSettingsDialogFinished()
625 {
626     KWPageSettingsDialog *dia = qobject_cast<KWPageSettingsDialog*>(QObject::sender());
627     m_lastPageSettingsTab = dia && dia->currentPage() ? dia->currentPage()->name() : QString();
628 }
629 
editSemanticStylesheets()630 void KWView::editSemanticStylesheets()
631 {
632 #ifdef SHOULD_BUILD_RDF
633     if (KoDocumentRdf *rdf = dynamic_cast<KoDocumentRdf*>(m_document->documentRdf())) {
634         KoSemanticStylesheetsEditor *dia = new KoSemanticStylesheetsEditor(this, rdf);
635         dia->show();
636         // TODO this leaks memory
637     }
638 #endif
639 }
640 
showRulers(bool visible)641 void KWView::showRulers(bool visible)
642 {
643     m_document->config().setViewRulers(visible);
644     m_gui->updateRulers();
645 }
646 
showStatusBar(bool toggled)647 void KWView::showStatusBar(bool toggled)
648 {
649     if (statusBar()) statusBar()->setVisible(toggled);
650 }
651 
setFullscreenMode(bool status)652 void KWView::setFullscreenMode(bool status)
653 {
654     m_isFullscreenMode = status;
655 
656     mainWindow()->toggleDockersVisibility(!status);
657     mainWindow()->menuBar()->setVisible(!status);
658 
659     mainWindow()->viewFullscreen(status);
660     foreach(KToolBar* toolbar, mainWindow()->toolBars()) {
661         if (toolbar->isVisible() == status) {
662             toolbar->setVisible(!status);
663         }
664     }
665 
666     if (status) {
667          QTimer::singleShot(2000, this, SLOT(hideUI()));
668     } else {
669          mainWindow()->statusBar()->setVisible(true);
670          static_cast<KoCanvasControllerWidget*>(m_gui->canvasController())->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOn);
671          static_cast<KoCanvasControllerWidget*>(m_gui->canvasController())->setHorizontalScrollBarPolicy(Qt::ScrollBarAsNeeded);
672     }
673     // Exit Fullscreen mode button.
674     m_dfmExitButton->setVisible(status);
675 
676     //Hide cursor.
677     if (status) {
678         m_hideCursorTimer->start(4000);
679     }
680     else {
681         // FIXME: Return back cursor to canvas if cursor is blank cursor.
682         m_hideCursorTimer->stop();
683     }
684 
685     // From time to time you can end up in a situation where the shape manager suddenly
686     // looses track of the current shape selection. So, we trick it here. Logically,
687     // it also makes sense to just make sure the text tool is active anyway when
688     // switching to/from fullscreen (since that's explicitly for typing things
689     // out, not layouting)
690     const QList<KoShape*> selection = m_canvas->shapeManager()->selection()->selectedShapes();
691     m_canvas->shapeManager()->selection()->deselectAll();
692     if (selection.count() > 0)
693         m_canvas->shapeManager()->selection()->select(selection.at(0));
694     KoToolManager::instance()->switchToolRequested("TextToolFactory_ID");
695 }
696 
hideUI()697 void KWView::hideUI()
698 {
699     if (m_isFullscreenMode) {
700         mainWindow()->statusBar()->setVisible(false);
701         // Hide vertical  and horizontal scroll bar.
702         static_cast<KoCanvasControllerWidget*>(m_gui->canvasController())->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
703         static_cast<KoCanvasControllerWidget*>(m_gui->canvasController())->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
704     }
705 }
706 
hideCursor()707 void KWView::hideCursor(){
708     m_canvas->setCursor(Qt::BlankCursor);
709     m_gui->setCursor(Qt::BlankCursor);
710 }
711 
exitFullscreenMode()712 void KWView::exitFullscreenMode()
713 {
714     if (m_isFullscreenMode) {
715         QAction *action = actionCollection()->action("view_fullscreen");
716         action->setChecked(false);
717         m_gui->setCursor(Qt::ArrowCursor);
718         setFullscreenMode(false);
719     }
720 }
721 
viewMouseMoveEvent(QMouseEvent * e)722 void KWView::viewMouseMoveEvent(QMouseEvent *e)
723 {
724     if (!m_isFullscreenMode)
725         return;
726 
727     m_gui->setCursor(Qt::ArrowCursor);
728 
729     // Handle status bar and horizontal scroll bar.
730     if (e->y() >= (m_gui->size().height() - statusBar()->size().height())) {
731         mainWindow()->statusBar()->setVisible(true);
732         static_cast<KoCanvasControllerWidget*>(m_gui->canvasController())->setHorizontalScrollBarPolicy(Qt::ScrollBarAsNeeded);
733     }
734     else {
735        mainWindow()->statusBar()->setVisible(false);
736        static_cast<KoCanvasControllerWidget*>(m_gui->canvasController())->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
737     }
738 
739     // Handle vertical scroll bar.
740     QScrollBar *vsb = static_cast<KoCanvasControllerWidget*>(m_gui->canvasController())->verticalScrollBar();
741     if (e->x() >= (m_gui->size().width() - vsb->size().width() - 10)) {
742          static_cast<KoCanvasControllerWidget*>(m_gui->canvasController())->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOn);
743     }
744     else {
745          static_cast<KoCanvasControllerWidget*>(m_gui->canvasController())->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
746     }
747 }
748 
editDeleteSelection()749 void KWView::editDeleteSelection()
750 {
751     canvasBase()->toolProxy()->deleteSelection();
752 }
753 
setGuideVisibility(bool on)754 void KWView::setGuideVisibility(bool on)
755 {
756     m_document->guidesData().setShowGuideLines(on);
757     m_canvas->update();
758 }
759 
760 
configure()761 void KWView::configure()
762 {
763     QPointer<KWConfigureDialog> dialog(new KWConfigureDialog(this));
764     dialog->exec();
765     delete dialog;
766     // TODO update canvas
767 }
768 
769 // end of actions
770 
popupContextMenu(const QPoint & globalPosition,const QList<QAction * > & actions)771 void KWView::popupContextMenu(const QPoint &globalPosition, const QList<QAction*> &actions)
772 {
773     unplugActionList("frameset_type_action");
774     plugActionList("frameset_type_action", actions);
775     if (factory() == 0) // we are a kpart, the factory is only set on the active component.
776         return;
777     QMenu *menu = dynamic_cast<QMenu*>(factory()->container("frame_popup", this));
778     if (menu)
779         menu->exec(globalPosition);
780 }
781 
zoomChanged(KoZoomMode::Mode mode,qreal zoom)782 void KWView::zoomChanged(KoZoomMode::Mode mode, qreal zoom)
783 {
784     m_document->config().setZoom(qRound(zoom * 100.0));
785     m_document->config().setZoomMode(mode);
786     m_canvas->update();
787 }
788 
selectionChanged()789 void KWView::selectionChanged()
790 {
791     KoShape *shape = canvasBase()->shapeManager()->selection()-> firstSelectedShape();
792 
793     if (shape) {
794         // Disallow shape properties action for auto-generated frames.
795         const KWFrame *frame = kwdocument()->frameOfShape(shape);
796         const bool enableAction = !frame || !Words::isAutoGenerated(KWFrameSet::from(frame->shape()));
797         m_actionFormatFrameSet->setEnabled(enableAction);
798         m_actionFormatFrameSet->setVisible(enableAction);
799     }
800 
801     // actions that need at least one shape selected
802     QAction *action = actionCollection()->action("anchor");
803     if (action)
804         action->setEnabled(shape && kwdocument()->mainFrameSet());
805 }
806 
setCurrentPage(const KWPage & currentPage)807 void KWView::setCurrentPage(const KWPage &currentPage)
808 {
809     Q_ASSERT(currentPage.isValid());
810     if (currentPage != m_currentPage) {
811         m_currentPage = currentPage;
812         m_canvas->resourceManager()->setResource(KoCanvasResourceManager::CurrentPage, m_currentPage.pageNumber());
813 
814         m_actionViewHeader->setEnabled(m_currentPage.pageStyle().headerPolicy() == Words::HFTypeNone);
815         m_actionViewFooter->setEnabled(m_currentPage.pageStyle().footerPolicy() == Words::HFTypeNone);
816     }
817 }
818 
goToPreviousPage(Qt::KeyboardModifiers modifiers)819 void KWView::goToPreviousPage(Qt::KeyboardModifiers modifiers)
820 {
821     // Scroll display
822     qreal moveDistance = m_canvas->canvasController()->visibleHeight() * 0.8;
823     m_canvas->canvasController()->pan(QPoint(0, -moveDistance));
824 
825     // Find current frameset, FIXME for now assume main
826     KWTextFrameSet *currentFrameSet = kwdocument()->mainFrameSet();
827 
828     // Since we move _up_ calculate the position where a frame would _start_ if
829     // we were scrolled to the _first_ page
830     QPointF pos = currentFrameSet->shapes().first()->absoluteTransformation(0).map(QPointF(0, 5));
831 
832     pos += m_canvas->viewMode()->viewToDocument(m_canvas->documentOffset(), viewConverter());
833 
834     // Find textshape under that position and from current frameset
835     QList<KoShape*> possibleTextShapes = m_canvas->shapeManager()->shapesAt(QRectF(pos.x() - 20, pos.y() -20, 40, 40));
836     KoTextShapeData *textShapeData = 0;
837     foreach (KoShape* shape, possibleTextShapes) {
838         KoShapeUserData *userData = shape->userData();
839         if ((textShapeData = dynamic_cast<KoTextShapeData*>(userData))) {
840             foreach (KoShape *s, currentFrameSet->shapes()) {
841                 if (s == shape) {
842                     pos = shape->absoluteTransformation(0).inverted().map(pos);
843                     pos += QPointF(0.0, textShapeData->documentOffset());
844 
845                     KoTextLayoutArea *area = textShapeData->rootArea();
846                     if (area) {
847                         int cursorPos = area->hitTest(pos, Qt::FuzzyHit).position;
848                         KoTextDocument(textShapeData->document()).textEditor()->setPosition(cursorPos, (modifiers & Qt::ShiftModifier) ? QTextCursor::KeepAnchor : QTextCursor::MoveAnchor);
849                     }
850                     return;
851                 }
852             }
853         }
854     }
855 }
856 
goToNextPage(Qt::KeyboardModifiers modifiers)857 void KWView::goToNextPage(Qt::KeyboardModifiers modifiers)
858 {
859     // Scroll display
860     qreal moveDistance = m_canvas->canvasController()->visibleHeight() * 0.8;
861     m_canvas->canvasController()->pan(QPoint(0, moveDistance));
862 
863     // Find current frameset, FIXME for now assume main
864     KWTextFrameSet *currentFrameSet = kwdocument()->mainFrameSet();
865 
866     // Since we move _down_ calculate the position where a frame would _end_ if
867     // we were scrolled to the _lasst_ page
868     KoShape *shape = currentFrameSet->shapes().last();
869     QPointF pos = shape->absoluteTransformation(0).map(QPointF(0, shape->size().height() - 5));
870     pos.setY(pos.y() - m_document->pageManager()->page(qreal(pos.y())).rect().bottom());
871 
872     pos += m_canvas->viewMode()->viewToDocument(m_canvas->documentOffset() + QPointF(0, m_canvas->canvasController()->visibleHeight()), viewConverter());
873 
874     // Find textshape under that position and from current frameset
875     QList<KoShape*> possibleTextShapes = m_canvas->shapeManager()->shapesAt(QRectF(pos.x() - 20, pos.y() -20, 40, 40));
876     KoTextShapeData *textShapeData = 0;
877     foreach (KoShape* shape, possibleTextShapes) {
878         KoShapeUserData *userData = shape->userData();
879         if ((textShapeData = dynamic_cast<KoTextShapeData*>(userData))) {
880             foreach (KoShape *s, currentFrameSet->shapes()) {
881                 if (s == shape) {
882                     pos = shape->absoluteTransformation(0).inverted().map(pos);
883                     pos += QPointF(0.0, textShapeData->documentOffset());
884 
885                     KoTextLayoutArea *area = textShapeData->rootArea();
886                     if (area) {
887                         int cursorPos = area->hitTest(pos, Qt::FuzzyHit).position;
888                         KoTextDocument(textShapeData->document()).textEditor()->setPosition(cursorPos, (modifiers & Qt::ShiftModifier) ? QTextCursor::KeepAnchor : QTextCursor::MoveAnchor);
889                     }
890                     return;
891                 }
892             }
893         }
894     }
895 }
896 
goToPage(const KWPage & page)897 void KWView::goToPage(const KWPage &page)
898 {
899     KoCanvasController *controller = m_gui->canvasController();
900     QPoint origPos = controller->scrollBarValue();
901     QPointF pos = m_canvas->viewMode()->documentToView(QPointF(0,
902                             page.offsetInDocument()), m_canvas->viewConverter());
903     origPos.setY((int)pos.y());
904     controller->setScrollBarValue(origPos);
905 }
906 
showEvent(QShowEvent * e)907 void KWView::showEvent(QShowEvent *e)
908 {
909     KoView::showEvent(e);
910     QTimer::singleShot(0, this, SLOT(updateStatusBarAction()));
911 }
912 
event(QEvent * event)913 bool KWView::event(QEvent* event)
914 {
915     switch(static_cast<int>(event->type())) {
916         case ViewModeSwitchEvent::AboutToSwitchViewModeEvent: {
917             ViewModeSynchronisationObject* syncObject = static_cast<ViewModeSwitchEvent*>(event)->synchronisationObject();
918             if (m_canvas) {
919                 syncObject->scrollBarValue = m_canvas->canvasController()->scrollBarValue();
920                 syncObject->zoomLevel = zoomController()->zoomAction()->effectiveZoom();
921                 syncObject->activeToolId = KoToolManager::instance()->activeToolId();
922                 syncObject->shapes = m_canvas->shapeManager()->shapes();
923                 syncObject->initialized = true;
924             }
925 
926             return true;
927         }
928         case ViewModeSwitchEvent::SwitchedToDesktopModeEvent: {
929             ViewModeSynchronisationObject* syncObject = static_cast<ViewModeSwitchEvent*>(event)->synchronisationObject();
930             if (m_canvas && syncObject->initialized) {
931                 m_canvas->canvasWidget()->setFocus();
932                 qApp->processEvents();
933 
934                 m_canvas->shapeManager()->setShapes(syncObject->shapes);
935 
936                 zoomController()->setZoom(KoZoomMode::ZOOM_CONSTANT, syncObject->zoomLevel);
937 
938                 qApp->processEvents();
939                 m_canvas->canvasController()->setScrollBarValue(syncObject->scrollBarValue);
940 
941                 qApp->processEvents();
942                 foreach(KoShape *shape, m_canvas->shapeManager()->shapesAt(currentPage().rect())) {
943                     if (qobject_cast<KoTextShapeDataBase*>(shape->userData())) {
944                         m_canvas->shapeManager()->selection()->select(shape);
945                         break;
946                     }
947                 }
948                 KoToolManager::instance()->switchToolRequested("TextToolFactory_ID");
949             }
950 
951             return true;
952         }
953     }
954     return QWidget::event(event);
955 }
956 
updateStatusBarAction()957 void KWView::updateStatusBarAction()
958 {
959     KToggleAction *action = (KToggleAction*) actionCollection()->action("showStatusBar");
960     if (action && statusBar())
961         action->setChecked(! statusBar()->isHidden());
962 }
963 
offsetInDocumentMoved(int yOffset)964 void KWView::offsetInDocumentMoved(int yOffset)
965 {
966     const qreal offset = -m_zoomHandler.viewToDocumentY(yOffset);
967     const qreal height = m_zoomHandler.viewToDocumentY(m_gui->viewportSize().height());
968 /*    if (m_currentPage.isValid()) { // most of the time the current will not change.
969         const qreal pageTop = m_currentPage.offsetInDocument();
970         const qreal pageBottom = pageTop + m_currentPage.height();
971         const qreal visibleArea = qMin(offset + height, pageBottom) - qMax(pageTop, offset);
972         if (visibleArea / height >= 0.45) // current page is just fine if > 45% is shown
973             return;
974 
975         // using 'next'/'prev' is much cheaper than using a documentOffset, so try that first.
976         if (pageTop > offset && pageTop < offset + height) { // check if the page above is a candidate.
977             KWPage page = m_currentPage.previous();
978             if (page.isValid() && pageTop - offset > visibleArea) {
979                 firstDrawnPage = page;
980                 return;
981             }
982         }
983         if (pageBottom > offset && pageBottom < offset + height) { // check if the page above is a candidate.
984             KWPage page = m_currentPage.next();
985             if (page.isValid() && m_currentPage.height() - height > visibleArea) {
986                 firstDrawnPage = page;
987                 return;
988             }
989         }
990     }
991 */
992     KWPage page = m_document->pageManager()->page(qreal(offset));
993     qreal pageTop = page.offsetInDocument();
994     QSizeF maxPageSize;
995     qreal minTextX = std::numeric_limits<qreal>::max();
996     qreal maxTextX = std::numeric_limits<qreal>::min();
997     int minPageNum = page.pageNumber();
998     int maxPageNum = page.pageNumber();
999     while (page.isValid() && pageTop < qreal(offset + height)) {
1000         pageTop += page.height();
1001         QSizeF pageSize = page.rect().size();
1002         maxPageSize = QSize(qMax(maxPageSize.width(), pageSize.width()),
1003                                      qMax(maxPageSize.height(), pageSize.height()));
1004         minTextX = qMin(minTextX, page.contentRect().left());
1005         maxTextX = qMax(maxTextX, page.contentRect().right());
1006         maxPageNum = page.pageNumber();
1007         page = page.next();
1008     }
1009 
1010     if (maxPageSize != m_pageSize) {
1011         m_pageSize = maxPageSize;
1012         QSizeF pageSize = m_pageSize;
1013         if (m_canvas->showAnnotations()) {
1014             pageSize += QSize(KWCanvasBase::AnnotationAreaWidth, 0.0);
1015         }
1016         m_zoomController->setPageSize(pageSize);
1017     }
1018     if (minTextX != m_textMinX || maxTextX != m_textMaxX) {
1019         m_textMinX = minTextX;
1020         m_textMaxX = maxTextX;
1021         m_zoomController->setTextMinMax(minTextX, maxTextX);
1022     }
1023     if (minPageNum != m_minPageNum || maxPageNum != m_maxPageNum) {
1024         m_minPageNum = minPageNum;
1025         m_maxPageNum = maxPageNum;
1026         emit shownPagesChanged();
1027     }
1028 }
1029 
1030 #ifdef SHOULD_BUILD_RDF
semanticObjectViewSiteUpdated(hKoRdfBasicSemanticItem basicitem,const QString & xmlid)1031 void KWView::semanticObjectViewSiteUpdated(hKoRdfBasicSemanticItem basicitem, const QString &xmlid)
1032 {
1033     hKoRdfSemanticItem item(static_cast<KoRdfSemanticItem *>(basicitem.data()));
1034     kDebug(30015) << "xmlid:" << xmlid << " reflow item:" << item->name();
1035     KoTextEditor *editor = KoTextEditor::getTextEditorFromCanvas(canvasBase());
1036     if (!editor) {
1037         kDebug(30015) << "no editor, not reflowing rdf semantic item.";
1038         return;
1039     }
1040     kDebug(30015) << "reflowing rdf semantic item.";
1041     KoRdfSemanticItemViewSite vs(item, xmlid);
1042     vs.reflowUsingCurrentStylesheet(editor);
1043 }
1044 #endif
1045 
findMatchFound(KoFindMatch match)1046 void KWView::findMatchFound(KoFindMatch match)
1047 {
1048     if(!match.isValid() || !match.location().canConvert<QTextCursor>() || !match.container().canConvert<QTextDocument*>()) {
1049         return;
1050     }
1051 
1052     QTextCursor cursor = match.location().value<QTextCursor>();
1053 
1054     m_canvas->resourceManager()->setResource(KoText::CurrentTextAnchor, cursor.anchor());
1055     m_canvas->resourceManager()->setResource(KoText::CurrentTextPosition, cursor.position());
1056 }
1057 
refreshFindTexts()1058 void KWView::refreshFindTexts()
1059 {
1060     QList<QTextDocument*> texts;
1061     foreach (KWFrameSet *fSet, m_document->frameSets()) {
1062         KWTextFrameSet *tFSet = dynamic_cast<KWTextFrameSet *>(fSet);
1063         if (tFSet) {
1064            texts.append(tFSet->document());
1065         }
1066     }
1067     m_find->setDocuments(texts);
1068 }
1069 
addImages(const QVector<QImage> & imageList,const QPoint & insertAt)1070 void KWView::addImages(const QVector<QImage> &imageList, const QPoint &insertAt)
1071 {
1072     if (!m_canvas) {
1073         // no canvas because we're not on the desktop?
1074         return;
1075     }
1076 
1077     QPointF pos = viewConverter()->viewToDocument(m_canvas->documentOffset() + insertAt - canvas()->pos());
1078     pos.setX(qMax(qreal(0), pos.x()));
1079     pos.setY(qMax(qreal(0), pos.y()));
1080 
1081     // create a factory
1082     KoShapeFactoryBase *factory = KoShapeRegistry::instance()->value("PictureShape");
1083 
1084     if (!factory) {
1085         warnWords << "No picture shape found, cannot drop images.";
1086         return;
1087     }
1088 
1089     foreach(const QImage &image, imageList) {
1090         KoProperties params;
1091         params.setProperty("qimage", image);
1092 
1093         KoShape *shape = factory->createShape(&params, kwdocument()->resourceManager());
1094 
1095         // resize the shape so it will fit in the document, with some nice
1096         // hard-coded constants.
1097         qreal pageWidth = currentPage().width();
1098         qreal pageHeight = currentPage().height();
1099 
1100         if (shape->size().width() > (pageWidth * 0.8) || shape->size().height() > pageHeight) {
1101             QSizeF sz = shape->size();
1102             sz.scale(QSizeF(pageWidth * 0.6, pageHeight *.6), Qt::KeepAspectRatio);
1103             shape->setSize(sz);
1104         }
1105 
1106         if (!shape) {
1107             warnWords << "Could not create a shape from the image";
1108             return;
1109         }
1110 
1111         shape->setTextRunAroundSide(KoShape::BothRunAroundSide);
1112 
1113         KoShapeAnchor *anchor = new KoShapeAnchor(shape);
1114         anchor->setAnchorType(KoShapeAnchor::AnchorPage);
1115         anchor->setHorizontalPos(KoShapeAnchor::HFromLeft);
1116         anchor->setVerticalPos(KoShapeAnchor::VFromTop);
1117         anchor->setHorizontalRel(KoShapeAnchor::HPage);
1118         anchor->setVerticalRel(KoShapeAnchor::VPage);
1119         shape->setAnchor(anchor);
1120         shape->setPosition(pos);
1121 
1122         pos += QPointF(25,25); // increase the position for each shape we insert so the
1123                                // user can see them all.
1124 
1125         // create the undo step.
1126         KWShapeCreateCommand *cmd = new KWShapeCreateCommand(kwdocument(), shape);
1127         KoSelection *selection = m_canvas->shapeManager()->selection();
1128         selection->deselectAll();
1129         selection->select(shape);
1130         m_canvas->addCommand(cmd);
1131     }
1132 }
1133 
1134 const qreal KWView::AnnotationAreaWidth = 200.0; // only static const integral data members can be initialized within a class
1135