File indexing completed on 2024-05-12 16:36:49

0001 /* This file is part of the KDE project
0002  * Copyright (C) 2007 Thomas Zander <zander@kde.org>
0003  * Copyright (C) 2007 Jan Hambrecht <jaham@gmx.net>
0004  * Copyright (C) 2008 C. Boemann <cbo@boemann.dk>
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 #include "KPrSoundData.h"
0023 
0024 #include "KPrSoundCollection.h"
0025 #include "StageDebug.h"
0026 
0027 #include <QTemporaryFile>
0028 #include <QIODevice>
0029 
0030 // make it a QSharedData
0031 class Q_DECL_HIDDEN KPrSoundData::Private
0032 {
0033 public:
0034     Private(KPrSoundCollection *c)
0035     : refCount(0)
0036     , collection(c)
0037     , tempFile(0)
0038     , taggedForSaving(false)
0039     { }
0040 
0041     ~Private() {
0042         delete tempFile;
0043     }
0044     QString tempFileName;
0045     QString title;
0046 
0047     int refCount;
0048     QString storeHref;
0049     KPrSoundCollection *collection;
0050     QTemporaryFile *tempFile;
0051     bool taggedForSaving;
0052 };
0053 
0054 KPrSoundData::KPrSoundData(KPrSoundCollection *collection, const QString &href)
0055     : d(new Private(collection))
0056 {
0057     Q_ASSERT(collection);
0058     collection->addSound(this);
0059     d->storeHref = href;
0060     //TODO make sure the title is not duplicated
0061     d->title = href.section('/', -1); // TODO only works on linux like filenames
0062     Q_ASSERT(d->refCount == 1);
0063 }
0064 
0065 KPrSoundData::KPrSoundData(const KPrSoundData &soundData)
0066 :    d(soundData.d)
0067 {
0068     d->refCount++;
0069 }
0070 
0071 KPrSoundData::~KPrSoundData() {
0072     if(--d->refCount == 0) {
0073         d->collection->removeSound(this);
0074         delete d;
0075     }
0076 }
0077 
0078 bool KPrSoundData::operator==(const KPrSoundData &other) const {
0079     return other.d == d;
0080 }
0081 
0082 QString KPrSoundData::tagForSaving() {
0083     d->taggedForSaving=true;
0084     d->storeHref = QString("Sounds/%1").arg(d->title);
0085 
0086     return d->storeHref;
0087 }
0088 
0089 QString KPrSoundData::storeHref() const {
0090     return d->storeHref;
0091 }
0092 
0093 QString KPrSoundData::nameOfTempFile() const {
0094     return d->tempFileName;
0095 }
0096 
0097 QString KPrSoundData::title() const {
0098     return d->title;
0099 }
0100 
0101 bool KPrSoundData::saveToFile(QIODevice *device)
0102 {
0103     if(! d->tempFile->open())
0104         return false;
0105     char * data = new char[32 * 1024];
0106     while(true) {
0107         bool failed = false;
0108         qint64 bytes = d->tempFile->read(data, 32*1024);
0109         if(bytes == 0)
0110             break;
0111         else if(bytes == -1) {
0112             warnStage << "Failed to read data from the tmpfile";
0113             failed = true;
0114         }
0115         while(! failed && bytes > 0) {
0116             qint64 written = device->write(data, bytes);
0117             if(written < 0) {// error!
0118                 warnStage << "Failed to copy the sound from the temp file";
0119                 failed = true;
0120             }
0121             bytes -= written;
0122         }
0123         if(failed) { // read or write failed; so lets cleanly abort.
0124                 delete[] data;
0125             return false;
0126         }
0127     }
0128     delete[] data;
0129     return true;
0130 }
0131 
0132 bool KPrSoundData::isTaggedForSaving()
0133 {
0134     return d->taggedForSaving;
0135 }
0136 
0137 
0138 bool KPrSoundData::loadFromFile(QIODevice *device) {
0139     struct Finally {
0140         Finally(QIODevice *d) : device (d), bytes(0) {}
0141         ~Finally() {
0142             delete device;
0143             delete[] bytes;
0144         }
0145         QIODevice *device;
0146         char *bytes;
0147     };
0148     Finally finally(device);
0149 
0150     // remove prev data
0151     delete d->tempFile;
0152     d->tempFile = 0;
0153 
0154     d->tempFile = new QTemporaryFile();
0155     if(! d->tempFile->open())
0156         return false;
0157     char * data = new char[32 * 1024];
0158     finally.bytes = data;
0159     while(true) {
0160         bool failed = false;
0161         qint64 bytes = device->read(data, 32*1024);
0162         if(bytes == 0)
0163             break;
0164         else if(bytes == -1) {
0165             warnStage << "Failed to read sound data";
0166             failed = true;
0167         }
0168         while(! failed && bytes > 0) {
0169             qint64 written = d->tempFile->write(data, bytes);
0170             if(written < 0) {// error!
0171                 warnStage << "Failed to copy the sound to temp";
0172                 failed = true;
0173             }
0174             bytes -= written;
0175         }
0176         if(failed) { // read or write failed; so lets cleanly abort.
0177             delete d->tempFile;
0178             d->tempFile = 0;
0179             return false;
0180         }
0181     }
0182     d->tempFileName = d->tempFile->fileName();
0183     d->tempFile->close();
0184     return true;
0185 }
0186 
0187 KPrSoundCollection * KPrSoundData::soundCollection()
0188 {
0189     return d->collection;
0190 }