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 }