|
|
|
/* 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.
|
|
|
|
*/
|
|
|
|
|
|
|
|
#ifndef KEXIBLOBBUFFER_H
|
|
|
|
#define KEXIBLOBBUFFER_H
|
|
|
|
|
|
|
|
#include <tqobject.h>
|
|
|
|
#include <tqintdict.h>
|
|
|
|
#include <tqdict.h>
|
|
|
|
#include <tqpixmap.h>
|
|
|
|
|
|
|
|
#include <kurl.h>
|
|
|
|
|
|
|
|
namespace KexiDB
|
|
|
|
{
|
|
|
|
class Connection;
|
|
|
|
}
|
|
|
|
|
|
|
|
//! Application-wide buffer for local BLOB data like pixmaps.
|
|
|
|
/*! For now only pixmaps are supported
|
|
|
|
@todo support any KPart-compatible objects and more...
|
|
|
|
|
|
|
|
Use this class by acessing to its singleton: KexiBLOBBuffer::self().
|
|
|
|
|
|
|
|
This class is used for buffering BLOB data,
|
|
|
|
to avoid duplicating object's data in memory and a need for loading (decoding)
|
|
|
|
the same object many times.
|
|
|
|
The data is always local, what means database storage is not employed here.
|
|
|
|
|
|
|
|
Each BLOB instance is identified by an unsigned integer number (Id_t type),
|
|
|
|
uniquely generated on BLOB loading. Each BLOB can have assigned source url
|
|
|
|
it has been loaded from (the url can be empty though, e.g. for data coming from clipboard).
|
|
|
|
|
|
|
|
References to KexiBLOBBuffer are counted, so when last reference is lost, data is freed
|
|
|
|
and the integer identifier is no longer pointing any valid data.
|
|
|
|
KexiBLOBBuffer::Handle is value-based class that describes handle based in an identifier.
|
|
|
|
Objects of this class are obtained e.g. from insertPixmap() method.
|
|
|
|
|
|
|
|
There are two kinds of identifiers:
|
|
|
|
- integers assigned for BLOBs already saved to a db backend,
|
|
|
|
when KexiBLOBBuffer::Handle::stored() is true
|
|
|
|
- temporary integers assigned for new BLOBs not yet saved to a db backend,
|
|
|
|
when KexiBLOBBuffer::Handle::stored() is false
|
|
|
|
KexiBLOBBuffer::Handle::setStoredWidthID() can be used to switch from unstored to stored state.
|
|
|
|
Among others, the state has effect on saving forms: only unstored BLOBs will be saved back
|
|
|
|
to the database; when a BLOB needs to be removed, only it will be physically removed only if it was stored.
|
|
|
|
|
|
|
|
KexiBLOBBuffer is also useful for two more reasons:
|
|
|
|
- Property editor's item for "image" property displays a preview of pixmap contents.
|
|
|
|
Without buffering, it would be needed to load pixmap data again: what if the file
|
|
|
|
it is loaded from is located remote and connection is slow? Memory would be also unnecessary doubled.
|
|
|
|
- Undo/Redo framework requires to store previous property values. Having a reference defined
|
|
|
|
by a single interger, memory can be handled more effectively.
|
|
|
|
|
|
|
|
Example use cases:
|
|
|
|
A large pixmap file "abc.jpg" is loaded as TQByteArray <b>once</b> and buffered:
|
|
|
|
integer identifier is returned.
|
|
|
|
Then, multiple image widgets are using "abc.jpg" for displaying.
|
|
|
|
Duplicating an image widget means only duplicating it's properties
|
|
|
|
like position and BLOB's id: BLOB itself (data of "abc.jpg") is not duplicated.
|
|
|
|
Creating a new image widget and assiging the same "abc.jpg" pixmap, means only
|
|
|
|
referencing KexiBLOBBuffer using the same identifier.
|
|
|
|
*/
|
|
|
|
class KEXICORE_EXPORT KexiBLOBBuffer : public TQObject
|
|
|
|
{
|
|
|
|
TQ_OBJECT
|
|
|
|
|
|
|
|
|
|
|
|
private:
|
|
|
|
class Item;
|
|
|
|
public:
|
|
|
|
//! long integer for unique identifying blobs
|
|
|
|
typedef long Id_t;
|
|
|
|
|
|
|
|
//! Access to KexiBLOBBuffer singleton
|
|
|
|
static KexiBLOBBuffer* self();
|
|
|
|
|
|
|
|
static void setConnection(KexiDB::Connection *conn);
|
|
|
|
|
|
|
|
//! Object handle used by KexiBLOBBuffer
|
|
|
|
class KEXICORE_EXPORT Handle {
|
|
|
|
public:
|
|
|
|
//! Constructs a null handle.
|
|
|
|
//! Null handles have empty pixap and data members, id == 0 and cast to boolean false.
|
|
|
|
Handle();
|
|
|
|
|
|
|
|
//! Constructs a copy of \a handle.
|
|
|
|
Handle(const Handle& handle);
|
|
|
|
|
|
|
|
~Handle();
|
|
|
|
|
|
|
|
Id_t id() const { return m_item ? m_item->id : 0; }
|
|
|
|
|
|
|
|
/*! \return true if this BLOB data pointed by this handle is stored at the db backend
|
|
|
|
or false if it is kept in memory. Null handles return false. */
|
|
|
|
bool stored() const { return m_item ? m_item->stored : false; }
|
|
|
|
|
|
|
|
//! \return true if this is null handle (i.e. one not pointing to any data)
|
|
|
|
operator bool() const { return m_item; }
|
|
|
|
|
|
|
|
Handle& operator=(const Handle& handle);
|
|
|
|
|
|
|
|
TQByteArray data() const { return m_item ? m_item->data() : TQByteArray(); }
|
|
|
|
|
|
|
|
TQPixmap pixmap() const { return m_item ? m_item->pixmap() : TQPixmap(); }
|
|
|
|
|
|
|
|
/*! Sets "stored" flag to true by setting non-temporary identifier.
|
|
|
|
Only call this method for unstored (in memory) BLOBs */
|
|
|
|
void setStoredWidthID(Id_t id);
|
|
|
|
|
|
|
|
TQString originalFileName() const { return m_item ? m_item->name: TQString(); }
|
|
|
|
|
|
|
|
TQString mimeType() const { return m_item ? m_item->mimeType : TQString(); }
|
|
|
|
|
|
|
|
Id_t folderId() const { return m_item ? m_item->folderId : 0; }
|
|
|
|
|
|
|
|
protected:
|
|
|
|
//! Constructs a handle based on \a item. Null handle is constructed for null \a item.
|
|
|
|
Handle(Item* item);
|
|
|
|
private:
|
|
|
|
Item* m_item;
|
|
|
|
friend class KexiBLOBBuffer;
|
|
|
|
};
|
|
|
|
|
|
|
|
//! @internal
|
|
|
|
KexiBLOBBuffer();
|
|
|
|
|
|
|
|
~KexiBLOBBuffer();
|
|
|
|
|
|
|
|
/*! Inserts a new pixmap loaded from a file at \a url.
|
|
|
|
If the same file has already been loaded before, it can be found in cache
|
|
|
|
and returned instantly. It is assumed that the BLOB is unstored, because it is loaded from
|
|
|
|
external source, so stored() will be equal to false for returned handle.
|
|
|
|
\return handle to the pixmap data or a null handle if such pixmap could not be loaded. */
|
|
|
|
Handle insertPixmap(const KURL& url);
|
|
|
|
|
|
|
|
/*! Inserts a new BLOB data.
|
|
|
|
@param data The data for BLOB object.
|
|
|
|
@param name The name for the object, usually a file name or empty
|
|
|
|
@param caption The more friendly than name, can be based on file name or empty or
|
|
|
|
defined by a user (this case is not yet used)
|
|
|
|
@param mimeType The mimeType for the object for easier and mor accurate decoding.
|
|
|
|
@param identifier Object's identifier. If positive, the "stored" flag for the data
|
|
|
|
will be set to true with \a identifer, otherwise (the default) the BLOB data will
|
|
|
|
have "stored" flag set to false, and a new temporary identifier will be assigned. */
|
|
|
|
Handle insertObject(const TQByteArray& data, const TQString& name,
|
|
|
|
const TQString& caption, const TQString& mimeType, Id_t identifier = 0);
|
|
|
|
|
|
|
|
/*! Inserts a new pixmap available in memory, e.g. coming from clipboard. */
|
|
|
|
Handle insertPixmap(const TQPixmap& pixmap);
|
|
|
|
|
|
|
|
/*! \return an object for a given \a id. If \a stored is true, stored BLOBs buffer
|
|
|
|
is browsed, otherwise unstored (in memory) BLOBs buffer is browsed.
|
|
|
|
If no object is cached for this id, null handle is returned. */
|
|
|
|
Handle objectForId(Id_t id, bool stored);
|
|
|
|
|
|
|
|
/*! \return an object for a given \a id. First, unstored object is checked, then unstored,
|
|
|
|
if stored was not found. */
|
|
|
|
Handle objectForId(Id_t id);
|
|
|
|
|
|
|
|
protected:
|
|
|
|
/*! Removes an object for a given \a id. If \a stored is true, stored BLOB is removed,
|
|
|
|
otherwise unstored (in memory) BLOB is removed. */
|
|
|
|
void removeItem(Id_t id, bool stored);
|
|
|
|
|
|
|
|
/*! Takes an object for a \a item out of the buffer. */
|
|
|
|
void takeItem(Item* item);
|
|
|
|
|
|
|
|
/*! Inserts an object for a given \a id into the buffer. */
|
|
|
|
void insertItem(Item* item);
|
|
|
|
|
|
|
|
private:
|
|
|
|
class KEXICORE_EXPORT Item {
|
|
|
|
public:
|
|
|
|
Item(const TQByteArray& data, Id_t ident,
|
|
|
|
bool stored,
|
|
|
|
const TQString& name = TQString(),
|
|
|
|
const TQString& caption = TQString(),
|
|
|
|
const TQString& mimeType = TQString(),
|
|
|
|
Id_t folderId = 0,
|
|
|
|
const TQPixmap& pixmap = TQPixmap());
|
|
|
|
~Item();
|
|
|
|
TQPixmap pixmap() const;
|
|
|
|
TQByteArray data() const;
|
|
|
|
// KexiBLOBBuffer* buf;
|
|
|
|
// KURL url;
|
|
|
|
TQString name;
|
|
|
|
TQString caption; //!< @todo for future use within image gallery
|
|
|
|
TQString mimeType;
|
|
|
|
uint refs;
|
|
|
|
Id_t id;
|
|
|
|
Id_t folderId;
|
|
|
|
bool stored : 1;
|
|
|
|
TQString prettyURL; //!< helper
|
|
|
|
private:
|
|
|
|
TQByteArray *m_data;
|
|
|
|
TQPixmap *m_pixmap;
|
|
|
|
bool *m_pixmapLoaded; //!< *m_pixmapLoaded will be set in Info::pixmap(),
|
|
|
|
//!< to avoid multiple pixmap decoding when it previously failed
|
|
|
|
friend class KexiBLOBBuffer;
|
|
|
|
};
|
|
|
|
class Private;
|
|
|
|
Private *d;
|
|
|
|
friend class Handle;
|
|
|
|
};
|
|
|
|
|
|
|
|
#endif
|