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 }