diff options
| author | tpearson <tpearson@283d02a7-25f6-0310-bc7c-ecb5cbfe19da> | 2010-01-20 01:29:50 +0000 | 
|---|---|---|
| committer | tpearson <tpearson@283d02a7-25f6-0310-bc7c-ecb5cbfe19da> | 2010-01-20 01:29:50 +0000 | 
| commit | 8362bf63dea22bbf6736609b0f49c152f975eb63 (patch) | |
| tree | 0eea3928e39e50fae91d4e68b21b1e6cbae25604 /kexi/core/kexiblobbuffer.cpp | |
| download | koffice-8362bf63dea22bbf6736609b0f49c152f975eb63.tar.gz koffice-8362bf63dea22bbf6736609b0f49c152f975eb63.zip | |
Added old abandoned KDE3 version of koffice
git-svn-id: svn://anonsvn.kde.org/home/kde/branches/trinity/applications/koffice@1077364 283d02a7-25f6-0310-bc7c-ecb5cbfe19da
Diffstat (limited to 'kexi/core/kexiblobbuffer.cpp')
| -rw-r--r-- | kexi/core/kexiblobbuffer.cpp | 373 | 
1 files changed, 373 insertions, 0 deletions
| diff --git a/kexi/core/kexiblobbuffer.cpp b/kexi/core/kexiblobbuffer.cpp new file mode 100644 index 000000000..d66d69af3 --- /dev/null +++ b/kexi/core/kexiblobbuffer.cpp @@ -0,0 +1,373 @@ +/* This file is part of the KDE project +   Copyright (C) 2005 Jaroslaw Staniek <js@iidea.pl> + +   This library is free software; you can redistribute it and/or +   modify it under the terms of the GNU Library General Public +   License as published by the Free Software Foundation; either +   version 2 of the License, or (at your option) any later version. + +   This library is distributed in the hope that it will be useful, +   but WITHOUT ANY WARRANTY; without even the implied warranty of +   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU +   Library General Public License for more details. + +   You should have received a copy of the GNU Library General Public License +   along with this library; see the file COPYING.LIB.  If not, write to +   the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. +*/ + +#include "kexiblobbuffer.h" + +#include <assert.h> + +#include <qfile.h> +#include <qfileinfo.h> +#include <qbuffer.h> + +#include <kdebug.h> +#include <kstaticdeleter.h> +#include <kimageio.h> + +#include <kexidb/connection.h> + +static KStaticDeleter<KexiBLOBBuffer> m_bufferDeleter; +static KexiBLOBBuffer* m_buffer = 0; + +//----------------- + +class KexiBLOBBuffer::Private +{ +	public: +		Private() +		 : maxId(0) +		 , inMemoryItems(1009) +		 , storedItems(1009) +		 , itemsByURL(1009) +		{ +		} +		Id_t maxId; //!< Used to compute maximal recently used identifier for unstored BLOB +//! @todo will be changed to QHash<quint64, Item> +		QIntDict<Item> inMemoryItems; //!< for unstored BLOBs +		QIntDict<Item> storedItems; //!< for stored items +		QDict<Item> itemsByURL; +		QGuardedPtr<KexiDB::Connection> conn; +}; + +//----------------- + +KexiBLOBBuffer::Handle::Handle(Item* item) + : m_item(item) +{ +	if (m_item) +		m_item->refs++; +} + +KexiBLOBBuffer::Handle::Handle(const Handle& handle) +{ +	*this = handle; +} + +KexiBLOBBuffer::Handle::Handle() + : m_item(0) +{ +} + +KexiBLOBBuffer::Handle::~Handle() +{ +	if (m_item) { +		m_item->refs--; +		if (m_item->refs<=0) +			KexiBLOBBuffer::self()->removeItem(m_item->id, m_item->stored); +	} +} + +KexiBLOBBuffer::Handle& KexiBLOBBuffer::Handle::operator=(const Handle& handle) +{ +	m_item = handle.m_item; +	if (m_item) +		m_item->refs++; +	return *this; +} + +void KexiBLOBBuffer::Handle::setStoredWidthID(KexiBLOBBuffer::Id_t id) +{ +	if (!m_item) +		return; +	if (m_item->stored) { +		kdWarning() << "KexiBLOBBuffer::Handle::setStoredWidthID(): object for id=" << id  +			<< " is aleady stored" << endl; +		return; +	} + +	KexiBLOBBuffer::self()->takeItem(m_item); +	m_item->id = id; //new id +	m_item->stored = true; +//! @todo What about other handles for this item?  +//! @todo They were assuming it's unstored item, but it's stored now.... +	KexiBLOBBuffer::self()->insertItem(m_item); +} + +//----------------- + +KexiBLOBBuffer::Item::Item(const QByteArray& data, KexiBLOBBuffer::Id_t ident, bool _stored, +	const QString& _name, const QString& _caption, const QString& _mimeType,  +	Id_t _folderId, const QPixmap& pixmap) + : name(_name), caption(_caption), mimeType(_mimeType), refs(0),  + id(ident), folderId(_folderId), stored(_stored), + m_pixmapLoaded(new bool(false)/*workaround for pixmap() const*/) +{ +	if (pixmap.isNull()) +		m_pixmap = new QPixmap(); +	else +		m_pixmap = new QPixmap(pixmap); + +	if (data.isEmpty()) +		m_data = new QByteArray(); +	else +		m_data = new QByteArray(data); +} + +KexiBLOBBuffer::Item::~Item() +{ +	kexipluginsdbg << "KexiBLOBBuffer::Item::~Item()" << endl; +	delete m_pixmap; +	m_pixmap = 0; +	delete m_data; +	m_data = 0; +	delete m_pixmapLoaded; +} + +QPixmap KexiBLOBBuffer::Item::pixmap() const +{ +	if (!*m_pixmapLoaded && m_pixmap->isNull() && !m_data->isEmpty()) { +		QString type( KImageIO::typeForMime(mimeType) ); +		if (!KImageIO::canRead( type ) || !m_pixmap->loadFromData(*m_data, type.latin1())) { +			//! @todo inform about error? +		} +		*m_pixmapLoaded = true; +	} +	return *m_pixmap; +} + +QByteArray KexiBLOBBuffer::Item::data() const +{ +	if (!m_data->isEmpty()) +		return *m_data; + +	if (m_data->isEmpty() && m_pixmap->isNull()) +		return QByteArray(); +	 +	if (m_data->isEmpty() && !m_pixmap->isNull()) { +		//convert pixmap to byte array +		//(do it only on demand) +		QBuffer buffer( *m_data ); +		buffer.open( IO_WriteOnly ); +		m_pixmap->save( &buffer, mimeType.isEmpty() ? (const char*)"PNG"/*! @todo default? */ : mimeType.latin1() ); +	} +	return *m_data; +} + +//----------------- + +KexiBLOBBuffer::KexiBLOBBuffer() + : QObject() + , d(new Private()) +{ +	Q_ASSERT(!m_buffer); +	d->inMemoryItems.setAutoDelete(true); +	d->storedItems.setAutoDelete(true); +} + +KexiBLOBBuffer::~KexiBLOBBuffer() +{ +	delete d; +} + +KexiBLOBBuffer::Handle KexiBLOBBuffer::insertPixmap(const KURL& url) +{ +	if (url.isEmpty() ) +		return KexiBLOBBuffer::Handle(); +	if (!url.isValid()) { +		kexipluginswarn << "::insertPixmap: INVALID URL '" << url << "'" << endl; +		return KexiBLOBBuffer::Handle(); +	} +//! @todo what about searching by filename only and then compare data? +	Item * item = d->itemsByURL.find(url.prettyURL()); +	if (item) +		return KexiBLOBBuffer::Handle(item); + +	QString fileName = url.isLocalFile() ? url.path() : url.prettyURL(); +//! @todo download the file if remote, then set fileName properly +	QFile f(fileName); +	if (!f.open(IO_ReadOnly)) { +		//! @todo err msg +		return KexiBLOBBuffer::Handle(); +	} +	QString mimeType( KImageIO::mimeType( fileName ) ); + +	QByteArray data( f.readAll() ); +	if (f.status()!=IO_Ok) { +		//! @todo err msg +		return KexiBLOBBuffer::Handle(); +	} +	QFileInfo fi(url.fileName()); +	QString caption(fi.baseName().replace('_', " ").simplifyWhiteSpace()); + +	item = new Item(data, ++d->maxId, /*!stored*/false, url.fileName(), caption, mimeType); +	insertItem(item); + +	//cache +	item->prettyURL = url.prettyURL(); +	d->itemsByURL.replace(url.prettyURL(), item); +	return KexiBLOBBuffer::Handle(item); +} + +KexiBLOBBuffer::Handle KexiBLOBBuffer::insertObject(const QByteArray& data,  +	const QString& name, const QString& caption, const QString& mimeType, KexiBLOBBuffer::Id_t identifier) +{ +	KexiBLOBBuffer::Id_t newIdentifier; +	if (identifier>0) +		newIdentifier = identifier; +	else +		newIdentifier = ++d->maxId; + +	Item *item = new Item(data, newIdentifier, identifier>0, name, caption, mimeType); +	insertItem( item ); +	return KexiBLOBBuffer::Handle(item); +} + +KexiBLOBBuffer::Handle KexiBLOBBuffer::insertPixmap(const QPixmap& pixmap) +{ +	if (pixmap.isNull()) +		return KexiBLOBBuffer::Handle(); + +	Item * item = new Item( +		QByteArray(), //(pixmap will be converted to byte array on demand) +		++d->maxId,  +		false, //not stored +		QString::null,  +		QString::null,  +		"image/png", //!< @todo OK? What about jpegs? +		0, //folder id +		pixmap); + +	insertItem(item); +	return KexiBLOBBuffer::Handle(item); +} + +KexiBLOBBuffer::Handle KexiBLOBBuffer::objectForId(Id_t id, bool stored) +{ +	if (id<=0) +		return KexiBLOBBuffer::Handle(); +	if (stored) { +		Item *item = d->storedItems.find(id); +		if (item || !d->conn) +			return KexiBLOBBuffer::Handle(item); +		//retrieve stored BLOB: + +//#if 0 +		assert(d->conn); +		KexiDB::TableSchema *blobsTable = d->conn->tableSchema("kexi__blobs");  +		if (!blobsTable) { +		//! @todo err msg +			return KexiBLOBBuffer::Handle(); +		} +/*		QStringList where; +		where << "o_id"; +		KexiDB::PreparedStatement::Ptr st = d->conn->prepareStatement( +			KexiDB::PreparedStatement::SelectStatement, *blobsTable, where);*/ +//! @todo use PreparedStatement +		KexiDB::QuerySchema schema; +		schema.addField( blobsTable->field("o_data") ); +		schema.addField( blobsTable->field("o_name") ); +		schema.addField( blobsTable->field("o_caption") ); +		schema.addField( blobsTable->field("o_mime") ); +		schema.addField( blobsTable->field("o_folder_id") ); +		schema.addToWhereExpression(blobsTable->field("o_id"), QVariant((Q_LLONG)id)); + +		KexiDB::RowData rowData; +		tristate res = d->conn->querySingleRecord( +			schema, +//			QString::fromLatin1("SELECT o_data, o_name, o_caption, o_mime FROM kexi__blobs where o_id=") +//			+QString::number(id),  +			rowData);  +		if (res!=true || rowData.size()<4) { +		//! @todo err msg +			kdWarning() << "KexiBLOBBuffer::objectForId("<<id<<","<<stored +			<<"): res!=true || rowData.size()<4; res=="<<res.toString()<<" rowData.size()=="<<rowData.size()<< endl; +			return KexiBLOBBuffer::Handle(); +		} + +		item = new Item( +			rowData[0].toByteArray(), +			id,  +			true, //stored +			rowData[1].toString(), +			rowData[2].toString(), +			rowData[3].toString(), +			(Id_t)rowData[4].toInt() //!< @todo folder id: fix Id_t for Qt4 +		); + +		insertItem(item); +		return KexiBLOBBuffer::Handle(item); +//#endif +	} +	else +		return KexiBLOBBuffer::Handle(d->inMemoryItems.find(id)); +} + +KexiBLOBBuffer::Handle KexiBLOBBuffer::objectForId(Id_t id) +{ +	KexiBLOBBuffer::Handle h(objectForId(id, false/*!stored*/)); +	if (h) +		return h; +	return objectForId(id, true/*stored*/); +} + +void KexiBLOBBuffer::removeItem(Id_t id, bool stored) +{ +	Item *item; +	if (stored) +		item = d->storedItems.take(id); +	else +		item = d->inMemoryItems.take(id); + +	if (item && !item->prettyURL.isEmpty()) { +		d->itemsByURL.remove(item->prettyURL); +	} +	delete item; +} + +void KexiBLOBBuffer::takeItem(Item *item) +{ +	assert(item); +	if (item->stored) +		d->storedItems.take(item->id); +	else +		d->inMemoryItems.take(item->id); +} + +void KexiBLOBBuffer::insertItem(Item *item) +{ +	assert(item); +	if (item->stored) +		d->storedItems.insert(item->id, item); +	else +		d->inMemoryItems.insert(item->id, item); +} + +void KexiBLOBBuffer::setConnection(KexiDB::Connection *conn) +{ +	KexiBLOBBuffer::self()->d->conn = conn; +} + +KexiBLOBBuffer* KexiBLOBBuffer::self() +{ +	if(!m_buffer) { +		m_bufferDeleter.setObject( m_buffer, new KexiBLOBBuffer() ); +	} +	return m_buffer; +} + +#include "kexiblobbuffer.moc" | 
