summaryrefslogtreecommitdiffstats
path: root/kview/modules/presenter/kviewpresenter.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'kview/modules/presenter/kviewpresenter.cpp')
-rw-r--r--kview/modules/presenter/kviewpresenter.cpp492
1 files changed, 492 insertions, 0 deletions
diff --git a/kview/modules/presenter/kviewpresenter.cpp b/kview/modules/presenter/kviewpresenter.cpp
new file mode 100644
index 00000000..bbc5e8eb
--- /dev/null
+++ b/kview/modules/presenter/kviewpresenter.cpp
@@ -0,0 +1,492 @@
+/* This file is part of the KDE project
+ Copyright (C) 2002 Matthias Kretz <kretz@kde.org>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License version 2
+ as published by the Free Software Foundation.
+
+ This program 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 General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+
+*/
+
+/* $Id$ */
+
+#include "kviewpresenter.h"
+#include "imagelistdialog.h"
+#include "imagelistitem.h"
+
+#include <qvbox.h>
+#include <qobjectlist.h>
+#include <qsignalslotimp.h>
+#include <qtimer.h>
+#include <qevent.h>
+#include <qdragobject.h>
+#include <qstringlist.h>
+
+#include <kpushbutton.h>
+#include <kapplication.h>
+#include <kaction.h>
+#include <klocale.h>
+#include <kgenericfactory.h>
+#include <kdebug.h>
+#include <kglobal.h>
+#include <kiconloader.h>
+#include <knuminput.h>
+#include <kfiledialog.h>
+#include <kimageio.h>
+#include <kimageviewer/viewer.h>
+#include <kimageviewer/canvas.h>
+#include <kio/netaccess.h>
+#include <kmessagebox.h>
+#include <ktempfile.h>
+#include <kurldrag.h>
+
+typedef KGenericFactory<KViewPresenter> KViewPresenterFactory;
+K_EXPORT_COMPONENT_FACTORY( kview_presenterplugin, KViewPresenterFactory( "kviewpresenterplugin" ) )
+
+KViewPresenter::KViewPresenter( QObject* parent, const char* name, const QStringList & )
+ : Plugin( parent, name )
+ , m_pImageList( new ImageListDialog() )
+ , m_paFileOpen( 0 )
+ , m_bDontAdd( false )
+ , m_pCurrentItem( 0 )
+ , m_pSlideshowTimer( new QTimer( this ) )
+{
+ kdDebug( 4630 ) << k_funcinfo << endl;
+ m_imagelist.setAutoDelete( true );
+
+ QObjectList * viewerList = parent->queryList( 0, "KImageViewer Part", false, false );
+ m_pViewer = static_cast<KImageViewer::Viewer *>( viewerList->getFirst() );
+ delete viewerList;
+ if( m_pViewer )
+ {
+ ( void ) new KAction( i18n( "&Image List..." ), 0, 0,
+ this, SLOT( slotImageList() ),
+ actionCollection(), "plugin_presenter_imageList" );
+ m_paSlideshow = new KToggleAction( i18n( "Start &Slideshow" ), Key_S, actionCollection(), "plugin_presenter_slideshow" );
+ ( void ) new KAction( i18n( "&Previous Image in List" ), "previous", ALT+Key_Left,
+ this, SLOT( prev() ),
+ actionCollection(), "plugin_presenter_prev" );
+ ( void ) new KAction( i18n( "&Next Image in List" ), "next", ALT+Key_Right,
+ this, SLOT( next() ),
+ actionCollection(), "plugin_presenter_next" );
+
+ connect( m_paSlideshow, SIGNAL( toggled( bool ) ), m_pImageList->m_pSlideshow, SLOT( setOn( bool ) ) );
+ connect( m_pImageList->m_pSlideshow, SIGNAL( toggled( bool ) ), m_paSlideshow, SLOT( setChecked( bool ) ) );
+
+ // search for file_open action
+ KXMLGUIClient * parentClient = static_cast<KXMLGUIClient*>( parent->qt_cast( "KXMLGUIClient" ) );
+ if( parentClient )
+ {
+ m_paFileOpen = parentClient->actionCollection()->action( "file_open" );
+ m_paFileClose = parentClient->actionCollection()->action( "file_close" );
+ }
+ if( m_paFileClose )
+ connect( m_paFileClose, SIGNAL( activated() ), this, SLOT( slotClose() ) );
+ if( m_paFileOpen )
+ {
+ disconnect( m_paFileOpen, SIGNAL( activated() ), parent, SLOT( slotOpenFile() ) );
+ connect( m_paFileOpen, SIGNAL( activated() ), this, SLOT( slotOpenFiles() ) );
+ }
+ else
+ {
+ (void) new KAction( i18n( "Open &Multiple Files..." ), "queue", CTRL+SHIFT+Key_O,
+ this, SLOT( slotOpenFiles() ),
+ actionCollection(), "plugin_presenter_openFiles" );
+ }
+ connect( m_pViewer, SIGNAL( imageOpened( const KURL & ) ),
+ SLOT( slotImageOpened( const KURL & ) ) );
+ }
+ else
+ kdWarning( 4630 ) << "no KImageViewer interface found - the presenter plugin won't work" << endl;
+
+ //( void )new KViewPresenterConfModule( this );
+
+ connect( m_pImageList->m_pListView, SIGNAL( executed( QListViewItem* ) ),
+ this, SLOT( changeItem( QListViewItem* ) ) );
+ connect( m_pImageList->m_pPrevious, SIGNAL( clicked() ),
+ this, SLOT( prev() ) );
+ connect( m_pImageList->m_pNext, SIGNAL( clicked() ),
+ this, SLOT( next() ) );
+ connect( m_pImageList->m_pListView, SIGNAL( spacePressed( QListViewItem* ) ),
+ this, SLOT( changeItem( QListViewItem* ) ) );
+ connect( m_pImageList->m_pListView, SIGNAL( returnPressed( QListViewItem* ) ),
+ this, SLOT( changeItem( QListViewItem* ) ) );
+ connect( m_pImageList->m_pSlideshow, SIGNAL( toggled( bool ) ),
+ this, SLOT( slideshow( bool ) ) );
+ connect( m_pImageList->m_pInterval, SIGNAL( valueChanged( int ) ),
+ this, SLOT( setSlideshowInterval( int ) ) );
+ connect( m_pImageList->m_pShuffle, SIGNAL( clicked() ),
+ this, SLOT( shuffle() ) );
+ connect( m_pImageList->m_pLoad, SIGNAL( clicked() ),
+ this, SLOT( loadList() ) );
+ connect( m_pImageList->m_pSave, SIGNAL( clicked() ),
+ this, SLOT( saveList() ) );
+ connect( m_pImageList->m_pCloseAll, SIGNAL( clicked() ),
+ this, SLOT( closeAll() ) );
+
+ // allow drop on the dialog
+ m_pImageList->installEventFilter( this );
+ m_pImageList->m_pListView->installEventFilter( this );
+ m_pImageList->m_pListView->viewport()->installEventFilter( this );
+
+ // grab drops on the main view
+ m_pViewer->widget()->installEventFilter( this );
+
+ connect( m_pSlideshowTimer, SIGNAL( timeout() ),
+ this, SLOT( next() ) );
+}
+
+KViewPresenter::~KViewPresenter()
+{
+ kdDebug( 4630 ) << k_funcinfo << endl;
+ if( m_paFileOpen )
+ {
+ disconnect( m_paFileOpen, SIGNAL( activated() ), this, SLOT( slotOpenFiles() ) );
+ // If the parent() doesn't exist we either leave the "File Open" action
+ // in an unusable state or KView was just shutting down and therefor we
+ // can ignore this. I've only seen the second one happening and to get
+ // rid of the QObject::connect warning we do the parent() check.
+ if( parent() )
+ connect( m_paFileOpen, SIGNAL( activated() ), parent(), SLOT( slotOpenFile() ) );
+ }
+}
+
+bool KViewPresenter::eventFilter( QObject *obj, QEvent *ev )
+{
+ if( obj == m_pImageList || obj == m_pImageList->m_pListView || obj == m_pImageList->m_pListView->viewport() || obj == m_pViewer->widget() )
+ {
+ switch( ev->type() )
+ {
+ case QEvent::DragEnter:
+ case QEvent::DragMove:
+ {
+ // drag enter event in the image list
+ //kdDebug( 4630 ) << "DragEnterEvent in the image list: " << obj->className() << endl;
+ QDragEnterEvent * e = static_cast<QDragEnterEvent*>( ev );
+ //for( int i = 0; e->format( i ); ++i )
+ //kdDebug( 4630 ) << " - " << e->format( i ) << endl;
+ if( KURLDrag::canDecode( e ) )// || QImageDrag::canDecode( e ) )
+ {
+ e->accept();
+ return true;
+ }
+ }
+ case QEvent::Drop:
+ {
+ // drop event in the image list
+ kdDebug( 4630 ) << "DropEvent in the image list: " << obj->className() << endl;
+ QDropEvent * e = static_cast<QDropEvent*>( ev );
+ QStringList l;
+ //QImage image;
+ if( KURLDrag::decodeToUnicodeUris( e, l ) )
+ {
+ for( QStringList::const_iterator it = l.begin(); it != l.end(); ++it )
+ {
+ ImageInfo * info = new ImageInfo( KURL( *it ) );
+ if( ! m_imagelist.contains( info ) )
+ {
+ m_imagelist.inSort( info );
+ ( void )new ImageListItem( m_pImageList->m_pListView, KURL( *it ) );
+ }
+ else
+ delete info;
+ }
+ return true;
+ }
+ //else if( QImageDrag::decode( e, image ) )
+ //newImage( image );
+ }
+ default: // do nothing
+ break;
+ }
+ }
+ return KParts::Plugin::eventFilter( obj, ev );
+}
+
+void KViewPresenter::slotImageOpened( const KURL & url )
+{
+ kdDebug( 4630 ) << k_funcinfo << endl;
+ if( ! m_bDontAdd )
+ {
+ kdDebug( 4630 ) << k_funcinfo << "imagelist:" << endl;
+ ImageInfo * info = new ImageInfo( url );
+ if( ! m_imagelist.contains( info ) )
+ {
+ m_imagelist.inSort( info );
+ QListViewItem * item = new ImageListItem( m_pImageList->m_pListView, url );
+ makeCurrent( item );
+ }
+ else
+ delete info;
+ }
+}
+
+void KViewPresenter::slotImageList()
+{
+ kdDebug( 4630 ) << k_funcinfo << endl;
+ m_pImageList->show();
+}
+
+void KViewPresenter::slotOpenFiles()
+{
+ kdDebug( 4630 ) << k_funcinfo << endl;
+ KURL::List urls = KFileDialog::getOpenURLs( ":load_image", KImageIO::pattern( KImageIO::Reading ), m_pViewer->widget() );
+
+ if( urls.isEmpty() )
+ return;
+
+ KURL::List::Iterator it = urls.begin();
+ m_pViewer->openURL( *it );
+ for( ++it; it != urls.end(); ++it )
+ {
+ ImageInfo * info = new ImageInfo( *it );
+ if( ! m_imagelist.contains( info ) )
+ {
+ m_imagelist.inSort( info );
+ ( void )new ImageListItem( m_pImageList->m_pListView, *it );
+ }
+ else
+ delete info;
+ }
+}
+
+void KViewPresenter::slotClose()
+{
+ QListViewItem * next = m_pCurrentItem->itemBelow() ? m_pCurrentItem->itemBelow() : m_pImageList->m_pListView->firstChild();
+ if( next == m_pCurrentItem )
+ next = 0;
+
+ ImageInfo info( m_pCurrentItem->url() );
+ m_imagelist.remove( &info );
+ delete m_pCurrentItem;
+ m_pCurrentItem = 0;
+
+ if( next )
+ changeItem( next );
+}
+
+void KViewPresenter::changeItem( QListViewItem * qitem )
+{
+ kdDebug( 4630 ) << k_funcinfo << endl;
+ if( qitem->rtti() == 48294 )
+ {
+ ImageListItem * item = static_cast<ImageListItem*>( qitem );
+ if( ! item->url().isEmpty() )
+ {
+ if( item->url().isLocalFile() && ! QFile::exists( item->url().path() ) )
+ {
+ kdDebug( 4630 ) << "file doesn't exist. removed." << endl;
+ ImageInfo info( item->url() );
+ m_imagelist.remove( &info );
+ if( m_pCurrentItem == item )
+ {
+ QListViewItem * next = m_pCurrentItem->itemBelow() ? m_pCurrentItem->itemBelow() : m_pImageList->m_pListView->firstChild();
+ if( next->rtti() != 48294 )
+ kdWarning( 4630 ) << "unknown ListView item" << endl;
+ else
+ m_pCurrentItem = static_cast<ImageListItem*>( next );
+
+ if( m_pCurrentItem == item )
+ m_pCurrentItem = 0; // don't create a dangling pointer
+ delete item;
+ if( m_pCurrentItem )
+ changeItem( m_pCurrentItem );
+ }
+ else
+ {
+ delete item;
+ next();
+ }
+ return;
+ }
+ kdDebug( 4630 ) << "got url" << endl;
+ makeCurrent( qitem );
+
+ bool dontadd = m_bDontAdd;
+ m_bDontAdd = true;
+ m_pViewer->openURL( item->url() );
+ m_bDontAdd = dontadd;
+ }
+ else
+ kdWarning( 4630 ) << "got nothing" << endl;
+ }
+ else
+ kdWarning( 4630 ) << "unknown ListView item" << endl;
+}
+
+void KViewPresenter::prev()
+{
+ kdDebug( 4630 ) << k_funcinfo << endl;
+ if( m_pCurrentItem )
+ {
+ QListViewItem * prev = m_pCurrentItem->itemAbove() ? m_pCurrentItem->itemAbove() : m_pImageList->m_pListView->lastItem();
+ if( prev )
+ changeItem( prev );
+ }
+}
+
+void KViewPresenter::next()
+{
+ kdDebug( 4630 ) << k_funcinfo << endl;
+ if( m_pCurrentItem )
+ {
+ QListViewItem * next = m_pCurrentItem->itemBelow() ? m_pCurrentItem->itemBelow() : m_pImageList->m_pListView->firstChild();
+ if( next )
+ changeItem( next );
+ }
+}
+
+void KViewPresenter::makeCurrent( QListViewItem * item )
+{
+ if( m_pCurrentItem )
+ m_pCurrentItem->setPixmap( 0, QPixmap() );
+ if( item->rtti() != 48294 )
+ kdWarning( 4630 ) << "unknown ListView item" << endl;
+ else
+ {
+ m_pCurrentItem = static_cast<ImageListItem*>( item );
+ m_pCurrentItem->setPixmap( 0, KGlobal::iconLoader()->loadIcon( "1rightarrow", KIcon::Small ) );
+ m_pImageList->m_pListView->ensureItemVisible( m_pCurrentItem );
+ }
+}
+
+void KViewPresenter::slideshow( bool running )
+{
+ if( running )
+ {
+ m_pSlideshowTimer->start( m_pImageList->m_pInterval->value() );
+ actionCollection()->action( "plugin_presenter_slideshow" )->setText( i18n( "Stop &Slideshow" ) );
+ m_pImageList->m_pSlideshow->setText( i18n( "Stop &Slideshow" ) );
+ }
+ else
+ {
+ m_pSlideshowTimer->stop();
+ actionCollection()->action( "plugin_presenter_slideshow" )->setText( i18n( "Start &Slideshow" ) );
+ m_pImageList->m_pSlideshow->setText( i18n( "Start &Slideshow" ) );
+ }
+}
+
+void KViewPresenter::setSlideshowInterval( int msec )
+{
+ if( m_pSlideshowTimer->isActive() )
+ m_pSlideshowTimer->changeInterval( msec );
+}
+
+void KViewPresenter::shuffle()
+{
+ m_pImageList->noSort();
+ KListView * listview = m_pImageList->m_pListView;
+ QPtrList<QListViewItem> items;
+ for( QListViewItem * item = listview->firstChild(); item; item = listview->firstChild() )
+ {
+ items.append( item );
+ listview->takeItem( item );
+ }
+ while( ! items.isEmpty() )
+ listview->insertItem( items.take( KApplication::random() % items.count() ) );
+}
+
+void KViewPresenter::closeAll()
+{
+ m_imagelist.clear();
+ m_pImageList->m_pListView->clear();
+ m_pCurrentItem = 0;
+ if( m_pViewer->closeURL() )
+ m_pViewer->canvas()->clear();
+}
+
+void KViewPresenter::loadList()
+{
+ KURL url = KFileDialog::getOpenURL( ":load_list", QString::null, m_pImageList );
+ if( url.isEmpty() )
+ return;
+
+ QString tempfile;
+ if( ! KIO::NetAccess::download( url, tempfile, m_pViewer->widget() ) )
+ {
+ KMessageBox::error( m_pImageList, i18n( "Could not load\n%1" ).arg( url.prettyURL() ) );
+ return;
+ }
+ QFile file( tempfile );
+ if( file.open( IO_ReadOnly ) )
+ {
+ QTextStream t( &file );
+ if( t.readLine() == "[KView Image List]" )
+ {
+ //clear old image list
+ closeAll();
+
+ QStringList list;
+ if( ! t.eof() )
+ m_pViewer->openURL( KURL( t.readLine() ) );
+ while( ! t.eof() )
+ {
+ KURL url ( t.readLine() );
+ ImageInfo * info = new ImageInfo( url );
+ if( ! m_imagelist.contains( info ) )
+ {
+ m_imagelist.inSort( info );
+ ( void )new ImageListItem( m_pImageList->m_pListView, url );
+ }
+ else
+ delete info;
+ }
+ }
+ else
+ {
+ KMessageBox::error( m_pImageList, i18n( "Wrong format\n%1" ).arg( url.prettyURL() ) );
+ }
+ file.close();
+ }
+ KIO::NetAccess::removeTempFile( tempfile );
+}
+
+void KViewPresenter::saveList()
+{
+ KURL url = KFileDialog::getSaveURL( ":save_list", QString::null, m_pImageList );
+
+ if( url.isEmpty() )
+ return;
+
+ QString tempfile;
+ if( url.isLocalFile() )
+ tempfile = url.path();
+ else
+ {
+ KTempFile ktempf;
+ tempfile = ktempf.name();
+ }
+
+ QFile file( tempfile );
+ if( file.open( IO_WriteOnly ) )
+ {
+ QTextStream t( &file );
+ // write header
+ t << "[KView Image List]" << endl;
+ QListViewItem * item = m_pImageList->m_pListView->firstChild();
+ while( item )
+ {
+ if( item->rtti() == 48294 )
+ t << static_cast<ImageListItem*>( item )->url().url() << endl;
+ item = item->itemBelow();
+ }
+ file.close();
+
+ if( ! url.isLocalFile() )
+ {
+ KIO::NetAccess::upload( tempfile, url, m_pViewer->widget() );
+ KIO::NetAccess::removeTempFile( tempfile );
+ }
+ }
+}
+
+// vim:sw=4:ts=4
+#include "kviewpresenter.moc"