Q3MimeSourceFactory Class Reference

#include <q3mimefactory.h>

Collaboration diagram for Q3MimeSourceFactory:

Collaboration graph
[legend]
List of all members.

Detailed Description

The Q3MimeSourceFactory class is an extensible provider of mime-typed data.

A Q3MimeSourceFactory 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 Q3ImageDrag::canDecode() and Q3ImageDrag::decode().

The base Q3MimeSourceFactory 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 Q3MimeSourceFactory to resolve references such as images or links within rich text documents. They either access the default factory (see {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:

    static const char* myimage_data[]={
    "...",
    ...
    "..."};

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:

    Q3MimeSourceFactory::defaultFactory()->setImage("myimage", QImage(myimage_data));

Now you can create a rich text QLabel with

    QLabel* label = new QLabel(
        "Rich text with embedded image:<img source=\"myimage\">"
        "Isn't that <em>cute</em>?");

When no longer needed, you can clear the data from the factory:

    delete label;
    Q3MimeSourceFactory::defaultFactory()->setData("myimage", 0);

Definition at line 42 of file q3mimefactory.h.

Public Member Functions

 Q3MimeSourceFactory ()
virtual ~Q3MimeSourceFactory ()
virtual const QMimeSourcedata (const QString &abs_name) const
virtual QString makeAbsolute (const QString &abs_or_rel_name, const QString &context) const
const QMimeSourcedata (const QString &abs_or_rel_name, const QString &context) const
virtual void setText (const QString &abs_name, const QString &text)
virtual void setImage (const QString &abs_name, const QImage &im)
virtual void setPixmap (const QString &abs_name, const QPixmap &pm)
virtual void setData (const QString &abs_name, QMimeSource *data)
virtual void setFilePath (const QStringList &)
void setFilePath (const QString &path)
virtual QStringList filePath () const
void addFilePath (const QString &)
virtual void setExtensionType (const QString &ext, const char *mimetype)

Static Public Member Functions

static Q3MimeSourceFactorydefaultFactory ()
static void setDefaultFactory (Q3MimeSourceFactory *)
static Q3MimeSourceFactorytakeDefaultFactory ()
static void addFactory (Q3MimeSourceFactory *f)
static void removeFactory (Q3MimeSourceFactory *f)

Private Member Functions

QMimeSourcedataInternal (const QString &abs_name, const QMap< QString, QString > &extensions) const

Private Attributes

Q3MimeSourceFactoryDatad


Constructor & Destructor Documentation

Q3MimeSourceFactory::Q3MimeSourceFactory (  ) 

Constructs a Q3MimeSourceFactory that has no file path and no stored content.

Definition at line 144 of file q3mimefactory.cpp.

References addFilePath(), and setExtensionType().

Referenced by defaultFactory().

00144                                          :
00145     d(new Q3MimeSourceFactoryData)
00146 {
00147     addFilePath(":/qt/q3mimesourcefactory/"); //to get from the resources
00148     // add some reasonable defaults
00149     setExtensionType("htm", "text/html;charset=iso8859-1");
00150     setExtensionType("html", "text/html;charset=iso8859-1");
00151     setExtensionType("txt", "text/plain");
00152     setExtensionType("xml", "text/xml;charset=UTF-8");
00153     setExtensionType("jpg", "image/jpeg"); // support misspelled jpeg files
00154 }

Here is the call graph for this function:

Q3MimeSourceFactory::~Q3MimeSourceFactory (  )  [virtual]

Destroys the Q3MimeSourceFactory, deleting all stored content.

Definition at line 159 of file q3mimefactory.cpp.

References d, defaultfactory, and defaultFactory().

00160 {
00161     if (defaultFactory() == this)
00162         defaultfactory = 0;
00163     delete d;
00164 }

Here is the call graph for this function:


Member Function Documentation

Q3MimeSourceFactory * Q3MimeSourceFactory::defaultFactory (  )  [static]

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.

See also:
setDefaultFactory()

Definition at line 452 of file q3mimefactory.cpp.

References defaultfactory, QTextImageHandler::externalLoader, Q3MimeSourceFactory(), qmime_cleanup_factory, and richTextImageLoader().

Referenced by addFactory(), data(), dataInternal(), Q3TextDocument::init(), qImageFromMimeSource(), qPixmapFromMimeSource(), removeFactory(), richTextImageLoader(), and ~Q3MimeSourceFactory().

00453 {
00454     if (!defaultfactory)
00455     {
00456         defaultfactory = new Q3MimeSourceFactory();
00457         qmime_cleanup_factory.set(&defaultfactory);
00458         QTextImageHandler::externalLoader = richTextImageLoader;
00459     }
00460     return defaultfactory;
00461 }

Here is the call graph for this function:

void Q3MimeSourceFactory::setDefaultFactory ( Q3MimeSourceFactory factory  )  [static]

Sets the default factory, destroying any previously set mime source provider. The ownership of the factory is transferred to Qt.

See also:
defaultFactory()

Definition at line 470 of file q3mimefactory.cpp.

References defaultfactory, and qmime_cleanup_factory.

00471 {
00472     if (!defaultfactory)
00473         qmime_cleanup_factory.set(&defaultfactory);
00474     else if (defaultfactory != factory)
00475         delete defaultfactory;
00476     defaultfactory = factory;
00477 }

Q3MimeSourceFactory * Q3MimeSourceFactory::takeDefaultFactory (  )  [static]

Sets the defaultFactory() to 0 and returns the previous one.

Definition at line 483 of file q3mimefactory.cpp.

References defaultfactory.

00484 {
00485     Q3MimeSourceFactory *f = defaultfactory;
00486     defaultfactory = 0;
00487     return f;
00488 }

void Q3MimeSourceFactory::addFactory ( Q3MimeSourceFactory f  )  [static]

Adds the Q3MimeSourceFactory 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.

See also:
removeFactory()

Definition at line 499 of file q3mimefactory.cpp.

References QList< T >::append(), d, defaultFactory(), and Q3MimeSourceFactoryData::factories.

00500 {
00501     Q3MimeSourceFactory::defaultFactory()->d->factories.append(f);
00502 }

Here is the call graph for this function:

void Q3MimeSourceFactory::removeFactory ( Q3MimeSourceFactory f  )  [static]

Removes the mimesource factory f from the list of available mimesource factories.

See also:
addFactory()

Definition at line 511 of file q3mimefactory.cpp.

References d, defaultFactory(), Q3MimeSourceFactoryData::factories, and QList< T >::removeAll().

Here is the call graph for this function:

const QMimeSource * Q3MimeSourceFactory::data ( const QString abs_name  )  const [virtual]

Returns a reference to the data associated with 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 abs_name in the factory's store, the factory tries to access the local filesystem. If abs_name isn't an absolute file name, the factory will search for it in all defined paths (see {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

    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");
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 Q3MimeSourceFactory 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.

Definition at line 252 of file q3mimefactory.cpp.

References QList< T >::at(), QList< T >::begin(), QMap< Key, T >::contains(), d, data(), dataInternal(), defaultFactory(), QList< T >::end(), Q3MimeSourceFactoryData::extensions, Q3MimeSourceFactoryData::factories, i, QString::isEmpty(), isLetter(), Q3MimeSourceFactoryData::path, QList< T >::size(), QString::startsWith(), and Q3MimeSourceFactoryData::stored.

Referenced by data(), dataInternal(), qImageFromMimeSource(), qPixmapFromMimeSource(), richTextImageLoader(), setData(), Q3TextDocument::setRichTextInternal(), and Q3TextBrowser::setSource().

00253 {
00254     if (d->stored.contains(abs_name))
00255         return d->stored[abs_name];
00256 
00257     const QMimeSource *r = 0;
00258     if (abs_name.isEmpty())
00259         return r;
00260     QStringList::Iterator it;
00261     if (abs_name[0] == '/'
00262 #ifdef Q_WS_WIN
00263             || (abs_name[0].isLetter() && abs_name[1] == ':') || abs_name.startsWith("\\\\")
00264 #endif
00265    )
00266     {
00267         // handle absolute file names directly
00268         r = dataInternal(abs_name, d->extensions);
00269     }
00270     else { // check list of paths
00271         for (it = d->path.begin(); !r && it != d->path.end(); ++it) {
00272             QString filename = *it;
00273             if (filename[(int)filename.length()-1] != '/')
00274                 filename += '/';
00275             filename += abs_name;
00276             r = dataInternal(filename, d->extensions);
00277         }
00278     }
00279 
00280     static bool looping = false;
00281     if (!r && this == defaultFactory()) {
00282         // we found no mime-source and we are the default factory, so
00283         // we know all the other installed mime-source factories, so
00284         // ask them
00285         if (!looping) {
00286             // to avoid endless recustions, don't enter the loop below
00287             // if data() got called from within the loop below
00288             looping = true;
00289             for (int i = 0; i < d->factories.size(); ++i) {
00290                 const Q3MimeSourceFactory *f = d->factories.at(i);
00291                 if (f == this)
00292                     continue;
00293                 r = static_cast<const QMimeSource *>(f->data(abs_name));
00294                 if (r) {
00295                     looping = false;
00296                     return r;
00297                 }
00298             }
00299             looping = false;
00300         }
00301     } else if (!r) {
00302         // we are not the default mime-source factory, so ask the
00303         // default one for the mime-source, as this one will loop over
00304         // all installed mime-source factories and ask these
00305         r = static_cast<const QMimeSource *>(defaultFactory()->data(abs_name));
00306     }
00307     return r;
00308 }

Here is the call graph for this function:

QString Q3MimeSourceFactory::makeAbsolute ( const QString abs_or_rel_name,
const QString context 
) const [virtual]

Converts the absolute or relative data item name abs_or_rel_name to an absolute name, interpreted within the context (path) of the data item named context (this must be an absolute name).

Definition at line 358 of file q3mimefactory.cpp.

References c, d, QString::isEmpty(), and QString::isNull().

Referenced by data(), and Q3TextBrowser::setSource().

00359 {
00360     if (context.isNull() ||
00361          !(context[0] == '/'
00362 #ifdef Q_WS_WIN
00363          || (context[0].isLetter() && context[1] == ':')
00364 #endif
00365           ))
00366         return abs_or_rel_name;
00367     if (abs_or_rel_name.isEmpty())
00368         return context;
00369     QFileInfo c(context);
00370     if (!c.isDir()) {
00371         QFileInfo r(c.dir(true), abs_or_rel_name);
00372         return r.absFilePath();
00373     } else {
00374         QDir d(context);
00375         QFileInfo r(d, abs_or_rel_name);
00376         return r.absFilePath();
00377     }
00378 }

Here is the call graph for this function:

const QMimeSource * Q3MimeSourceFactory::data ( const QString abs_or_rel_name,
const QString context 
) const

This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts. A convenience function. See data(const QString& abs_name). The file name is given in abs_or_rel_name and the path is in context.

Definition at line 386 of file q3mimefactory.cpp.

References d, data(), QList< T >::isEmpty(), makeAbsolute(), and Q3MimeSourceFactoryData::path.

00387 {
00388     const QMimeSource* r = data(makeAbsolute(abs_or_rel_name,context));
00389     if (!r && !d->path.isEmpty())
00390         r = data(abs_or_rel_name);
00391     return r;
00392 }

Here is the call graph for this function:

void Q3MimeSourceFactory::setText ( const QString abs_name,
const QString text 
) [virtual]

Sets text to be the data item associated with the absolute name abs_name.

Equivalent to setData(abs_name, new Q3TextDrag(text)).

Definition at line 401 of file q3mimefactory.cpp.

References setData().

00402 {
00403     setData(abs_name, new Q3TextDrag(text));
00404 }

Here is the call graph for this function:

void Q3MimeSourceFactory::setImage ( const QString abs_name,
const QImage image 
) [virtual]

Sets image to be the data item associated with the absolute name abs_name.

Equivalent to setData(abs_name, new Q3ImageDrag(image)).

Definition at line 412 of file q3mimefactory.cpp.

References image, and setData().

00413 {
00414     setData(abs_name, new Q3ImageDrag(image));
00415 }

Here is the call graph for this function:

void Q3MimeSourceFactory::setPixmap ( const QString abs_name,
const QPixmap pixmap 
) [virtual]

Sets pixmap to be the data item associated with the absolute name abs_name.

Definition at line 421 of file q3mimefactory.cpp.

References setData().

00422 {
00423     setData(abs_name, new Q3ImageDrag(pixmap.convertToImage()));
00424 }

Here is the call graph for this function:

void Q3MimeSourceFactory::setData ( const QString abs_name,
QMimeSource data 
) [virtual]

Sets data to be the data item associated with the absolute name abs_name. Note that the ownership of 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.

Definition at line 434 of file q3mimefactory.cpp.

References QMap< Key, T >::contains(), d, data(), QMap< Key, T >::insert(), and Q3MimeSourceFactoryData::stored.

Referenced by setImage(), setPixmap(), and setText().

00435 {
00436     if (d->stored.contains(abs_name))
00437         delete d->stored[abs_name];
00438     d->stored.insert(abs_name,data);
00439 }

Here is the call graph for this function:

void Q3MimeSourceFactory::setFilePath ( const QStringList  )  [virtual]

Definition at line 319 of file q3mimefactory.cpp.

References d, path, and Q3MimeSourceFactoryData::path.

00320 {
00321     d->path = path;
00322 }

void Q3MimeSourceFactory::setFilePath ( const QString path  )  [inline]

Sets the list of directories that will be searched when named data is requested to those given in the string list path.

See also:
filePath()

Definition at line 62 of file q3mimefactory.h.

References path.

QStringList Q3MimeSourceFactory::filePath (  )  const [virtual]

Returns the currently set search paths.

Definition at line 327 of file q3mimefactory.cpp.

References d, and Q3MimeSourceFactoryData::path.

00328 {
00329     return d->path;
00330 }

void Q3MimeSourceFactory::addFilePath ( const QString p  ) 

Adds another search path, p to the existing search paths.

See also:
setFilePath()

Definition at line 337 of file q3mimefactory.cpp.

References d, p, and Q3MimeSourceFactoryData::path.

Referenced by Q3MimeSourceFactory().

00338 {
00339     d->path += p;
00340 }

void Q3MimeSourceFactory::setExtensionType ( const QString ext,
const char *  mimetype 
) [virtual]

Sets the mime-type to be associated with the file name extension, ext to mimetype. This determines the mime-type for files found via the paths set by setFilePath().

Definition at line 347 of file q3mimefactory.cpp.

References d, Q3MimeSourceFactoryData::extensions, and QMap< Key, T >::insert().

Referenced by Q3MimeSourceFactory().

00348 {
00349     d->extensions.insert(ext, mimetype);
00350 }

Here is the call graph for this function:

QMimeSource * Q3MimeSourceFactory::dataInternal ( const QString abs_name,
const QMap< QString, QString > &  extensions 
) const [private]

Definition at line 166 of file q3mimefactory.cpp.

References QMap< Key, T >::contains(), d, data(), defaultFactory(), QImageReader::imageFormat(), QByteArray::isEmpty(), QFileInfo::isReadable(), Q3MimeSourceFactoryData::last, QFile::open(), QIODevice::ReadOnly, Q3StoredDrag::setEncodedData(), QFile::size(), and QByteArray::toLower().

Referenced by data().

00167 {
00168     QMimeSource* r = 0;
00169     QStringList attempted_names(abs_name);
00170     QFileInfo fi(abs_name);
00171     if (fi.isReadable()) {
00172         // get the right mimetype
00173         QString e = fi.extension(false);
00174         QByteArray mimetype("application/octet-stream");
00175         if (extensions.contains(e))
00176             mimetype = extensions[e].latin1();
00177         QByteArray imgfmt = QImageReader::imageFormat(abs_name);
00178         if (!imgfmt.isEmpty())
00179             mimetype = "image/" + imgfmt.toLower();
00180 
00181         QFile f(abs_name);
00182         if (f.open(QIODevice::ReadOnly) && f.size()) {
00183             QByteArray ba;
00184             ba.resize(f.size());
00185             f.readBlock(ba.data(), ba.size());
00186             Q3StoredDrag* sr = new Q3StoredDrag(mimetype);
00187             sr->setEncodedData(ba);
00188             delete d->last;
00189             d->last = r = sr;
00190         }
00191     }
00192 
00193     // we didn't find the mime-source, so ask the default factory for
00194     // the mime-source (this one will iterate over all installed ones)
00195     //
00196     // this looks dangerous, as this dataInternal() function will be
00197     // called again when the default factory loops over all installed
00198     // factories (including this), but the static bool looping in
00199     // data() avoids endless recursions
00200     if (!r && this != defaultFactory())
00201         r = (QMimeSource*)defaultFactory()->data(abs_name);
00202 
00203     return r;
00204 }

Here is the call graph for this function:


Member Data Documentation

Q3MimeSourceFactoryData* Q3MimeSourceFactory::d [private]

Definition at line 69 of file q3mimefactory.h.

Referenced by addFactory(), addFilePath(), data(), dataInternal(), filePath(), makeAbsolute(), removeFactory(), setData(), setExtensionType(), setFilePath(), and ~Q3MimeSourceFactory().


The documentation for this class was generated from the following files:
Generated on Thu Mar 15 16:11:56 2007 for Qt 4.2 User's Guide by  doxygen 1.5.1