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

List:       ktexteditor-devel
Subject:    Re: KTextEditor container extension
From:       Dominik Haumann <dhdev () gmx ! de>
Date:       2007-08-13 8:57:18
Message-ID: 200708131057.18582.dhdev () gmx ! de
[Download RAW message or body]

On Sunday 12 August 2007, Philippe Fremy wrote:
>      Hi Guys,
>
> I was on holyday last week, which is why it took me so long for the next
> iteration.
>
> I followed Dominik's and Joseph's recommendations (to the extent of my
> capabilities).
>
> So here it is:
> - only one file, containerinterface.h for all the classes
> - ContainerInterface is obtained by qobject-casting KTextEditor::editor()
> - the lonely Container class has been dropped
> - ContainerInterface is used to set and fetch a container as a QObject
> - MultiDocMultiViewContainer has been renamed MdiContainer
> - MdiContainer is pure virtual and does not inherit anything
>
> Like Joseph suggested, somebody willing to provide a container should
> provide a class inheriting QObject and the MdiContainer, and declare it
> with Q_DECLARE_INTERFACES().

yes, + Q_INTERFACES for the class that inherits e.g. MdiContainer.

> I find the design quite neat now, and it does not even break binary
> compatibility, thanks to qobject tricks.
>
> As always, comments are welcome.
>
>         Philippe
>
>
>
>
> Index: containerinterface.h
> ===================================================================
> --- containerinterface.h        (revision 0)
> +++ containerinterface.h        (revision 0)
[...]
> +/**
> + * \brief Class that allows the kpart host to provide some extensions.
> + *
> + * \ingroup kte_group_command_extensions

should be: kte_group_editor_extensions

> + * The KTextEditor framework allows the kpart host to provide additional
> + * services to the kpart. Those services are provided through the
> + * ContainerInterface class.
> + *
> + * If the container supports those specific services, it should set an
> + * instance of the service class with
> ContainerInterface::setContainer(). That + * instance should inherit
> QObject and have the Q_OBJECT macro, in order for + * the qobject_cast
> mechanism to work.
> + *
> + * To obtain a ContainerInterface, in order to set a specific container
> + * extension, the kpart host should do:
> + * \code
> + * // inside the kpart host
> + * Editor * editor = KTextEditor::EditorChooser::editor();
> + * ContainerInterface * iface = qobject_cast<ConainterInterace *>(
> editor ); + * if (iface != NULL) {
> + *   iface->setContainer( myContainerExtension );
> + * } else {
> + *   // the kpart does not support ContainerInterface.
> + * }
> + * \endcode
> + *
> + * It is then up to the kpart to use it.
> + *
> + */
> +class KTEXTEDITOR_EXPORT ContainerInterface
> +{
> +  public:
> +
> +    /** Virtual Destructor */
> +    ~ContainerInterface() {}
> +
> +    /**
> +     * Set the KTextEditor container.
> +     *
> +     * This method is used by the KTextEditor host to set an instance
> +     * of a class providing optional container extensions.
> +     *
> +     * \sa container
> +     */
> +    virtual void setContainer( QObject * container ) = 0;
> +
> +    /**
> +     * Fetch the container extension.
> +     *
> +     * This method is used by the KTextEditor component to know
> +     * which extensions are supported by the KTextEditor host.
> +     *
> +     * The kpart will cast the result with qobject_cast() to the right
> +     * container extension to see if that particular extension is
> supported: +     *
> +     * <b>Example:</b>
> +     * \code
> +     * // inside the kpart
> +     *
> +     * Editor * editor = KTextEditor::EditorChooser::editor();
> +     * ContainerInterface * iface = qobject_cast<ConainterInterace *>(
> editor ); +     * SomeContainerExtension * myExt =
> +     *     qobject_cast<SomeContainerExtension *>( iface->container() );
> +     *
> +     * if (myExt) {
> +     *     // do some stuff with the specific container extension
> +     *     // ...
> +     * } else {
> +     *     // too bad, that extesion is not supported.
> +     * }
> +     * \endcode
> +     *
> +     * \sa setContainer
> +     */
> +    virtual QObject * container() = 0;
> +
> +}; // class ContainerInterface
> +
> +
> +/**
> + * A container for MDI-capable kpart hosts.
> + *
> + * The kpart container for the KTextEditor interface may have different
> + * capabilities. For example, inside KDevelop or Kate, the container can
> + * manage multiple views and multiple documents. However, if the kpart
> text + * is used inside konqueror as a replacement of the text entry in
> html + * forms, the container will only support one view with one
> document. + *
> + * This class allows the kpart component to create and delete views,
> create + * and delete documents, fetch and set the current view. Note
> that the + * ktexteditor framework already supports multiple document and
> views and + * that the kpart host can create them and delete them as it
> wishes. What + * this class provides is the ability for the <i>kpart
> component</i> being + * hosted to do the same.
> + *
> + * An instance of this extension should be set with
> + * ContainerInterface::setContainerExtension().Check
> ContainerInterface() to + * see how to obtain an instance of
> ContainerInterface. The instance should + * inherit QObject as well, and
> declare the Q_OBJECT macro.

and add: Q_INTERFACES(KTextEditor::MdiContainer)

> + * To check if the kpart hosts supports the MDI container:
> + * \code
> + * Editor * editor = KTextEditor::EditorChooser::editor();
> + * ContainerInterface * iface = qobject_cast<ContainerInterface *>(
> editor ); + * if (iface) {
> + *   MdiContainer * mdiContainer = qobject_cast<MdiContainer *>(
> iface->container() ); + *   if (MdiContainer != NULL ) {
> + *    // great, I can create addtional views
> + *    // ...
> + *   }
> + * }
> + * \endcode
> + */

