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

List:       koffice-devel
Subject:    Re: RFD: loading/pasting/DnD in Flake?
From:       "Benjamin K. Stuhl" <benjamin.stuhl () colorado ! edu>
Date:       2006-08-24 4:35:02
Message-ID: 20060823223503.116ed8ed () localhost
[Download RAW message or body]

[Attachment #2 (multipart/signed)]


On Mon, 21 Aug 2006 19:26:05 +0200, Thomas Zander inscribed:
> First some general thoughts.
> - Tools are for manipulating shapes, and there can be more then one
> tool that handles one shape-type. Only the KoCreateShapesTool can
> create shapes due to it being passed a controller.

So the KoCreateShapesTool is how shapes can associate themselves to a
parent document or shape? Ok, I can work with that.
 
> - There is a KoShapeContainer that allows any number of children. So 
> anyone that is able to show child shapes should extend that class
> instead of the normal KoShape.
> 
> I would say that filling a shapes data should be done in the shape
> itself, preferable, due to encapsulation. The idea was that a shape
> can load / save itself in the ODF format.
> You are right that nested shapes are a bit more tricky.
> A shape that somehow finds data it can not load should be able to
> delegate that. Effectively creating a new shape that loads that data.
> I'm not sure how 'nested' ODF is, but I am sure that since the
> creation of new shapes is something that the shapeCreatorTool should
> do, some createShape(QDomElement) method should be added on that.
> 
> A shape that finds out it needs to create a child-shape then needs to
> call that.
> Effectively;
> myTool::paste(QDomElement e) {
> 	firstSelectedObject->paste(e,
>           KoToolManager::instance()->shapeCreatorTool(m_canvas);

How does this work when only a subset of a shape (e.g. a few words in a
KoTextShape) is selected? I guess the tool needs some (perhaps private)
way of informing the shape what the current selection is. (e.g. the
KoTextTool could pass a QTextCursor or something to the KoTextShape?)

> }
> KoShape::paste(e, createTool) {
>    // foo
> }
> KoCreateShapesTool::createShape(QDomElement elem);
> 
>  It would use the ShapeRegistry to find out which shapeFactory can be
> used for the datatype.  This means some mime-type should be
> registered on the KoShapeFactory.

Fleshing this out a bit more, I think that appropriate method
signatures would be something like

void KoShape::loadAs(QIODevice *source, const QString& mimeType,
KoCreateShapesTool *createTool) {
  // we can create a KoStore from |source|, or read an image from it,
  // or insert it as raw data, or whatever is appropriate
  // 
}

enum SaveWhat { SaveSelection, SaveEntireShape };

void KoShape::saveAs(QIODevice *dest, const QString& mimeType,
KoShape::SaveWhat what) {
  // store either the selection or the entire shape into |dest|;
  // the definition of the selection is privately negotiated between
  // a shape and its tools
}

// returns list of supported mime types, perhaps from
//  a KServiceTypeTrader query for import plugins?
QList<QString> KoShape::canLoadAs() const;

// returns list of supported mime types, perhaps from
//  a KServiceTypeTrader query for export plugins?
QList<QString> KoShape::canSaveAs() const;

(Method names are, of course, open to better suggestions.)

The can*As() queries are then duplicated into KoTool, which can
delegate the queries to the selected shape or restrict them to a
subset or add new ones (e.g., the KoTextTool might add whatever the
mime type is for a literal URL to its canLoadAs() list, since it
knows how to insert links, even though it doesn't make much sense
IMHO for the KoTextShape to pretend to be able to "load" from them):

QList<QString> KoTool::canSaveAs() const;
QList<QString> KoTool::canLoadAs() const;

The queries are useful to populate open or save as
dialogs, as well as tp decide whether to give drops or paste requests
to the current tool. I think it's reasonable to assume that if the
clipboard or drop request is of a type that the current tool knows
how to handle, it should be expected to accept it? 

(How do drop requests get handled when there is no current tool? As a
user, I would expect dropping an image from Firefox on to my document 
to depend only on where I drop it, not on whether I had the TextTool 
selected or not... Maybe there should be a KoDropTool that is 
automatically created on a dragStarted() or dragEntered() event, that 
then delegates the drop to the default tool of whatever shape the drop 
is on?)

As you can see, I'm also trying to figure out where import and export
plugins fit into this... I think that they should be discovered and
used by the appropriate Shapes? So e.g. the KoTextShape could query for
and find a KoHtmlTextImporter that knows how to take HTML and feed it
into a KoTextShape? Perhaps just KoImporterPlugin::importAs() which
mirrors KoShape::loadAs(), except that it manipulates an external
shape, and likewise for KoExporterPlugin::exportAs() and
KoShape::saveAs()? The plugins wouldn't need can*As(), since that would
be declared in their .desktop... For a constructor, maybe just

KoImporterPlugin::KoImporterPlugin(KoShape *target);

and the constructor does a static_cast<> to the appropriate shape
(e.g. static_cast<KoTextShape> for the KoHtmlTextImporter)?

As for the KoCreateShapesTool, it needs a

  KoShape * KoCreateShapesTool::createShape(QIODevice *src, const
QString& mimeType);

and also, to do much of the real work, (for ODF at least), a

  KoShape * KoCreateShapesTool::createShape(KoStore *store, QDomElement
elem);

The KoStore is important, since e.g. images are stored out-of-line, in
another file in the ODF zip archve.

What about error handling? Should the shape simply have a 

signals:
  void loadFailed(const QString& reason);

to report when something didn't work? Or do we want something a bit more
complex so that we can let the user do partial imports up to the broken
point?

> > Also, what about pasting? Do 
> > we need an explicit notion of a cursor, or do we just define that
> > loading a chunk of data into a Tool is defined to always occur at
> > the current insertion point, overwriting any preexisting selection?
> 
> I think that using the current cursor position certainly is best.
> And tools that don't have a cursor position should probably just deny 
> pasting leading the application to paste it to the parent (probably a 
> page).

Sounds good to me.
 
> >   Also, what about the flip side? Tools should probably know how to
> > serialize their shapes, too? (After all, the tool is the logical
> > element to provide data sources for cut/copy operations, and
> > probably should be responsible for saving its shapes, too?)
> 
> Tools themselves don't hold data and there is no guarantee that there
> is one tool per shape. But if you replace 'tool' with 'shape' in your 
> question, then yes, each shape should be able to save itself in the
> ODF format. I would think that this format is used by DnD as well.
> This makes a KoShape method 'fillClipboard()' easy enough for the
> majority of the cases. It just uses the ODF.

My idea was that this would simply be a saveAs(buf, mimeType,
KoShape::SaveSeleection), where buf is a QBuffer; the underlying
QByteArray can then be given to a QMimeData.

> [other stuff snipped for now]

KoTools should probably be given some extensions to adequately deal
with selections and such... perhaps

signals:
// emitted as true when something is selected, false when the selection
// is cleared -- good for (e.g.) enabling the cut and copy actions
  void KoTool::hasSelection(bool);

public:
// asks the tool to paste as the given mimetype, or as the best
// available if |mimeType| is empty -- lets applications implement
// "Paste As..." logic, while letting shapes decide what the "best"
// format is
  void KoTool::paste(QMimeData *source, const QString& mimeType);

Thinking further on the "Paste As..." menu, that is really IMHO a
property of the current clipboard contents, and so _has_ to be managed
by the application, perhaps with the help of the shape registry.

That's probably enough for now, it's getting kind of late here. Let me
know what you think.

Thanks,
-- BKS

["signature.asc" (application/pgp-signature)]

_______________________________________________
koffice-devel mailing list
koffice-devel@kde.org
https://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