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

List:       ktexteditor-devel
Subject:    Re: KTextEditor container extension
From:       Philippe Fremy <phil () freehackers ! org>
Date:       2007-08-12 14:31:05
Message-ID: 46BF19A9.9050209 () freehackers ! org
[Download RAW message or body]

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().

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




["kte-container-ext-6.diff" (text/x-diff)]

Index: containerinterface.h
===================================================================
--- containerinterface.h	(revision 0)
+++ containerinterface.h	(revision 0)
@@ -0,0 +1,251 @@
+/* This file is part of the KDE libraries
+   Copyright (C) 2007 Philippe Fremy (phil at freehackers dot org)
+
+   This library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Library General Public
+   License version 2 as published by the Free Software Foundation.
+
+   This library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Library General Public License for more details.
+
+   You should have received a copy of the GNU Library General Public License
+   along with this library; see the file COPYING.LIB.  If not, write to
+   the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+   Boston, MA 02110-1301, USA.
+*/
+
+#ifndef KDELIBS_KTEXTEDITOR_CONTAINER_INTERFACE_H
+#define KDELIBS_KTEXTEDITOR_CONTAINER_INTERFACE_H
+
+#include <ktexteditor/ktexteditor_export.h>
+
+namespace KTextEditor
+{
+
+class Document;
+class View;
+
+
+/** 
+ * \brief Class that allows the kpart host to provide some extensions.
+ *
+ * \ingroup kte_group_command_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.
+ *
+ * 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 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;
+
+    /** 
+     * 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
+
+
Index: editorchooser.h
===================================================================
--- editorchooser.h	(revision 699245)
+++ editorchooser.h	(working copy)
@@ -123,6 +123,10 @@
     /**
      * Static accessor to get the Editor instance of the currently used
      * KTextEditor component.
+     *
+     * That Editor instance can be qobject-cast to specific extensions.
+     * If the result of the cast is not NULL, that extension is supported:
+     *
      * \param postfix config group postfix string
      * \param fallBackToKatePart if \e true, the returned Editor component
      *        will be a katepart if no other implementation can be found
Index: CMakeLists.txt
===================================================================
--- CMakeLists.txt	(revision 699245)
+++ CMakeLists.txt	(working copy)
@@ -59,6 +59,7 @@
     codecompletioninterface.h
     codecompletionmodel.h
     configinterface.h
+    containerinterface.h
     DESTINATION  ${INCLUDE_INSTALL_DIR}/ktexteditor )
 
 install( FILES ktexteditor.desktop ktexteditorplugin.desktop  DESTINATION  ${SERVICETYPES_INSTALL_DIR} )


_______________________________________________
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