[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