class documentation of MdiContainer missing :)

> +class KTEXTEDITOR_EXPORT MdiContainer
> +{
> +
> +  public:
> +
> +    /** Constructor */
> +    MdiContainer();
> +
> +    /** Virtual destructor */
> +    virtual ~MdiContainer();
> +
> +    /**
> +     * Set the \p view requested by the part as the active view.
> +     *
> +     * \sa activeView
> +     */
> +    virtual void setActiveView( View * view )=0;
> +
> +    /**
> +     * Get the current activew view.
> +     *
> +     * \return the active view.
> +     *
> +     * \sa setActiveView
> +     */
> +    virtual View * activeView()=0;
> +
> +    /**
> +     * Create a new Document and return it to the kpart.
> +     *
> +     * Canonical implementation is:
> +     * \code
> +     * Document * createDocument()
> +     * {
> +     *     Document * doc;
> +     *     // set parentQObject to relevant value
> +     *     doc = editor->createDocument( parentQObject );
> +     *     // integrate the new document in the document list of the
> +     *     // container, ...
> +     *     return doc;
> +     * }
> +     * \endcode
> +     *
> +     * The signal documentCreated() will be emitted during the creation.
> +     *
> +     * \return a pointer to the new Document object.
> +     */
> +    virtual Document * createDocument()=0;
> +
> +    /**
> +     * Removes of document \p doc .
> +     *
> +     * The document is about to be removed but is still valid when this
> +     * call is made. The Document does not contain any view when this
> +     * call is made (removeView() has been called on all the views of
> the +     * document previously).
> +     *
> +     * The signal aboutToClose() is emitted before this method is
> +     * called.
> +     *
> +     * \return true if the removal is authorized and acted, or
> +     *     false if removing documents by the kpart is not supported
> +     *     by the container.
> +     */
> +    virtual bool removeDocument( Document * doc )=0;

when I read that now I wonder whether it would be better to name it 
closeDocument() (and closeView()), that's what it really does, isn't it?

> +    /**
> +     * Creates a new View and return it to the kpart.
> +     *
> +     * Canonical implementation is:
> +     * \code
> +     * View * createView( Document * doc )
> +     * {
> +     *     // set parentWidget to relevant value
> +     *     return doc->createView( parentWidget );
> +     * }
> +     * \endcode
> +     *
> +     * The signal viewCreated() will be emitted during the createView()
> +     * call.
> +     *
> +     * \return a pointer to the new View created.
> +     */
> +    virtual View * createView( Document * doc )=0;
> +
> +    /**
> +     * Removes the View \p view .
> +     *
> +     * The view is still valid when this call is made but will be
> deleted +     * shortly after.
> +     *
> +     * \return true if the removal is authorized and acted, or
> +     *     false if the container does not support view removing from
> +     *     the kpart, or
> +     */
> +    virtual bool removeView( View * view )=0;
> +
> +}; // class MdiContainer
> +
> +} // namespace KTextEditor
> +
> +Q_DECLARE_INTERFACE(KTextEditor::ContainerInterface,
> "org.kde.KTextEditor.ContainerInterface") +
> +#endif // KDELIBS_KTEXTEDITOR_CONTAINER_EXTENSION_H
> +
> +

No comments from my side :)

Thanks,
Dominik
_______________________________________________
KTextEditor-Devel mailing list
KTextEditor-Devel@kde.org
https://mail.kde.org/mailman/listinfo/ktexteditor-devel

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

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