File indexing completed on 2024-05-19 16:07:55
0001 /* This file is part of the KDE project 0002 * Copyright (C) 2006-2007, 2009 Thomas Zander <zander@kde.org> 0003 * Copyright (C) 2007 Jan Hambrecht <jaham@gmx.net> 0004 * Copyright (C) 2008 Thorsten Zachmann <zachmann@kde.org> 0005 * Copyright (C) 2009 C. Boemann <cbo@boemann.dk> 0006 * Copyright (C) 2012 Gopalakrishna Bhat A <gopalakbhat@gmail.com> 0007 * 0008 * This library is free software; you can redistribute it and/or 0009 * modify it under the terms of the GNU Library General Public 0010 * License as published by the Free Software Foundation; either 0011 * version 2 of the License, or (at your option) any later version. 0012 * 0013 * This library is distributed in the hope that it will be useful, 0014 * but WITHOUT ANY WARRANTY; without even the implied warranty of 0015 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 0016 * Library General Public License for more details. 0017 * 0018 * You should have received a copy of the GNU Library General Public License 0019 * along with this library; see the file COPYING.LIB. If not, write to 0020 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 0021 * Boston, MA 02110-1301, USA. 0022 */ 0023 0024 #include "VideoShape.h" 0025 0026 #include <KoViewConverter.h> 0027 #include <VideoEventAction.h> 0028 #include <VideoCollection.h> 0029 #include <VideoData.h> 0030 #ifdef SHOULD_BUILD_THUMBNAIL 0031 #include <VideoThumbnailer.h> 0032 #endif 0033 #include "VideoDebug.h" 0034 0035 #include <KoShapeLoadingContext.h> 0036 #include <KoOdfLoadingContext.h> 0037 #include <KoShapeSavingContext.h> 0038 #include <KoXmlWriter.h> 0039 #include <KoXmlNS.h> 0040 #include <KoStore.h> 0041 #include <KoIcon.h> 0042 0043 #include <QUrl> 0044 #include <QPainter> 0045 0046 VideoShape::VideoShape() 0047 : KoFrameShape(KoXmlNS::draw, "plugin") 0048 , m_videoCollection(0) 0049 , m_videoEventAction(new VideoEventAction(this)) 0050 #ifdef SHOULD_BUILD_THUMBNAIL 0051 , m_thumbnailer(new VideoThumbnailer()) 0052 #endif 0053 , m_oldVideoData(0) 0054 , m_icon(koIcon("video-x-generic")) 0055 { 0056 setKeepAspectRatio(true); 0057 addEventAction(m_videoEventAction); 0058 } 0059 0060 VideoShape::~VideoShape() 0061 { 0062 #ifdef SHOULD_BUILD_THUMBNAIL 0063 delete m_thumbnailer; 0064 #endif 0065 } 0066 0067 void VideoShape::paint(QPainter &painter, const KoViewConverter &converter, KoShapePaintingContext &) 0068 { 0069 QRectF pixelsF = converter.documentToView(QRectF(QPointF(0,0), size())); 0070 0071 VideoData *currentVideoData = videoData(); 0072 #ifdef SHOULD_BUILD_THUMBNAIL 0073 if (currentVideoData && currentVideoData != m_oldVideoData) { 0074 //generate thumbnails 0075 m_oldVideoData = currentVideoData; 0076 m_thumbnailer->createThumbnail(currentVideoData, pixelsF.size().toSize()); 0077 } 0078 QImage thumnailImage = m_thumbnailer->thumbnail(); 0079 if (thumnailImage.isNull()) { 0080 painter.fillRect(pixelsF, QColor(Qt::gray)); 0081 painter.setPen(QPen(Qt::black, 0)); 0082 painter.drawRect(pixelsF); 0083 0084 m_icon.paint(&painter, pixelsF.toRect()); 0085 } else { 0086 painter.drawImage(pixelsF, thumnailImage); 0087 } 0088 #else 0089 painter.fillRect(pixelsF, QColor(Qt::gray)); 0090 painter.setPen(QPen(Qt::black, 0)); 0091 painter.drawRect(pixelsF); 0092 0093 m_icon.paint(&painter, pixelsF.toRect()); 0094 #endif 0095 } 0096 0097 void VideoShape::saveOdf(KoShapeSavingContext &context) const 0098 { 0099 // make sure we have a valid image data pointer before saving 0100 VideoData *videoData = qobject_cast<VideoData*>(userData()); 0101 if (videoData == 0) 0102 return; 0103 0104 KoXmlWriter &writer = context.xmlWriter(); 0105 0106 writer.startElement("draw:frame"); 0107 saveOdfAttributes(context, OdfAllAttributes); 0108 writer.startElement("draw:plugin"); 0109 // In the spec, only the xlink:href attribute is marked as mandatory, cool :) 0110 QString name = videoData->tagForSaving(m_videoCollection->saveCounter); 0111 writer.addAttribute("xlink:type", "simple"); 0112 writer.addAttribute("xlink:show", "embed"); 0113 writer.addAttribute("xlink:actuate", "onLoad"); 0114 writer.addAttribute("xlink:href", name); 0115 writer.addAttribute("draw:mime-type", "application/vnd.sun.star.media"); 0116 writer.endElement(); // draw:plugin 0117 saveOdfCommonChildElements(context); 0118 writer.endElement(); // draw:frame 0119 0120 context.addDataCenter(m_videoCollection); 0121 } 0122 0123 bool VideoShape::loadOdf(const KoXmlElement &element, KoShapeLoadingContext &context) 0124 { 0125 loadOdfAttributes(element, context, OdfAllAttributes); 0126 return loadOdfFrame(element, context); 0127 } 0128 0129 bool VideoShape::loadOdfFrameElement(const KoXmlElement &element, KoShapeLoadingContext &context) 0130 { 0131 /* the loading of the attributes might set the event actions which removes the m_videoEventAction 0132 * when there are other eventactions for the shape. Therefore we need to add it again. It is no 0133 * problem to add it again as internally a set is used and so it is not problematic when it is 0134 * already set. */ 0135 addEventAction(m_videoEventAction); 0136 0137 if (m_videoCollection) { 0138 const QString href = element.attribute("href"); 0139 // this can happen in case it is a presentation:placeholder 0140 if (!href.isEmpty()) { 0141 QUrl url = QUrl::fromUserInput(href); 0142 VideoData *data=0; 0143 0144 if(href.startsWith("../")) { 0145 // file is outside store 0146 QUrl url = context.odfLoadingContext().store()->urlOfStore(); 0147 QString path = url.path(); 0148 if (!path.endsWith(QLatin1Char('/'))) { 0149 path.append(QLatin1Char('/')); 0150 } 0151 path.append(href.mid(3)); 0152 url.setPath(path); 0153 data = m_videoCollection->createExternalVideoData(url, false); 0154 } else if(!url.isRelative()) { 0155 // file is outside store and absolute 0156 data = m_videoCollection->createExternalVideoData(QUrl::fromUserInput(href), false); 0157 } else { 0158 // file is inside store 0159 KoStore *store = context.odfLoadingContext().store(); 0160 data = m_videoCollection->createVideoData(href, store); 0161 } 0162 setUserData(data); 0163 } 0164 } 0165 0166 return true; 0167 } 0168 0169 VideoCollection *VideoShape::videoCollection() const 0170 { 0171 return m_videoCollection; 0172 } 0173 0174 void VideoShape::setVideoCollection(VideoCollection *collection) 0175 { 0176 m_videoCollection = collection; 0177 } 0178 0179 VideoData *VideoShape::videoData() const 0180 { 0181 return qobject_cast<VideoData *>(userData()); 0182 }