File indexing completed on 2024-05-12 16:37:14

0001 /* This file is part of the KDE project
0002  * Copyright (C) 2001 David Faure <faure@kde.org>
0003  * Copyright (C) 2005-2007, 2009, 2010 Thomas Zander <zander@kde.org>
0004  * Copyright (C) 2010-2011 Boudewijn Rempt <boud@kogmbh.com>
0005  *
0006  * This library is free software; you can redistribute it and/or
0007  * modify it under the terms of the GNU Library General Public
0008  * License as published by the Free Software Foundation; either
0009  * version 2 of the License, or (at your option) any later version.
0010  *
0011  * This library is distributed in the hope that it will be useful,
0012  * but WITHOUT ANY WARRANTY; without even the implied warranty of
0013  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
0014  * Library General Public License for more details.
0015  *
0016  * You should have received a copy of the GNU Library General Public License
0017  * along with this library; see the file COPYING.LIB.  If not, write to
0018  * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
0019  * Boston, MA 02110-1301, USA
0020  */
0021 
0022 // words includes
0023 #define  SHOW_ANNOTATIONS 1
0024 #include "KWView.h"
0025 
0026 #include "KWGui.h"
0027 #include "KWDocument.h"
0028 #include "KWCanvas.h"
0029 #include "KWFactory.h"
0030 #include "KWStatusBar.h"
0031 #include "KWPageManager.h"
0032 #include "frames/KWFrame.h"
0033 #include "frames/KWCopyShape.h"
0034 #include "frames/KWTextFrameSet.h"
0035 #include "dialogs/KWFrameDialog.h"
0036 #include "dialogs/KWPageSettingsDialog.h"
0037 #include "dialogs/KWPrintingDialog.h"
0038 #include "dialogs/KWCreateBookmarkDialog.h"
0039 #include "dialogs/KWSelectBookmarkDialog.h"
0040 #include "dialogs/KWConfigureDialog.h"
0041 #include "commands/KWShapeCreateCommand.h"
0042 #include "widgets/KoFindToolbar.h"
0043 #include "ui_KWInsertImage.h"
0044 #include "gemini/ViewModeSwitchEvent.h"
0045 #include "WordsDebug.h"
0046 
0047 // calligra libs includes
0048 #include <KoShapeCreateCommand.h>
0049 #include <CalligraVersionWrapper.h>
0050 #include <KoShapeRegistry.h>
0051 #include <KoShapeFactoryBase.h>
0052 #include <KoProperties.h>
0053 #include <KoCopyController.h>
0054 #include <KoTextDocument.h>
0055 #include <KoTextShapeData.h>
0056 #include <KoCanvasResourceManager.h>
0057 #include <KoCutController.h>
0058 #include <KoStandardAction.h>
0059 #include <KoTemplateCreateDia.h>
0060 #include <KoPasteController.h>
0061 #include <KoShape.h>
0062 #include <KoText.h>
0063 #include <KoFind.h>
0064 #include <KoShapeContainer.h>
0065 #include <KoShapeManager.h>
0066 #include <KoSelection.h>
0067 #include <KoPointedAt.h>
0068 #include <KoTextRangeManager.h>
0069 #include <KoAnnotationManager.h>
0070 #include <KoAnnotation.h>
0071 #include <KoTextEditor.h>
0072 #include <KoToolManager.h>
0073 #include <KoToolProxy.h>
0074 #include <KoGuidesData.h>
0075 #include <KoGridData.h>
0076 #include <KoShapeAnchor.h>
0077 #include <KoShapeGroupCommand.h>
0078 #include <KoZoomController.h>
0079 #include <KoInlineTextObjectManager.h>
0080 #include <KoBookmark.h>
0081 #include <KoPathShape.h> // for KoPathShapeId
0082 #include <KoCanvasController.h>
0083 #include <KoDocumentRdfBase.h>
0084 #include <KoDocumentInfo.h>
0085 #include <KoAnnotationLayoutManager.h>
0086 #include <KoMainWindow.h>
0087 #include <KoCanvasControllerWidget.h>
0088 #include <KoPart.h>
0089 
0090 #ifdef SHOULD_BUILD_RDF
0091 #include <KoDocumentRdf.h>
0092 #include <KoSemanticStylesheetsEditor.h>
0093 #endif
0094 
0095 #include <KoComponentData.h>
0096 #include <KoFindText.h>
0097 #include <KoTextLayoutRootArea.h>
0098 #include <KoIcon.h>
0099 
0100 // KF5
0101 #include <klocalizedstring.h>
0102 #include <ktoggleaction.h>
0103 #include <kactioncollection.h>
0104 #include <kactionmenu.h>
0105 #include <kxmlguifactory.h>
0106 #include <ktoolbar.h>
0107 
0108 // Qt
0109 #include <QTimer>
0110 #include <QScrollBar>
0111 #include <QStatusBar>
0112 #include <QPushButton>
0113 #include <QClipboard>
0114 #include <QMenuBar>
0115 
0116 #include <limits>
0117 
0118 KWView::KWView(KoPart *part, KWDocument *document, QWidget *parent)
0119         : KoView(part, document, parent)
0120         , m_canvas(0)
0121         , m_textMinX(1)
0122         , m_textMaxX(600)
0123         , m_minPageNum(1)
0124         , m_maxPageNum(1)
0125         , m_isFullscreenMode(false)
0126 {
0127     setAcceptDrops(true);
0128 
0129     m_document = document;
0130     m_snapToGrid = m_document->gridData().snapToGrid();
0131     m_gui = new KWGui(QString(), this);
0132     m_canvas = m_gui->canvas();
0133 
0134     setFocusProxy(m_canvas);
0135     QVBoxLayout *layout = new QVBoxLayout(this);
0136     layout->setMargin(0);
0137     layout->addWidget(m_gui);
0138 
0139     setComponentName(KWFactory::componentData().componentName(), KWFactory::componentData().componentDisplayName());
0140     setXMLFile("calligrawords.rc");
0141 
0142     m_currentPage = m_document->pageManager()->begin();
0143 
0144     m_document->annotationLayoutManager()->setShapeManager(m_canvas->shapeManager());
0145     m_document->annotationLayoutManager()->setCanvasBase(m_canvas);
0146     m_document->annotationLayoutManager()->setViewContentWidth(m_canvas->viewMode()->contentsSize().width());
0147     connect(m_document->annotationLayoutManager(), SIGNAL(hasAnnotationsChanged(bool)), this, SLOT(hasNotes(bool)));
0148     //We need to create associate widget before connect them in actions
0149     //Perhaps there is a better place for the WordCount widget creates here
0150     //If you know where to move it in a better place, just do it
0151     buildAssociatedWidget();
0152 
0153     setupActions();
0154 
0155     connect(m_canvas->shapeManager()->selection(), SIGNAL(selectionChanged()), this, SLOT(selectionChanged()));
0156 
0157     m_find = new KoFindText(this);
0158     KoFindToolbar *toolbar = new KoFindToolbar(m_find, actionCollection(), this);
0159     toolbar->setVisible(false);
0160     connect(m_find, SIGNAL(matchFound(KoFindMatch)), this, SLOT(findMatchFound(KoFindMatch)));
0161     connect(m_find, SIGNAL(updateCanvas()), m_canvas, SLOT(update()));
0162     // The text documents to search in will potentially change when we add/remove shapes and after load
0163     connect(m_document, SIGNAL(shapeAdded(KoShape*,KoShapeManager::Repaint)), this, SLOT(refreshFindTexts()));
0164     connect(m_document, SIGNAL(shapeRemoved(KoShape*)), this, SLOT(refreshFindTexts()));
0165 
0166 
0167     refreshFindTexts();
0168 
0169     layout->addWidget(toolbar);
0170 
0171     m_zoomController = new KoZoomController(m_gui->canvasController(), &m_zoomHandler, actionCollection(), 0, this);
0172     if (statusBar())
0173         KWStatusBar::addViewControls(statusBar(), this);
0174 
0175     // the zoom controller needs to be initialized after the status bar gets initialized as
0176     // that resulted in bug 180759
0177     QSizeF pageSize = m_currentPage.rect().size();
0178     if (m_canvas->showAnnotations()) {
0179         pageSize += QSize(KWCanvasBase::AnnotationAreaWidth, 0.0);
0180     }
0181     m_zoomController->setPageSize(pageSize);
0182     m_zoomController->setTextMinMax(m_currentPage.contentRect().left(), m_currentPage.contentRect().right());
0183     KoZoomMode::Modes modes = KoZoomMode::ZOOM_WIDTH | KoZoomMode::ZOOM_TEXT;
0184     if (m_canvas->viewMode()->hasPages())
0185         modes |= KoZoomMode::ZOOM_PAGE;
0186     m_zoomController->zoomAction()->setZoomModes(modes);
0187     connect(m_canvas, SIGNAL(documentSize(QSizeF)), m_zoomController, SLOT(setDocumentSize(QSizeF)));
0188     m_canvas->updateSize(); // to emit the doc size at least once
0189     m_zoomController->setZoom(m_document->config().zoomMode(), m_document->config().zoom() / 100.);
0190     connect(m_zoomController, SIGNAL(zoomChanged(KoZoomMode::Mode,qreal)), this, SLOT(zoomChanged(KoZoomMode::Mode,qreal)));
0191 
0192     //Timer start in Fullscreen mode view.
0193     m_hideCursorTimer = new QTimer(this);
0194     connect(m_hideCursorTimer, SIGNAL(timeout()), this, SLOT(hideCursor()));
0195 
0196     m_dfmExitButton = new QPushButton(i18n("Exit Fullscreen Mode"));
0197     addStatusBarItem(m_dfmExitButton, 0);
0198     m_dfmExitButton->setVisible(false);
0199     connect(m_dfmExitButton, SIGNAL(clicked()), this, SLOT(exitFullscreenMode()));
0200 
0201 #ifdef SHOULD_BUILD_RDF
0202     if (KoDocumentRdf *rdf = dynamic_cast<KoDocumentRdf*>(m_document->documentRdf())) {
0203         connect(rdf, SIGNAL(semanticObjectViewSiteUpdated(hKoRdfBasicSemanticItem,QString)),
0204                 this, SLOT(semanticObjectViewSiteUpdated(hKoRdfBasicSemanticItem,QString)));
0205     }
0206 #endif
0207 }
0208 
0209 KWView::~KWView()
0210 {
0211     KoToolManager::instance()->removeCanvasController(m_gui->canvasController());
0212 
0213     m_canvas = 0;
0214 }
0215 
0216 KoCanvasBase *KWView::canvasBase() const
0217 {
0218     return m_canvas;
0219 }
0220 
0221 const KWPage KWView::currentPage() const
0222 {
0223     return m_currentPage;
0224 }
0225 
0226 QWidget *KWView::canvas() const
0227 {
0228     return m_canvas;
0229 }
0230 
0231 void KWView::updateReadWrite(bool readWrite)
0232 {
0233     m_actionFormatFrameSet->setEnabled(readWrite);
0234     m_actionViewHeader->setEnabled(readWrite);
0235     m_actionViewFooter->setEnabled(readWrite);
0236     m_actionViewSnapToGrid->setEnabled(readWrite);
0237     QAction *action = actionCollection()->action("insert_framebreak");
0238     if (action) action->setEnabled(readWrite);
0239     action = actionCollection()->action("insert_variable");
0240     if (action) action->setEnabled(readWrite);
0241     action = actionCollection()->action("format_page");
0242     if (action) action->setEnabled(readWrite);
0243     action = actionCollection()->action("anchor");
0244     if (action) action->setEnabled(readWrite);
0245     action = actionCollection()->action("edit_cut");
0246     if (action) action->setEnabled(readWrite);
0247     action = actionCollection()->action("edit_copy");
0248     if (action) action->setEnabled(readWrite);
0249     action = actionCollection()->action("edit_paste");
0250     if (action) action->setEnabled(readWrite);
0251     action = actionCollection()->action("edit_paste_text");
0252     if (action) action->setEnabled(readWrite);
0253     action = actionCollection()->action("delete_page");
0254     if (action) action->setEnabled(readWrite);
0255     action = actionCollection()->action("edit_delete");
0256     if (action) action->setEnabled(readWrite);
0257     action = actionCollection()->action("create_linked_frame");
0258     if (action) action->setEnabled(readWrite);
0259     action = actionCollection()->action("create_custom_outline");
0260     if (action) action->setEnabled(readWrite);
0261 }
0262 
0263 void KWView::buildAssociatedWidget() {
0264     wordCount = new KWStatisticsWidget(this,true);
0265     wordCount->setLayoutDirection(KWStatisticsWidget::LayoutHorizontal);
0266     wordCount->setCanvas(dynamic_cast<KWCanvas*>(this->canvas()));
0267     statusBar()->insertWidget(0,wordCount);
0268 }
0269 
0270 void KWView::setupActions()
0271 {
0272     m_actionFormatFrameSet  = new QAction(i18n("Shape Properties..."), this);
0273     actionCollection()->addAction("format_frameset", m_actionFormatFrameSet);
0274     m_actionFormatFrameSet->setToolTip(i18n("Change how the shape behave"));
0275     m_actionFormatFrameSet->setEnabled(false);
0276     connect(m_actionFormatFrameSet, SIGNAL(triggered()), this, SLOT(editFrameProperties()));
0277 
0278     QAction *action = actionCollection()->addAction(KStandardAction::Prior,  "page_previous", this, SLOT(goToPreviousPage()));
0279 
0280     action = actionCollection()->addAction(KStandardAction::Next,  "page_next", this, SLOT(goToNextPage()));
0281 
0282     // -------------- File menu
0283     m_actionCreateTemplate = new QAction(i18n("Create Template From Document..."), this);
0284     m_actionCreateTemplate->setToolTip(i18n("Save this document and use it later as a template"));
0285     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."));
0286     actionCollection()->addAction("extra_template", m_actionCreateTemplate);
0287     connect(m_actionCreateTemplate, SIGNAL(triggered()), this, SLOT(createTemplate()));
0288 
0289     // -------------- Edit actions
0290     action = actionCollection()->addAction(KStandardAction::Cut,  "edit_cut", 0, 0);
0291     new KoCutController(canvasBase(), action);
0292     action = actionCollection()->addAction(KStandardAction::Copy,  "edit_copy", 0, 0);
0293     new KoCopyController(canvasBase(), action);
0294     action = actionCollection()->addAction(KStandardAction::Paste,  "edit_paste", 0, 0);
0295     new KoPasteController(canvasBase(), action);
0296 
0297     action = new QAction(koIcon("edit-delete"), i18n("Delete"), this);
0298     action->setShortcut(QKeySequence("Del"));
0299     connect(action, SIGNAL(triggered()), this, SLOT(editDeleteSelection()));
0300     connect(canvasBase()->toolProxy(), SIGNAL(selectionChanged(bool)), action, SLOT(setEnabled(bool)));
0301     actionCollection()->addAction("edit_delete", action);
0302 
0303     // -------------- View menu
0304     action = new QAction(i18n("Show Formatting Characters"), this);
0305     action->setCheckable(true);
0306     actionCollection()->addAction("view_formattingchars", action);
0307     connect(action, SIGNAL(toggled(bool)), this, SLOT(setShowFormattingChars(bool)));
0308     m_canvas->resourceManager()->setResource(KoCanvasResourceManager::ShowFormattingCharacters, QVariant(false));
0309     action->setChecked(m_document->config().showFormattingChars()); // will change resource if true
0310     action->setToolTip(i18n("Toggle the display of non-printing characters"));
0311     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."));
0312 
0313     action = new QAction(i18n("Show Field Shadings"), this);
0314     action->setCheckable(true);
0315     actionCollection()->addAction("view_fieldshadings", action);
0316     connect(action, SIGNAL(toggled(bool)), this, SLOT(setShowInlineObjectVisualization(bool)));
0317     m_canvas->resourceManager()->setResource(KoCanvasResourceManager::ShowInlineObjectVisualization, QVariant(false));
0318     action->setChecked(m_document->config().showInlineObjectVisualization()); // will change resource if true
0319     action->setToolTip(i18n("Toggle the shaded background of fields"));
0320     action->setWhatsThis(i18n("Toggle the visualization of fields (variables etc.) by drawing their background in a contrasting color."));
0321 
0322     action = new QAction(i18n("Show Text Shape Borders"), this);
0323     action->setToolTip(i18n("Turns the border display on and off"));
0324     action->setCheckable(true);
0325     actionCollection()->addAction("view_frameborders", action);
0326     connect(action, SIGNAL(toggled(bool)), this, SLOT(toggleViewFrameBorders(bool)));
0327     m_canvas->resourceManager()->setResource(KoCanvasResourceManager::ShowTextShapeOutlines, QVariant(false));
0328     action->setChecked(m_document->config().viewFrameBorders()); // will change resource if true
0329     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."));
0330 
0331     action = new QAction(i18n("Show Table Borders"), this);
0332     action->setCheckable(true);
0333     actionCollection()->addAction("view_tableborders", action);
0334     connect(action, SIGNAL(toggled(bool)), this, SLOT(setShowTableBorders(bool)));
0335     m_canvas->resourceManager()->setResource(KoCanvasResourceManager::ShowTableBorders, QVariant(false));
0336     action->setChecked(m_document->config().showTableBorders()); // will change resource if true
0337     action->setToolTip(i18n("Toggle the display of table borders"));
0338     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."));
0339 
0340     action = new QAction(i18n("Show Section Bounds"), this);
0341     action->setCheckable(true);
0342     actionCollection()->addAction("view_sectionbounds", action);
0343     connect(action, SIGNAL(toggled(bool)), this, SLOT(setShowSectionBounds(bool)));
0344     m_canvas->resourceManager()->setResource(KoCanvasResourceManager::ShowSectionBounds, QVariant(false));
0345     action->setChecked(m_document->config().showSectionBounds()); // will change resource if true
0346     action->setToolTip(i18n("Toggle the display of section bounds"));
0347     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."));
0348 
0349     action = new QAction(i18n("Show Rulers"), this);
0350     action->setCheckable(true);
0351     action->setToolTip(i18n("Shows or hides rulers"));
0352     action->setWhatsThis(i18n("The rulers are the white measuring spaces top and left of the "
0353                               "document. The rulers show the position and width of pages and of frames and can "
0354                               "be used to position tabulators among others.<p>Uncheck this to disable "
0355                               "the rulers from being displayed.</p>"));
0356     action->setChecked(m_document->config().viewRulers());
0357     actionCollection()->addAction("show_ruler", action);
0358     connect(action, SIGNAL(toggled(bool)), this, SLOT(showRulers(bool)));
0359 
0360     action = m_document->gridData().gridToggleAction(m_canvas);
0361     actionCollection()->addAction("view_grid", action);
0362 
0363     m_actionViewSnapToGrid = new KToggleAction(i18n("Snap to Grid"), this);
0364     actionCollection()->addAction("view_snaptogrid", m_actionViewSnapToGrid);
0365     m_actionViewSnapToGrid->setChecked(m_snapToGrid);
0366     connect(m_actionViewSnapToGrid, SIGNAL(triggered()), this, SLOT(toggleSnapToGrid()));
0367 
0368     KToggleAction *guides = KoStandardAction::showGuides(this, SLOT(setGuideVisibility(bool)), actionCollection());
0369     guides->setChecked(m_document->guidesData().showGuideLines());
0370 
0371     KToggleAction *tAction = new KToggleAction(i18n("Show Status Bar"), this);
0372     tAction->setToolTip(i18n("Shows or hides the status bar"));
0373     actionCollection()->addAction("showStatusBar", tAction);
0374     connect(tAction, SIGNAL(toggled(bool)), this, SLOT(showStatusBar(bool)));
0375 
0376     mainWindow()->actionCollection()->action("view_fullscreen")->setEnabled(false);
0377     tAction = new KToggleAction(i18n("Fullscreen Mode"), this);
0378     tAction->setToolTip(i18n("Set view in fullscreen mode"));
0379     tAction->setShortcut(QKeySequence(Qt::CTRL + Qt::SHIFT + Qt::Key_F));
0380     actionCollection()->addAction("view_fullscreen", tAction);
0381     connect(tAction, SIGNAL(toggled(bool)), this, SLOT(setFullscreenMode(bool)));
0382 
0383 #ifdef SHOULD_BUILD_RDF
0384     action = new QAction(i18n("Semantic Stylesheets..."), this);
0385     actionCollection()->addAction("edit_semantic_stylesheets", action);
0386     action->setToolTip(i18n("Modify and add semantic stylesheets"));
0387     action->setWhatsThis(i18n("Stylesheets are used to format the display of information which is stored in RDF."));
0388     connect(action, SIGNAL(triggered()), this, SLOT(editSemanticStylesheets()));
0389 
0390     if (KoDocumentRdf* rdf = dynamic_cast<KoDocumentRdf*>(m_document->documentRdf())) {
0391         QAction* createRef = rdf->createInsertSemanticObjectReferenceAction(canvasBase());
0392         actionCollection()->addAction("insert_semanticobject_ref", createRef);
0393         KActionMenu *subMenu = new KActionMenu(i18n("Create"), this);
0394         actionCollection()->addAction("insert_semanticobject_new", subMenu);
0395         foreach(QAction *action, rdf->createInsertSemanticObjectNewActions(canvasBase())) {
0396             subMenu->addAction(action);
0397         }
0398     }
0399 #endif
0400 
0401     // -------------- Settings menu
0402     action = new QAction(koIcon("configure"), i18n("Configure..."), this);
0403     actionCollection()->addAction("configure", action);
0404     connect(action, SIGNAL(triggered()), this, SLOT(configure()));
0405     // not sure why this isn't done through KStandardAction, but since it isn't
0406     // we ought to set the MenuRole manually so the item ends up in the appropriate
0407     // menu on OS X:
0408     action->setMenuRole(QAction::PreferencesRole);
0409 
0410     // -------------- Page tool
0411     action = new QAction(i18n("Page Layout..."), this);
0412     actionCollection()->addAction("format_page", action);
0413     action->setToolTip(i18n("Change properties of entire page"));
0414     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>"));
0415     connect(action, SIGNAL(triggered()), this, SLOT(formatPage()));
0416 
0417     m_actionViewHeader = new QAction(i18n("Create Header"), this);
0418     actionCollection()->addAction("insert_header", m_actionViewHeader);
0419     if (m_currentPage.isValid())
0420         m_actionViewHeader->setEnabled(m_currentPage.pageStyle().headerPolicy() == Words::HFTypeNone);
0421     connect(m_actionViewHeader, SIGNAL(triggered()), this, SLOT(enableHeader()));
0422 
0423     m_actionViewFooter = new QAction(i18n("Create Footer"), this);
0424     actionCollection()->addAction("insert_footer", m_actionViewFooter);
0425     if (m_currentPage.isValid())
0426         m_actionViewFooter->setEnabled(m_currentPage.pageStyle().footerPolicy() == Words::HFTypeNone);
0427     connect(m_actionViewFooter, SIGNAL(triggered()), this, SLOT(enableFooter()));
0428 
0429     // -------- Show annotations (called Comments in the UI)
0430     tAction = new KToggleAction(i18n("Show Comments"), this);
0431     tAction->setToolTip(i18n("Shows comments in the document"));
0432     tAction->setChecked(m_canvas && m_canvas->showAnnotations());
0433     actionCollection()->addAction("view_notes", tAction);
0434     connect(tAction, SIGNAL(toggled(bool)), this, SLOT(showNotes(bool)));
0435 
0436     // -------- Statistics in the status bar
0437     KToggleAction *tActionBis = new KToggleAction(i18n("Word Count"), this);
0438     tActionBis->setToolTip(i18n("Shows or hides word counting in status bar"));
0439     tActionBis->setChecked(kwdocument()->config().statusBarShowWordCount());
0440     actionCollection()->addAction("view_wordCount", tActionBis);
0441     connect(tActionBis, SIGNAL(toggled(bool)), this, SLOT(showWordCountInStatusBar(bool)));
0442     wordCount->setVisible(kwdocument()->config().statusBarShowWordCount());
0443 
0444     /* ********** From old kwview ****
0445     We probably want to have each of these again, so just move them when you want to implement it
0446     This saves problems with finding out which we missed near the end.
0447 
0448     m_actionEditCustomVarsEdit = new QAction(i18n("Custom Variables..."), 0,
0449             this, SLOT(editCustomVars()), // TODO: new dialog w add etc.
0450             actionCollection(), "custom_vars");
0451 
0452     m_actionEditCustomVars = new QAction(i18n("Edit Variable..."), 0,
0453             this, SLOT(editCustomVariable()),
0454             actionCollection(), "edit_customvars");
0455 
0456     m_actionImportStyle= new QAction(i18n("Import Styles..."), 0,
0457             this, SLOT(importStyle()),
0458             actionCollection(), "import_style");
0459 
0460     m_actionConfigureCompletion = new QAction(i18n("Configure Completion..."), 0,
0461             this, SLOT(configureCompletion()),
0462             actionCollection(), "configure_completion");
0463     m_actionConfigureCompletion->setToolTip(i18n("Change the words and options for autocompletion"));
0464     m_actionConfigureCompletion->setWhatsThis(i18n("Add words or change the options for autocompletion."));
0465 
0466     new QAction(i18n("Completion"), KStdAccel::shortcut(KStdAccel::TextCompletion), this, SLOT(slotCompletion()), actionCollection(), "completion");
0467     */
0468 }
0469 
0470 QList<KoShape *> KWView::selectedShapes() const
0471 {
0472     return canvasBase()->shapeManager()->selection()->selectedShapes(KoFlake::TopLevelSelection);
0473 }
0474 
0475 KoShape* KWView::selectedShape() const
0476 {
0477     KoSelection *selection = canvasBase()->shapeManager()->selection();
0478 
0479     foreach (KoShape *s, selection->selectedShapes(KoFlake::TopLevelSelection)) {
0480         if (s->isGeometryProtected())
0481             continue;
0482         return s;
0483     }
0484 
0485     return 0;
0486 }
0487 
0488 // -------------------- Actions -----------------------
0489 
0490 void KWView::pasteRequested()
0491 {
0492     QImage img = QApplication::clipboard()->image();
0493 
0494     if (!img.isNull()) {
0495         QVector<QImage> images;
0496         images.append(img);
0497         addImages(images, canvas()->mapFromGlobal(QCursor::pos()));
0498     }
0499 }
0500 
0501 void KWView::showNotes(bool show)
0502 {
0503     m_canvas->setShowAnnotations(show);
0504     m_canvas->updateSize();
0505 }
0506 
0507 void KWView::hasNotes(bool has)
0508 {
0509     m_canvas->setShowAnnotations(has);
0510     m_canvas->updateSize();
0511 
0512     KToggleAction *action = (KToggleAction*) actionCollection()->action("view_notes");
0513     action->setEnabled(has);
0514     action->setChecked(has);
0515 }
0516 
0517 void KWView::showWordCountInStatusBar(bool doShow)
0518 {
0519     kwdocument()->config().setStatusBarShowWordCount(doShow);
0520     wordCount->setVisible(doShow);
0521 }
0522 
0523 void KWView::editFrameProperties()
0524 {
0525     const QList<KoShape *> &shapes = selectedShapes();
0526     if (!shapes.isEmpty()) {
0527         QPointer<KWFrameDialog> frameDialog = new KWFrameDialog(shapes, m_document, m_canvas);
0528         frameDialog->exec();
0529         delete frameDialog;
0530     }
0531 }
0532 
0533 KoPrintJob *KWView::createPrintJob()
0534 {
0535     KWPrintingDialog *dia = new KWPrintingDialog(m_document, m_canvas->shapeManager(), this);
0536     dia->printer().setResolution(600);
0537     dia->printer().setCreator(QString::fromLatin1("Calligra Words %1").arg(CalligraVersionWrapper::versionString()));
0538     dia->printer().setFullPage(true); // ignore printer margins
0539     return dia;
0540 }
0541 
0542 void KWView::createTemplate()
0543 {
0544     KoTemplateCreateDia::createTemplate(koDocument()->documentPart()->templatesResourcePath(), ".ott",
0545                                         m_document, this);
0546 }
0547 
0548 void KWView::enableHeader()
0549 {
0550     if (!m_currentPage.isValid())
0551         return;
0552     Q_ASSERT(m_currentPage.pageStyle().isValid());
0553     m_currentPage.pageStyle().setHeaderPolicy(Words::HFTypeUniform);
0554     m_actionViewHeader->setEnabled(false);
0555     m_document->relayout();
0556 }
0557 
0558 void KWView::enableFooter()
0559 {
0560     if (!m_currentPage.isValid())
0561         return;
0562     Q_ASSERT(m_currentPage.pageStyle().isValid());
0563     m_currentPage.pageStyle().setFooterPolicy(Words::HFTypeUniform);
0564     m_actionViewFooter->setEnabled(false);
0565     m_document->relayout();
0566 }
0567 
0568 void KWView::toggleSnapToGrid()
0569 {
0570     m_snapToGrid = !m_snapToGrid;
0571     m_document->gridData().setSnapToGrid(m_snapToGrid); // for persistency
0572 }
0573 
0574 
0575 void KWView::toggleViewFrameBorders(bool on)
0576 {
0577     m_canvas->resourceManager()->setResource(KoCanvasResourceManager::ShowTextShapeOutlines, on);
0578     m_canvas->update();
0579     m_document->config().setViewFrameBorders(on);
0580 }
0581 
0582 void KWView::setShowInlineObjectVisualization(bool on)
0583 {
0584     m_canvas->resourceManager()->setResource(KoCanvasResourceManager::ShowInlineObjectVisualization, QVariant(on));
0585     m_canvas->update();
0586     m_document->config().setShowInlineObjectVisualization(on);
0587 }
0588 
0589 void KWView::setShowFormattingChars(bool on)
0590 {
0591     m_canvas->resourceManager()->setResource(KoCanvasResourceManager::ShowFormattingCharacters, QVariant(on));
0592     m_canvas->update();
0593     m_document->config().setShowFormattingChars(on);
0594 }
0595 
0596 void KWView::setShowTableBorders(bool on)
0597 {
0598     m_canvas->resourceManager()->setResource(KoCanvasResourceManager::ShowTableBorders, QVariant(on));
0599     m_canvas->update();
0600     m_document->config().setShowTableBorders(on);
0601 }
0602 
0603 void KWView::setShowSectionBounds(bool on)
0604 {
0605     m_canvas->resourceManager()->setResource(KoCanvasResourceManager::ShowSectionBounds, QVariant(on));
0606     m_canvas->update();
0607 //     m_document->config().setShowSectionBounds(on);
0608 }
0609 
0610 void KWView::formatPage()
0611 {
0612     if (! m_currentPage.isValid())
0613         return;
0614     KWPageSettingsDialog *dia = new KWPageSettingsDialog(this, m_document, m_currentPage);
0615     if (!m_lastPageSettingsTab.isEmpty()) {
0616         KPageWidgetItem *item = dia->pageItem(m_lastPageSettingsTab);
0617         if (item)
0618             dia->setCurrentPage(item);
0619     }
0620     connect(dia, SIGNAL(finished(int)), this, SLOT(pageSettingsDialogFinished()));
0621     dia->show();
0622 }
0623 
0624 void KWView::pageSettingsDialogFinished()
0625 {
0626     KWPageSettingsDialog *dia = qobject_cast<KWPageSettingsDialog*>(QObject::sender());
0627     m_lastPageSettingsTab = dia && dia->currentPage() ? dia->currentPage()->name() : QString();
0628 }
0629 
0630 void KWView::editSemanticStylesheets()
0631 {
0632 #ifdef SHOULD_BUILD_RDF
0633     if (KoDocumentRdf *rdf = dynamic_cast<KoDocumentRdf*>(m_document->documentRdf())) {
0634         KoSemanticStylesheetsEditor *dia = new KoSemanticStylesheetsEditor(this, rdf);
0635         dia->show();
0636         // TODO this leaks memory
0637     }
0638 #endif
0639 }
0640 
0641 void KWView::showRulers(bool visible)
0642 {
0643     m_document->config().setViewRulers(visible);
0644     m_gui->updateRulers();
0645 }
0646 
0647 void KWView::showStatusBar(bool toggled)
0648 {
0649     if (statusBar()) statusBar()->setVisible(toggled);
0650 }
0651 
0652 void KWView::setFullscreenMode(bool status)
0653 {
0654     m_isFullscreenMode = status;
0655 
0656     mainWindow()->toggleDockersVisibility(!status);
0657     mainWindow()->menuBar()->setVisible(!status);
0658 
0659     mainWindow()->viewFullscreen(status);
0660     foreach(KToolBar* toolbar, mainWindow()->toolBars()) {
0661         if (toolbar->isVisible() == status) {
0662             toolbar->setVisible(!status);
0663         }
0664     }
0665 
0666     if (status) {
0667          QTimer::singleShot(2000, this, SLOT(hideUI()));
0668     } else {
0669          mainWindow()->statusBar()->setVisible(true);
0670          static_cast<KoCanvasControllerWidget*>(m_gui->canvasController())->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOn);
0671          static_cast<KoCanvasControllerWidget*>(m_gui->canvasController())->setHorizontalScrollBarPolicy(Qt::ScrollBarAsNeeded);
0672     }
0673     // Exit Fullscreen mode button.
0674     m_dfmExitButton->setVisible(status);
0675 
0676     //Hide cursor.
0677     if (status) {
0678         m_hideCursorTimer->start(4000);
0679     }
0680     else {
0681         // FIXME: Return back cursor to canvas if cursor is blank cursor.
0682         m_hideCursorTimer->stop();
0683     }
0684 
0685     // From time to time you can end up in a situation where the shape manager suddenly
0686     // looses track of the current shape selection. So, we trick it here. Logically,
0687     // it also makes sense to just make sure the text tool is active anyway when
0688     // switching to/from fullscreen (since that's explicitly for typing things
0689     // out, not layouting)
0690     const QList<KoShape*> selection = m_canvas->shapeManager()->selection()->selectedShapes();
0691     m_canvas->shapeManager()->selection()->deselectAll();
0692     if (selection.count() > 0)
0693         m_canvas->shapeManager()->selection()->select(selection.at(0));
0694     KoToolManager::instance()->switchToolRequested("TextToolFactory_ID");
0695 }
0696 
0697 void KWView::hideUI()
0698 {
0699     if (m_isFullscreenMode) {
0700         mainWindow()->statusBar()->setVisible(false);
0701         // Hide vertical  and horizontal scroll bar.
0702         static_cast<KoCanvasControllerWidget*>(m_gui->canvasController())->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
0703         static_cast<KoCanvasControllerWidget*>(m_gui->canvasController())->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
0704     }
0705 }
0706 
0707 void KWView::hideCursor(){
0708     m_canvas->setCursor(Qt::BlankCursor);
0709     m_gui->setCursor(Qt::BlankCursor);
0710 }
0711 
0712 void KWView::exitFullscreenMode()
0713 {
0714     if (m_isFullscreenMode) {
0715         QAction *action = actionCollection()->action("view_fullscreen");
0716         action->setChecked(false);
0717         m_gui->setCursor(Qt::ArrowCursor);
0718         setFullscreenMode(false);
0719     }
0720 }
0721 
0722 void KWView::viewMouseMoveEvent(QMouseEvent *e)
0723 {
0724     if (!m_isFullscreenMode)
0725         return;
0726 
0727     m_gui->setCursor(Qt::ArrowCursor);
0728 
0729     // Handle status bar and horizontal scroll bar.
0730     if (e->y() >= (m_gui->size().height() - statusBar()->size().height())) {
0731         mainWindow()->statusBar()->setVisible(true);
0732         static_cast<KoCanvasControllerWidget*>(m_gui->canvasController())->setHorizontalScrollBarPolicy(Qt::ScrollBarAsNeeded);
0733     }
0734     else {
0735        mainWindow()->statusBar()->setVisible(false);
0736        static_cast<KoCanvasControllerWidget*>(m_gui->canvasController())->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
0737     }
0738 
0739     // Handle vertical scroll bar.
0740     QScrollBar *vsb = static_cast<KoCanvasControllerWidget*>(m_gui->canvasController())->verticalScrollBar();
0741     if (e->x() >= (m_gui->size().width() - vsb->size().width() - 10)) {
0742          static_cast<KoCanvasControllerWidget*>(m_gui->canvasController())->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOn);
0743     }
0744     else {
0745          static_cast<KoCanvasControllerWidget*>(m_gui->canvasController())->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
0746     }
0747 }
0748 
0749 void KWView::editDeleteSelection()
0750 {
0751     canvasBase()->toolProxy()->deleteSelection();
0752 }
0753 
0754 void KWView::setGuideVisibility(bool on)
0755 {
0756     m_document->guidesData().setShowGuideLines(on);
0757     m_canvas->update();
0758 }
0759 
0760 
0761 void KWView::configure()
0762 {
0763     QPointer<KWConfigureDialog> dialog(new KWConfigureDialog(this));
0764     dialog->exec();
0765     delete dialog;
0766     // TODO update canvas
0767 }
0768 
0769 // end of actions
0770 
0771 void KWView::popupContextMenu(const QPoint &globalPosition, const QList<QAction*> &actions)
0772 {
0773     unplugActionList("frameset_type_action");
0774     plugActionList("frameset_type_action", actions);
0775     if (factory() == 0) // we are a kpart, the factory is only set on the active component.
0776         return;
0777     QMenu *menu = dynamic_cast<QMenu*>(factory()->container("frame_popup", this));
0778     if (menu)
0779         menu->exec(globalPosition);
0780 }
0781 
0782 void KWView::zoomChanged(KoZoomMode::Mode mode, qreal zoom)
0783 {
0784     m_document->config().setZoom(qRound(zoom * 100.0));
0785     m_document->config().setZoomMode(mode);
0786     m_canvas->update();
0787 }
0788 
0789 void KWView::selectionChanged()
0790 {
0791     KoShape *shape = canvasBase()->shapeManager()->selection()-> firstSelectedShape();
0792 
0793     if (shape) {
0794         // Disallow shape properties action for auto-generated frames.
0795         const KWFrame *frame = kwdocument()->frameOfShape(shape);
0796         const bool enableAction = !frame || !Words::isAutoGenerated(KWFrameSet::from(frame->shape()));
0797         m_actionFormatFrameSet->setEnabled(enableAction);
0798         m_actionFormatFrameSet->setVisible(enableAction);
0799     }
0800 
0801     // actions that need at least one shape selected
0802     QAction *action = actionCollection()->action("anchor");
0803     if (action)
0804         action->setEnabled(shape && kwdocument()->mainFrameSet());
0805 }
0806 
0807 void KWView::setCurrentPage(const KWPage &currentPage)
0808 {
0809     Q_ASSERT(currentPage.isValid());
0810     if (currentPage != m_currentPage) {
0811         m_currentPage = currentPage;
0812         m_canvas->resourceManager()->setResource(KoCanvasResourceManager::CurrentPage, m_currentPage.pageNumber());
0813 
0814         m_actionViewHeader->setEnabled(m_currentPage.pageStyle().headerPolicy() == Words::HFTypeNone);
0815         m_actionViewFooter->setEnabled(m_currentPage.pageStyle().footerPolicy() == Words::HFTypeNone);
0816     }
0817 }
0818 
0819 void KWView::goToPreviousPage(Qt::KeyboardModifiers modifiers)
0820 {
0821     // Scroll display
0822     qreal moveDistance = m_canvas->canvasController()->visibleHeight() * 0.8;
0823     m_canvas->canvasController()->pan(QPoint(0, -moveDistance));
0824 
0825     // Find current frameset, FIXME for now assume main
0826     KWTextFrameSet *currentFrameSet = kwdocument()->mainFrameSet();
0827 
0828     // Since we move _up_ calculate the position where a frame would _start_ if
0829     // we were scrolled to the _first_ page
0830     QPointF pos = currentFrameSet->shapes().first()->absoluteTransformation(0).map(QPointF(0, 5));
0831 
0832     pos += m_canvas->viewMode()->viewToDocument(m_canvas->documentOffset(), viewConverter());
0833 
0834     // Find textshape under that position and from current frameset
0835     QList<KoShape*> possibleTextShapes = m_canvas->shapeManager()->shapesAt(QRectF(pos.x() - 20, pos.y() -20, 40, 40));
0836     KoTextShapeData *textShapeData = 0;
0837     foreach (KoShape* shape, possibleTextShapes) {
0838         KoShapeUserData *userData = shape->userData();
0839         if ((textShapeData = dynamic_cast<KoTextShapeData*>(userData))) {
0840             foreach (KoShape *s, currentFrameSet->shapes()) {
0841                 if (s == shape) {
0842                     pos = shape->absoluteTransformation(0).inverted().map(pos);
0843                     pos += QPointF(0.0, textShapeData->documentOffset());
0844 
0845                     KoTextLayoutArea *area = textShapeData->rootArea();
0846                     if (area) {
0847                         int cursorPos = area->hitTest(pos, Qt::FuzzyHit).position;
0848                         KoTextDocument(textShapeData->document()).textEditor()->setPosition(cursorPos, (modifiers & Qt::ShiftModifier) ? QTextCursor::KeepAnchor : QTextCursor::MoveAnchor);
0849                     }
0850                     return;
0851                 }
0852             }
0853         }
0854     }
0855 }
0856 
0857 void KWView::goToNextPage(Qt::KeyboardModifiers modifiers)
0858 {
0859     // Scroll display
0860     qreal moveDistance = m_canvas->canvasController()->visibleHeight() * 0.8;
0861     m_canvas->canvasController()->pan(QPoint(0, moveDistance));
0862 
0863     // Find current frameset, FIXME for now assume main
0864     KWTextFrameSet *currentFrameSet = kwdocument()->mainFrameSet();
0865 
0866     // Since we move _down_ calculate the position where a frame would _end_ if
0867     // we were scrolled to the _lasst_ page
0868     KoShape *shape = currentFrameSet->shapes().last();
0869     QPointF pos = shape->absoluteTransformation(0).map(QPointF(0, shape->size().height() - 5));
0870     pos.setY(pos.y() - m_document->pageManager()->page(qreal(pos.y())).rect().bottom());
0871 
0872     pos += m_canvas->viewMode()->viewToDocument(m_canvas->documentOffset() + QPointF(0, m_canvas->canvasController()->visibleHeight()), viewConverter());
0873 
0874     // Find textshape under that position and from current frameset
0875     QList<KoShape*> possibleTextShapes = m_canvas->shapeManager()->shapesAt(QRectF(pos.x() - 20, pos.y() -20, 40, 40));
0876     KoTextShapeData *textShapeData = 0;
0877     foreach (KoShape* shape, possibleTextShapes) {
0878         KoShapeUserData *userData = shape->userData();
0879         if ((textShapeData = dynamic_cast<KoTextShapeData*>(userData))) {
0880             foreach (KoShape *s, currentFrameSet->shapes()) {
0881                 if (s == shape) {
0882                     pos = shape->absoluteTransformation(0).inverted().map(pos);
0883                     pos += QPointF(0.0, textShapeData->documentOffset());
0884 
0885                     KoTextLayoutArea *area = textShapeData->rootArea();
0886                     if (area) {
0887                         int cursorPos = area->hitTest(pos, Qt::FuzzyHit).position;
0888                         KoTextDocument(textShapeData->document()).textEditor()->setPosition(cursorPos, (modifiers & Qt::ShiftModifier) ? QTextCursor::KeepAnchor : QTextCursor::MoveAnchor);
0889                     }
0890                     return;
0891                 }
0892             }
0893         }
0894     }
0895 }
0896 
0897 void KWView::goToPage(const KWPage &page)
0898 {
0899     KoCanvasController *controller = m_gui->canvasController();
0900     QPoint origPos = controller->scrollBarValue();
0901     QPointF pos = m_canvas->viewMode()->documentToView(QPointF(0,
0902                             page.offsetInDocument()), m_canvas->viewConverter());
0903     origPos.setY((int)pos.y());
0904     controller->setScrollBarValue(origPos);
0905 }
0906 
0907 void KWView::showEvent(QShowEvent *e)
0908 {
0909     KoView::showEvent(e);
0910     QTimer::singleShot(0, this, SLOT(updateStatusBarAction()));
0911 }
0912 
0913 bool KWView::event(QEvent* event)
0914 {
0915     switch(static_cast<int>(event->type())) {
0916         case ViewModeSwitchEvent::AboutToSwitchViewModeEvent: {
0917             ViewModeSynchronisationObject* syncObject = static_cast<ViewModeSwitchEvent*>(event)->synchronisationObject();
0918             if (m_canvas) {
0919                 syncObject->scrollBarValue = m_canvas->canvasController()->scrollBarValue();
0920                 syncObject->zoomLevel = zoomController()->zoomAction()->effectiveZoom();
0921                 syncObject->activeToolId = KoToolManager::instance()->activeToolId();
0922                 syncObject->shapes = m_canvas->shapeManager()->shapes();
0923                 syncObject->initialized = true;
0924             }
0925 
0926             return true;
0927         }
0928         case ViewModeSwitchEvent::SwitchedToDesktopModeEvent: {
0929             ViewModeSynchronisationObject* syncObject = static_cast<ViewModeSwitchEvent*>(event)->synchronisationObject();
0930             if (m_canvas && syncObject->initialized) {
0931                 m_canvas->canvasWidget()->setFocus();
0932                 qApp->processEvents();
0933 
0934                 m_canvas->shapeManager()->setShapes(syncObject->shapes);
0935 
0936                 zoomController()->setZoom(KoZoomMode::ZOOM_CONSTANT, syncObject->zoomLevel);
0937 
0938                 qApp->processEvents();
0939                 m_canvas->canvasController()->setScrollBarValue(syncObject->scrollBarValue);
0940 
0941                 qApp->processEvents();
0942                 foreach(KoShape *shape, m_canvas->shapeManager()->shapesAt(currentPage().rect())) {
0943                     if (qobject_cast<KoTextShapeDataBase*>(shape->userData())) {
0944                         m_canvas->shapeManager()->selection()->select(shape);
0945                         break;
0946                     }
0947                 }
0948                 KoToolManager::instance()->switchToolRequested("TextToolFactory_ID");
0949             }
0950 
0951             return true;
0952         }
0953     }
0954     return QWidget::event(event);
0955 }
0956 
0957 void KWView::updateStatusBarAction()
0958 {
0959     KToggleAction *action = (KToggleAction*) actionCollection()->action("showStatusBar");
0960     if (action && statusBar())
0961         action->setChecked(! statusBar()->isHidden());
0962 }
0963 
0964 void KWView::offsetInDocumentMoved(int yOffset)
0965 {
0966     const qreal offset = -m_zoomHandler.viewToDocumentY(yOffset);
0967     const qreal height = m_zoomHandler.viewToDocumentY(m_gui->viewportSize().height());
0968 /*    if (m_currentPage.isValid()) { // most of the time the current will not change.
0969         const qreal pageTop = m_currentPage.offsetInDocument();
0970         const qreal pageBottom = pageTop + m_currentPage.height();
0971         const qreal visibleArea = qMin(offset + height, pageBottom) - qMax(pageTop, offset);
0972         if (visibleArea / height >= 0.45) // current page is just fine if > 45% is shown
0973             return;
0974 
0975         // using 'next'/'prev' is much cheaper than using a documentOffset, so try that first.
0976         if (pageTop > offset && pageTop < offset + height) { // check if the page above is a candidate.
0977             KWPage page = m_currentPage.previous();
0978             if (page.isValid() && pageTop - offset > visibleArea) {
0979                 firstDrawnPage = page;
0980                 return;
0981             }
0982         }
0983         if (pageBottom > offset && pageBottom < offset + height) { // check if the page above is a candidate.
0984             KWPage page = m_currentPage.next();
0985             if (page.isValid() && m_currentPage.height() - height > visibleArea) {
0986                 firstDrawnPage = page;
0987                 return;
0988             }
0989         }
0990     }
0991 */
0992     KWPage page = m_document->pageManager()->page(qreal(offset));
0993     qreal pageTop = page.offsetInDocument();
0994     QSizeF maxPageSize;
0995     qreal minTextX = std::numeric_limits<qreal>::max();
0996     qreal maxTextX = std::numeric_limits<qreal>::min();
0997     int minPageNum = page.pageNumber();
0998     int maxPageNum = page.pageNumber();
0999     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
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 
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 
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 
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