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

List:       koffice-devel
Subject:    Updated kpresenter dbus slideshow control patch
From:       James Hogan <james () albanarts ! com>
Date:       2008-10-23 18:17:06
Message-ID: 200810231917.11371.james () albanarts ! com
[Download RAW message or body]

Hi

I've attached an updated patch implementing a dbus interface for controlling 
slideshows from programs such as kworship. It is based off koffice 2.0 beta-2. 
Sorry it took so long for me to get around to updating it.

Thorsten: I'd really appreciate if you could take another look and let me know 
if there are any more problems and if you approve of the use of dbus signals. 
Email me if you have any more questions.

Rough changes since previous patch:

* generally tidied up, style fixes
* removed the dbus method for showing edit custom slideshow dialog as it is 
unnecessary and not the best way of doing it anyway.
* view adaptor doesn't use KPrAnimationDirector directly, instead interfacing 
through KPrViewModePresentation
* added pageNotes dbus method to get slide notes in plain text or html
* added exportPageThumbnail dbus method to save a thumbnail to file (adapted 
from koffice 1.6.3)
* added documentOpened and documentClosed dbus signals to application

overall dbus interface additions:

These signals apply to all koffice applications and allow a controlling 
program to know when it needs to modify its list of open documents. Without 
these I imagine a controller would have to poll for changes to the document 
list or the user would have to manually refresh the list when they wanted to 
control a newly opened document.
* KoApplicationAdaptor::documentOpened(QString dbus_ref) signal is emitted 
when a document is opened (and its first view created).
* KoApplicationAdaptor::documentClosed(QString dbus_ref) signal is emitted 
when a document is closed (its last view destroyed).

The following methods/signals are in a new adaptor KPrViewAdaptor 
(org.kde.koffice.presentation.view)

Custom slideshows - this basically allows a controlling program to show a list 
of custom slideshows, keep it up to date and synchronised, and change the 
active custom slideshow ready for starting a presentation.
* QStringList customSlideShows() - returns a list of custom slideshow names
* QString activeCustomSlideShow() - returns the current custom slideshow name
* void setActiveCustomSlideShow(QString) - sets the current custom slideshow
* signal activeCustomSlideShowChanged(QString) - emitted when the active 
custom slideshow is changed
* signal customSlideShowsModified() - emitted when the custom slideshows have 
been edited and the controller needs to update its list

slide information. These allow the controlling program to list the slides in 
the active slideshow (with thumbnails) and show slide notes during 
presentations
* int numCustomSlideShowSlides() - returns the number of slides in the active 
custom slideshow
* QString pageNotes(int page, QString format) - returns the notes for a given 
page in the active slideshow (format can be "plain" or "html")
* bool exportPageThumbnail(int page, ...) - saves a thumbnail of a slide in 
the active custom slideshow to an image file.

presentation control methods. these allow navigation of the running 
presentation and are pretty much self explanatory
* presentationStart()
* presentationStartFromFirst()
* presentationStop()
* presentationPrev() - previous step
* presentationNext() - next step
* presentationPrevSlide()
* presentationFirst()
* presentationLast()
* gotoPresentationPage(int)

presentation accessors - the current state of the presentation can be accessed 
for feedback to the user from the controller gui
* bool isPresentationRunning()
* int currentPresentationPage()
* int currentPresentationStep()
* int numStepsInPresentationPage()
* int numPresentationPages()

presentation signals - allow the controller gui to be kept up to date when the 
presentation state changes not as a result of an action by the controller 
(e.g. timed transitions)
* presentationStarted(int numSlides)
* presentationStopped()
* presentationPageChanged(int page, int stepsInPage)
* presentationStepChanged(int step)

Cheers

-- 
James Hogan

["kpresenter_dbus_2.patch" (text/x-diff)]

diff --git a/kpresenter/part/CMakeLists.txt b/kpresenter/part/CMakeLists.txt
index 3c5b830..a228134 100644
--- a/kpresenter/part/CMakeLists.txt
+++ b/kpresenter/part/CMakeLists.txt
@@ -16,6 +16,7 @@ set( kpresenterprivate_LIB_SRCS
      KPrFactory.cpp
      KPrDocument.cpp
      KPrView.cpp
+     KPrViewAdaptor.cpp
      KPrViewModePresentation.cpp
      KPrViewModeNotes.cpp
      KPrViewModePreviewPageEffect.cpp
diff --git a/kpresenter/part/KPrAnimationDirector.cpp \
b/kpresenter/part/KPrAnimationDirector.cpp index d5e826a..3dd1601 100644
--- a/kpresenter/part/KPrAnimationDirector.cpp
+++ b/kpresenter/part/KPrAnimationDirector.cpp
@@ -139,6 +139,26 @@ KoViewConverter * KPrAnimationDirector::viewConverter()
     return &m_zoomHandler;
 }
 
