diff options
Diffstat (limited to 'tqtinterface/qt4/src/kernel/tqmime.cpp')
-rw-r--r-- | tqtinterface/qt4/src/kernel/tqmime.cpp | 1158 |
1 files changed, 1158 insertions, 0 deletions
diff --git a/tqtinterface/qt4/src/kernel/tqmime.cpp b/tqtinterface/qt4/src/kernel/tqmime.cpp new file mode 100644 index 0000000..46d07d3 --- /dev/null +++ b/tqtinterface/qt4/src/kernel/tqmime.cpp @@ -0,0 +1,1158 @@ +/**************************************************************************** +** +** Implementation of MIME support +** +** Copyright (C) 2010 Timothy Pearson and (C) 1992-2008 Trolltech ASA. +** +** This file is part of the kernel module of the TQt GUI Toolkit. +** +** This file may be used under the terms of the GNU General +** Public License versions 2.0 or 3.0 as published by the Free +** Software Foundation and appearing in the files LICENSE.GPL2 +** and LICENSE.GPL3 included in the packaging of this file. +** Alternatively you may (at your option) use any later version +** of the GNU General Public License if such license has been +** publicly approved by Trolltech ASA (or its successors, if any) +** and the KDE Free TQt Foundation. +** +** Please review the following information to ensure GNU General +** Public Licensing requirements will be met: +** http://trolltech.com/products/qt/licenses/licensing/opensource/. +** If you are unsure which license is appropriate for your use, please +** review the following information: +** http://trolltech.com/products/qt/licenses/licensing/licensingoverview +** or contact the sales department at sales@trolltech.com. +** +** This file may be used under the terms of the Q Public License as +** defined by Trolltech ASA and appearing in the file LICENSE.TQPL +** included in the packaging of this file. Licensees holding valid TQt +** Commercial licenses may use this file in accordance with the TQt +** Commercial License Agreement provided with the Software. +** +** This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted +** herein. +** +**********************************************************************/ + +#include "tqmime.h" + +#ifndef TQT_NO_MIME + +#include "tqmap.h" +#include "tqstringlist.h" +#include "tqfileinfo.h" +#include "tqdir.h" +#include "tqdragobject.h" +#include "tqcleanuphandler.h" +#include "tqapplication.h" // ### for now +#include "tqclipboard.h" // ### for now + +#ifdef USE_QT4 + +#include "Qt/qmap.h" +#include "Qt/qstringlist.h" +#include "Qt/qfileinfo.h" +#include "Qt/qdir.h" +#include "tqdragobject.h" +#include "Qt/qpixmap.h" +#include "Qt/qimagereader.h" +#include "tqcleanuphandler.h" +#include "private/qt4_qtextimagehandler_p.h" + +#endif // USE_QT4 + +static int qt_mime_serial_number = 0; +static TQMimeSourceFactory* defaultfactory = 0; +static TQSingleCleanupHandler<TQMimeSourceFactory> qmime_cleanup_factory; + +#ifdef USE_QT4 +// #if 0 + +TQMimeSource::TQMimeSource() : QMimeSource() { + cacheType = NoCache; + ser_no = qt_mime_serial_number++; +} + +/*! + \fn int TQMimeSource::serialNumber() const + + Returns the mime source's globally unique serial number. +*/ + + +void TQMimeSource::clearCache() +{ + if ( cacheType == Text ) { + delete cache.txt.str; + delete cache.txt.subtype; + cache.txt.str = 0; + cache.txt.subtype = 0; + } else if ( cacheType == Graphics ) { + delete cache.gfx.img; + delete cache.gfx.pix; + cache.gfx.img = 0; + cache.gfx.pix = 0; + } + cacheType = NoCache; +} + +#else // USE_QT4 + +/*! + \class TQMimeSource tqmime.h + \brief The TQMimeSource class is an abstraction of objects which provide formatted data of a certain MIME type. + + \ingroup io + \ingroup draganddrop + \ingroup misc + + \link dnd.html Drag-and-drop\endlink and + \link TQClipboard clipboard\endlink use this abstraction. + + \sa \link http://www.isi.edu/in-notes/iana/assignments/media-types/ + IANA list of MIME media types\endlink +*/ + +/*! + Constructs a mime source and assigns a globally unique serial + number to it. + + \sa serialNumber() +*/ + +TQMimeSource::TQMimeSource() +{ + ser_no = qt_mime_serial_number++; + cacheType = NoCache; +} + +/*! + \fn int TQMimeSource::serialNumber() const + + Returns the mime source's globally unique serial number. +*/ + + +void TQMimeSource::clearCache() +{ + if ( cacheType == Text ) { + delete cache.txt.str; + delete cache.txt.subtype; + cache.txt.str = 0; + cache.txt.subtype = 0; + } else if ( cacheType == Graphics ) { + delete cache.gfx.img; + delete cache.gfx.pix; + cache.gfx.img = 0; + cache.gfx.pix = 0; + } + cacheType = NoCache; +} + +/*! + Provided to ensure that subclasses destroy themselves correctly. +*/ +TQMimeSource::~TQMimeSource() +{ +#ifndef TQT_NO_CLIPBOARD + extern void qt_clipboard_cleanup_mime_source(TQMimeSource *); + qt_clipboard_cleanup_mime_source(this); +#endif + clearCache(); +} + +/*! + \fn TQByteArray TQMimeSource::tqencodedData(const char*) const + + Returns the encoded data of this object in the specified MIME + format. + + Subclasses must reimplement this function. +*/ + + + +/*! + Returns TRUE if the object can provide the data in format \a + mimeType; otherwise returns FALSE. + + If you inherit from TQMimeSource, for consistency reasons it is + better to implement the more abstract canDecode() functions such + as TQTextDrag::canDecode() and TQImageDrag::canDecode(). +*/ +bool TQMimeSource::provides(const char* mimeType) const +{ + const char* fmt; + for (int i=0; (fmt = format(i)); i++) { + if ( !qstricmp(mimeType,fmt) ) + return TRUE; + } + return FALSE; +} + +#endif // USE_QT4 + +// #ifdef USE_QT4 +#if 0 + +QT_BEGIN_NAMESPACE + +class TQMimeSourceFactoryData { +public: + TQMimeSourceFactoryData() : + last(0) + { + } + + ~TQMimeSourceFactoryData() + { + QMap<QString, QMimeSource*>::Iterator it = stored.begin(); + while (it != stored.end()) { + delete *it; + ++it; + } + delete last; + } + + QMap<QString, QMimeSource*> stored; + QMap<QString, QString> extensions; + QStringList path; + QMimeSource* last; + QList<TQMimeSourceFactory*> factories; +}; + +static QImage richTextImageLoader(const QString &name, const QString &context) +{ + QImage img; + + const TQMimeSource *src = static_cast<const TQMimeSource*>(TQMimeSourceFactory::defaultFactory()->data(name, context)); + if (src && TQImageDrag::decode(src, img)) + return img; + + return QImage(); +} + +/*! + \class TQMimeSourceFactory + \brief The TQMimeSourceFactory class is an extensible provider of mime-typed data. + + \compat + + A TQMimeSourceFactory provides an abstract interface to a + collection of information. Each piece of information is + represented by a QMimeSource object which can be examined and + converted to concrete data types by functions such as + TQImageDrag::canDecode() and TQImageDrag::decode(). + + The base TQMimeSourceFactory can be used in two ways: as an + abstraction of a collection of files or as specifically stored + data. For it to access files, call setFilePath() before accessing + data. For stored data, call setData() for each item (there are + also convenience functions, e.g. setText(), setImage() and + setPixmap(), that simply call setData() with appropriate + parameters). + + The rich text widgets, QTextEdit and QTextBrowser, use + TQMimeSourceFactory to resolve references such as images or links + within rich text documents. They either access the default factory + (see \l{defaultFactory()}) or their own. Other classes that are + capable of displaying rich text (such as QLabel, QWhatsThis or + QMessageBox) always use the default factory. + + A factory can also be used as a container to store data associated + with a name. This technique is useful whenever rich text contains + images that are stored in the program itself, not loaded from the + hard disk. Your program may, for example, define some image data + as: + \snippet doc/src/snippets/code/src_qt3support_other_q3mimefactory.cpp 0 + + To be able to use this image within some rich text, for example + inside a QLabel, you must create a QImage from the raw data and + insert it into the factory with a unique name: + \snippet doc/src/snippets/code/src_qt3support_other_q3mimefactory.cpp 1 + + Now you can create a rich text QLabel with + + \snippet doc/src/snippets/code/src_qt3support_other_q3mimefactory.cpp 2 + + When no longer needed, you can clear the data from the factory: + + \snippet doc/src/snippets/code/src_qt3support_other_q3mimefactory.cpp 3 +*/ + + +/*! + Constructs a TQMimeSourceFactory that has no file path and no + stored content. +*/ +TQMimeSourceFactory::TQMimeSourceFactory() : + d(new TQMimeSourceFactoryData) +{ +// addFilePath(QLatin1String(":/qt/q3mimesourcefactory/")); //to get from the resources // Where did this come from??!?!?!? + // add some reasonable defaults + setExtensionType(QLatin1String("htm"), "text/html;charset=iso8859-1"); + setExtensionType(QLatin1String("html"), "text/html;charset=iso8859-1"); + setExtensionType(QLatin1String("txt"), "text/plain"); + setExtensionType(QLatin1String("xml"), "text/xml;charset=UTF-8"); + setExtensionType(QLatin1String("jpg"), "image/jpeg"); // support misspelled jpeg files +} + +/*! + Destroys the TQMimeSourceFactory, deleting all stored content. +*/ +TQMimeSourceFactory::~TQMimeSourceFactory() +{ + if (defaultFactory() == this) + defaultfactory = 0; + delete d; +} + +QMimeSource* TQMimeSourceFactory::dataInternal(const QString& abs_name, const QMap<QString, QString> &extensions) const +{ + QMimeSource* r = 0; + QStringList attempted_names(abs_name); + TQFileInfo fi(abs_name); + if (fi.isReadable()) { + // get the right mimetype + QString e = fi.extension(false); + QByteArray mimetype("application/octet-stream"); + if (extensions.contains(e)) + mimetype = TQT_TQSTRING(extensions[e]).latin1(); + if (!QImageReader::imageFormat(abs_name).isEmpty()) + mimetype = "application/x-qt-image"; + + TQFile f(abs_name); + if (f.open(QIODevice::ReadOnly) && f.size()) { + QByteArray ba; + ba.resize(f.size()); + f.readBlock(ba.data(), ba.size()); + TQStoredDrag* sr = new TQStoredDrag(mimetype); + sr->setEncodedData(TQT_TQBYTEARRAY_OBJECT(ba)); + delete d->last; + d->last = r = sr; + } + } + + // we didn't find the mime-source, so ask the default factory for + // the mime-source (this one will iterate over all installed ones) + // + // this looks dangerous, as this dataInternal() function will be + // called again when the default factory loops over all installed + // factories (including this), but the static bool looping in + // data() avoids endless recursions + if (!r && this != defaultFactory()) + r = (QMimeSource*)defaultFactory()->data(abs_name); + + return r; +} + + +/*! + Returns a reference to the data associated with \a abs_name. The + return value remains valid only until the next data() or setData() + call, so you should immediately decode the result. + + If there is no data associated with \a abs_name in the factory's + store, the factory tries to access the local filesystem. If \a + abs_name isn't an absolute file name, the factory will search for + it in all defined paths (see \l{setFilePath()}). + + The factory understands all the image formats supported by + QImageReader. Any other mime types are determined by the file name + extension. The default settings are + \snippet doc/src/snippets/code/src_qt3support_other_q3mimefactory.cpp 4 + The effect of these is that file names ending in "txt" will be + treated as text encoded in the local encoding; those ending in + "xml" will be treated as text encoded in Unicode UTF-8 encoding. + The text/html type is treated specially, since the encoding can be + specified in the html file itself. "html" or "htm" will be treated + as text encoded in the encoding specified by the html meta tag, if + none could be found, the charset of the mime type will be used. + The text subtype ("html", "plain", or "xml") does not affect the + factory, but users of the factory may behave differently. We + recommend creating "xml" files where practical. These files can be + viewed regardless of the runtime encoding and can encode any + Unicode characters without resorting to encoding definitions + inside the file. + + Any file data that is not recognized will be retrieved as a + QMimeSource providing the "application/octet-stream" mime type, + meaning uninterpreted binary data. + + You can add further extensions or change existing ones with + subsequent calls to setExtensionType(). If the extension mechanism + is not sufficient for your problem domain, you can inherit + TQMimeSourceFactory and reimplement this function to perform some + more specialized mime-type detection. The same applies if you want + to use the mime source factory to access URL referenced data over + a network. +*/ +const TQMimeSource *TQMimeSourceFactory::data(const QString& abs_name) const +{ + if (d->stored.contains(abs_name)) + return static_cast<TQMimeSource*>(d->stored[abs_name]); + + const QMimeSource *r = 0; + if (abs_name.isEmpty()) + return static_cast<const TQMimeSource*>(r); + QStringList::Iterator it; + if (abs_name[0] == QLatin1Char('/') +#ifdef Q_WS_WIN + || (abs_name[0].isLetter() && abs_name[1] == QLatin1Char(':')) || abs_name.startsWith(QLatin1String("\\\\")) +#endif + ) + { + // handle absolute file names directly + r = dataInternal(abs_name, d->extensions); + } + else { // check list of paths + for (it = d->path.begin(); !r && it != d->path.end(); ++it) { + QString filename = *it; + if (filename[(int)filename.length()-1] != QLatin1Char('/')) + filename += QLatin1Char('/'); + filename += abs_name; + r = dataInternal(filename, d->extensions); + } + } + + static bool looping = false; + if (!r && this == defaultFactory()) { + // we found no mime-source and we are the default factory, so + // we know all the other installed mime-source factories, so + // ask them + if (!looping) { + // to avoid endless recustions, don't enter the loop below + // if data() got called from within the loop below + looping = true; + for (int i = 0; i < d->factories.size(); ++i) { + const TQMimeSourceFactory *f = d->factories.at(i); + if (f == this) + continue; + r = static_cast<const QMimeSource *>(f->data(abs_name)); + if (r) { + looping = false; + return static_cast<const TQMimeSource*>(r); + } + } + looping = false; + } + } else if (!r) { + // we are not the default mime-source factory, so ask the + // default one for the mime-source, as this one will loop over + // all installed mime-source factories and ask these + r = static_cast<const QMimeSource *>(defaultFactory()->data(abs_name)); + } + return static_cast<const TQMimeSource*>(r); +} + +/*! + \fn void TQMimeSourceFactory::setFilePath(const QStringList &path) + \fn void TQMimeSourceFactory::setFilePath(const QString &path) + + Sets the list of directories that will be searched when named data + is requested to those given in the string list \a path. + + \sa filePath() +*/ +void TQMimeSourceFactory::setFilePath(const QStringList& path) +{ + d->path = path; +} + +/*! + Returns the currently set search paths. +*/ +TQStringList TQMimeSourceFactory::filePath() const +{ + return TQT_TQSTRINGLIST_OBJECT(d->path); +} + +/*! + Adds another search path, \a p to the existing search paths. + + \sa setFilePath() +*/ +void TQMimeSourceFactory::addFilePath(const QString& p) +{ + d->path += p; +} + +/*! + Sets the mime-type to be associated with the file name extension, + \a ext to \a mimetype. This determines the mime-type for files + found via the paths set by setFilePath(). +*/ +void TQMimeSourceFactory::setExtensionType(const QString& ext, const char* mimetype) +{ + d->extensions.insert(ext, QLatin1String(mimetype)); +} + +/*! + Converts the absolute or relative data item name \a + abs_or_rel_name to an absolute name, interpreted within the + context (path) of the data item named \a context (this must be an + absolute name). +*/ +TQString TQMimeSourceFactory::makeAbsolute(const QString& abs_or_rel_name, const QString& context) const +{ + if (context.isNull() || + !(context[0] == QLatin1Char('/') +#ifdef Q_WS_WIN + || (context[0].isLetter() && context[1] == QLatin1Char(':')) +#endif + )) + return abs_or_rel_name; + if (abs_or_rel_name.isEmpty()) + return context; + TQFileInfo c(context); + if (!c.isDir()) { + TQFileInfo r(c.dir(true), abs_or_rel_name); + return r.absFilePath(); + } else { + TQDir d(context); + TQFileInfo r(d, abs_or_rel_name); + return r.absFilePath(); + } +} + +/*! + \overload + A convenience function. See data(const QString& abs_name). The + file name is given in \a abs_or_rel_name and the path is in \a + context. +*/ +const TQMimeSource* TQMimeSourceFactory::data(const QString& abs_or_rel_name, const QString& context) const +{ + const QMimeSource* r = data(makeAbsolute(abs_or_rel_name,context)); + if (!r && !d->path.isEmpty()) + r = data(abs_or_rel_name); + return static_cast<const TQMimeSource*>(r); +} + + +/*! + Sets \a text to be the data item associated with the absolute name + \a abs_name. + + Equivalent to setData(abs_name, new TQTextDrag(text)). +*/ +void TQMimeSourceFactory::setText(const QString& abs_name, const QString& text) +{ + setData(abs_name, new TQTextDrag(text)); +} + +/*! + Sets \a image to be the data item associated with the absolute + name \a abs_name. + + Equivalent to setData(abs_name, new TQImageDrag(image)). +*/ +void TQMimeSourceFactory::setImage(const QString& abs_name, const QImage& image) +{ + setData(abs_name, new TQImageDrag(image)); +} + +/*! + Sets \a pixmap to be the data item associated with the absolute + name \a abs_name. +*/ +void TQMimeSourceFactory::setPixmap(const QString& abs_name, const QPixmap& pixmap) +{ + setData(abs_name, new TQImageDrag(TQT_TQPIXMAP_OBJECT(pixmap).convertToImage())); +} + +/*! + Sets \a data to be the data item associated with + the absolute name \a abs_name. Note that the ownership of \a data is + transferred to the factory: do not delete or access the pointer after + passing it to this function. + + Passing 0 for data removes previously stored data. +*/ +void TQMimeSourceFactory::setData(const QString& abs_name, QMimeSource* data) +{ + if (d->stored.contains(abs_name)) + delete d->stored[abs_name]; + d->stored.insert(abs_name,data); +} + + +/*! + Returns the application-wide default mime source factory. This + factory is used by rich text rendering classes such as + QSimpleRichText, QWhatsThis and QMessageBox to resolve named + references within rich text documents. It serves also as the + initial factory for the more complex render widgets, QTextEdit and + QTextBrowser. + + \sa setDefaultFactory() +*/ +TQMimeSourceFactory* TQMimeSourceFactory::defaultFactory() +{ + if (!defaultfactory) + { + defaultfactory = new TQMimeSourceFactory(); + qmime_cleanup_factory.set(&defaultfactory); + QTextImageHandler::externalLoader = richTextImageLoader; + } + return defaultfactory; +} + +/*! + Sets the default \a factory, destroying any previously set mime + source provider. The ownership of the factory is transferred to + Qt. + + \sa defaultFactory() +*/ +void TQMimeSourceFactory::setDefaultFactory(TQMimeSourceFactory* factory) +{ + if (!defaultfactory) + qmime_cleanup_factory.set(&defaultfactory); + else if (defaultfactory != factory) + delete defaultfactory; + defaultfactory = factory; +} + +/*! + Sets the defaultFactory() to 0 and returns the previous one. +*/ + +TQMimeSourceFactory* TQMimeSourceFactory::takeDefaultFactory() +{ + TQMimeSourceFactory *f = defaultfactory; + defaultfactory = 0; + return f; +} + +/*! + Adds the TQMimeSourceFactory \a f to the list of available + mimesource factories. If the defaultFactory() can't resolve a + data() it iterates over the list of installed mimesource factories + until the data can be resolved. + + \sa removeFactory() +*/ + +void TQMimeSourceFactory::addFactory(TQMimeSourceFactory *f) +{ + TQMimeSourceFactory::defaultFactory()->d->factories.append(f); +} + +/*! + Removes the mimesource factory \a f from the list of available + mimesource factories. + + \sa addFactory() +*/ + +void TQMimeSourceFactory::removeFactory(TQMimeSourceFactory *f) +{ + TQMimeSourceFactory::defaultFactory()->d->factories.removeAll(f); +} + +QPixmap qPixmapFromMimeSource(const QString &abs_name) +{ + const TQMimeSource *m = TQT_TQMIMESOURCE_CONST(TQMimeSourceFactory::defaultFactory()->data(abs_name)); + if (!m) { + if (QFile::exists(abs_name)) + return QPixmap(abs_name); + if (!abs_name.isEmpty()) + qWarning("QPixmap::fromMimeSource: Cannot find pixmap \"%s\" in the mime source factory", + TQT_TQSTRING(abs_name).latin1()); + return QPixmap(); + } + QPixmap pix; + TQImageDrag::decode(m, pix); + return pix; +} + +QImage qImageFromMimeSource(const QString &abs_name) +{ + const TQMimeSource *m = TQT_TQMIMESOURCE_CONST(TQMimeSourceFactory::defaultFactory()->data(abs_name)); + if (!m) { + qWarning("QImage::fromMimeSource: Cannot find image \"%s\" in the mime source factory", TQT_TQSTRING(abs_name).latin1()); + return QImage(); + } + QImage img; + TQImageDrag::decode(m, img); + return img; +} + +QT_END_NAMESPACE + +#else // USE_QT4 + +/*! + \fn const char * TQMimeSource::format(int i) const + + Returns the \a{i}-th supported MIME format, or 0. +*/ + + + +class TQMimeSourceFactoryData { +public: + TQMimeSourceFactoryData() : + last(0) + { + } + + ~TQMimeSourceFactoryData() + { + TQMap<TQString, TQMimeSource*>::Iterator it = stored.begin(); + while ( it != stored.end() ) { + delete *it; + ++it; + } + delete last; + } + + TQMap<TQString, TQMimeSource*> stored; + TQMap<TQString, TQString> extensions; + TQStringList path; + TQMimeSource* last; + TQPtrList<TQMimeSourceFactory> factories; +}; + +/*! + \class TQMimeSourceFactory tqmime.h + \brief The TQMimeSourceFactory class is an extensible provider of mime-typed data. + + \ingroup io + \ingroup environment + + A TQMimeSourceFactory provides an abstract interface to a + collection of information. Each piece of information is + represented by a TQMimeSource object which can be examined and + converted to concrete data types by functions such as + TQImageDrag::canDecode() and TQImageDrag::decode(). + + The base TQMimeSourceFactory can be used in two ways: as an + abstraction of a collection of files or as specifically stored + data. For it to access files, call setFilePath() before accessing + data. For stored data, call setData() for each item (there are + also convenience functions, e.g. setText(), setImage() and + setPixmap(), that simply call setData() with appropriate + parameters). + + The rich text widgets, TQTextEdit and TQTextBrowser, use + TQMimeSourceFactory to resolve references such as images or links + within rich text documents. They either access the default factory + (see \l{defaultFactory()}) or their own (see + \l{TQTextEdit::setMimeSourceFactory()}). Other classes that are + capable of displaying rich text (such as TQLabel, TQWhatsThis or + TQMessageBox) always use the default factory. + + A factory can also be used as a container to store data associated + with a name. This technique is useful whenever rich text tqcontains + images that are stored in the program itself, not loaded from the + hard disk. Your program may, for example, define some image data + as: + \code + static const char* myimage_data[]={ + "...", + ... + "..."}; + \endcode + + To be able to use this image within some rich text, for example + inside a TQLabel, you must create a TQImage from the raw data and + insert it into the factory with a unique name: + \code + TQMimeSourceFactory::defaultFactory()->setImage( "myimage", TQImage(myimage_data) ); + \endcode + + Now you can create a rich text TQLabel with + + \code + TQLabel* label = new TQLabel( + "Rich text with embedded image:<img source=\"myimage\">" + "Isn't that <em>cute</em>?" ); + \endcode + + When no longer needed, you can clear the data from the factory: + + \code + delete label; + TQMimeSourceFactory::defaultFactory()->setData( "myimage", 0 ); + \endcode +*/ + + +/*! + Constructs a TQMimeSourceFactory that has no file path and no + stored content. +*/ +TQMimeSourceFactory::TQMimeSourceFactory() : + d(new TQMimeSourceFactoryData) +{ + // add some reasonable defaults + setExtensionType("htm", "text/html;charset=iso8859-1"); + setExtensionType("html", "text/html;charset=iso8859-1"); + setExtensionType("txt", "text/plain"); + setExtensionType("xml", "text/xml;charset=UTF-8"); + setExtensionType("jpg", "image/jpeg"); // support misspelled jpeg files +} + +/*! + Destroys the TQMimeSourceFactory, deleting all stored content. +*/ +TQMimeSourceFactory::~TQMimeSourceFactory() +{ + if ( defaultFactory() == this ) + defaultfactory = 0; + delete d; +} + +TQMimeSource* TQMimeSourceFactory::dataInternal(const TQString& abs_name, const TQMap<TQString, TQString> &extensions ) const +{ + TQMimeSource* r = 0; + TQFileInfo fi(abs_name); + if ( fi.isReadable() ) { + + // get the right mimetype + TQString e = fi.extension(FALSE); + TQCString mimetype = "application/octet-stream"; + const char* imgfmt; + if ( extensions.tqcontains(e) ) + mimetype = extensions[e].latin1(); + else if ( ( imgfmt = TQImage::imageFormat( abs_name ) ) ) + mimetype = TQCString("image/")+TQCString(imgfmt).lower(); + + TQFile f(abs_name); + if ( f.open(IO_ReadOnly) && f.size() ) { + TQByteArray ba(f.size()); + f.readBlock(ba.data(), ba.size()); + TQStoredDrag* sr = new TQStoredDrag( mimetype ); + sr->setEncodedData( ba ); + delete d->last; + d->last = r = sr; + } + } + + // we didn't tqfind the mime-source, so ask the default factory for + // the mime-source (this one will iterate over all installed ones) + // + // this looks dangerous, as this dataInternal() function will be + // called again when the default factory loops over all installed + // factories (including this), but the static bool looping in + // data() avoids endless recursions + if ( !r && this != defaultFactory() ) + r = (TQMimeSource*)defaultFactory()->data( abs_name ); + + return r; +} + + +/*! + Returns a reference to the data associated with \a abs_name. The + return value remains valid only until the next data() or setData() + call, so you should immediately decode the result. + + If there is no data associated with \a abs_name in the factory's + store, the factory tries to access the local filesystem. If \a + abs_name isn't an absolute file name, the factory will search for + it in all defined paths (see \l{setFilePath()}). + + The factory understands all the image formats supported by + TQImageIO. Any other mime types are determined by the file name + extension. The default settings are + \code + setExtensionType("html", "text/html;charset=iso8859-1"); + setExtensionType("htm", "text/html;charset=iso8859-1"); + setExtensionType("txt", "text/plain"); + setExtensionType("xml", "text/xml;charset=UTF-8"); + \endcode + The effect of these is that file names ending in "txt" will be + treated as text encoded in the local encoding; those ending in + "xml" will be treated as text encoded in Unicode UTF-8 encoding. + The text/html type is treated specially, since the encoding can be + specified in the html file itself. "html" or "htm" will be treated + as text encoded in the encoding specified by the html meta tag, if + none could be found, the charset of the mime type will be used. + The text subtype ("html", "plain", or "xml") does not affect the + factory, but users of the factory may behave differently. We + recommend creating "xml" files where practical. These files can be + viewed regardless of the runtime encoding and can encode any + Unicode characters without resorting to encoding definitions + inside the file. + + Any file data that is not recognized will be retrieved as a + TQMimeSource providing the "application/octet-stream" mime type, + meaning uninterpreted binary data. + + You can add further extensions or change existing ones with + subsequent calls to setExtensionType(). If the extension mechanism + is not sufficient for your problem domain, you can inherit + TQMimeSourceFactory and reimplement this function to perform some + more specialized mime-type detection. The same applies if you want + to use the mime source factory to access URL referenced data over + a network. +*/ +const TQMimeSource* TQMimeSourceFactory::data(const TQString& abs_name) const +{ + if ( d->stored.tqcontains(abs_name) ) + return d->stored[abs_name]; + + TQMimeSource* r = 0; + TQStringList::Iterator it; + if ( abs_name[0] == '/' +#ifdef TQ_WS_WIN + || ( abs_name[0] && abs_name[1] == ':' ) || abs_name.startsWith("\\\\") +#endif + ) + { + // handle absolute file names directly + r = dataInternal( abs_name, d->extensions); + } + else { // check list of paths + for ( it = d->path.begin(); !r && it != d->path.end(); ++it ) { + TQString filename = *it; + if ( filename[(int)filename.length()-1] != '/' ) + filename += '/'; + filename += abs_name; + r = dataInternal( filename, d->extensions ); + } + } + + static bool looping = FALSE; + if ( !r && this == defaultFactory() ) { + // we found no mime-source and we are the default factory, so + // we know all the other installed mime-source factories, so + // ask them + if ( !looping ) { + // to avoid endless recursions, don't enter the loop below + // if data() got called from within the loop below + looping = TRUE; + TQPtrListIterator<TQMimeSourceFactory> it( d->factories ); + TQMimeSourceFactory *f; + while ( ( f = it.current() ) ) { + ++it; + if ( f == this ) + continue; + r = (TQMimeSource*)f->data( abs_name ); + if ( r ) { + looping = FALSE; + return r; + } + } + looping = FALSE; + } + } else if ( !r ) { + // we are not the default mime-source factory, so ask the + // default one for the mime-source, as this one will loop over + // all installed mime-source factories and ask these + r = (TQMimeSource*)defaultFactory()->data( abs_name ); + } + + return r; +} + +/*! + Sets the list of directories that will be searched when named data + is requested to the those given in the string list \a path. + + \sa filePath() +*/ +void TQMimeSourceFactory::setFilePath( const TQStringList& path ) +{ + d->path = path; +} + +/*! + Returns the currently set search paths. +*/ +TQStringList TQMimeSourceFactory::filePath() const +{ + return d->path; +} + +/*! + Adds another search path, \a p to the existing search paths. + + \sa setFilePath() +*/ +void TQMimeSourceFactory::addFilePath( const TQString& p ) +{ + d->path += p; +} + +/*! + Sets the mime-type to be associated with the file name extension, + \a ext to \a mimetype. This determines the mime-type for files + found via the paths set by setFilePath(). +*/ +void TQMimeSourceFactory::setExtensionType( const TQString& ext, const char* mimetype ) +{ + d->extensions.tqreplace(ext, mimetype); +} + +/*! + Converts the absolute or relative data item name \a + abs_or_rel_name to an absolute name, interpreted within the + context (path) of the data item named \a context (this must be an + absolute name). +*/ +TQString TQMimeSourceFactory::makeAbsolute(const TQString& abs_or_rel_name, const TQString& context) const +{ + if ( context.isNull() || + !(context[0] == '/' +#ifdef TQ_WS_WIN + || ( context[0] && context[1] == ':') +#endif + )) + return abs_or_rel_name; + if ( abs_or_rel_name.isEmpty() ) + return context; + TQFileInfo c( context ); + if (!c.isDir()) { + TQFileInfo r( c.dir(TRUE), abs_or_rel_name ); + return r.absFilePath(); + } else { + TQDir d(context); + TQFileInfo r(d, abs_or_rel_name); + return r.absFilePath(); + } +} + +/*! + \overload + A convenience function. See data(const TQString& abs_name). The + file name is given in \a abs_or_rel_name and the path is in \a + context. +*/ +const TQMimeSource* TQMimeSourceFactory::data(const TQString& abs_or_rel_name, const TQString& context) const +{ + const TQMimeSource* r = data(makeAbsolute(abs_or_rel_name,context)); + if ( !r && !d->path.isEmpty() ) + r = data(abs_or_rel_name); + return r; +} + + +/*! + Sets \a text to be the data item associated with the absolute name + \a abs_name. + + Equivalent to setData(abs_name, new TQTextDrag(text)). +*/ +void TQMimeSourceFactory::setText( const TQString& abs_name, const TQString& text ) +{ + setData(abs_name, new TQTextDrag(text)); +} + +/*! + Sets \a image to be the data item associated with the absolute + name \a abs_name. + + Equivalent to setData(abs_name, new TQImageDrag(image)). +*/ +void TQMimeSourceFactory::setImage( const TQString& abs_name, const TQImage& image ) +{ + setData(abs_name, new TQImageDrag(image)); +} + +/*! + Sets \a pixmap to be the data item associated with the absolute + name \a abs_name. +*/ +void TQMimeSourceFactory::setPixmap( const TQString& abs_name, const TQPixmap& pixmap ) +{ + setData(abs_name, new TQImageDrag(pixmap.convertToImage())); +} + +/*! + Sets \a data to be the data item associated with + the absolute name \a abs_name. Note that the ownership of \a data is + transferred to the factory: do not delete or access the pointer after + passing it to this function. + + Passing 0 for data removes previously stored data. +*/ +void TQMimeSourceFactory::setData( const TQString& abs_name, TQMimeSource* data ) +{ + if ( d->stored.tqcontains(abs_name) ) + delete d->stored[abs_name]; + d->stored.tqreplace(abs_name,data); +} + + +/*! + Returns the application-wide default mime source factory. This + factory is used by rich text rendering classes such as + TQSimpleRichText, TQWhatsThis and TQMessageBox to resolve named + references within rich text documents. It serves also as the + initial factory for the more complex render widgets, TQTextEdit and + TQTextBrowser. + + \sa setDefaultFactory() +*/ +TQMimeSourceFactory* TQMimeSourceFactory::defaultFactory() +{ + if (!defaultfactory) + { + defaultfactory = new TQMimeSourceFactory(); + qmime_cleanup_factory.set( &defaultfactory ); + } + return defaultfactory; +} + +/*! + Sets the default \a factory, destroying any previously set mime + source provider. The ownership of the factory is transferred to + TQt. + + \sa defaultFactory() +*/ +void TQMimeSourceFactory::setDefaultFactory( TQMimeSourceFactory* factory) +{ + if ( !defaultfactory ) + qmime_cleanup_factory.set( &defaultfactory ); + else if ( defaultfactory != factory ) + delete defaultfactory; + defaultfactory = factory; +} + +/*! + Sets the defaultFactory() to 0 and returns the previous one. +*/ + +TQMimeSourceFactory* TQMimeSourceFactory::takeDefaultFactory() +{ + TQMimeSourceFactory *f = defaultfactory; + defaultfactory = 0; + return f; +} + +/*! + Adds the TQMimeSourceFactory \a f to the list of available + mimesource factories. If the defaultFactory() can't resolve a + data() it iterates over the list of installed mimesource factories + until the data can be resolved. + + \sa removeFactory(); +*/ + +void TQMimeSourceFactory::addFactory( TQMimeSourceFactory *f ) +{ + TQMimeSourceFactory::defaultFactory()->d->factories.append( f ); +} + +/*! + Removes the mimesource factory \a f from the list of available + mimesource factories. + + \sa addFactory(); +*/ + +void TQMimeSourceFactory::removeFactory( TQMimeSourceFactory *f ) +{ + TQMimeSourceFactory::defaultFactory()->d->factories.removeRef( f ); +} + +#endif // USE_QT4 + +#endif // TQT_NO_MIME |