|
|
// vim: set tabstop=4 shiftwidth=4 noexpandtab:
|
|
|
/*
|
|
|
Gwenview - A simple image viewer for TDE
|
|
|
Copyright 2000-2004 Aur<75>ien G<>eau
|
|
|
|
|
|
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; either version 2
|
|
|
of the License, or (at your option) any later version.
|
|
|
|
|
|
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.
|
|
|
|
|
|
*/
|
|
|
|
|
|
// TQt
|
|
|
#include <tqcheckbox.h>
|
|
|
#include <tqdatetimeedit.h>
|
|
|
#include <tqhbox.h>
|
|
|
#include <tqlayout.h>
|
|
|
#include <tqpopupmenu.h>
|
|
|
#include <tqpushbutton.h>
|
|
|
#include <tqtooltip.h>
|
|
|
#include <tqwidgetstack.h>
|
|
|
|
|
|
// KDE
|
|
|
#include <tdeaction.h>
|
|
|
#include <tdeapplication.h>
|
|
|
#include <kcombobox.h>
|
|
|
#include <kdebug.h>
|
|
|
#include <kdirlister.h>
|
|
|
#include <kicontheme.h>
|
|
|
#include <kiconeffect.h>
|
|
|
#include <kiconloader.h>
|
|
|
#include <kimageio.h>
|
|
|
#include <tdelistview.h>
|
|
|
#include <tdelocale.h>
|
|
|
#include <kpropertiesdialog.h>
|
|
|
#include <kprotocolinfo.h>
|
|
|
#include <kstdaction.h>
|
|
|
#include <tdetoolbar.h>
|
|
|
#include <tdetoolbarlabelaction.h>
|
|
|
#include <kurldrag.h>
|
|
|
#include <tdeio/job.h>
|
|
|
#include <tdeio/file.h>
|
|
|
|
|
|
// Local
|
|
|
#include "archive.h"
|
|
|
#include "cache.h"
|
|
|
#include "clicklineedit.h"
|
|
|
#include "cursortracker.h"
|
|
|
#include "filedetailview.h"
|
|
|
#include "fileoperation.h"
|
|
|
#include "filethumbnailview.h"
|
|
|
#include "filterbar.h"
|
|
|
#include "imageloader.h"
|
|
|
#include "mimetypeutils.h"
|
|
|
#include "timeutils.h"
|
|
|
#include "thumbnailsize.h"
|
|
|
#include "fileviewconfig.h"
|
|
|
#include "miscconfig.h"
|
|
|
|
|
|
#include "fileviewcontroller.moc"
|
|
|
namespace Gwenview {
|
|
|
|
|
|
#undef ENABLE_LOG
|
|
|
#undef LOG
|
|
|
//#define ENABLE_LOG
|
|
|
#ifdef ENABLE_LOG
|
|
|
#define LOG(x) kdDebug() << k_funcinfo << x << endl
|
|
|
#else
|
|
|
#define LOG(x) ;
|
|
|
#endif
|
|
|
|
|
|
static const int SLIDER_RESOLUTION=4;
|
|
|
|
|
|
|
|
|
//-----------------------------------------------------------------------
|
|
|
//
|
|
|
// internal class which allows dynamically turning off visual error reporting
|
|
|
//
|
|
|
//-----------------------------------------------------------------------
|
|
|
class DirLister : public KDirLister {
|
|
|
public:
|
|
|
DirLister()
|
|
|
: KDirLister()
|
|
|
, mError(false)
|
|
|
, mCheck(false) {}
|
|
|
|
|
|
virtual bool validURL(const KURL& url) const {
|
|
|
if( !url.isValid()) mError = true;
|
|
|
if( mCheck ) return KDirLister::validURL( url );
|
|
|
return url.isValid();
|
|
|
}
|
|
|
|
|
|
virtual void handleError(TDEIO::Job* job) {
|
|
|
mError = true;
|
|
|
if(mCheck) KDirLister::handleError( job );
|
|
|
};
|
|
|
|
|
|
bool error() const {
|
|
|
return mError;
|
|
|
}
|
|
|
|
|
|
void clearError() {
|
|
|
mError = false;
|
|
|
}
|
|
|
|
|
|
void setCheck(bool c) {
|
|
|
mCheck = c;
|
|
|
}
|
|
|
|
|
|
void setDateFilter(const TQDate& from, const TQDate& to) {
|
|
|
mFromDate = from;
|
|
|
mToDate =to;
|
|
|
}
|
|
|
|
|
|
virtual bool itemMatchFilters(const KFileItem* item) const {
|
|
|
if (!matchesFilter(item)) return false;
|
|
|
return matchesMimeFilter(item);
|
|
|
}
|
|
|
|
|
|
public:
|
|
|
virtual bool matchesMimeFilter(const KFileItem* item) const {
|
|
|
// Do mime filtering ourself because we use startsWith instead of ==
|
|
|
TQStringList lst = mimeFilters();
|
|
|
TQStringList::Iterator it = lst.begin(), end = lst.end();
|
|
|
bool result = false;
|
|
|
TQString type = item->mimetype();
|
|
|
for (; it!=end; ++it) {
|
|
|
if (type.startsWith(*it)) {
|
|
|
result = true;
|
|
|
break;
|
|
|
}
|
|
|
}
|
|
|
if (!result) return false;
|
|
|
|
|
|
if (item->isDir() || Archive::fileItemIsArchive(item)) {
|
|
|
// Do not filter out dirs or archives
|
|
|
return true;
|
|
|
}
|
|
|
|
|
|
if (!mFromDate.isValid() && !mToDate.isValid()) return result;
|
|
|
|
|
|
// Convert item time to a TQDate
|
|
|
time_t time=TimeUtils::getTime(item);
|
|
|
TQDateTime dateTime;
|
|
|
dateTime.setTime_t(time);
|
|
|
TQDate date=dateTime.date();
|
|
|
|
|
|
if (mFromDate.isValid() && date < mFromDate) return false;
|
|
|
if (mToDate.isValid() && date > mToDate) return false;
|
|
|
return true;
|
|
|
}
|
|
|
|
|
|
private:
|
|
|
mutable bool mError;
|
|
|
bool mCheck;
|
|
|
TQDate mFromDate;
|
|
|
TQDate mToDate;
|
|
|
};
|
|
|
|
|
|
|
|
|
//-----------------------------------------------------------------------
|
|
|
//
|
|
|
// FileViewController::Private
|
|
|
//
|
|
|
//-----------------------------------------------------------------------
|
|
|
class FileViewController::Private {
|
|
|
public:
|
|
|
~Private() {
|
|
|
delete mSliderTracker;
|
|
|
}
|
|
|
FileViewController* that;
|
|
|
FilterBar* mFilterBar;
|
|
|
TDEToolBar* mToolBar;
|
|
|
TQWidgetStack* mStack;
|
|
|
TDESelectAction* mSortAction;
|
|
|
TDEToggleAction* mRevertSortAction;
|
|
|
TipTracker* mSliderTracker;
|
|
|
|
|
|
TQHBox* mFilterHBox;
|
|
|
TQComboBox* mFilterComboBox;
|
|
|
TQCheckBox* mShowFilterBarCheckBox;
|
|
|
|
|
|
void initFilterBar() {
|
|
|
mFilterBar=new FilterBar(that);
|
|
|
mFilterBar->setSizePolicy(TQSizePolicy::Preferred, TQSizePolicy::Fixed);
|
|
|
mFilterBar->hide();
|
|
|
|
|
|
TQIconSet resetIS=BarIcon("locationbar_erase");
|
|
|
mFilterBar->mResetNameCombo->setIconSet(resetIS);
|
|
|
mFilterBar->mResetFrom->setIconSet(resetIS);
|
|
|
mFilterBar->mResetTo->setIconSet(resetIS);
|
|
|
|
|
|
TQObject::connect(
|
|
|
mFilterBar->mResetNameCombo, TQT_SIGNAL(clicked()),
|
|
|
that, TQT_SLOT(resetNameFilter()) );
|
|
|
TQObject::connect(
|
|
|
mFilterBar->mResetFrom, TQT_SIGNAL(clicked()),
|
|
|
that, TQT_SLOT(resetFromFilter()) );
|
|
|
TQObject::connect(
|
|
|
mFilterBar->mResetTo, TQT_SIGNAL(clicked()),
|
|
|
that, TQT_SLOT(resetToFilter()) );
|
|
|
|
|
|
TQObject::connect(
|
|
|
mFilterBar->mFilterButton, TQT_SIGNAL(clicked()),
|
|
|
that, TQT_SLOT(applyFilter()) );
|
|
|
}
|
|
|
|
|
|
void initFilterCombo() {
|
|
|
mFilterHBox=new TQHBox(mToolBar, "tde toolbar widget");
|
|
|
mFilterHBox->setSpacing(KDialog::spacingHint());
|
|
|
|
|
|
mFilterComboBox=new TQComboBox(mFilterHBox);
|
|
|
mFilterComboBox->insertItem(i18n("All files"), ALL);
|
|
|
mFilterComboBox->insertItem(i18n("Images only"), IMAGES_ONLY);
|
|
|
mFilterComboBox->insertItem(i18n("Videos only"), VIDEOS_ONLY);
|
|
|
|
|
|
TQObject::connect(
|
|
|
mFilterComboBox, TQT_SIGNAL(activated(int)),
|
|
|
that, TQT_SLOT(applyFilter()) );
|
|
|
|
|
|
mShowFilterBarCheckBox = new TQCheckBox(i18n("More"), mFilterHBox);
|
|
|
TQObject::connect(
|
|
|
mShowFilterBarCheckBox, TQT_SIGNAL(toggled(bool)),
|
|
|
mFilterBar, TQT_SLOT(setShown(bool)) );
|
|
|
TQObject::connect(
|
|
|
mShowFilterBarCheckBox, TQT_SIGNAL(toggled(bool)),
|
|
|
that, TQT_SLOT(applyFilter()) );
|
|
|
}
|
|
|
|
|
|
|
|
|
void loadFilterSettings() {
|
|
|
mFilterComboBox->setCurrentItem(FileViewConfig::filterMode());
|
|
|
mShowFilterBarCheckBox->setChecked(FileViewConfig::showFilterBar());
|
|
|
mFilterBar->mNameEdit->setText(FileViewConfig::nameFilter());
|
|
|
mFilterBar->mFromDateEdit->setDate(FileViewConfig::fromDateFilter().date());
|
|
|
mFilterBar->mToDateEdit->setDate(FileViewConfig::toDateFilter().date());
|
|
|
}
|
|
|
};
|
|
|
|
|
|
|
|
|
//-----------------------------------------------------------------------
|
|
|
//
|
|
|
// FileViewController
|
|
|
//
|
|
|
//-----------------------------------------------------------------------
|
|
|
FileViewController::FileViewController(TQWidget* parent,TDEActionCollection* actionCollection)
|
|
|
: TQWidget(parent)
|
|
|
, mMode(FILE_LIST)
|
|
|
, mPrefetch( NULL )
|
|
|
, mChangeDirStatus(CHANGE_DIR_STATUS_NONE)
|
|
|
, mBrowsing(false)
|
|
|
, mSelecting(false)
|
|
|
{
|
|
|
d=new Private;
|
|
|
d->that=this;
|
|
|
setMinimumWidth(1);
|
|
|
d->mToolBar=new TDEToolBar(this, "", true);
|
|
|
d->initFilterBar();
|
|
|
d->initFilterCombo();
|
|
|
d->mStack=new TQWidgetStack(this);
|
|
|
|
|
|
TQVBoxLayout *layout=new TQVBoxLayout(this);
|
|
|
layout->addWidget(d->mToolBar);
|
|
|
layout->addWidget(d->mFilterBar);
|
|
|
layout->addWidget(d->mStack);
|
|
|
|
|
|
// Actions
|
|
|
mSelectFirst=new TDEAction(i18n("&First"),
|
|
|
TQApplication::reverseLayout() ? "2rightarrow":"2leftarrow", Key_Home,
|
|
|
TQT_TQOBJECT(this),TQT_SLOT(slotSelectFirst()), actionCollection, "first");
|
|
|
|
|
|
mSelectLast=new TDEAction(i18n("&Last"),
|
|
|
TQApplication::reverseLayout() ? "2leftarrow":"2rightarrow", Key_End,
|
|
|
TQT_TQOBJECT(this),TQT_SLOT(slotSelectLast()), actionCollection, "last");
|
|
|
|
|
|
mSelectPrevious=new TDEAction(i18n("&Previous"),
|
|
|
TQApplication::reverseLayout() ? "1rightarrow":"1leftarrow", Key_BackSpace,
|
|
|
TQT_TQOBJECT(this),TQT_SLOT(slotSelectPrevious()), actionCollection, "previous");
|
|
|
|
|
|
mSelectNext=new TDEAction(i18n("&Next"),
|
|
|
TQApplication::reverseLayout() ? "1leftarrow":"1rightarrow", Key_Space,
|
|
|
TQT_TQOBJECT(this),TQT_SLOT(slotSelectNext()), actionCollection, "next");
|
|
|
|
|
|
mSelectPreviousDir=new TDEAction(i18n("&Previous Folder"),
|
|
|
TQApplication::reverseLayout() ? "media-seek-forward":"media-seek-backward", ALT + Key_BackSpace,
|
|
|
TQT_TQOBJECT(this),TQT_SLOT(slotSelectPreviousDir()), actionCollection, "previous_folder");
|
|
|
|
|
|
mSelectNextDir=new TDEAction(i18n("&Next Folder"),
|
|
|
TQApplication::reverseLayout() ? "media-seek-backward":"media-seek-forward", ALT + Key_Space,
|
|
|
TQT_TQOBJECT(this),TQT_SLOT(slotSelectNextDir()), actionCollection, "next_folder");
|
|
|
|
|
|
mSelectFirstSubDir=new TDEAction(i18n("&First Sub Folder"), "go-down", ALT + Key_Down,
|
|
|
TQT_TQOBJECT(this),TQT_SLOT(slotSelectFirstSubDir()), actionCollection, "first_sub_folder");
|
|
|
|
|
|
mListMode=new TDERadioAction(i18n("Details"),"view_detailed",0,TQT_TQOBJECT(this),TQT_SLOT(updateViewMode()),actionCollection,"list_mode");
|
|
|
mListMode->setExclusiveGroup("thumbnails");
|
|
|
mSideThumbnailMode=new TDERadioAction(i18n("Thumbnails with Info on Side"),"view_multicolumn",0,TQT_TQOBJECT(this),TQT_SLOT(updateViewMode()),actionCollection,"side_thumbnail_mode");
|
|
|
mSideThumbnailMode->setExclusiveGroup("thumbnails");
|
|
|
mBottomThumbnailMode=new TDERadioAction(i18n("Thumbnails with Info on Bottom"),"view_icon",0,TQT_TQOBJECT(this),TQT_SLOT(updateViewMode()),actionCollection,"bottom_thumbnail_mode");
|
|
|
mBottomThumbnailMode->setExclusiveGroup("thumbnails");
|
|
|
|
|
|
// Size slider
|
|
|
mSizeSlider=new TQSlider(Horizontal, d->mToolBar);
|
|
|
mSizeSlider->setFixedWidth(120);
|
|
|
mSizeSlider->setRange(
|
|
|
ThumbnailSize::MIN/SLIDER_RESOLUTION,
|
|
|
ThumbnailSize::LARGE/SLIDER_RESOLUTION);
|
|
|
mSizeSlider->setValue(FileViewConfig::thumbnailSize() / SLIDER_RESOLUTION);
|
|
|
|
|
|
connect(mSizeSlider, TQT_SIGNAL(valueChanged(int)), TQT_TQOBJECT(this), TQT_SLOT(updateThumbnailSize(int)) );
|
|
|
connect(mListMode, TQT_SIGNAL(toggled(bool)), mSizeSlider, TQT_SLOT(setDisabled(bool)) );
|
|
|
TDEAction* sliderAction=new KWidgetAction(mSizeSlider, i18n("Thumbnail Size"), 0, 0, 0, actionCollection, "size_slider");
|
|
|
d->mSliderTracker=new TipTracker("", mSizeSlider);
|
|
|
// /Size slider
|
|
|
|
|
|
mShowDotFiles=new TDEToggleAction(i18n("Show &Hidden Files"),CTRL + Key_H,TQT_TQOBJECT(this),TQT_SLOT(toggleShowDotFiles()),actionCollection,"show_dot_files");
|
|
|
|
|
|
d->mSortAction=new TDESelectAction(i18n("Sort"), 0, TQT_TQOBJECT(this), TQT_SLOT(setSorting()), actionCollection, "view_sort");
|
|
|
TQStringList sortItems;
|
|
|
sortItems << i18n("By Name") << i18n("By Date") << i18n("By Size");
|
|
|
d->mSortAction->setItems(sortItems);
|
|
|
d->mSortAction->setCurrentItem(0);
|
|
|
|
|
|
d->mRevertSortAction=new TDEToggleAction(i18n("Descending"),0, TQT_TQOBJECT(this), TQT_SLOT(setSorting()), actionCollection, "descending");
|
|
|
TQPopupMenu* sortMenu=d->mSortAction->popupMenu();
|
|
|
Q_ASSERT(sortMenu);
|
|
|
sortMenu->insertSeparator();
|
|
|
d->mRevertSortAction->plug(sortMenu);
|
|
|
|
|
|
// Dir lister
|
|
|
mDirLister=new DirLister;
|
|
|
mDirLister->setMainWindow(topLevelWidget());
|
|
|
connect(mDirLister,TQT_SIGNAL(clear()),
|
|
|
TQT_TQOBJECT(this),TQT_SLOT(dirListerClear()) );
|
|
|
|
|
|
connect(mDirLister,TQT_SIGNAL(newItems(const KFileItemList&)),
|
|
|
TQT_TQOBJECT(this),TQT_SLOT(dirListerNewItems(const KFileItemList&)) );
|
|
|
|
|
|
connect(mDirLister,TQT_SIGNAL(deleteItem(KFileItem*)),
|
|
|
TQT_TQOBJECT(this),TQT_SLOT(dirListerDeleteItem(KFileItem*)) );
|
|
|
|
|
|
connect(mDirLister,TQT_SIGNAL(refreshItems(const KFileItemList&)),
|
|
|
TQT_TQOBJECT(this),TQT_SLOT(dirListerRefreshItems(const KFileItemList&)) );
|
|
|
|
|
|
connect(mDirLister,TQT_SIGNAL(started(const KURL&)),
|
|
|
TQT_TQOBJECT(this),TQT_SLOT(dirListerStarted()) );
|
|
|
|
|
|
connect(mDirLister,TQT_SIGNAL(completed()),
|
|
|
TQT_TQOBJECT(this),TQT_SLOT(dirListerCompleted()) );
|
|
|
|
|
|
connect(mDirLister,TQT_SIGNAL(canceled()),
|
|
|
TQT_TQOBJECT(this),TQT_SLOT(dirListerCanceled()) );
|
|
|
|
|
|
// Propagate canceled signals
|
|
|
connect(mDirLister,TQT_SIGNAL(canceled()),
|
|
|
this,TQT_SIGNAL(canceled()) );
|
|
|
|
|
|
// File detail widget
|
|
|
mFileDetailView=new FileDetailView(d->mStack, "filedetailview");
|
|
|
d->mStack->addWidget(mFileDetailView,0);
|
|
|
mFileDetailView->viewport()->installEventFilter(this);
|
|
|
|
|
|
connect(mFileDetailView,TQT_SIGNAL(executed(TQListViewItem*)),
|
|
|
TQT_TQOBJECT(this),TQT_SLOT(slotViewExecuted()) );
|
|
|
connect(mFileDetailView,TQT_SIGNAL(returnPressed(TQListViewItem*)),
|
|
|
TQT_TQOBJECT(this),TQT_SLOT(slotViewExecuted()) );
|
|
|
connect(mFileDetailView,TQT_SIGNAL(currentChanged(TQListViewItem*)),
|
|
|
TQT_TQOBJECT(this),TQT_SLOT(slotViewClicked()) );
|
|
|
connect(mFileDetailView,TQT_SIGNAL(selectionChanged()),
|
|
|
TQT_TQOBJECT(this),TQT_SLOT(slotViewClicked()) );
|
|
|
connect(mFileDetailView,TQT_SIGNAL(clicked(TQListViewItem*)),
|
|
|
TQT_TQOBJECT(this),TQT_SLOT(slotViewClicked()) );
|
|
|
connect(mFileDetailView,TQT_SIGNAL(contextMenu(TDEListView*, TQListViewItem*, const TQPoint&)),
|
|
|
TQT_TQOBJECT(this),TQT_SLOT(openContextMenu(TDEListView*, TQListViewItem*, const TQPoint&)) );
|
|
|
connect(mFileDetailView,TQT_SIGNAL(dropped(TQDropEvent*,KFileItem*)),
|
|
|
TQT_TQOBJECT(this),TQT_SLOT(openDropURLMenu(TQDropEvent*, KFileItem*)) );
|
|
|
connect(mFileDetailView, TQT_SIGNAL(sortingChanged(TQDir::SortSpec)),
|
|
|
this, TQT_SLOT(updateSortMenu(TQDir::SortSpec)) );
|
|
|
connect(mFileDetailView, TQT_SIGNAL(doubleClicked(TQListViewItem*)),
|
|
|
this, TQT_SLOT(slotViewDoubleClicked()) );
|
|
|
connect(mFileDetailView, TQT_SIGNAL(selectionChanged()),
|
|
|
this, TQT_SIGNAL(selectionChanged()) );
|
|
|
|
|
|
// Thumbnail widget
|
|
|
mFileThumbnailView=new FileThumbnailView(d->mStack);
|
|
|
d->mStack->addWidget(mFileThumbnailView,1);
|
|
|
mFileThumbnailView->viewport()->installEventFilter(this);
|
|
|
|
|
|
connect(mFileThumbnailView,TQT_SIGNAL(executed(TQIconViewItem*)),
|
|
|
TQT_TQOBJECT(this),TQT_SLOT(slotViewExecuted()) );
|
|
|
connect(mFileThumbnailView,TQT_SIGNAL(returnPressed(TQIconViewItem*)),
|
|
|
TQT_TQOBJECT(this),TQT_SLOT(slotViewExecuted()) );
|
|
|
connect(mFileThumbnailView,TQT_SIGNAL(currentChanged(TQIconViewItem*)),
|
|
|
TQT_TQOBJECT(this),TQT_SLOT(slotViewClicked()) );
|
|
|
connect(mFileThumbnailView,TQT_SIGNAL(selectionChanged()),
|
|
|
TQT_TQOBJECT(this),TQT_SLOT(slotViewClicked()) );
|
|
|
connect(mFileThumbnailView,TQT_SIGNAL(clicked(TQIconViewItem*)),
|
|
|
TQT_TQOBJECT(this),TQT_SLOT(slotViewClicked()) );
|
|
|
connect(mFileThumbnailView,TQT_SIGNAL(contextMenuRequested(TQIconViewItem*,const TQPoint&)),
|
|
|
TQT_TQOBJECT(this),TQT_SLOT(openContextMenu(TQIconViewItem*,const TQPoint&)) );
|
|
|
connect(mFileThumbnailView,TQT_SIGNAL(dropped(TQDropEvent*,KFileItem*)),
|
|
|
TQT_TQOBJECT(this),TQT_SLOT(openDropURLMenu(TQDropEvent*, KFileItem*)) );
|
|
|
connect(mFileThumbnailView, TQT_SIGNAL(doubleClicked(TQIconViewItem*)),
|
|
|
this, TQT_SLOT(slotViewDoubleClicked()) );
|
|
|
connect(mFileThumbnailView, TQT_SIGNAL(selectionChanged()),
|
|
|
this, TQT_SIGNAL(selectionChanged()) );
|
|
|
|
|
|
// Thumbnail details dialog
|
|
|
TDEAction* thumbnailDetailsDialogAction=new TDEAction(i18n("Edit Thumbnail Details..."), "configure", 0, TQT_TQOBJECT(mFileThumbnailView), TQT_SLOT(showThumbnailDetailsDialog()), actionCollection, "thumbnail_details_dialog");
|
|
|
connect(mBottomThumbnailMode, TQT_SIGNAL(toggled(bool)),
|
|
|
thumbnailDetailsDialogAction, TQT_SLOT(setEnabled(bool)) );
|
|
|
|
|
|
// Fill toolbar
|
|
|
mListMode->plug(d->mToolBar);
|
|
|
mSideThumbnailMode->plug(d->mToolBar);
|
|
|
mBottomThumbnailMode->plug(d->mToolBar);
|
|
|
d->mToolBar->insertSeparator();
|
|
|
sliderAction->plug(d->mToolBar);
|
|
|
d->mToolBar->insertSeparator();
|
|
|
thumbnailDetailsDialogAction->plug(d->mToolBar);
|
|
|
|
|
|
int id=d->mToolBar->insertWidget(-1, 0, d->mFilterHBox);
|
|
|
d->mToolBar->alignItemRight(id, true);
|
|
|
|
|
|
mShowDotFiles->setChecked(FileViewConfig::showDotFiles());
|
|
|
|
|
|
bool startWithThumbnails=FileViewConfig::startWithThumbnails();
|
|
|
setMode(startWithThumbnails?THUMBNAIL:FILE_LIST);
|
|
|
mSizeSlider->setEnabled(startWithThumbnails);
|
|
|
|
|
|
if (startWithThumbnails) {
|
|
|
if (mFileThumbnailView->itemTextPos()==TQIconView::Right) {
|
|
|
mSideThumbnailMode->setChecked(true);
|
|
|
} else {
|
|
|
mBottomThumbnailMode->setChecked(true);
|
|
|
}
|
|
|
// Make sure the thumbnail view and the slider tooltip are updated
|
|
|
updateThumbnailSize(mSizeSlider->value());
|
|
|
mFileThumbnailView->startThumbnailUpdate();
|
|
|
} else {
|
|
|
mListMode->setChecked(true);
|
|
|
}
|
|
|
thumbnailDetailsDialogAction->setEnabled(mBottomThumbnailMode->isChecked());
|
|
|
|
|
|
if (MiscConfig::rememberFilter()) {
|
|
|
d->loadFilterSettings();
|
|
|
}
|
|
|
updateFromSettings();
|
|
|
}
|
|
|
|
|
|
|
|
|
FileViewController::~FileViewController() {
|
|
|
// Save various settings
|
|
|
FileViewConfig::setStartWithThumbnails(mMode==THUMBNAIL);
|
|
|
|
|
|
int filterMode = d->mFilterComboBox->currentItem();
|
|
|
FileViewConfig::setFilterMode(filterMode);
|
|
|
|
|
|
FileViewConfig::setShowFilterBar(d->mShowFilterBarCheckBox->isChecked());
|
|
|
FileViewConfig::setNameFilter(d->mFilterBar->mNameEdit->text());
|
|
|
FileViewConfig::setFromDateFilter(d->mFilterBar->mFromDateEdit->date());
|
|
|
FileViewConfig::setToDateFilter(d->mFilterBar->mToDateEdit->date());
|
|
|
|
|
|
FileViewConfig::writeConfig();
|
|
|
delete mDirLister;
|
|
|
delete d;
|
|
|
}
|
|
|
|
|
|
|
|
|
void FileViewController::setFocus() {
|
|
|
currentFileView()->widget()->setFocus();
|
|
|
}
|
|
|
|
|
|
|
|
|
/**
|
|
|
* Do not let double click events propagate if Ctrl or Shift is down, to avoid
|
|
|
* toggling fullscreen
|
|
|
*/
|
|
|
bool FileViewController::eventFilter(TQObject*, TQEvent* event) {
|
|
|
if (event->type()!=TQEvent::MouseButtonDblClick) return false;
|
|
|
|
|
|
TQMouseEvent* mouseEvent=TQT_TQMOUSEEVENT(event);
|
|
|
if (mouseEvent->state() & TQt::ControlButton || mouseEvent->state() & TQt::ShiftButton) {
|
|
|
return true;
|
|
|
}
|
|
|
return false;
|
|
|
}
|
|
|
|
|
|
|
|
|
bool FileViewController::lastURLError() const {
|
|
|
return mDirLister->error();
|
|
|
}
|
|
|
|
|
|
|
|
|
//-----------------------------------------------------------------------
|
|
|
//
|
|
|
// Public slots
|
|
|
//
|
|
|
//-----------------------------------------------------------------------
|
|
|
void FileViewController::setDirURL(const KURL& url) {
|
|
|
LOG(url.prettyURL());
|
|
|
if ( mDirURL.equals(url,true) ) {
|
|
|
LOG("Same URL");
|
|
|
return;
|
|
|
}
|
|
|
prefetchDone();
|
|
|
mDirURL=url;
|
|
|
if (!KProtocolInfo::supportsListing(mDirURL)) {
|
|
|
LOG("Protocol does not support listing");
|
|
|
return;
|
|
|
}
|
|
|
|
|
|
mDirLister->clearError();
|
|
|
currentFileView()->setShownFileItem(0L);
|
|
|
mFileNameToSelect=TQString();
|
|
|
mDirLister->openURL(mDirURL);
|
|
|
emit urlChanged(mDirURL);
|
|
|
emit directoryChanged(mDirURL);
|
|
|
updateActions();
|
|
|
}
|
|
|
|
|
|
|
|
|
/**
|
|
|
* Sets the file to select once the dir lister is done. If it's not running,
|
|
|
* immediatly selects the file.
|
|
|
*/
|
|
|
void FileViewController::setFileNameToSelect(const TQString& fileName) {
|
|
|
mFileNameToSelect=fileName;
|
|
|
if (mDirLister->isFinished()) {
|
|
|
browseToFileNameToSelect();
|
|
|
}
|
|
|
}
|
|
|
|
|
|
void FileViewController::prefetch( KFileItem* item ) {
|
|
|
prefetchDone();
|
|
|
if( item == NULL ) return;
|
|
|
mPrefetch = ImageLoader::loader( item->url(), TQT_TQOBJECT(this), BUSY_PRELOADING );
|
|
|
connect( mPrefetch, TQT_SIGNAL( imageLoaded( bool )), TQT_SLOT( prefetchDone()));
|
|
|
}
|
|
|
|
|
|
void FileViewController::prefetchDone() {
|
|
|
if( mPrefetch != NULL ) {
|
|
|
mPrefetch->release( TQT_TQOBJECT(this) );
|
|
|
mPrefetch = NULL;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
void FileViewController::slotSelectFirst() {
|
|
|
browseTo( findFirstImage());
|
|
|
prefetch( findNextImage());
|
|
|
}
|
|
|
|
|
|
void FileViewController::slotSelectLast() {
|
|
|
browseTo(findLastImage());
|
|
|
prefetch( findPreviousImage());
|
|
|
}
|
|
|
|
|
|
void FileViewController::slotSelectPrevious() {
|
|
|
browseTo(findPreviousImage());
|
|
|
prefetch( findPreviousImage());
|
|
|
}
|
|
|
|
|
|
void FileViewController::slotSelectNext() {
|
|
|
browseTo(findNextImage());
|
|
|
prefetch( findNextImage());
|
|
|
}
|
|
|
|
|
|
void FileViewController::slotSelectPreviousDir() {
|
|
|
mChangeDirStatus = CHANGE_DIR_STATUS_PREV;
|
|
|
mDirLister->clearError();
|
|
|
mDirLister->openURL(mDirURL.upURL());
|
|
|
}
|
|
|
|
|
|
void FileViewController::slotSelectNextDir() {
|
|
|
mChangeDirStatus = CHANGE_DIR_STATUS_NEXT;
|
|
|
mDirLister->clearError();
|
|
|
mDirLister->openURL(mDirURL.upURL());
|
|
|
}
|
|
|
|
|
|
void FileViewController::slotSelectFirstSubDir() {
|
|
|
KFileItem* item=currentFileView()->firstFileItem();
|
|
|
while (item && !Archive::fileItemIsDirOrArchive(item)) {
|
|
|
item=currentFileView()->nextItem(item);
|
|
|
}
|
|
|
if (!item) {
|
|
|
LOG("No item found");
|
|
|
return;
|
|
|
}
|
|
|
LOG("item->url(): " << item->url().prettyURL());
|
|
|
KURL tmp=item->url();
|
|
|
if (Archive::fileItemIsArchive(item)) {
|
|
|
tmp.setProtocol(Archive::protocolForMimeType(item->mimetype()));
|
|
|
}
|
|
|
tmp.adjustPath(1);
|
|
|
setDirURL(tmp);
|
|
|
}
|
|
|
|
|
|
|
|
|
void FileViewController::resetNameFilter() {
|
|
|
d->mFilterBar->mNameEdit->clear();
|
|
|
}
|
|
|
|
|
|
|
|
|
void FileViewController::resetFromFilter() {
|
|
|
d->mFilterBar->mFromDateEdit->setDate(TQDate());
|
|
|
}
|
|
|
|
|
|
|
|
|
void FileViewController::resetToFilter() {
|
|
|
d->mFilterBar->mToDateEdit->setDate(TQDate());
|
|
|
}
|
|
|
|
|
|
|
|
|
void FileViewController::browseTo(KFileItem* item) {
|
|
|
prefetchDone();
|
|
|
if (mBrowsing) return;
|
|
|
mBrowsing = true;
|
|
|
if (item) {
|
|
|
currentFileView()->setCurrentItem(item);
|
|
|
currentFileView()->clearSelection();
|
|
|
currentFileView()->setSelected(item,true);
|
|
|
currentFileView()->ensureItemVisible(item);
|
|
|
if (!item->isDir() && !Archive::fileItemIsArchive(item)) {
|
|
|
emitURLChanged();
|
|
|
}
|
|
|
}
|
|
|
updateActions();
|
|
|
mBrowsing = false;
|
|
|
}
|
|
|
|
|
|
|
|
|
void FileViewController::browseToFileNameToSelect() {
|
|
|
// There's something to select
|
|
|
if (!mFileNameToSelect.isEmpty()) {
|
|
|
browseTo(findItemByFileName(mFileNameToSelect));
|
|
|
mFileNameToSelect=TQString();
|
|
|
return;
|
|
|
}
|
|
|
|
|
|
// Nothing to select, but an item is already shown
|
|
|
if (currentFileView()->shownFileItem()) return;
|
|
|
|
|
|
// Now we have to make some default choice
|
|
|
slotSelectFirst();
|
|
|
|
|
|
// If no item is selected, make sure the first one is
|
|
|
if (currentFileView()->selectedItems()->count()==0) {
|
|
|
KFileItem* item=currentFileView()->firstFileItem();
|
|
|
if (item) {
|
|
|
currentFileView()->setCurrentItem(item);
|
|
|
currentFileView()->setSelected(item, true);
|
|
|
currentFileView()->ensureItemVisible(item);
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
|
|
|
|
|
|
void FileViewController::updateThumbnail(const KURL& url) {
|
|
|
if (mMode==FILE_LIST) return;
|
|
|
|
|
|
KFileItem* item=mDirLister->findByURL(url);
|
|
|
if (!item) return;
|
|
|
mFileThumbnailView->updateThumbnail(item);
|
|
|
}
|
|
|
|
|
|
|
|
|
//-----------------------------------------------------------------------
|
|
|
//
|
|
|
// Private slots
|
|
|
//
|
|
|
//-----------------------------------------------------------------------
|
|
|
void FileViewController::slotViewExecuted() {
|
|
|
KFileItem* item=currentFileView()->currentFileItem();
|
|
|
if (!item) return;
|
|
|
|
|
|
bool isDir=item->isDir();
|
|
|
bool isArchive=Archive::fileItemIsArchive(item);
|
|
|
if (isDir || isArchive) {
|
|
|
KURL tmp=url();
|
|
|
|
|
|
if (isArchive) {
|
|
|
tmp.setProtocol(Archive::protocolForMimeType(item->mimetype()));
|
|
|
}
|
|
|
tmp.adjustPath(1);
|
|
|
setDirURL(tmp);
|
|
|
} else {
|
|
|
emitURLChanged();
|
|
|
}
|
|
|
}
|
|
|
|
|
|
|
|
|
void FileViewController::slotViewClicked() {
|
|
|
updateActions();
|
|
|
KFileItem* item=currentFileView()->currentFileItem();
|
|
|
if (!item || Archive::fileItemIsDirOrArchive(item)) return;
|
|
|
|
|
|
mSelecting = true;
|
|
|
emitURLChanged();
|
|
|
mSelecting = false;
|
|
|
}
|
|
|
|
|
|
|
|
|
void FileViewController::slotViewDoubleClicked() {
|
|
|
updateActions();
|
|
|
KFileItem* item=currentFileView()->currentFileItem();
|
|
|
if (item && !Archive::fileItemIsDirOrArchive(item)) emit imageDoubleClicked();
|
|
|
}
|
|
|
|
|
|
|
|
|
void FileViewController::updateViewMode() {
|
|
|
if (mListMode->isChecked()) {
|
|
|
setMode(FILE_LIST);
|
|
|
return;
|
|
|
}
|
|
|
if (mSideThumbnailMode->isChecked()) {
|
|
|
mFileThumbnailView->setItemTextPos(TQIconView::Right);
|
|
|
} else {
|
|
|
mFileThumbnailView->setItemTextPos(TQIconView::Bottom);
|
|
|
}
|
|
|
|
|
|
// Only switch the view if we are going from no thumbs to either side or
|
|
|
// bottom thumbs, not when switching between side and bottom thumbs
|
|
|
if (mMode==FILE_LIST) {
|
|
|
setMode(THUMBNAIL);
|
|
|
} else {
|
|
|
KFileItemList items=*mFileThumbnailView->items();
|
|
|
KFileItem* shownFileItem=mFileThumbnailView->shownFileItem();
|
|
|
|
|
|
mFileThumbnailView->FileViewBase::clear();
|
|
|
mFileThumbnailView->addItemList(items);
|
|
|
mFileThumbnailView->setShownFileItem(shownFileItem);
|
|
|
}
|
|
|
|
|
|
updateThumbnailSize(mSizeSlider->value());
|
|
|
mFileThumbnailView->startThumbnailUpdate();
|
|
|
}
|
|
|
|
|
|
|
|
|
void FileViewController::updateThumbnailSize(int size) {
|
|
|
size*=SLIDER_RESOLUTION;
|
|
|
d->mSliderTracker->setText(i18n("Thumbnail size: %1x%2").arg(size).arg(size));
|
|
|
FileViewConfig::setThumbnailSize(size);
|
|
|
mFileThumbnailView->setThumbnailSize(size);
|
|
|
Cache::instance()->checkThumbnailSize(size);
|
|
|
}
|
|
|
|
|
|
|
|
|
void FileViewController::toggleShowDotFiles() {
|
|
|
mDirLister->setShowingDotFiles(mShowDotFiles->isChecked());
|
|
|
mDirLister->openURL(mDirURL);
|
|
|
}
|
|
|
|
|
|
|
|
|
void FileViewController::updateSortMenu(TQDir::SortSpec _spec) {
|
|
|
int spec=_spec & (TQDir::Name | TQDir::Time | TQDir::Size);
|
|
|
int item;
|
|
|
switch (spec) {
|
|
|
case TQDir::Name:
|
|
|
item=0;
|
|
|
break;
|
|
|
case TQDir::Time:
|
|
|
item=1;
|
|
|
break;
|
|
|
case TQDir::Size:
|
|
|
item=2;
|
|
|
break;
|
|
|
default:
|
|
|
item=-1;
|
|
|
break;
|
|
|
}
|
|
|
d->mSortAction->setCurrentItem(item);
|
|
|
}
|
|
|
|
|
|
|
|
|
void FileViewController::setSorting() {
|
|
|
TQDir::SortSpec spec;
|
|
|
|
|
|
switch (d->mSortAction->currentItem()) {
|
|
|
case 0: // Name
|
|
|
spec=TQDir::Name;
|
|
|
break;
|
|
|
case 1: // Date
|
|
|
spec=TQDir::Time;
|
|
|
break;
|
|
|
case 2: // Size
|
|
|
spec=TQDir::Size;
|
|
|
break;
|
|
|
default:
|
|
|
return;
|
|
|
}
|
|
|
if (d->mRevertSortAction->isChecked()) {
|
|
|
spec=TQDir::SortSpec(spec | TQDir::Reversed);
|
|
|
}
|
|
|
currentFileView()->setSorting(TQDir::SortSpec(spec | TQDir::DirsFirst));
|
|
|
emit sortingChanged();
|
|
|
}
|
|
|
|
|
|
|
|
|
//-----------------------------------------------------------------------
|
|
|
//
|
|
|
// Context menu
|
|
|
//
|
|
|
//-----------------------------------------------------------------------
|
|
|
void FileViewController::openContextMenu(TDEListView*,TQListViewItem* item,const TQPoint& pos) {
|
|
|
emit requestContextMenu(pos, item!=0);
|
|
|
}
|
|
|
|
|
|
|
|
|
void FileViewController::openContextMenu(TQIconViewItem* item,const TQPoint& pos) {
|
|
|
emit requestContextMenu(pos, item!=0);
|
|
|
}
|
|
|
|
|
|
|
|
|
//-----------------------------------------------------------------------
|
|
|
//
|
|
|
// Drop URL menu
|
|
|
//
|
|
|
//-----------------------------------------------------------------------
|
|
|
void FileViewController::openDropURLMenu(TQDropEvent* event, KFileItem* item) {
|
|
|
KURL dest;
|
|
|
|
|
|
if (item) {
|
|
|
dest=item->url();
|
|
|
} else {
|
|
|
dest=mDirURL;
|
|
|
}
|
|
|
|
|
|
KURL::List urls;
|
|
|
if (!KURLDrag::decode(event,urls)) return;
|
|
|
|
|
|
FileOperation::openDropURLMenu(d->mStack, urls, dest);
|
|
|
}
|
|
|
|
|
|
|
|
|
//-----------------------------------------------------------------------
|
|
|
//
|
|
|
// File operations
|
|
|
//
|
|
|
//-----------------------------------------------------------------------
|
|
|
KURL::List FileViewController::selectedURLs() const {
|
|
|
KURL::List list;
|
|
|
|
|
|
KFileItemListIterator it( *currentFileView()->selectedItems() );
|
|
|
for ( ; it.current(); ++it ) {
|
|
|
list.append(it.current()->url());
|
|
|
}
|
|
|
if (list.isEmpty()) {
|
|
|
const KFileItem* item=currentFileView()->shownFileItem();
|
|
|
if (item) list.append(item->url());
|
|
|
}
|
|
|
return list;
|
|
|
}
|
|
|
|
|
|
|
|
|
KURL::List FileViewController::selectedImageURLs() const {
|
|
|
KURL::List list;
|
|
|
|
|
|
KFileItemListIterator it( *currentFileView()->selectedItems() );
|
|
|
for ( ; it.current(); ++it ) {
|
|
|
KFileItem* item=it.current();
|
|
|
if (!Archive::fileItemIsDirOrArchive(item)) {
|
|
|
list.append(item->url());
|
|
|
}
|
|
|
}
|
|
|
if (list.isEmpty()) {
|
|
|
const KFileItem* item=currentFileView()->shownFileItem();
|
|
|
if (item && !Archive::fileItemIsDirOrArchive(item)) list.append(item->url());
|
|
|
}
|
|
|
return list;
|
|
|
}
|
|
|
|
|
|
|
|
|
//-----------------------------------------------------------------------
|
|
|
//
|
|
|
// Properties
|
|
|
//
|
|
|
//-----------------------------------------------------------------------
|
|
|
TQString FileViewController::fileName() const {
|
|
|
KFileItem* item=currentFileView()->currentFileItem();
|
|
|
if (!item) return "";
|
|
|
return item->text();
|
|
|
}
|
|
|
|
|
|
|
|
|
FileViewBase* FileViewController::currentFileView() const {
|
|
|
if (mMode==FILE_LIST) {
|
|
|
return mFileDetailView;
|
|
|
} else {
|
|
|
return mFileThumbnailView;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
|
|
|
uint FileViewController::fileCount() const {
|
|
|
uint count=currentFileView()->count();
|
|
|
|
|
|
KFileItem* item=currentFileView()->firstFileItem();
|
|
|
while (item && Archive::fileItemIsDirOrArchive(item)) {
|
|
|
item=currentFileView()->nextItem(item);
|
|
|
count--;
|
|
|
}
|
|
|
return count;
|
|
|
}
|
|
|
|
|
|
|
|
|
int FileViewController::shownFilePosition() const {
|
|
|
KFileItem* shownItem=currentFileView()->shownFileItem();
|
|
|
if (!shownItem) return -1;
|
|
|
KFileItem* item=currentFileView()->firstFileItem();
|
|
|
int position=0;
|
|
|
for (;
|
|
|
item && item!=shownItem;
|
|
|
item=currentFileView()->nextItem(item) )
|
|
|
{
|
|
|
if (!Archive::fileItemIsDirOrArchive(item)) ++position;
|
|
|
}
|
|
|
return position;
|
|
|
}
|
|
|
|
|
|
|
|
|
KURL FileViewController::url() const {
|
|
|
KFileItem* item=currentFileView()->currentFileItem();
|
|
|
if (!item) return mDirURL;
|
|
|
return item->url();
|
|
|
}
|
|
|
|
|
|
KURL FileViewController::dirURL() const {
|
|
|
return mDirURL;
|
|
|
}
|
|
|
|
|
|
|
|
|
uint FileViewController::selectionSize() const {
|
|
|
const KFileItemList* selectedItems=currentFileView()->selectedItems();
|
|
|
return selectedItems->count();
|
|
|
}
|
|
|
|
|
|
|
|
|
void FileViewController::setMode(FileViewController::Mode mode) {
|
|
|
const KFileItemList* items;
|
|
|
FileViewBase* oldView;
|
|
|
FileViewBase* newView;
|
|
|
|
|
|
mMode=mode;
|
|
|
|
|
|
if (mMode==FILE_LIST) {
|
|
|
mFileThumbnailView->stopThumbnailUpdate();
|
|
|
oldView=mFileThumbnailView;
|
|
|
newView=mFileDetailView;
|
|
|
} else {
|
|
|
oldView=mFileDetailView;
|
|
|
newView=mFileThumbnailView;
|
|
|
}
|
|
|
|
|
|
bool wasFocused=oldView->widget()->hasFocus();
|
|
|
// Show the new active view
|
|
|
d->mStack->raiseWidget(newView->widget());
|
|
|
if (wasFocused) newView->widget()->setFocus();
|
|
|
|
|
|
// Fill the new view
|
|
|
newView->clear();
|
|
|
newView->addItemList(*oldView->items());
|
|
|
|
|
|
// Set the new view to the same state as the old
|
|
|
items=oldView->selectedItems();
|
|
|
for(KFileItemListIterator it(*items);it.current()!=0L;++it) {
|
|
|
newView->setSelected(it.current(), true);
|
|
|
}
|
|
|
newView->setShownFileItem(oldView->shownFileItem());
|
|
|
newView->setCurrentItem(oldView->currentFileItem());
|
|
|
|
|
|
// Remove references to the old view from KFileItems
|
|
|
items=oldView->items();
|
|
|
for(KFileItemListIterator it(*items);it.current()!=0L;++it) {
|
|
|
it.current()->removeExtraData(oldView);
|
|
|
}
|
|
|
|
|
|
// Update sorting
|
|
|
newView->setSorting(oldView->sorting());
|
|
|
|
|
|
// Clear the old view
|
|
|
oldView->FileViewBase::clear();
|
|
|
}
|
|
|
|
|
|
|
|
|
void FileViewController::updateFromSettings() {
|
|
|
applyFilter();
|
|
|
mFileThumbnailView->setMarginSize(FileViewConfig::thumbnailMarginSize());
|
|
|
mFileThumbnailView->setItemDetails(FileViewConfig::thumbnailDetails());
|
|
|
currentFileView()->widget()->update();
|
|
|
}
|
|
|
|
|
|
|
|
|
void FileViewController::setSilentMode( bool silent ) {
|
|
|
mDirLister->setCheck( !silent );
|
|
|
}
|
|
|
|
|
|
|
|
|
void FileViewController::retryURL() {
|
|
|
mDirLister->clearError();
|
|
|
mDirLister->openURL( url());
|
|
|
}
|
|
|
|
|
|
|
|
|
//-----------------------------------------------------------------------
|
|
|
//
|
|
|
// Dir lister slots
|
|
|
//
|
|
|
//-----------------------------------------------------------------------
|
|
|
void FileViewController::dirListerDeleteItem(KFileItem* item) {
|
|
|
KFileItem* newShownItem=0L;
|
|
|
const KFileItem* shownItem=currentFileView()->shownFileItem();
|
|
|
if (shownItem==item) {
|
|
|
newShownItem=findNextImage();
|
|
|
if (!newShownItem) newShownItem=findPreviousImage();
|
|
|
}
|
|
|
|
|
|
currentFileView()->removeItem(item);
|
|
|
|
|
|
if (shownItem==item) {
|
|
|
currentFileView()->setCurrentItem(newShownItem);
|
|
|
currentFileView()->setSelected(newShownItem, true);
|
|
|
if (newShownItem) {
|
|
|
emit urlChanged(newShownItem->url());
|
|
|
} else {
|
|
|
emit urlChanged(KURL());
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
|
|
|
|
|
|
void FileViewController::dirListerNewItems(const KFileItemList& items) {
|
|
|
LOG("");
|
|
|
mThumbnailsNeedUpdate=true;
|
|
|
currentFileView()->addItemList(items);
|
|
|
}
|
|
|
|
|
|
|
|
|
void FileViewController::dirListerRefreshItems(const KFileItemList& list) {
|
|
|
LOG("");
|
|
|
const KFileItem* item=currentFileView()->shownFileItem();
|
|
|
KFileItemListIterator it(list);
|
|
|
for (; *it!=0L; ++it) {
|
|
|
currentFileView()->updateView(*it);
|
|
|
if (*it==item) {
|
|
|
emit shownFileItemRefreshed(item);
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
|
|
|
|
|
|
void FileViewController::refreshItems(const KURL::List& urls) {
|
|
|
LOG("");
|
|
|
KFileItemList list;
|
|
|
for( KURL::List::ConstIterator it = urls.begin();
|
|
|
it != urls.end();
|
|
|
++it ) {
|
|
|
KURL dir = *it;
|
|
|
dir.setFileName( TQString() );
|
|
|
if( dir != mDirURL ) continue;
|
|
|
// TODO this could be quite slow for many images?
|
|
|
KFileItem* item = findItemByFileName( (*it).filename());
|
|
|
if( item ) list.append( item );
|
|
|
}
|
|
|
dirListerRefreshItems( list );
|
|
|
}
|
|
|
|
|
|
|
|
|
void FileViewController::dirListerClear() {
|
|
|
currentFileView()->clear();
|
|
|
}
|
|
|
|
|
|
|
|
|
void FileViewController::dirListerStarted() {
|
|
|
LOG("");
|
|
|
mThumbnailsNeedUpdate=false;
|
|
|
}
|
|
|
|
|
|
|
|
|
void FileViewController::dirListerCompleted() {
|
|
|
LOG("");
|
|
|
// Delay the code to be executed when the dir lister has completed its job
|
|
|
// to avoid crash in KDirLister (see bug #57991)
|
|
|
TQTimer::singleShot(0,TQT_TQOBJECT(this),TQT_SLOT(delayedDirListerCompleted()));
|
|
|
}
|
|
|
|
|
|
|
|
|
void FileViewController::delayedDirListerCompleted() {
|
|
|
// The call to sort() is a work around to a bug which causes
|
|
|
// FileThumbnailView::firstFileItem() to return a wrong item. This work
|
|
|
// around is not in firstFileItem() because it's const and sort() is a non
|
|
|
// const method
|
|
|
if (mMode!=FILE_LIST) {
|
|
|
mFileThumbnailView->sort(mFileThumbnailView->sortDirection());
|
|
|
}
|
|
|
|
|
|
if (mChangeDirStatus != CHANGE_DIR_STATUS_NONE) {
|
|
|
KFileItem *item;
|
|
|
TQString fileName = mDirURL.filename();
|
|
|
for (item=currentFileView()->firstFileItem(); item; item=currentFileView()->nextItem(item) ) {
|
|
|
if (item->name() == fileName) {
|
|
|
if (mChangeDirStatus == CHANGE_DIR_STATUS_NEXT) {
|
|
|
do {
|
|
|
item=currentFileView()->nextItem(item);
|
|
|
} while (item && !Archive::fileItemIsDirOrArchive(item));
|
|
|
} else {
|
|
|
do {
|
|
|
item=currentFileView()->prevItem(item);
|
|
|
} while (item && !Archive::fileItemIsDirOrArchive(item));
|
|
|
}
|
|
|
break;
|
|
|
};
|
|
|
}
|
|
|
mChangeDirStatus = CHANGE_DIR_STATUS_NONE;
|
|
|
if (!item) {
|
|
|
mDirLister->openURL(mDirURL);
|
|
|
} else {
|
|
|
KURL tmp=item->url();
|
|
|
LOG("item->url(): " << item->url().prettyURL());
|
|
|
if (Archive::fileItemIsArchive(item)) {
|
|
|
tmp.setProtocol(Archive::protocolForMimeType(item->mimetype()));
|
|
|
}
|
|
|
tmp.adjustPath(1);
|
|
|
setDirURL(tmp);
|
|
|
}
|
|
|
} else {
|
|
|
browseToFileNameToSelect();
|
|
|
emit completed();
|
|
|
|
|
|
if (mMode!=FILE_LIST && mThumbnailsNeedUpdate) {
|
|
|
mFileThumbnailView->startThumbnailUpdate();
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
|
|
|
|
|
|
void FileViewController::dirListerCanceled() {
|
|
|
if (mMode!=FILE_LIST) {
|
|
|
mFileThumbnailView->stopThumbnailUpdate();
|
|
|
}
|
|
|
|
|
|
browseToFileNameToSelect();
|
|
|
}
|
|
|
|
|
|
|
|
|
void FileViewController::setShowFilterBar(bool value) {
|
|
|
d->mShowFilterBarCheckBox->setChecked(value);
|
|
|
}
|
|
|
|
|
|
|
|
|
void FileViewController::setFilterMode(int mode) {
|
|
|
d->mFilterComboBox->setCurrentItem(mode);
|
|
|
}
|
|
|
|
|
|
|
|
|
void FileViewController::setFilterName(const TQString& name) {
|
|
|
d->mFilterBar->mNameEdit->setText(name);
|
|
|
}
|
|
|
|
|
|
|
|
|
void FileViewController::setFilterFromDate(const TQDate& date) {
|
|
|
d->mFilterBar->mFromDateEdit->setDate(date);
|
|
|
}
|
|
|
|
|
|
|
|
|
void FileViewController::setFilterToDate(const TQDate& date) {
|
|
|
d->mFilterBar->mToDateEdit->setDate(date);
|
|
|
}
|
|
|
|
|
|
|
|
|
void FileViewController::applyFilter() {
|
|
|
TQStringList mimeTypes;
|
|
|
FilterMode filterMode = static_cast<FilterMode>( d->mFilterComboBox->currentItem() );
|
|
|
|
|
|
if (FileViewConfig::showDirs()) {
|
|
|
mimeTypes << "inode/directory";
|
|
|
mimeTypes += Archive::mimeTypes();
|
|
|
}
|
|
|
|
|
|
if (filterMode != VIDEOS_ONLY) {
|
|
|
mimeTypes += MimeTypeUtils::rasterImageMimeTypes();
|
|
|
mimeTypes << "image/svg";
|
|
|
}
|
|
|
|
|
|
if (filterMode != IMAGES_ONLY) {
|
|
|
mimeTypes << "video/";
|
|
|
}
|
|
|
|
|
|
if (d->mShowFilterBarCheckBox->isChecked()) {
|
|
|
TQString txt=d->mFilterBar->mNameEdit->text();
|
|
|
TQDate from=d->mFilterBar->mFromDateEdit->date();
|
|
|
TQDate to=d->mFilterBar->mToDateEdit->date();
|
|
|
|
|
|
mDirLister->setNameFilter(txt);
|
|
|
mDirLister->setDateFilter(from, to);
|
|
|
} else {
|
|
|
mDirLister->setNameFilter(TQString());
|
|
|
mDirLister->setDateFilter(TQDate(), TQDate());
|
|
|
}
|
|
|
|
|
|
mDirLister->setShowingDotFiles(mShowDotFiles->isChecked());
|
|
|
mDirLister->setMimeFilter(mimeTypes);
|
|
|
|
|
|
// Find next item matching the filter if any, so that we can keep it
|
|
|
// current
|
|
|
KFileItem* item=currentFileView()->currentFileItem();
|
|
|
for (; item; item=currentFileView()->nextItem(item)) {
|
|
|
if (mDirLister->itemMatchFilters(item)) {
|
|
|
mFileNameToSelect=item->name();
|
|
|
break;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
mDirLister->openURL(mDirURL);
|
|
|
}
|
|
|
|
|
|
|
|
|
void FileViewController::updateActions() {
|
|
|
KFileItem* firstImage=findFirstImage();
|
|
|
|
|
|
// There isn't any image, no need to continue
|
|
|
if (!firstImage) {
|
|
|
mSelectFirst->setEnabled(false);
|
|
|
mSelectPrevious->setEnabled(false);
|
|
|
mSelectNext->setEnabled(false);
|
|
|
mSelectLast->setEnabled(false);
|
|
|
return;
|
|
|
}
|
|
|
|
|
|
// We did not select any image, let's activate everything
|
|
|
KFileItem* currentItem=currentFileView()->currentFileItem();
|
|
|
if (!currentItem || Archive::fileItemIsDirOrArchive(currentItem)) {
|
|
|
mSelectFirst->setEnabled(true);
|
|
|
mSelectPrevious->setEnabled(true);
|
|
|
mSelectNext->setEnabled(true);
|
|
|
mSelectLast->setEnabled(true);
|
|
|
return;
|
|
|
}
|
|
|
|
|
|
// There is at least one image, and an image is selected, let's be precise
|
|
|
bool isFirst=currentItem==firstImage;
|
|
|
bool isLast=currentItem==findLastImage();
|
|
|
|
|
|
mSelectFirst->setEnabled(!isFirst);
|
|
|
mSelectPrevious->setEnabled(!isFirst);
|
|
|
mSelectNext->setEnabled(!isLast);
|
|
|
mSelectLast->setEnabled(!isLast);
|
|
|
}
|
|
|
|
|
|
|
|
|
void FileViewController::emitURLChanged() {
|
|
|
KFileItem* item=currentFileView()->currentFileItem();
|
|
|
currentFileView()->setShownFileItem(item);
|
|
|
|
|
|
// We use a tmp value because the signal parameter is a reference
|
|
|
KURL tmp=url();
|
|
|
LOG("urlChanged: " << tmp.prettyURL());
|
|
|
emit urlChanged(tmp);
|
|
|
}
|
|
|
|
|
|
KFileItem* FileViewController::findFirstImage() const {
|
|
|
KFileItem* item=currentFileView()->firstFileItem();
|
|
|
while (item && Archive::fileItemIsDirOrArchive(item)) {
|
|
|
item=currentFileView()->nextItem(item);
|
|
|
}
|
|
|
if (item) {
|
|
|
LOG("item->url(): " << item->url().prettyURL());
|
|
|
} else {
|
|
|
LOG("No item found");
|
|
|
}
|
|
|
return item;
|
|
|
}
|
|
|
|
|
|
KFileItem* FileViewController::findLastImage() const {
|
|
|
KFileItem* item=currentFileView()->items()->getLast();
|
|
|
while (item && Archive::fileItemIsDirOrArchive(item)) {
|
|
|
item=currentFileView()->prevItem(item);
|
|
|
}
|
|
|
return item;
|
|
|
}
|
|
|
|
|
|
KFileItem* FileViewController::findPreviousImage() const {
|
|
|
KFileItem* item=currentFileView()->shownFileItem();
|
|
|
if (!item) return 0L;
|
|
|
do {
|
|
|
item=currentFileView()->prevItem(item);
|
|
|
} while (item && Archive::fileItemIsDirOrArchive(item));
|
|
|
return item;
|
|
|
}
|
|
|
|
|
|
KFileItem* FileViewController::findNextImage() const {
|
|
|
KFileItem* item=currentFileView()->shownFileItem();
|
|
|
if (!item) return 0L;
|
|
|
do {
|
|
|
item=currentFileView()->nextItem(item);
|
|
|
} while (item && Archive::fileItemIsDirOrArchive(item));
|
|
|
return item;
|
|
|
}
|
|
|
|
|
|
KFileItem* FileViewController::findItemByFileName(const TQString& fileName) const {
|
|
|
KFileItem *item;
|
|
|
if (fileName.isEmpty()) return 0L;
|
|
|
for (item=currentFileView()->firstFileItem();
|
|
|
item;
|
|
|
item=currentFileView()->nextItem(item) ) {
|
|
|
if (item->name()==fileName) return item;
|
|
|
}
|
|
|
|
|
|
return 0L;
|
|
|
}
|
|
|
|
|
|
|
|
|
} // namespace
|