+int KPrAnimationDirector::numPages() const
+{
+    return m_pages.size();
+}
+
+int KPrAnimationDirector::currentPage() const
+{
+    return m_pageIndex;
+}
+
+int KPrAnimationDirector::numStepsInPage() const
+{
+    return m_steps.size();
+}
+
+int KPrAnimationDirector::currentStep() const
+{
+    return m_stepIndex;
+}
+
 bool KPrAnimationDirector::navigate( Navigation navigation )
 {
     bool finished = false;
@@ -183,6 +203,13 @@ bool KPrAnimationDirector::navigate( Navigation navigation )
 
 void KPrAnimationDirector::navigateToPage( KoPAPageBase *page )
 {
+    navigateToPageIndex( m_pages.indexOf( page ) );
+}
+
+void KPrAnimationDirector::navigateToPageIndex( int page )
+{
+    Q_ASSERT( page >= 0 && page < m_pages.size() );
+
     if ( m_pageEffectRunner ) {
         m_pageEffectRunner->finish();
         finishAnimations();
@@ -195,11 +222,11 @@ void KPrAnimationDirector::navigateToPage( KoPAPageBase *page )
         m_timeLine.stop();
     }
 
-    m_pageIndex = m_pages.indexOf( page );
+    m_pageIndex = page;
 
     m_stepIndex = 0;
 
-    updateActivePage( page );
+    updateActivePage( m_pages[page] );
     updateAnimations();
 
     // trigger a repaint
diff --git a/kpresenter/part/KPrAnimationDirector.h \
b/kpresenter/part/KPrAnimationDirector.h index 6f27dfc..4c757a9 100644
--- a/kpresenter/part/KPrAnimationDirector.h
+++ b/kpresenter/part/KPrAnimationDirector.h
@@ -64,6 +64,26 @@ public:
     KoViewConverter * viewConverter();
 
     /**
+     * get the number of pages
+     */
+    int numPages() const;
+
+    /**
+     * get the current page number
+     */
+    int currentPage() const;
+
+    /**
+     * get the number of steps in this page
+     */
+    int numStepsInPage() const;
+
+    /**
+     * get the current step
+     */
+    int currentStep() const;
+
+    /**
      * do the next step in the presentation
      *
      * @return true if slideshow is finished and should be exited, false otherwise
@@ -76,6 +96,11 @@ public:
     void navigateToPage( KoPAPageBase * page );
 
     /**
+     * do the navigation to the page index specified
+     */
+    void navigateToPageIndex( int page );
+
+    /**
      * Check if the shape is shown
      *
      * A shape is visible when there are no animations on it or when it
diff --git a/kpresenter/part/KPrDocument.cpp b/kpresenter/part/KPrDocument.cpp
index 676b333..2b28ec5 100644
--- a/kpresenter/part/KPrDocument.cpp
+++ b/kpresenter/part/KPrDocument.cpp
@@ -217,6 +217,7 @@ void KPrDocument::setCustomSlideShows( KPrCustomSlideShows* \
replacement )  {
     delete m_customSlideShows;
     m_customSlideShows = replacement;
+    customSlideShowsModified();
 }
 
 int KPrDocument::presentationMonitor()
@@ -256,7 +257,10 @@ QString KPrDocument::activeCustomSlideShow() const
 
 void KPrDocument::setActiveCustomSlideShow( const QString &customSlideShow )
 {
-    m_activeCustomSlideShow = customSlideShow;
+    if ( customSlideShow != m_activeCustomSlideShow ) {
+        m_activeCustomSlideShow = customSlideShow;
+        activeCustomSlideShowChanged( customSlideShow );
+    }
 }
 
 #include "KPrDocument.moc"
diff --git a/kpresenter/part/KPrDocument.h b/kpresenter/part/KPrDocument.h
index e564cd3..6993be5 100644
--- a/kpresenter/part/KPrDocument.h
+++ b/kpresenter/part/KPrDocument.h
@@ -120,6 +120,21 @@ public:
     /// reimplemented
     virtual void saveOdfDocumentStyles( KoPASavingContext & context );
 
+signals:
+    /**
+     * Emitted when the active custom slide show changes.
+     * This is to allow for signalling dbus interfaces.
+     *
+     * @param customSlideShow the new active custom slide show
+     */
+    void activeCustomSlideShowChanged(const QString &customSlideShow);
+
+    /**
+     * Emitted when the custom slide shows have been modified.
+     * This is to allow for signalling dbus interfaces.
+     */
+    void customSlideShowsModified();
+
 protected:
     /// reimplemented
     virtual KoView * createViewInstance( QWidget *parent );
diff --git a/kpresenter/part/KPrView.cpp b/kpresenter/part/KPrView.cpp
index 6bef4e4..f24d314 100644
--- a/kpresenter/part/KPrView.cpp
+++ b/kpresenter/part/KPrView.cpp
@@ -34,6 +34,7 @@
 #include "KPrPage.h"
 #include "KPrMasterPage.h"
 #include "KPrPageApplicationData.h"
+#include "KPrViewAdaptor.h"
 #include "KPrViewModePresentation.h"
 #include "KPrViewModeNotes.h"
 #include "KPrShapeManagerDisplayMasterStrategy.h"
@@ -61,6 +62,8 @@ KPrView::KPrView( KPrDocument *document, QWidget *parent )
     initActions();
 
     masterShapeManager()->setPaintingStrategy( new \
KPrShapeManagerDisplayMasterStrategy( masterShapeManager() ) ); +
+    m_dbus = new KPrViewAdaptor( this );
 }
 
 KPrView::~KPrView()
@@ -74,6 +77,26 @@ KoViewConverter * KPrView::viewConverter( KoPACanvas * canvas )
     return viewMode()->viewConverter( canvas );
 }
 
