summaryrefslogtreecommitdiffstats
path: root/kuickshow/src/filewidget.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'kuickshow/src/filewidget.cpp')
-rw-r--r--kuickshow/src/filewidget.cpp464
1 files changed, 464 insertions, 0 deletions
diff --git a/kuickshow/src/filewidget.cpp b/kuickshow/src/filewidget.cpp
new file mode 100644
index 00000000..d4b99f0a
--- /dev/null
+++ b/kuickshow/src/filewidget.cpp
@@ -0,0 +1,464 @@
+/* This file is part of the KDE project
+ Copyright (C) 1998-2003 Carsten Pfeiffer <pfeiffer@kde.org>
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public
+ License as published by the Free Software Foundation, version 2.
+
+ 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; see the file COPYING. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#include <qkeycode.h>
+
+#include <kdeversion.h>
+#include <kglobal.h>
+#include <kglobalsettings.h>
+#include <klocale.h>
+#include <kpopupmenu.h>
+#include <kpropertiesdialog.h>
+#include <kurlcompletion.h>
+
+#include "filefinder.h"
+#include "filewidget.h"
+#include "kuickdata.h"
+#include "kuickshow.h"
+
+#ifdef KeyPress
+#undef KeyPress
+#endif
+
+FileWidget::FileWidget( const KURL& url, QWidget *parent, const char *name )
+ : KDirOperator( url, parent, name ),
+ m_validCompletion( false ),
+ m_fileFinder( 0L )
+{
+ setEnableDirHighlighting( true );
+
+#if KDE_VERSION >= 310
+ setViewConfig( KGlobal::config(), "Filebrowser" );
+#endif
+ readConfig( KGlobal::config(), "Filebrowser" );
+ setView( KFile::Default );
+
+ // setOnlyDoubleClickSelectsFiles( true );
+ reloadConfiguration();
+
+ completionObject()->setCompletionMode( KGlobalSettings::CompletionAuto );
+ dirCompletionObject()->setCompletionMode( KGlobalSettings::CompletionAuto);
+
+ slotViewChanged();
+ connect( this, SIGNAL( viewChanged( KFileView * )),
+ SLOT( slotViewChanged() ));
+
+ connect( dirLister(), SIGNAL( clear() ), SLOT( slotItemsCleared() ));
+ connect( dirLister(), SIGNAL( deleteItem( KFileItem * ) ),
+ SLOT( slotItemDeleted( KFileItem *) ));
+
+ connect( this, SIGNAL( fileHighlighted( const KFileItem * )),
+ SLOT( slotHighlighted( const KFileItem * )));
+
+ connect( this, SIGNAL(urlEntered(const KURL&)),
+ SLOT( slotURLEntered( const KURL& )));
+
+ // should actually be KDirOperator's job!
+ connect( this, SIGNAL( finishedLoading() ), SLOT( slotFinishedLoading() ));
+}
+
+FileWidget::~FileWidget()
+{
+ delete m_fileFinder;
+}
+
+void FileWidget::initActions()
+{
+ int index = 0;
+ KActionCollection *coll = actionCollection();
+ KActionSeparator *sep = new KActionSeparator( coll, "kuicksep" );
+ KActionMenu *menu = static_cast<KActionMenu*>( coll->action("popupMenu") );
+
+ menu->insert( coll->action("kuick_showInOtherWindow"), index++ );
+ menu->insert( coll->action("kuick_showInSameWindow"), index++ );
+ menu->insert( coll->action("kuick_showFullscreen"), index++ );
+ menu->insert( sep, index++ );
+
+ // support for older kdelibs, remove somewhen...
+ if ( coll->action("kuick_delete") )
+ menu->insert( coll->action("kuick_delete"), 9 );
+
+ // properties dialog is now in kfile, but not at the right position,
+ // so we move it to the real bottom
+ menu->remove( coll->action( "properties" ) );
+
+ QPopupMenu *pMenu = menu->popupMenu();
+ int lastItemId = pMenu->idAt( pMenu->count() - 1 );
+ QMenuItem *mItem = pMenu->findItem( lastItemId );
+ if ( mItem && !mItem->isSeparator() )
+ menu->insert( sep );
+
+ // those at the bottom
+ menu->insert( coll->action("kuick_print") );
+ menu->insert( sep );
+ menu->insert( coll->action("properties") );
+}
+
+void FileWidget::reloadConfiguration()
+{
+ if ( kdata->fileFilter != nameFilter() ) {
+ // At first, our list must have folders
+ QStringList mimes;
+ mimes.append("inode/directory");
+
+ // Then, all the images!
+ KMimeType::List l = KMimeType::allMimeTypes();
+ for (KMimeType::List::iterator it = l.begin(); it != l.end(); ++it)
+ if ((*it)->name().startsWith( "image/" ))
+ mimes.append( (*it)->name() );
+
+ // Ok, show what we've done
+ setMimeFilter (mimes);
+ updateDir();
+ }
+}
+
+bool FileWidget::hasFiles() const
+{
+ return (numFiles() > 0);
+}
+
+void FileWidget::activatedMenu( const KFileItem *item, const QPoint& pos )
+{
+ bool image = isImage( item );
+ actionCollection()->action("kuick_showInSameWindow")->setEnabled( image );
+ actionCollection()->action("kuick_showInOtherWindow")->setEnabled( image );
+ actionCollection()->action("kuick_showFullscreen")->setEnabled( image );
+ actionCollection()->action("kuick_print")->setEnabled( image );
+ actionCollection()->action("properties")->setEnabled( item );
+
+ bool hasSelection = (item != 0L);
+ if ( actionCollection()->action("kuick_delete") )
+ actionCollection()->action("kuick_delete")->setEnabled( hasSelection );
+
+ KDirOperator::activatedMenu( item, pos );
+}
+
+void FileWidget::findCompletion( const QString& text )
+{
+ if ( text.at(0) == '/' || text.at(0) == '~' ||
+ text.find('/') != -1 ) {
+ QString t = m_fileFinder->completion()->makeCompletion( text );
+
+ if (m_fileFinder->completionMode() == KGlobalSettings::CompletionPopup ||
+ m_fileFinder->completionMode() == KGlobalSettings::CompletionPopupAuto)
+ m_fileFinder->setCompletedItems(
+ m_fileFinder->completion()->allMatches() );
+ else
+ if ( !t.isNull() )
+ m_fileFinder->setCompletedText( t );
+
+ return;
+ }
+
+ QString file = makeDirCompletion( text );
+ if ( file.isNull() )
+ file = makeCompletion( text );
+
+ m_validCompletion = !file.isNull();
+
+ if ( m_validCompletion )
+ KDirOperator::setCurrentItem( file );
+}
+
+bool FileWidget::eventFilter( QObject *o, QEvent *e )
+{
+ if ( e->type() == QEvent::KeyPress ) {
+ QKeyEvent *k = static_cast<QKeyEvent*>( e );
+
+ if ( (k->state() & (ControlButton | AltButton)) == 0 ) {
+ int key = k->key();
+ if ( actionCollection()->action("delete")->shortcut().contains( key ) )
+ {
+ k->accept();
+ KFileItem *item = getCurrentItem( false );
+ if ( item ) {
+ KFileItemList list;
+ list.append( item );
+ del( list, (k->state() & ShiftButton) == 0 );
+ }
+ return true;
+ }
+
+ const QString& text = k->text();
+ if ( !text.isEmpty() && text.unicode()->isPrint() ) {
+ k->accept();
+
+ if ( !m_fileFinder ) {
+ m_fileFinder = new FileFinder( this, "file finder" );
+ connect( m_fileFinder, SIGNAL( completion(const QString&)),
+ SLOT( findCompletion( const QString& )));
+ connect( m_fileFinder,
+ SIGNAL( enterDir( const QString& ) ),
+ SLOT( slotReturnPressed( const QString& )));
+ m_fileFinder->move( width() - m_fileFinder->width(),
+ height() - m_fileFinder->height() );
+ }
+
+ bool first = m_fileFinder->isHidden();
+
+ m_fileFinder->setText( text );
+ m_fileFinder->raise();
+ m_fileFinder->show();
+ m_fileFinder->setFocus();
+ if ( first )
+ findCompletion( text );
+
+ return true;
+ }
+ }
+
+ k->ignore();
+ }
+ return KDirOperator::eventFilter( o, e );
+}
+
+
+// KIO::NetAccess::stat() does NOT give us the right mimetype, while
+// KIO::NetAccess::mimetype() does. So we have this hacklet to tell
+// showImage that the KFileItem is really an image.
+#define IS_IMAGE 5
+#define MY_TYPE 55
+
+bool FileWidget::isImage( const KFileItem *item )
+{
+// return item && !item->isDir();
+ if ( item )
+ {
+ return item->isReadable() && item->mimetype().startsWith( "image/") ||
+ item->extraData( (void*) MY_TYPE ) == (void*) IS_IMAGE;
+ }
+ return false;
+}
+
+void FileWidget::setImage( KFileItem& item, bool enable )
+{
+ if ( enable )
+ item.setExtraData( (void*) MY_TYPE, (void*) IS_IMAGE );
+ else
+ item.removeExtraData( (void*) MY_TYPE );
+}
+
+KFileItem * FileWidget::gotoFirstImage()
+{
+ KFileItemListIterator it( *(fileView()->items()) );
+
+ while ( it.current() ) {
+ if ( isImage( it.current() ) ) {
+ setCurrentItem( it.current() );
+ return it.current();
+ }
+ ++it;
+ }
+
+ return 0L;
+}
+
+KFileItem * FileWidget::gotoLastImage()
+{
+ KFileItemListIterator it( *(fileView()->items()) );
+ it.toLast();
+
+ while ( it.current() ) {
+ if ( isImage( it.current() ) ) {
+ setCurrentItem( it.current() );
+ return it.current();
+ }
+ --it;
+ }
+
+ return 0L;
+}
+
+KFileItem * FileWidget::getNext( bool go )
+{
+ KFileItem *item = getItem( Next, true );
+ if ( item ) {
+ if ( go )
+ setCurrentItem( item );
+ return item;
+ }
+
+ return 0L;
+}
+
+KFileItem * FileWidget::getPrevious( bool go )
+{
+ KFileItem *item = getItem( Previous, true );
+ if ( item ) {
+ if ( go )
+ setCurrentItem( item );
+ return item;
+ }
+
+ return 0L;
+}
+
+// returns 0L when there is no previous/next item/image
+// this sucks! Use KFileView::currentFileItem() when implemented
+KFileItem * FileWidget::getItem( WhichItem which, bool onlyImage ) const
+{
+ KFileItemListIterator it( *(fileView()->items()) );
+
+ while ( it.current() ) { // find the iterator to the current item
+ if ( it.current()->url() == m_currentURL )
+ break;
+
+ ++it;
+ }
+
+ if ( it.current() ) {
+ switch ( which ) {
+ case Previous: {
+ --it;
+ while ( it.current() ) {
+ if ( isImage( it.current() ) || !onlyImage )
+ return it.current();
+ --it;
+ }
+ return 0L; // no previous item / image
+ }
+
+ case Next: {
+ ++it;
+ while ( it.current() ) {
+ if ( isImage( it.current() ) || !onlyImage )
+ return it.current();
+ ++it;
+ }
+ return 0L; // no further item / image
+ }
+
+ case Current:
+ default:
+ return it.current();
+ }
+ }
+
+ return 0L;
+}
+
+void FileWidget::slotViewChanged()
+{
+ fileView()->widget()->installEventFilter( this );
+}
+
+void FileWidget::slotItemsCleared()
+{
+ m_currentURL = QString::null;
+}
+
+void FileWidget::slotItemDeleted( KFileItem *item )
+{
+ KFileItem *current = getCurrentItem( false );
+ if ( item != current ) {
+ return; // all ok, we already have a new current item
+ }
+
+ KFileItem *next = getNext();
+ if ( !next )
+ next = getPrevious();
+
+ if ( next )
+ m_currentURL = next->url().url();
+}
+
+void FileWidget::slotHighlighted( const KFileItem *item )
+{
+ m_currentURL = item->url().url();
+}
+
+void FileWidget::slotReturnPressed( const QString& t )
+{
+ // we need a / at the end, otherwise replacedPath() will cut off the dir,
+ // assuming it is a filename
+ QString text = t;
+ if ( text.at( text.length()-1 ) != '/' )
+ text += '/';
+
+ if ( text.at(0) == '/' || text.at(0) == '~' ) {
+ QString dir = m_fileFinder->completion()->replacedPath( text );
+
+ KURL url;
+ url.setPath( dir );
+ setURL( url, true );
+ }
+
+ else if ( text.find('/') != (int) text.length() -1 ) { // relative path
+ QString dir = m_fileFinder->completion()->replacedPath( text );
+ KURL u( url(), dir );
+ setURL( u, true );
+ }
+
+ else if ( m_validCompletion ) {
+ KFileItem *item = getCurrentItem( true );
+
+ if ( item ) {
+ if ( item->isDir() )
+ setURL( item->url(), true );
+ else
+ emit fileSelected( item );
+ }
+ }
+}
+
+void FileWidget::setCurrentItem( const KFileItem *item )
+{
+ if ( item ) {
+ fileView()->setCurrentItem( item );
+ fileView()->ensureItemVisible( item );
+ }
+}
+
+void FileWidget::setInitialItem( const QString& filename )
+{
+ m_initialName = filename;
+}
+
+void FileWidget::slotURLEntered( const KURL& url )
+{
+ if ( m_fileFinder )
+ m_fileFinder->completion()->setDir( url.path() );
+}
+
+void FileWidget::slotFinishedLoading()
+{
+ KFileItem *current = getCurrentItem( false );
+ if ( !m_initialName.isEmpty() )
+ setCurrentItem( m_initialName );
+ else if ( !current )
+ setCurrentItem( view()->items()->getFirst() );
+
+ m_initialName = QString::null;
+ emit finished();
+}
+
+QSize FileWidget::sizeHint() const
+{
+ return QSize( 300, 300 );
+}
+
+void FileWidget::resizeEvent( QResizeEvent *e )
+{
+ KDirOperator::resizeEvent( e );
+ if ( m_fileFinder )
+ m_fileFinder->move( width() - m_fileFinder->width(),
+ height() - m_fileFinder->height() );
+}
+
+#include "filewidget.moc"