Warning, file /office/calligra/braindump/src/Canvas.cpp was not indexed or was modified since last indexation (in which case cross-reference links may be missing, inaccurate or erroneous).
0001 /* 0002 * Copyright (c) 2006,2007 Thorsten Zachmann <zachmann@kde.org> 0003 * Copyright (c) 2009,2010 Cyrille Berger <cberger@cberger.net> 0004 * 0005 * This library is free software; you can redistribute it and/or 0006 * modify it under the terms of the GNU Lesser General Public 0007 * License as published by the Free Software Foundation; 0008 * either version 2, or (at your option) any later version of the License. 0009 * 0010 * This library is distributed in the hope that it will be useful, 0011 * but WITHOUT ANY WARRANTY; without even the implied warranty of 0012 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 0013 * Lesser General Public License for more details. 0014 * 0015 * You should have received a copy of the GNU Lesser General Public License 0016 * along with this library; see the file COPYING. If not, write to 0017 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 0018 * Boston, MA 02110-1301, USA. 0019 */ 0020 0021 #include "Canvas.h" 0022 0023 #include <QMenu> 0024 #include <QMouseEvent> 0025 #include <QPainter> 0026 0027 #include <kxmlguifactory.h> 0028 #include <kundo2command.h> 0029 0030 #include <KoCanvasController.h> 0031 #include <KoSelection.h> 0032 #include <KoShapeManager.h> 0033 #include <KoShapeLayer.h> 0034 #include <KoToolProxy.h> 0035 #include <KoUnit.h> 0036 0037 #include "RootSection.h" 0038 #include "View.h" 0039 #include "ViewManager.h" 0040 #include "Section.h" 0041 #include "Layout.h" 0042 #include "SectionContainer.h" 0043 0044 Canvas::Canvas(View* view, RootSection* doc, Section* currentSection) 0045 : QWidget(view) 0046 , KoCanvasBase(currentSection ? currentSection->sectionContainer() : 0) 0047 , m_origin(0, 0) 0048 , m_view(view) 0049 , m_doc(doc) 0050 { 0051 m_shapeManager = new KoShapeManager(this); 0052 connect(m_shapeManager, SIGNAL(selectionChanged()), SLOT(updateOriginAndSize())); 0053 m_toolProxy = new KoToolProxy(this); 0054 setFocusPolicy(Qt::StrongFocus); 0055 // this is much faster than painting it in the paintevent 0056 QPalette pal = palette(); 0057 pal.setColor(QPalette::Base, Qt::white); 0058 pal.setColor(QPalette::Text, Qt::black); 0059 setPalette(pal); 0060 setBackgroundRole(QPalette::Base); 0061 setAutoFillBackground(true); 0062 setAttribute(Qt::WA_InputMethodEnabled, true); 0063 0064 if(currentSection) { 0065 0066 QList<KoShape*> shapes; 0067 shapes.push_back(currentSection->sectionContainer()->layer()); 0068 shapeManager()->setShapes(shapes, KoShapeManager::AddWithoutRepaint); 0069 0070 KoShapeLayer* layer = currentSection->sectionContainer()->layer(); 0071 shapeManager()->selection()->setActiveLayer(layer); 0072 0073 // Make sure the canvas is enabled 0074 setEnabled(true); 0075 0076 update(); 0077 } else { 0078 setEnabled(false); 0079 } 0080 } 0081 0082 Canvas::~Canvas() 0083 { 0084 delete m_toolProxy; 0085 delete m_shapeManager; 0086 } 0087 0088 void Canvas::setDocumentOffset(const QPoint &offset) 0089 { 0090 m_originalOffset = offset; 0091 updateOffset(); 0092 } 0093 0094 void Canvas::addCommand(KUndo2Command *command) 0095 { 0096 m_doc->addCommand(m_view->activeSection(), command); 0097 updateOriginAndSize(); 0098 } 0099 0100 KoShapeManager * Canvas::shapeManager() const 0101 { 0102 return m_shapeManager; 0103 } 0104 0105 void Canvas::updateCanvas(const QRectF& rc) 0106 { 0107 QRect clipRect(viewToWidget(viewConverter()->documentToView(rc).toRect())); 0108 clipRect.adjust(-2, -2, 2, 2); // Resize to fit anti-aliasing 0109 clipRect.moveTopLeft(clipRect.topLeft() - m_documentOffset); 0110 update(clipRect); 0111 0112 emit canvasUpdated(); 0113 } 0114 0115 KoViewConverter * Canvas::viewConverter() const 0116 { 0117 return m_view->zoomHandler(); 0118 } 0119 0120 KoUnit Canvas::unit() const 0121 { 0122 return KoUnit(KoUnit::Centimeter); 0123 } 0124 0125 const QPoint & Canvas::documentOffset() const 0126 { 0127 return m_documentOffset; 0128 } 0129 0130 QPoint Canvas::documentOrigin() const 0131 { 0132 return m_origin; 0133 } 0134 0135 void Canvas::paintEvent(QPaintEvent *event) 0136 { 0137 QPainter painter(this); 0138 0139 painter.translate(-documentOffset()); 0140 painter.setRenderHint(QPainter::Antialiasing); 0141 QRectF clipRect = event->rect().translated(documentOffset()); 0142 painter.setClipRect(clipRect); 0143 0144 painter.translate(m_origin.x(), m_origin.y()); 0145 0146 const KoViewConverter* converter = viewConverter(); 0147 shapeManager()->paint(painter, *converter, false); 0148 painter.setRenderHint(QPainter::Antialiasing, false); 0149 0150 painter.setRenderHint(QPainter::Antialiasing); 0151 m_toolProxy->paint(painter, *converter); 0152 } 0153 0154 void Canvas::tabletEvent(QTabletEvent *event) 0155 { 0156 m_toolProxy->tabletEvent(event, viewConverter()->viewToDocument(widgetToView(event->pos() + m_documentOffset))); 0157 } 0158 0159 void Canvas::mousePressEvent(QMouseEvent *event) 0160 { 0161 m_toolProxy->mousePressEvent(event, viewConverter()->viewToDocument(widgetToView(event->pos() + m_documentOffset))); 0162 0163 if(!event->isAccepted() && event->button() == Qt::RightButton) { 0164 showContextMenu(event->globalPos(), toolProxy()->popupActionList()); 0165 } 0166 0167 event->setAccepted(true); 0168 } 0169 0170 void Canvas::mouseDoubleClickEvent(QMouseEvent *event) 0171 { 0172 m_toolProxy->mouseDoubleClickEvent(event, viewConverter()->viewToDocument(widgetToView(event->pos() + m_documentOffset))); 0173 } 0174 0175 void Canvas::mouseMoveEvent(QMouseEvent *event) 0176 { 0177 m_toolProxy->mouseMoveEvent(event, viewConverter()->viewToDocument(widgetToView(event->pos() + m_documentOffset))); 0178 } 0179 0180 void Canvas::mouseReleaseEvent(QMouseEvent *event) 0181 { 0182 m_toolProxy->mouseReleaseEvent(event, viewConverter()->viewToDocument(widgetToView(event->pos() + m_documentOffset))); 0183 } 0184 0185 void Canvas::keyPressEvent(QKeyEvent *event) 0186 { 0187 m_toolProxy->keyPressEvent(event); 0188 #if 0 0189 0190 if(! event->isAccepted()) { 0191 event->accept(); 0192 switch(event->key()) { 0193 case Qt::Key_Home: 0194 m_view->navigatePage(KoPageApp::PageFirst); 0195 break; 0196 case Qt::Key_PageUp: 0197 m_view->navigatePage(KoPageApp::PagePrevious); 0198 break; 0199 case Qt::Key_PageDown: 0200 m_view->navigatePage(KoPageApp::PageNext); 0201 break; 0202 case Qt::Key_End: 0203 m_view->navigatePage(KoPageApp::PageLast); 0204 break; 0205 default: 0206 event->ignore(); 0207 break; 0208 } 0209 } 0210 if(! event->isAccepted()) { 0211 if(event->key() == Qt::Key_Backtab 0212 or(event->key() == Qt::Key_Tab && (event->modifiers() & Qt::ShiftModifier))) { 0213 focusNextPrevChild(false); 0214 } else if(event->key() == Qt::Key_Tab) { 0215 focusNextPrevChild(true); 0216 } 0217 } 0218 #endif 0219 } 0220 0221 void Canvas::keyReleaseEvent(QKeyEvent *event) 0222 { 0223 m_toolProxy->keyReleaseEvent(event); 0224 } 0225 0226 void Canvas::wheelEvent(QWheelEvent * event) 0227 { 0228 m_toolProxy->wheelEvent(event, viewConverter()->viewToDocument(widgetToView(event->pos() + m_documentOffset))); 0229 } 0230 0231 void Canvas::closeEvent(QCloseEvent * event) 0232 { 0233 event->ignore(); 0234 } 0235 0236 void Canvas::updateInputMethodInfo() 0237 { 0238 updateMicroFocus(); 0239 } 0240 0241 QVariant Canvas::inputMethodQuery(Qt::InputMethodQuery query) const 0242 { 0243 if (query == Qt::ImMicroFocus) { 0244 QRectF rect = (m_toolProxy->inputMethodQuery(query, *(viewConverter())).toRectF()).toRect(); 0245 QPointF scroll(canvasController()->scrollBarValue()); 0246 rect.translate(documentOrigin() - scroll); 0247 return rect.toRect(); 0248 } 0249 return m_toolProxy->inputMethodQuery(query, *(viewConverter())); 0250 } 0251 0252 void Canvas::inputMethodEvent(QInputMethodEvent *event) 0253 { 0254 m_toolProxy->inputMethodEvent(event); 0255 } 0256 0257 void Canvas::resizeEvent(QResizeEvent * event) 0258 { 0259 emit sizeChanged(event->size()); 0260 updateOriginAndSize(); 0261 } 0262 0263 void Canvas::showContextMenu(const QPoint& globalPos, const QList<QAction*>& actionList) 0264 { 0265 m_view->unplugActionList("toolproxy_action_list"); 0266 m_view->plugActionList("toolproxy_action_list", actionList); 0267 QMenu *menu = dynamic_cast<QMenu*>(m_view->factory()->container("default_canvas_popup", m_view)); 0268 0269 if(menu) 0270 menu->exec(globalPos); 0271 } 0272 0273 void Canvas::setBackgroundColor(const QColor &color) 0274 { 0275 QPalette pal = palette(); 0276 pal.setColor(QPalette::Normal, backgroundRole(), color); 0277 pal.setColor(QPalette::Inactive, backgroundRole(), color); 0278 setPalette(pal); 0279 } 0280 0281 void Canvas::updateOriginAndSize() 0282 { 0283 if(m_view->activeSection()) { 0284 QRectF rect = m_view->activeSection()->layout()->boundingBox(); 0285 if(rect != m_oldDocumentRect) { 0286 m_oldDocumentRect = rect; 0287 emit(documentRect(rect)); 0288 update(); 0289 } 0290 QRect viewRect = viewConverter()->documentToView(rect).toRect(); 0291 if(m_oldViewDocumentRect != viewRect) { 0292 m_oldViewDocumentRect = viewRect; 0293 m_origin = -viewRect.topLeft(); 0294 KoCanvasController* controller = canvasController(); 0295 if(controller) { 0296 // tell canvas controller the new document size in pixel 0297 controller->updateDocumentSize(viewRect.size(), true); 0298 // make sure the actual selection is visible 0299 KoSelection * selection = m_shapeManager->selection(); 0300 if(selection->count()) 0301 controller->ensureVisible(viewConverter()->documentToView(selection->boundingRect())); 0302 updateOffset(); 0303 } 0304 } 0305 } 0306 } 0307 0308 void Canvas::updateOffset() 0309 { 0310 qreal dx = qMax(0, (size().width() - m_oldViewDocumentRect.size().width()) / 2); 0311 qreal dy = qMax(0, (size().height() - m_oldViewDocumentRect.size().height()) / 2); 0312 m_documentOffset = m_originalOffset - QPoint(dx, dy); 0313 } 0314 0315 void Canvas::gridSize(qreal *horizontal, qreal *vertical) const 0316 { 0317 *horizontal = 1; 0318 *vertical = 1; 0319 } 0320 0321 bool Canvas::snapToGrid() const 0322 { 0323 return false; 0324 } 0325 0326 void Canvas::setCursor(const QCursor &cursor) 0327 { 0328 QWidget::setCursor(cursor); 0329 } 0330 0331 void Canvas::focusInEvent(QFocusEvent * event) 0332 { 0333 QWidget::focusInEvent(event); 0334 emit(canvasReceivedFocus()); 0335 } 0336 0337 QPoint Canvas::widgetToView(const QPoint& p) const 0338 { 0339 return p - m_origin; 0340 } 0341 0342 QRect Canvas::widgetToView(const QRect& r) const 0343 { 0344 return r.translated(- m_origin); 0345 } 0346 0347 QPoint Canvas::viewToWidget(const QPoint& p) const 0348 { 0349 return p + m_origin; 0350 } 0351 0352 QRect Canvas::viewToWidget(const QRect& r) const 0353 { 0354 return r.translated(m_origin); 0355 }