+KPrDocument * KPrView::kprDocument()
+{
+    return dynamic_cast<KPrDocument *>( m_doc );
+}
+
+KPrViewAdaptor * KPrView::dbusObject()
+{
+    return m_dbus;
+}
+
+KPrViewModePresentation * KPrView::presentationMode()
+{
+    return m_presentationMode;
+}
+
+bool KPrView::isPresentationRunning()
+{
+    return ( viewMode() == m_presentationMode );
+}
+
 void KPrView::updateActivePage(KoPAPageBase *page)
 {
     viewMode()->updateActivePage( page );
@@ -157,6 +180,13 @@ void KPrView::startPresentationFromBeginning()
     startPresentation();
 }
 
+void KPrView::stopPresentation()
+{
+    if ( isPresentationRunning() ) {
+        m_presentationMode->activateSavedViewMode();
+    }
+}
+
 void KPrView::createAnimation()
 {
     static int animationcount = 0;
diff --git a/kpresenter/part/KPrView.h b/kpresenter/part/KPrView.h
index f7d435e..30ee444 100644
--- a/kpresenter/part/KPrView.h
+++ b/kpresenter/part/KPrView.h
@@ -27,6 +27,7 @@
 #include <KoPAView.h>
 
 class KPrDocument;
+class KPrViewAdaptor;
 class KPrViewModeNotes;
 class KPrViewModePresentation;
 class KPrViewModePresenterView;
@@ -42,16 +43,23 @@ public:
 
     virtual KoViewConverter * viewConverter( KoPACanvas * canvas);
 
+    KPrDocument * kprDocument();
+    virtual KPrViewAdaptor * dbusObject();
+
+    KPrViewModePresentation * presentationMode();
+    bool isPresentationRunning();
+
 public slots:
     void updateActivePage(KoPAPageBase *page);
+    void startPresentation();
+    void startPresentationFromBeginning();
+    void stopPresentation();
 
 protected:
     void initGUI();
     void initActions();
 
 protected slots:
-    void startPresentation();
-    void startPresentationFromBeginning();
     void createAnimation();
     void showNormal();
     void showNotes();
@@ -66,6 +74,8 @@ private:
     KAction *m_actionViewModeNotes;
     KAction *m_actionCreateCustomSlideShowsDialog;
 
+    KPrViewAdaptor *m_dbus;
+
     KPrViewModePresentation *m_presentationMode;
     KoPAViewMode *m_normalMode;
     KPrViewModeNotes *m_notesMode;
diff --git a/kpresenter/part/KPrViewAdaptor.cpp b/kpresenter/part/KPrViewAdaptor.cpp
new file mode 100644
index 0000000..ce3f857
--- /dev/null
+++ b/kpresenter/part/KPrViewAdaptor.cpp
@@ -0,0 +1,250 @@
+/*  This file is part of the KDE project
+    Copyright (C) 2008 James Hogan <james@albanarts.com>
+
+    This library is free software; you can redistribute it and/or
+    modify it under the terms of the GNU Lesser General Public
+    License as published by the Free Software Foundation; either
+    version 2 of the License, or (at your option) any later version.
+
+    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
+    Lesser General Public License for more details.
+
+    You should have received a copy of the GNU Lesser General Public
+    License along with this library; if not, write to the Free Software
+    Foundation, Inc., 51 Franklin Street, Fifth Floor,
+    Boston, MA  02110-1301  USA
+*/
+
+#include "KPrViewAdaptor.h"
+#include "KPrView.h"
+#include "KPrViewModePresentation.h"
+#include "KPrAnimationDirector.h"
+#include "KPrDocument.h"
+#include "KPrNotes.h"
+#include "KPrPage.h"
+#include "KoTextShapeData.h"
+
+#include <KUrl>
+
+#include <QTextDocument>
+
+KPrViewAdaptor::KPrViewAdaptor( KPrView* view )
+: KoViewAdaptor( view )
+, m_view( view )
+{
+    KPrDocument *doc = m_view->kprDocument();
+    Q_ASSERT( 0 != doc );
+    connect( doc, SIGNAL( activeCustomSlideShowChanged( const QString & ) ), this, \
SIGNAL( activeCustomSlideShowChanged( const QString & ) ) ); +    connect( doc, \
SIGNAL( customSlideShowsModified() ), this, SIGNAL( customSlideShowsModified() ) ); +
+    // We need to know when the presentation is started and stopped, and when it is \
navigated +    connect( m_view->presentationMode(), SIGNAL( activated() ), this, \
SLOT( presentationActivated() ) ); +    connect( m_view->presentationMode(), SIGNAL( \
deactivated() ), this, SIGNAL( presentationStopped() ) ); +    connect( \
m_view->presentationMode(), SIGNAL( pageChanged( int, int ) ), this, SIGNAL( \
presentationPageChanged( int, int ) ) ); +    connect( m_view->presentationMode(), \
SIGNAL( stepChanged( int ) ), this, SIGNAL( presentationStepChanged( int ) ) ); +}
+
+KPrViewAdaptor::~KPrViewAdaptor()
+{
+}
+
+// custom slideshows
+
+QStringList KPrViewAdaptor::customSlideShows() const
+{
+    KPrDocument *doc = m_view->kprDocument();
+    Q_ASSERT( 0 != doc );
+    return doc->customSlideShows()->names();
+}
+
+QString KPrViewAdaptor::activeCustomSlideShow() const
+{
+    KPrDocument *doc = m_view->kprDocument();
+    Q_ASSERT( 0 != doc );
+    return doc->activeCustomSlideShow();
+}
+
+void KPrViewAdaptor::setActiveCustomSlideShow( QString name )
+{
+    // Check that the custom slideshow exists
+    if ( name.isEmpty() || customSlideShows().contains( name ) ) {
+        KPrDocument *doc = m_view->kprDocument();
+        Q_ASSERT( 0 != doc );
+        doc->setActiveCustomSlideShow( name );
+    }
+}
+
+// slides in the custom slideshow
+
+int KPrViewAdaptor::numCustomSlideShowSlides() const
+{
+    return m_view->kprDocument()->slideShow().size();
+}
+
+QString KPrViewAdaptor::pageNotes( int page, QString format ) const
+{
+    KPrDocument *doc = m_view->kprDocument();
+    Q_ASSERT( 0 != doc );
+
+    QList<KoPAPageBase *> slideShow = doc->slideShow();
+    if ( page >= 0 && page < slideShow.size() ) {
+        KPrPage *prPage = dynamic_cast<KPrPage *>( slideShow[page] );
+        Q_ASSERT( prPage );
+        KPrNotes *pageNotes = prPage->pageNotes();
+        KoShape *textShape = pageNotes->textShape();
+        KoTextShapeData *textShapeData = dynamic_cast<KoTextShapeData *>( \
textShape->userData() ); +        Q_ASSERT( textShapeData );
+
+        if ( format == "plain" ) {
+            return textShapeData->document()->toPlainText();
+        }
+        else if ( format == "html" ) {
+            return textShapeData->document()->toHtml();
+        }
+    }
+    return QString();
+}
+
+bool KPrViewAdaptor::exportPageThumbnail( int page, int width, int height,
+                                          QString filename, QString format, int \
quality ) +{
+    KPrDocument *doc = m_view->kprDocument();
+    Q_ASSERT( 0 != doc );
+
+    QList<KoPAPageBase *> slideShow = doc->slideShow();
+    if ( page >= 0 && page < slideShow.size() ) {
+        KoPAPageBase *pageObject = slideShow[page];
+        Q_ASSERT( pageObject );
+        return m_view->exportPageThumbnail( pageObject, KUrl( filename ),
+                                            QSize( QMAX( 0, width ), QMAX( 0, height \
) ), +                                            format.isEmpty() ? "PNG" : \
format.toLatin1(), +                                            QMAX( -1, QMIN( 100, \
quality ) ) ); +    }
+    else {
+        return false;
+    }
+}
+    
+// Presentation control
+
+void KPrViewAdaptor::presentationStart()
+{
+    m_view->startPresentation();
+}
+
+void KPrViewAdaptor::presentationStartFromFirst()
+{
+    m_view->startPresentationFromBeginning();
+}
+
+void KPrViewAdaptor::presentationStop()
+{
+    m_view->stopPresentation();
+}
+
+void KPrViewAdaptor::presentationPrev()
+{
+    if ( m_view->isPresentationRunning() ) {
+        m_view->presentationMode()->navigate( KPrAnimationDirector::PreviousStep );
+    }
+}
+
+void KPrViewAdaptor::presentationNext()
+{
+    if ( m_view->isPresentationRunning() ) {
+        m_view->presentationMode()->navigate( KPrAnimationDirector::NextStep );
+    }
+}
+
+void KPrViewAdaptor::presentationPrevSlide()
+{
+    if ( m_view->isPresentationRunning() ) {
+        m_view->presentationMode()->navigate( KPrAnimationDirector::PreviousPage );
+    }
+}
+
+void KPrViewAdaptor::presentationNextSlide()
+{
+    if ( m_view->isPresentationRunning() ) {
+        m_view->presentationMode()->navigate( KPrAnimationDirector::NextPage );
+    }
+}
+
+void KPrViewAdaptor::presentationFirst()
+{
+    if ( m_view->isPresentationRunning() ) {
+        m_view->presentationMode()->navigate( KPrAnimationDirector::FirstPage );
+    }
+}
+
+void KPrViewAdaptor::presentationLast()
+{
+    if ( m_view->isPresentationRunning() ) {
+        m_view->presentationMode()->navigate( KPrAnimationDirector::LastPage );
+    }
+}
+
+void KPrViewAdaptor::gotoPresentationPage( int pg )
+{
+    if ( m_view->isPresentationRunning() ) {
+        m_view->presentationMode()->navigateToPageIndex( pg );
+    }
+}
+
+// Presentation accessors
+
+bool KPrViewAdaptor::isPresentationRunning() const
+{
+    return m_view->isPresentationRunning();
+}
+
+int KPrViewAdaptor::currentPresentationPage() const
+{
+    if ( m_view->isPresentationRunning() ) {
+        return m_view->presentationMode()->currentPage();
+    }
+    else {
+        return -1;
+    }
+}
+
+int KPrViewAdaptor::currentPresentationStep() const
+{
+    if ( m_view->isPresentationRunning() ) {
+        return m_view->presentationMode()->currentStep();
+    }
+    else {
+        return -1;
+    }
+}
+
+int KPrViewAdaptor::numStepsInPresentationPage() const
+{
+    if ( m_view->isPresentationRunning() ) {
+        return m_view->presentationMode()->numStepsInPage();
+    }
+    else {
+        return -1;
+    }
+}
+
+int KPrViewAdaptor::numPresentationPages() const
+{
+    if ( m_view->isPresentationRunning() ) {
+        return m_view->presentationMode()->numPages();
+    }
+    else {
+        return -1;
+    }
+}
+
+/**
+ * Fired when the presentation is activated.
+ */
+void KPrViewAdaptor::presentationActivated()
+{
+    presentationStarted( numPresentationPages() );
+}
+
diff --git a/kpresenter/part/KPrViewAdaptor.h b/kpresenter/part/KPrViewAdaptor.h
new file mode 100644
index 0000000..2eed636
--- /dev/null
+++ b/kpresenter/part/KPrViewAdaptor.h
@@ -0,0 +1,147 @@
+/*  This file is part of the KDE project
+    Copyright (C) 2008 James Hogan <james@albanarts.com>
+
+    This library is free software; you can redistribute it and/or
+    modify it under the terms of the GNU Lesser General Public
+    License as published by the Free Software Foundation; either
+    version 2 of the License, or (at your option) any later version.
+
+    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
+    Lesser General Public License for more details.
+
+    You should have received a copy of the GNU Lesser General Public
+    License along with this library; if not, write to the Free Software
+    Foundation, Inc., 51 Franklin Street, Fifth Floor,
+    Boston, MA  02110-1301  USA
+*/
+
+#ifndef KPR_VIEW_ADAPTOR_H
+#define KPR_VIEW_ADAPTOR_H
+
+#include <KoViewAdaptor.h>
+
+class KPrView;
+
+class KPrViewAdaptor : public KoViewAdaptor
+{
+    Q_OBJECT
+    Q_CLASSINFO("D-Bus Interface", "org.kde.koffice.presentation.view")
+
+public:
+    explicit KPrViewAdaptor( KPrView* view );
+    virtual ~KPrViewAdaptor();
+
+public slots:
+
+    // custom slideshows
+    QStringList customSlideShows() const;
+    QString activeCustomSlideShow() const;
+    void setActiveCustomSlideShow( QString name );
+
+    // slides in the custom slideshow
+
+    int numCustomSlideShowSlides() const;
+
+    /**
+     * Get the notes associated with a page of the slideshow.
+     *
+     * The notes can be obtained in plain text or HTML.
+     *
+     * @param page The page index within the current slideshow.
+     * @param format The format of the return value.  Possible values are "plain" \
and "html". +     * @returns The notes associated with page @p page in the format \
specified by @p format. +     *          An empty string is returned when @p format \
is not recognised or @p page is invalid. +     */
+    QString pageNotes( int page, QString format ) const;
+
+    /**
+     * Save page to an image file.
+     *
+     * Export a page of the current presentation to disk
+     * using a bitmap file like e.g. PNG
+     * This method uses a QPixmap::save() call.
+     *
+     * @param page the page index within the current slideshow
+     * @param width the desired image width in px
+     * @param height the desired image height in px
+     * @param filename the name of the image file to be created (see \
QPixmap::save()) +     * @param format the format of the image file (see \
QPixmap::save()) +     * @param quality the quality of the image in [0,100] or -1 to \
use default (see QPixmap::save()) +     *
+     * @returns whether the image was successfully saved
+     */
+    bool exportPageThumbnail( int page, int width, int height,
+                              QString filename, QString format, int quality );
+
+    // Presentation control
+    void presentationStart();
+    void presentationStartFromFirst();
+    void presentationStop();
+    void presentationPrev();
+    void presentationNext();
+    void presentationPrevSlide();
+    void presentationNextSlide();
+    void presentationFirst();
+    void presentationLast();
+    void gotoPresentationPage( int pg );
+
+    // Presentation accessors
+    bool isPresentationRunning() const;
+    int currentPresentationPage() const;
+    int currentPresentationStep() const;
+    int numStepsInPresentationPage() const;
+    int numPresentationPages() const;
+
+signals:
+    /**
+     * Emitted when the active custom slide show changes.
+     *
+     * @param customSlideShow the new active custom slide show
+     */
+    void activeCustomSlideShowChanged( const QString &customSlideShow );
+
+    /**
+     * Emitted when the custom slide shows have been modified.
+     */
+    void customSlideShowsModified();
+
+    /**
+     * Emitted when the slideshow is started.
+     *
+     * @param numSlides Number of slides in the slideshow
+     */
+    void presentationStarted( int numSlides );
+
+    /**
+     * Emitted when the slideshow is finished.
+     */
+    void presentationStopped();
+
+    /**
+     * Emitted when the presentation page is changed.
+     *
+     * @param page new page index within the current slideshow
+     * @param stepsInPage the number of steps in the new page
+     */
+    void presentationPageChanged( int page, int stepsInPage );
+
+    /**
+     * Emitted when the presentation step is changed.
+     *
+     * @param step new step index within the page
+     */
+    void presentationStepChanged( int step );
+
+private slots:
+    /**
+     * Fired when the presentation is activated.
+     */
+    void presentationActivated();
+
+private:
+    KPrView* m_view;
+};
+
+#endif
diff --git a/kpresenter/part/KPrViewModePresentation.cpp \
b/kpresenter/part/KPrViewModePresentation.cpp index adc3115..a001123 100644
--- a/kpresenter/part/KPrViewModePresentation.cpp
+++ b/kpresenter/part/KPrViewModePresentation.cpp
@@ -180,10 +180,16 @@ void KPrViewModePresentation::activate( KoPAViewMode * \
previousViewMode )  m_tool->activate(false);
 
     m_animationDirector = new KPrAnimationDirector( m_view, m_canvas, pages, \
m_view->activePage() ); +
+    activated();
+    pageChanged( m_animationDirector->currentPage(), \
m_animationDirector->numStepsInPage() ); +    stepChanged( \
m_animationDirector->currentStep() );  }
 
 void KPrViewModePresentation::deactivate()
 {
+    deactivated();
+
     KoPAPageBase * page = m_view->activePage();
     if ( m_endOfSlideShowPage ) {
         if ( page == m_endOfSlideShowPage ) {
@@ -232,13 +238,45 @@ KPrAnimationDirector * \
KPrViewModePresentation::animationDirector()  return m_animationDirector;
 }
 
+int KPrViewModePresentation::numPages() const
+{
+    Q_ASSERT( 0 != m_animationDirector );
+    return m_animationDirector->numPages();
+}
+
+int KPrViewModePresentation::currentPage() const
+{
+    Q_ASSERT( 0 != m_animationDirector );
+    return m_animationDirector->currentPage();
+}
+
+int KPrViewModePresentation::numStepsInPage() const
+{
+    Q_ASSERT( 0 != m_animationDirector );
+    return m_animationDirector->numStepsInPage();
+}
+
+int KPrViewModePresentation::currentStep() const
+{
+    Q_ASSERT( 0 != m_animationDirector );
+    return m_animationDirector->currentStep();
+}
+
 void KPrViewModePresentation::navigate( KPrAnimationDirector::Navigation navigation \
)  {
+    Q_ASSERT( 0 != m_animationDirector );
+    int previousPage = m_animationDirector->currentPage();
     bool finished = m_animationDirector->navigate( navigation );
     if ( m_pvAnimationDirector ) {
         finished = m_pvAnimationDirector->navigate( navigation ) && finished;
     }
 
+    int newPage = m_animationDirector->currentPage();
+    if ( previousPage != newPage ) {
+        pageChanged( m_animationDirector->currentPage(), \
m_animationDirector->numStepsInPage() ); +    }
+    stepChanged( m_animationDirector->currentStep() );
+
     if ( finished ) {
         activateSavedViewMode();
     }
@@ -246,9 +284,25 @@ void KPrViewModePresentation::navigate( \
KPrAnimationDirector::Navigation navigat  
 void KPrViewModePresentation::navigateToPage( KoPAPageBase * page )
 {
+    Q_ASSERT( 0 != m_animationDirector );
     m_animationDirector->navigateToPage( page );
     if ( m_pvAnimationDirector ) {
         m_pvAnimationDirector->navigateToPage( page );
     }
+
+    pageChanged( m_animationDirector->currentPage(), \
m_animationDirector->numStepsInPage() ); +    stepChanged( \
m_animationDirector->currentStep() ); +}
+
+void KPrViewModePresentation::navigateToPageIndex( int page )
+{
+    Q_ASSERT( 0 != m_animationDirector );
+    m_animationDirector->navigateToPageIndex( page );
+    if ( m_pvAnimationDirector ) {
+        m_pvAnimationDirector->navigateToPageIndex( page );
+    }
+
+    pageChanged( m_animationDirector->currentPage(), \
m_animationDirector->numStepsInPage() ); +    stepChanged( \
m_animationDirector->currentStep() );  }
 
diff --git a/kpresenter/part/KPrViewModePresentation.h \
b/kpresenter/part/KPrViewModePresentation.h index 13be8c0..9894194 100644
--- a/kpresenter/part/KPrViewModePresentation.h
+++ b/kpresenter/part/KPrViewModePresentation.h
@@ -32,6 +32,8 @@ class KPrEndOfSlideShowPage;
 
 class KPrViewModePresentation : public KoPAViewMode
 {
+    Q_OBJECT
+
 public:
     KPrViewModePresentation( KoPAView * view, KoPACanvas * m_canvas );
     ~KPrViewModePresentation();
@@ -72,12 +74,69 @@ public:
     KPrAnimationDirector * animationDirector();
 
     /**
+     * Get the number of pages.
+     *
+     * This assumes that the presentation is active.
+     */
+    int numPages() const;
+
+    /**
+     * Get the current page number.
+     *
+     * This assumes that the presentation is active.
+     */
+    int currentPage() const;
+
+    /**
+     * Get the number of steps in this page.
+     *
+     * This assumes that the presentation is active.
+     */
+    int numStepsInPage() const;
+
+    /**
+     * get the current step.
+     *
+     * This assumes that the presentation is active.
+     */
+    int currentStep() const;
+
+    /**
      * Navigate in the presentation.
      */
     void navigate( KPrAnimationDirector::Navigation navigation );
 
     void navigateToPage( KoPAPageBase * page );
 
+    void navigateToPageIndex( int page );
+
+signals:
+
+    /**
+     * Emitted when the presentation is activated.
+     */
+    void activated();
+
+    /**
+     * Emitted when the presentation is about to be deactivated.
+     */
+    void deactivated();
+
+    /**
+     * Emitted when the page changes.
+     *
+     * @param page new page index within the current slideshow
+     * @param stepsInPage the number of steps in the new page
+     */
+    void pageChanged( int page, int stepsInPage );
+
+    /**
+     * Emitted when the step changes.
+     *
+     * @param step new step index within the page
+     */
+    void stepChanged( int step );
+
 protected:
     KoPAViewMode * m_savedViewMode;
     QWidget * m_savedParent;
diff --git a/libs/kopageapp/KoPAView.cpp b/libs/kopageapp/KoPAView.cpp
index 8821790..eb30d32 100644
--- a/libs/kopageapp/KoPAView.cpp
+++ b/libs/kopageapp/KoPAView.cpp
@@ -74,6 +74,8 @@
 #include <kstatusbar.h>
 #include <kparts/event.h>
 #include <kparts/partmanager.h>
+#include <ktemporaryfile.h>
+#include <kio/netaccess.h>
 
 KoPAView::KoPAView( KoPADocument *document, QWidget *parent )
 : KoView( document, parent )
@@ -588,6 +590,47 @@ void KoPAView::setActionEnabled( int actions, bool enable )
     }
 }
 
+bool KoPAView::exportPageThumbnail( KoPAPageBase * page, const KUrl& url, const \
QSize& size, +                                    const char * format, int quality )
+{
+    bool res = false;
+    QPixmap pix = page->thumbnail(size);
+    if ( !pix.isNull() ) {
+        // Depending on the desired target size due to rounding
+        // errors during zoom the resulting pixmap *might* be
+        // 1 pixel or 2 pixels wider/higher than desired: we just
+        // remove the additional columns/rows.  This can be done
+        // since KPresenter is leaving a minimal border below/at
+        // the right of the image anyway.
+        if ( size != pix.size() ) {
+            pix = pix.copy( 0, 0, size.width(), size.height() );
+        }
+        // save the pixmap to the desired file
+        KUrl fileUrl(url);
+        if ( fileUrl.protocol().isEmpty() ) {
+            fileUrl.setProtocol( "file" );
+        }
+        const bool bLocalFile = fileUrl.isLocalFile();
+        KTemporaryFile* tmpFile = bLocalFile ? 0 : new KTemporaryFile();
+        if( bLocalFile || tmpFile->open() ) {
+            QFile file( bLocalFile ? fileUrl.path() : tmpFile->fileName() );
+            if ( file.open( IO_ReadWrite ) ) {
+                res = pix.save( &file, format, quality );
+                file.close();
+            }
+            if ( !bLocalFile ) {
+                if ( res ) {
+                    res = KIO::NetAccess::upload( tmpFile->fileName(), fileUrl, this \
); +                }
+            }
+        }
+        if ( !bLocalFile ) {
+            delete tmpFile;
+        }
+   }
+   return res;
+}
+
 KoPADocumentStructureDocker* KoPAView::documentStructureDocker() const
 {
     return m_documentStructureDocker;
diff --git a/libs/kopageapp/KoPAView.h b/libs/kopageapp/KoPAView.h
index 0d560cd..ec44ab3 100644
--- a/libs/kopageapp/KoPAView.h
+++ b/libs/kopageapp/KoPAView.h
@@ -28,6 +28,8 @@
 #include "KoPageApp.h"
 #include "kopageapp_export.h"
 
+#include <KUrl>
+
 class KoCanvasController;
 class KoFind;
 class KoPACanvas;
@@ -114,6 +116,23 @@ public:
      */
     void setActionEnabled( int actions, bool enable );
 
+    /**
+     * Save thumbnail to an image file.
+     *
+     * Export a thumbnail to disk using a pixmap file like e.g. PNG
+     * This method uses a QPixmap::save() call.
+     *
+     * @param filename the name of the image file to be created (see \
QPixmap::save()) +     * @param width the desired image width in px
+     * @param height the desired image height in px
+     * @param format the format of the image file (see QPixmap::save())
+     * @param quality the quality of the image in [0,100] or -1 to use default (see \
QPixmap::save()) +     *
+     * @returns whether the image was successfully saved
+     */
+    bool exportPageThumbnail( KoPAPageBase * page, const KUrl& url, const QSize& \
size = QSize( 512, 512 ), +                              const char * format = 0, int \
quality = -1 ); +
 public slots:
     /// Set the active page and updates the UI
     void updateActivePage( KoPAPageBase * page );
diff --git a/libs/main/KoApplication.h b/libs/main/KoApplication.h
index db0a0d2..1178ed1 100644
--- a/libs/main/KoApplication.h
+++ b/libs/main/KoApplication.h
@@ -74,6 +74,20 @@ public:
      */
     static bool isStarting();
 
+signals:
+    /// KoDocument needs to be able to emit document signals from here.
+    friend class KoDocument;
+
+    /**
+     * emitted when a new document is opened.
+     */
+    void documentOpened(QString ref);
+
+    /**
+     * emitted when an old document is closed.
+     */
+    void documentClosed(QString ref);
+
 private:
     bool initHack();
     KoApplicationPrivate * const d;
diff --git a/libs/main/KoApplicationAdaptor.h b/libs/main/KoApplicationAdaptor.h
index ca663da..c4edeab 100644
--- a/libs/main/KoApplicationAdaptor.h
+++ b/libs/main/KoApplicationAdaptor.h
@@ -66,6 +66,17 @@ public Q_SLOTS: // METHODS
      * (see KoMainWindowIface)
      */
     Q_SCRIPTABLE QStringList getWindows();
+
+signals:
+    /**
+     * emitted when a new document is opened.
+     */
+    void documentOpened(QString ref);
+
+    /**
+     * emitted when an old document is closed.
+     */
+    void documentClosed(QString ref);
 };
 
 #endif
diff --git a/libs/main/KoDocument.cpp b/libs/main/KoDocument.cpp
index 2fa5b39..dd2026f 100644
--- a/libs/main/KoDocument.cpp
+++ b/libs/main/KoDocument.cpp
@@ -35,6 +35,7 @@
 #include "KoEmbeddedDocumentSaver.h"
 #include "KoXmlNS.h"
 #include "KoOpenPane.h"
+#include "KoApplication.h"
 
 #include <KoXmlWriter.h>
 
@@ -657,11 +658,25 @@ void KoDocument::addView(KoView *view)
 
     d->m_views.append(view);
     view->updateReadWrite(isReadWrite());
+
+    if (d->m_views.size() == 1) {
+        KoApplication* app = \
qobject_cast<KoApplication*>(KApplication::kApplication()); +        if (0 != app) {
+            app->documentOpened('/'+objectName());
+        }
+    }
 }
 
 void KoDocument::removeView(KoView *view)
 {
     d->m_views.removeAll(view);
+
+    if (d->m_views.isEmpty()) {
+        KoApplication* app = \
qobject_cast<KoApplication*>(KApplication::kApplication()); +        if (0 != app) {
+            app->documentClosed('/'+objectName());
+        }
+    }
 }
 
 QList<KoView*> KoDocument::views() const



_______________________________________________
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