File indexing completed on 2024-05-12 16:36:46
0001 /* This file is part of the KDE project 0002 * Copyright (C) 2007-2009 Thorsten Zachmann <zachmann@kde.org> 0003 * Copyright (C) 2008 Jim Courtiau <jeremy.courtiau@gmail.com> 0004 * Copyright (C) 2009 Alexia Allanic <alexia_allanic@yahoo.fr> 0005 * Copyright (C) 2009 Jean-Nicolas Artaud <jeannicolasartaud@gmail.com> 0006 * Copyright (C) 2009 Jérémy Lugagne <jejewindsurf@hotmail.com> 0007 * Copyright (C) 2009 Johann Hingue <yoan1703@hotmail.fr> 0008 * 0009 * This library is free software; you can redistribute it and/or 0010 * modify it under the terms of the GNU Library General Public 0011 * License as published by the Free Software Foundation; either 0012 * version 2 of the License, or (at your option) any later version. 0013 * 0014 * This library is distributed in the hope that it will be useful, 0015 * but WITHOUT ANY WARRANTY; without even the implied warranty of 0016 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 0017 * Library General Public License for more details. 0018 * 0019 * You should have received a copy of the GNU Library General Public License 0020 * along with this library; see the file COPYING.LIB. If not, write to 0021 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 0022 * Boston, MA 02110-1301, USA. 0023 */ 0024 0025 #include "KPrPresentationTool.h" 0026 0027 #include <QWidget> 0028 #include <QVBoxLayout> 0029 #include <QPainter> 0030 #include <QKeyEvent> 0031 #include <QAbstractTextDocumentLayout> 0032 #include <QDesktopServices> 0033 #include <QUrl> 0034 #include <QDBusConnection> 0035 #include <QFrame> 0036 0037 #include <KoShape.h> 0038 #include <KoShapeManager.h> 0039 #include <KoPointerEvent.h> 0040 #include <KoEventAction.h> 0041 #include <KoPACanvasBase.h> 0042 #include <KoTextShapeData.h> 0043 #include <KoTextLayoutRootArea.h> 0044 #include <KoPointedAt.h> 0045 0046 #include "KPrViewModePresentation.h" 0047 #include "KPrPresentationStrategy.h" 0048 #include "KPrPresentationHighlightStrategy.h" 0049 #include "KPrPresentationDrawStrategy.h" 0050 #include "KPrPresentationBlackStrategy.h" 0051 #include "ui/KPrPresentationToolWidget.h" 0052 0053 #ifndef QT_NO_DBUS 0054 #include "KPrPresentationToolAdaptor.h" 0055 #endif 0056 0057 0058 KPrPresentationTool::KPrPresentationTool( KPrViewModePresentation &viewMode ) 0059 : KoToolBase( viewMode.canvas() ) 0060 , m_viewMode( viewMode ) 0061 , m_strategy( new KPrPresentationStrategy( this ) ) 0062 #ifndef QT_NO_DBUS 0063 , m_bus ( new KPrPresentationToolAdaptor( this ) ) 0064 #endif 0065 { 0066 #ifndef QT_NO_DBUS 0067 QDBusConnection::sessionBus().registerObject("/kpresenter/PresentationTools", this); 0068 #endif 0069 0070 // tool box 0071 m_frame = new QFrame( m_viewMode.canvas()->canvasWidget() ); 0072 0073 QVBoxLayout *frameLayout = new QVBoxLayout(); 0074 0075 m_presentationToolWidget = new KPrPresentationToolWidget(m_viewMode.canvas()->canvasWidget()); 0076 frameLayout->addWidget( m_presentationToolWidget, 0, Qt::AlignLeft | Qt::AlignBottom ); 0077 m_frame->setLayout( frameLayout ); 0078 m_frame->show(); 0079 0080 m_presentationToolWidget->raise(); 0081 m_presentationToolWidget->setVisible( false ); 0082 m_presentationToolWidget->installEventFilter(this); 0083 0084 // Connections of button clicked to slots 0085 connect( m_presentationToolWidget->presentationToolUi().penButton, SIGNAL(clicked()), this, SLOT(drawOnPresentation()) ); 0086 connect( m_presentationToolWidget->presentationToolUi().highLightButton, SIGNAL(clicked()), this, SLOT(highlightPresentation()) ); 0087 connect( m_presentationToolWidget->presentationToolUi().blackButton, SIGNAL(clicked()), this, SLOT(blackPresentation()) ); 0088 0089 } 0090 0091 KPrPresentationTool::~KPrPresentationTool() 0092 { 0093 delete m_strategy; 0094 } 0095 0096 bool KPrPresentationTool::wantsAutoScroll() const 0097 { 0098 return false; 0099 } 0100 0101 void KPrPresentationTool::paint( QPainter &painter, const KoViewConverter &converter ) 0102 { 0103 Q_UNUSED(painter); 0104 Q_UNUSED(converter); 0105 } 0106 0107 void KPrPresentationTool::mousePressEvent( KoPointerEvent *event ) 0108 { 0109 if ( event->button() & Qt::LeftButton ) { 0110 event->accept(); 0111 finishEventActions(); 0112 KoShape * shapeClicked = canvas()->shapeManager()->shapeAt( event->point ); 0113 if (shapeClicked) { 0114 QString link; 0115 if (checkHyperlink(event, shapeClicked, link)) { 0116 runHyperlink(link); 0117 return; 0118 } 0119 0120 m_eventActions = shapeClicked->eventActions(); 0121 if (!m_eventActions.isEmpty()) { 0122 foreach ( KoEventAction * eventAction, m_eventActions ) { 0123 eventAction->start(); 0124 } 0125 // don't do next step if a action was executed 0126 return; 0127 } 0128 } 0129 m_viewMode.navigate( KPrAnimationDirector::NextStep ); 0130 } 0131 else if ( event->button() & Qt::RightButton ) { 0132 event->accept(); 0133 finishEventActions(); 0134 m_viewMode.navigate( KPrAnimationDirector::PreviousStep ); 0135 } 0136 } 0137 0138 void KPrPresentationTool::mouseDoubleClickEvent( KoPointerEvent *event ) 0139 { 0140 Q_UNUSED(event); 0141 } 0142 0143 void KPrPresentationTool::mouseMoveEvent( KoPointerEvent *event ) 0144 { 0145 KoShape * shape = canvas()->shapeManager()->shapeAt(event->point); 0146 0147 QString link; 0148 if (checkHyperlink(event, shape, link)) { 0149 canvas()->setCursor(Qt::PointingHandCursor); 0150 return; 0151 } 0152 0153 canvas()->setCursor(Qt::ArrowCursor); 0154 } 0155 0156 void KPrPresentationTool::mouseReleaseEvent( KoPointerEvent *event ) 0157 { 0158 Q_UNUSED(event); 0159 } 0160 0161 void KPrPresentationTool::keyPressEvent( QKeyEvent *event ) 0162 { 0163 finishEventActions(); 0164 // first try to handle the event in the strategy if it is done there no need to use the default action 0165 if ( ! m_strategy->keyPressEvent( event ) ) { 0166 switch ( event->key() ) 0167 { 0168 case Qt::Key_Escape: 0169 m_viewMode.activateSavedViewMode(); 0170 break; 0171 case Qt::Key_Home: 0172 m_viewMode.navigate( KPrAnimationDirector::FirstPage ); 0173 break; 0174 case Qt::Key_Up: 0175 case Qt::Key_PageUp: 0176 m_viewMode.navigate( KPrAnimationDirector::PreviousPage ); 0177 break; 0178 case Qt::Key_Backspace: 0179 case Qt::Key_Left: 0180 m_viewMode.navigate( KPrAnimationDirector::PreviousStep ); 0181 break; 0182 case Qt::Key_Right: 0183 case Qt::Key_Space: 0184 m_viewMode.navigate( KPrAnimationDirector::NextStep ); 0185 break; 0186 case Qt::Key_Down: 0187 case Qt::Key_PageDown: 0188 m_viewMode.navigate( KPrAnimationDirector::NextPage ); 0189 break; 0190 case Qt::Key_End: 0191 m_viewMode.navigate( KPrAnimationDirector::LastPage ); 0192 break; 0193 default: 0194 event->ignore(); 0195 break; 0196 } 0197 } 0198 } 0199 0200 void KPrPresentationTool::keyReleaseEvent( QKeyEvent *event ) 0201 { 0202 Q_UNUSED( event ); 0203 } 0204 0205 void KPrPresentationTool::wheelEvent( KoPointerEvent * event ) 0206 { 0207 Q_UNUSED( event ); 0208 } 0209 0210 void KPrPresentationTool::activate(ToolActivation toolActivation, const QSet<KoShape*> &shapes) 0211 { 0212 Q_UNUSED(toolActivation); 0213 Q_UNUSED(shapes); 0214 m_frame->setGeometry( canvas()->canvasWidget()->geometry() ); 0215 m_presentationToolWidget->setVisible( false ); 0216 // redirect event to tool widget 0217 m_frame->installEventFilter( this ); 0218 // activate tracking for show/hide tool buttons 0219 m_frame->setMouseTracking( true ); 0220 } 0221 0222 void KPrPresentationTool::deactivate() 0223 { 0224 switchStrategy( new KPrPresentationStrategy( this ) ); 0225 finishEventActions(); 0226 } 0227 0228 void KPrPresentationTool::finishEventActions() 0229 { 0230 foreach ( KoEventAction * eventAction, m_eventActions ) { 0231 eventAction->finish(); 0232 } 0233 } 0234 0235 void KPrPresentationTool::switchStrategy( KPrPresentationStrategyBase * strategy ) 0236 { 0237 Q_ASSERT( strategy ); 0238 Q_ASSERT( m_strategy != strategy ); 0239 delete m_strategy; 0240 m_strategy = strategy; 0241 } 0242 0243 // SLOTS 0244 void KPrPresentationTool::highlightPresentation() 0245 { 0246 KPrPresentationStrategyBase * strategy; 0247 if ( dynamic_cast<KPrPresentationHighlightStrategy *>( m_strategy ) ) { 0248 strategy = new KPrPresentationStrategy( this ); 0249 } 0250 else { 0251 strategy = new KPrPresentationHighlightStrategy( this ); 0252 } 0253 switchStrategy( strategy ); 0254 } 0255 0256 void KPrPresentationTool::drawOnPresentation() 0257 { 0258 KPrPresentationStrategyBase * strategy; 0259 if ( dynamic_cast<KPrPresentationDrawStrategy*>( m_strategy ) ) { 0260 strategy = new KPrPresentationStrategy( this ); 0261 } 0262 else { 0263 strategy = new KPrPresentationDrawStrategy( this ); 0264 } 0265 switchStrategy( strategy ); 0266 } 0267 0268 void KPrPresentationTool::blackPresentation() 0269 { 0270 KPrPresentationStrategyBase * strategy; 0271 if ( dynamic_cast<KPrPresentationBlackStrategy*>( m_strategy ) ) { 0272 strategy = new KPrPresentationStrategy( this ); 0273 } 0274 else { 0275 strategy = new KPrPresentationBlackStrategy( this ); 0276 } 0277 switchStrategy( strategy ); 0278 } 0279 0280 bool KPrPresentationTool::eventFilter( QObject *obj, QEvent * event ) 0281 { 0282 if ( event->type() == QEvent::MouseMove ) { 0283 QMouseEvent *mouseEvent = static_cast<QMouseEvent*>( event ); 0284 QWidget *source = static_cast<QWidget*>( obj ); 0285 QPoint pos = source->mapFrom( m_viewMode.canvas()->canvasWidget(), mouseEvent->pos() ); 0286 0287 QSize buttonSize = m_presentationToolWidget->size() + QSize( 20, 20 ); 0288 QRect geometry = QRect( 0, m_frame->height() - buttonSize.height(), buttonSize.width(), buttonSize.height() ); 0289 if ( geometry.contains( pos ) ) { 0290 m_presentationToolWidget->setVisible( true ); 0291 } 0292 else { 0293 m_presentationToolWidget->setVisible( false ); 0294 } 0295 } 0296 return false; 0297 } 0298 0299 bool KPrPresentationTool::checkHyperlink(KoPointerEvent *event, KoShape *shape, QString & hyperLink) 0300 { 0301 if (!shape) { 0302 return false; 0303 } 0304 0305 KoTextShapeData *textShapeData = qobject_cast<KoTextShapeData*>(shape->userData()); 0306 if (textShapeData) { 0307 if (!textShapeData->rootArea()) { 0308 return false ; // not layouted yet 0309 } 0310 QPointF p = shape->absoluteTransformation(0).inverted().map(event->point); 0311 p = p + QPointF(0.0, textShapeData->documentOffset()); 0312 0313 KoPointedAt pointedAt = textShapeData->rootArea()->hitTest(p, Qt::ExactHit); 0314 0315 if (!textShapeData->isDirty() && !pointedAt.externalHRef.isEmpty()) { 0316 hyperLink = pointedAt.externalHRef; 0317 return true; 0318 } 0319 } 0320 return false; 0321 } 0322 0323 void KPrPresentationTool::runHyperlink(const QString &hyperLink) 0324 { 0325 QUrl url = QUrl::fromUserInput(hyperLink); 0326 0327 QDesktopServices::openUrl(url); 0328 } 0329 0330 KPrPresentationStrategyBase *KPrPresentationTool::strategy() 0331 { 0332 return m_strategy; 0333 } 0334 0335 KPrViewModePresentation &KPrPresentationTool::viewModePresentation() 0336 { 0337 return m_viewMode; 0338 } 0339 0340 0341 void KPrPresentationTool::normalPresentation() 0342 { 0343 switchStrategy( new KPrPresentationStrategy( this ) ); 0344 }