You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
464 lines
12 KiB
464 lines
12 KiB
/* 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 <tqkeycode.h> |
|
|
|
#include <tdeversion.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, TQWidget *parent, const char *name ) |
|
: KDirOperator( url, parent, name ), |
|
m_validCompletion( false ), |
|
m_fileFinder( 0L ) |
|
{ |
|
setEnableDirHighlighting( true ); |
|
|
|
#if TDE_VERSION >= 310 |
|
setViewConfig( TDEGlobal::config(), "Filebrowser" ); |
|
#endif |
|
readConfig( TDEGlobal::config(), "Filebrowser" ); |
|
setView( KFile::Default ); |
|
|
|
// setOnlyDoubleClickSelectsFiles( true ); |
|
reloadConfiguration(); |
|
|
|
completionObject()->setCompletionMode( TDEGlobalSettings::CompletionAuto ); |
|
dirCompletionObject()->setCompletionMode( TDEGlobalSettings::CompletionAuto); |
|
|
|
slotViewChanged(); |
|
connect( this, TQT_SIGNAL( viewChanged( KFileView * )), |
|
TQT_SLOT( slotViewChanged() )); |
|
|
|
connect( dirLister(), TQT_SIGNAL( clear() ), TQT_SLOT( slotItemsCleared() )); |
|
connect( dirLister(), TQT_SIGNAL( deleteItem( KFileItem * ) ), |
|
TQT_SLOT( slotItemDeleted( KFileItem *) )); |
|
|
|
connect( this, TQT_SIGNAL( fileHighlighted( const KFileItem * )), |
|
TQT_SLOT( slotHighlighted( const KFileItem * ))); |
|
|
|
connect( this, TQT_SIGNAL(urlEntered(const KURL&)), |
|
TQT_SLOT( slotURLEntered( const KURL& ))); |
|
|
|
// should actually be KDirOperator's job! |
|
connect( this, TQT_SIGNAL( finishedLoading() ), TQT_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 tdelibs, remove somewhen... |
|
if ( coll->action("kuick_delete") ) |
|
menu->insert( coll->action("kuick_delete"), 9 ); |
|
|
|
// properties dialog is now in tdefile, but not at the right position, |
|
// so we move it to the real bottom |
|
menu->remove( coll->action( "properties" ) ); |
|
|
|
TQPopupMenu *pMenu = menu->popupMenu(); |
|
int lastItemId = pMenu->idAt( pMenu->count() - 1 ); |
|
TQMenuItem *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 |
|
TQStringList 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 TQPoint& 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 TQString& text ) |
|
{ |
|
if ( text.at(0) == '/' || text.at(0) == '~' || |
|
text.find('/') != -1 ) { |
|
TQString t = m_fileFinder->completion()->makeCompletion( text ); |
|
|
|
if (m_fileFinder->completionMode() == TDEGlobalSettings::CompletionPopup || |
|
m_fileFinder->completionMode() == TDEGlobalSettings::CompletionPopupAuto) |
|
m_fileFinder->setCompletedItems( |
|
m_fileFinder->completion()->allMatches() ); |
|
else |
|
if ( !t.isNull() ) |
|
m_fileFinder->setCompletedText( t ); |
|
|
|
return; |
|
} |
|
|
|
TQString file = makeDirCompletion( text ); |
|
if ( file.isNull() ) |
|
file = makeCompletion( text ); |
|
|
|
m_validCompletion = !file.isNull(); |
|
|
|
if ( m_validCompletion ) |
|
KDirOperator::setCurrentItem( file ); |
|
} |
|
|
|
bool FileWidget::eventFilter( TQObject *o, TQEvent *e ) |
|
{ |
|
if ( e->type() == TQEvent::KeyPress ) { |
|
TQKeyEvent *k = TQT_TQKEYEVENT( 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 TQString& text = k->text(); |
|
if ( !text.isEmpty() && text.unicode()->isPrint() ) { |
|
k->accept(); |
|
|
|
if ( !m_fileFinder ) { |
|
m_fileFinder = new FileFinder( this, "file finder" ); |
|
connect( m_fileFinder, TQT_SIGNAL( completion(const TQString&)), |
|
TQT_SLOT( findCompletion( const TQString& ))); |
|
connect( m_fileFinder, |
|
TQT_SIGNAL( enterDir( const TQString& ) ), |
|
TQT_SLOT( slotReturnPressed( const TQString& ))); |
|
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 ); |
|
} |
|
|
|
|
|
// TDEIO::NetAccess::stat() does NOT give us the right mimetype, while |
|
// TDEIO::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 = TQString(); |
|
} |
|
|
|
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 TQString& t ) |
|
{ |
|
// we need a / at the end, otherwise replacedPath() will cut off the dir, |
|
// assuming it is a filename |
|
TQString text = t; |
|
if ( text.at( text.length()-1 ) != '/' ) |
|
text += '/'; |
|
|
|
if ( text.at(0) == '/' || text.at(0) == '~' ) { |
|
TQString dir = m_fileFinder->completion()->replacedPath( text ); |
|
|
|
KURL url; |
|
url.setPath( dir ); |
|
setURL( url, true ); |
|
} |
|
|
|
else if ( text.find('/') != (int) text.length() -1 ) { // relative path |
|
TQString 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 TQString& 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 = TQString(); |
|
emit finished(); |
|
} |
|
|
|
TQSize FileWidget::sizeHint() const |
|
{ |
|
return TQSize( 300, 300 ); |
|
} |
|
|
|
void FileWidget::resizeEvent( TQResizeEvent *e ) |
|
{ |
|
KDirOperator::resizeEvent( e ); |
|
if ( m_fileFinder ) |
|
m_fileFinder->move( width() - m_fileFinder->width(), |
|
height() - m_fileFinder->height() ); |
|
} |
|
|
|
#include "filewidget.moc"
|
|
|