[prev in list] [next in list] [prev in thread] [next in thread] 

List:       koffice-devel
Subject:    KoFilter, Snippets (long)
From:       Werner Trobin <trobin () kde ! org>
Date:       2001-09-07 10:51:05
[Download RAW message or body]

Hi!

Sorry that it took me so long, but I finally finished
the design document. It's not very detailed but still
quite long. Feel free to ask if something is missing.


Desing plans for the new KOffice Filter API:

Features, "Highlights":
1) It's possible to apply more than one filter to open or save a file.
2) We finally create real support for so called "snippets"[1] and provide
   drag & drop support from the library. It will also be possible to use
   filters for drag & drop (and clipboard) content.
3) We will have a cleaner looking API (only *one* filter method) and
   still support all the advanced techniques.
4) "Embedding" documents will be (nearly) transparent

[1] A snippet is a small part of a document copied to the clipboard or
directly
    dragged around. If such a snipped is pasted/dropped to some different
    KOffice application we create a native part for this data and embed it. If
    we "hit" a native application it's just pasted as usual.

Implementation details:

KoFilter:
---------
1) There will be two kinds of filters:
   - 1st level filters, which import or export a native KOffice mimetype.
These
     filters can use File -> File, File -> QDomDocument, File -> KoDocument,
or
     KoDocument -> File.
   - 2nd level filters, our "auxilliary" filters, which don't import or export
     any native KOffice mimetype. These filters only are allowed to use
     File -> File for obvious reasons.

   KoFilter::filter(const QString &from, const QString &to,
                    const QString &config=QString::null) will be the only
   filter() method available.

2) KoFilter takes a pointer to a KoFilterChain (see below) as parameter for
its
   constructor and stores it as a private value (Alternative to prevent 
   filters from doing something "evil" -> have one KoFilterChain method as
   friend which sets this pointer right after creation, but that looks a bit
   messy and brittle to me).

   We're holding that pointer as we provide some protected methods in KoFilter
   which have to be used to get hold of e.g. the file to import from. (e.g
   inputFile()). We also should provide a way to access KoStorage files in
   that way, but to do that we need to rework the KoStore interface. Right now
   it assumes that one "user" accesses exactly one stream and that's it. I
hope
   it's possible to create (concurrent) "readers" and "writers" on a storage
   and give those readers/writers to the filters (e.g. inputStream). The
   advantage is that the filters can't do anything nasty, and we can share a
   lot of code which is now duplicated. This is also very important as soon as
   embedding filters comes into consideration -- more on that below.

   All this also has to be done for the output side (with input and output I
   mean the I/O of a filter regardless of import/export). As soon as a filter
   wants to write results out it gets the appropriate "device" (a file, a
writer
   on a storage, a QDomDocument, a KoDocument) from the filter chain and
   starts to write out.

   Due to the fact that all requests for files, streams,... are handled by the
   filter chain (which basically just forwards is to the filter manager) we
can
   remove the "Implemented" field from the .desktop files. I also suggest
   renaming "Import" to "X-KDE-Import" (same for "Export"). As I'll explain
   below we'll also need a new field called X-KDE-FilterWeight or similar
which
   defaults to 1 and may be increased to prevent certain paths (see below).

KoFilterManager:
----------------
The KoFilterManager constructor gets a "parent" KoFilterManager which is 0 by
default, but as soon as embedding is involved we get a real parent. We need
this parent to keep track of the current "prefix" we have to obey when we
construct KoStorage readers/writers.

It's able to handle all the requests from the filter (filename to im/export,
KoDocument, storage stuff,...). Some changes:
- fileSelectorList should be made static, same for prepareDialog, as this
  doesn't require any internal state.
- get rid of the no-op cleanUp()
- get rid of all the prefix things. We should handle that in a different way,
  see below.
- remove all the "singleton" traces in KoFilterManager, it should be a plain
  class you can instanciate multiple times.

Note on embedding filters: As we always query "our" filter manager for files,
streams,... it's possible to implement embedding support in a transparent way.
All we have to do is to take care about the prefix when we got a non-0 parent.

From a filter's POV embedding a document is just a matter of creating a new
instance of KoFilterManager and let it convert the file (yes, the "embedded"
part has to be saved to disk and I see no way to do that in the libs). After
a successful conversion it should be possible to embed the results. 

Image handling should be a matter of asking the filter manager for a image
stream (i.e. a plain KoStreamWriter or however, but with an image "url" inside
the storage).


Additional Classes:
-------------------
We will need something like a KoFilterChain class which can hold a path of
KoFilters (or just one in 90% of all cases). This means that it takes care to
pass the information around, i.e. the output file of the first filter is the
input file of the 2nd,... It should just forward most of the input/output
calls to the filter manager.

Then we need one/a few private classes in koFilterManager.cc (not in the
public
API) which implement some helper functionality (e.g. determining the supported
mimetypes, finding the shortest path through the filter-graph,...). As these
classes aren't in the public API it's not very important to specify their
interfaces. The path finding algorithm honors the "weight" of a filter to make
it possible to prevent some strange paths ;)

Snippets:
---------
According to the Qt documentation it should be possible to implement
copy&paste
the same way as drag&drop by passing around dragging stuff in the clipboard.
Please correct me if I got that wrong.
Due to that we only need to implement drag&drop for snippet support.

- Every application has to have a snippet mimetype
(application/x-kfoo-snippet)
- If the application gets a snippet from any KOffice application we embed the
  appropriate part in case it's not native. The only question which remains
for
  me is how we determine the size of the embedded part. We could create our
own
  QDragFoo class to pass such a hint around.
- We pass around complete KoStore "files". It's possible to create such a
  device on a byte array so that shouldn't be a problem.
- If we get a non-koffice snippet we have to query the filter manager whether
  it's possible to convert that mimetype (most likely rtf or html) to some(!)
  snippet mimetype. Here it should be possible to specify a preference for the
  native snippet mimetype, and if that fails fall back to the KOffice snippet.
  This means that e.g. dropping a html table on KSpread would try to create a
  application/x-kspread-snippet first and if that's not supported fall back to
  application/x-kword-snippet and embed a KWord part.

As I said -- copy and paste should also work that way with the exception that
we use the cursor position as position to insert it instead of the mouse
position from the drop event.


What do you think? Comments? Suggestions?

Thanks for reading all that,
Werner
_______________________________________________
Koffice-devel mailing list
Koffice-devel@mail.kde.org
http://mail.kde.org/mailman/listinfo/koffice-devel

[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic