diff options
Diffstat (limited to 'src/sq_widgetstack.cpp')
-rw-r--r-- | src/sq_widgetstack.cpp | 781 |
1 files changed, 781 insertions, 0 deletions
diff --git a/src/sq_widgetstack.cpp b/src/sq_widgetstack.cpp new file mode 100644 index 0000000..aec29e1 --- /dev/null +++ b/src/sq_widgetstack.cpp @@ -0,0 +1,781 @@ +/*************************************************************************** + sq_widgetstack.cpp - description + ------------------- + begin : Mon Mar 15 2004 + copyright : (C) 2004 by Baryshev Dmitry + email : [email protected] + ***************************************************************************/ + +/*************************************************************************** + * * + * 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. * + * * + ***************************************************************************/ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include <tqlabel.h> +#include <tqbuttongroup.h> +#include <tqpushbutton.h> +#include <tqtoolbutton.h> +#include <tqtimer.h> +#include <tqapplication.h> + +#include <tdeaction.h> +#include <kcombobox.h> +#include <kstandarddirs.h> +#include <tdestdaccel.h> +#include <tdelocale.h> +#include <tdeio/job.h> +#include <tdefiledialog.h> +#include <tdemessagebox.h> +#include <kstringhandler.h> + +#include "ksquirrel.h" +#include "sq_config.h" +#include "sq_fileiconview.h" +#include "sq_filethumbview.h" +#include "sq_filedetailview.h" +#include "sq_widgetstack.h" +#include "sq_externaltool.h" +#include "sq_treeview.h" +#include "sq_hloptions.h" +#include "sq_archivehandler.h" +#include "sq_glview.h" +#include "sq_glwidget.h" +#include "sq_libraryhandler.h" +#include "sq_diroperator.h" +#include "sq_bookmarkowner.h" +#include "sq_thumbnailsize.h" +#include "sq_progressbox.h" +#include "sq_thumbnailloadjob.h" +#include "sq_pixmapcache.h" +#include "sq_selectdeselectgroup.h" +#include "sq_navigatordropmenu.h" + +SQ_WidgetStack * SQ_WidgetStack::m_instance = 0; + +SQ_WidgetStack::SQ_WidgetStack(TQWidget *parent, const int id) : TQObject(parent) +{ + m_instance = this; + + SQ_DirOperator::ViewT m_type = static_cast<SQ_DirOperator::ViewT>(id); + + KURL url; + + // Check Options for path + SQ_Config::instance()->setGroup("Fileview"); + + if(SQ_HLOptions::instance()->dir.isEmpty()) + { + switch(SQ_Config::instance()->readNumEntry("set path", 0)) + { + case 0: url = KURL::fromPathOrURL(SQ_Config::instance()->readEntry("last visited", "/")); break; + case 1: url = KURL::fromPathOrURL(TQDir::current().path()); break; + case 2: url = KURL::fromPathOrURL(SQ_Config::instance()->readEntry("custom directory", "/")); break; + + default: url = KURL::fromPathOrURL("/"); + } + } + else // path from command line + url = SQ_HLOptions::instance()->dir; + + dirop = new SQ_DirOperator(url, static_cast<SQ_DirOperator::ViewT>(id), parent); + + raiseWidget(m_type, false); + + connect(KSquirrel::app(), TQ_SIGNAL(thumbSizeChanged(const TQString&)), dirop, TQ_SLOT(slotSetThumbSize(const TQString&))); + connect(dirop, TQ_SIGNAL(runSeparately(KFileItem *)), this, TQ_SLOT(slotRunSeparately())); + + KSquirrel::app()->historyCombo()->setEditText(url.isLocalFile() ? url.path() : url.prettyURL()); + + timerShowProgress = new TQTimer(this); + connect(timerShowProgress, TQ_SIGNAL(timeout()), this, TQ_SLOT(slotDelayedShowProgress())); +} + +SQ_WidgetStack::~SQ_WidgetStack() +{} + +/* + * Get current url of visible diroperator. + */ +KURL SQ_WidgetStack::url() const +{ + return dirop->url(); +} + +void SQ_WidgetStack::init() +{ + SQ_Config::instance()->setGroup("Fileview"); + + fileaction = static_cast<SQ_WidgetStack::FileAction>(SQ_Config::instance()->readNumEntry("last_action", SQ_WidgetStack::Unknown)); + KURL uu = KURL::fromPathOrURL(SQ_Config::instance()->readEntry("last_url")); + + connect(SQ_NavigatorDropMenu::instance(), TQ_SIGNAL(done(const KURL &, int)), + this, TQ_SLOT(slotTreeMenuDone(const KURL &, int))); + + emitNewLastURL(uu); +} + +void SQ_WidgetStack::slotTreeMenuDone(const KURL &url, int a) +{ + if(a == SQ_NavigatorDropMenu::Copy) + fileaction = SQ_WidgetStack::Copy; + else if(a == SQ_NavigatorDropMenu::Move) + fileaction = SQ_WidgetStack::Cut; + else if(a == SQ_NavigatorDropMenu::Link) + fileaction = SQ_WidgetStack::Link; + + lastURL = url; + + emitNewLastURL(lastURL); +} + +void SQ_WidgetStack::setURL(const KURL &newurl, bool parseTree) +{ + KURL url = newurl; + url.adjustPath(+1); + + // update bookmarks' url + if(SQ_BookmarkOwner::instance()) + SQ_BookmarkOwner::instance()->setURL(url); + + // update history combobox + KSquirrel::app()->historyCombo()->setEditText(url.isLocalFile() ? url.path() : url.prettyURL()); + KSquirrel::app()->historyCombo()->addToHistory(url.isLocalFile() ? url.path() : url.prettyURL()); + + // set url for file tree + if(SQ_TreeView::instance() && parseTree) + { + SQ_Config::instance()->setGroup("Fileview"); + int sync_type = SQ_Config::instance()->readNumEntry("sync type", 0); + + if(sync_type != 2) + SQ_TreeView::instance()->emitNewURL(url); + } +} + +/* + * Select next/prevous supported image in filemanager. + * Do nothing, if no more supported images found in given + * direction. + */ +int SQ_WidgetStack::moveTo(Direction direction, KFileItem *it, bool useSupported) +{ + KFileView *local; + KFileItem *item; + + // current fileview + local = dirop->view(); + + if(it) + item = it; + else + item = (direction == SQ_WidgetStack::Next)? + local->nextItem(local->currentFileItem()): + local->prevItem(local->currentFileItem()); + + if(!item) + return moveFailed; + + if(useSupported) + { + while(true) + { + if(item->isFile()) + // supported image type ? +// if(SQ_LibraryHandler::instance()->libraryForFile(item->url().path())) + if(SQ_LibraryHandler::instance()->maybeSupported(item->url()) != SQ_LibraryHandler::No) + break; + + item = (direction == SQ_WidgetStack::Next)? + (local->nextItem(item)): + (local->prevItem(item)); + + if(!item) + return moveFailed; + } + } + + // set current file, select it + dirop->setCurrentItem(item); + + return moveSuccess; +} + +/* + * Set filter. + */ +void SQ_WidgetStack::setNameFilter(const TQString &f) +{ + dirop->setNameFilter(f); + dirop->actionCollection()->action("reload")->activate(); +} + +/* + * Get current filter. + */ +TQString SQ_WidgetStack::nameFilter() const +{ + return dirop->nameFilter(); +} + +/* + * Change view type. See SQ_DirOperator::ViewT for more. + */ +void SQ_WidgetStack::raiseWidget(SQ_DirOperator::ViewT id, bool doUpdate) +{ + if(doUpdate) dirop->stopThumbnailUpdate(); + + dirop->removeCdUpItem(); + dirop->prepareView(id); + + switch(id) + { + case SQ_DirOperator::TypeList: + case SQ_DirOperator::TypeIcons: + { + SQ_FileIconView *iv = dynamic_cast<SQ_FileIconView *>(dirop->preparedView()); + + dirop->setPreparedView(); + iv->setSelectionMode(KFile::Extended); + action("short view")->activate(); + + if(id == SQ_DirOperator::TypeList) + iv->actionCollection()->action("small columns")->activate(); + else + iv->actionCollection()->action("large rows")->activate(); + } + break; + + case SQ_DirOperator::TypeDetailed: + { + SQ_FileDetailView *dv = dynamic_cast<SQ_FileDetailView *>(dirop->preparedView()); + + dirop->setPreparedView(); + dv->setSelectionMode(KFile::Extended); + } + break; + + case SQ_DirOperator::TypeThumbs: + { + SQ_FileThumbView *tv = dynamic_cast<SQ_FileThumbView *>(dirop->preparedView()); + tv->actionCollection()->action("large rows")->activate(); + dirop->setPreparedView(); + action("short view")->activate(); + tv->setSelectionMode(KFile::Extended); + updateGrid(true); + if(doUpdate) dirop->startOrNotThumbnailUpdate(); + } + break; + } + + // enable/disable menu with thumbnail sizes + KSquirrel::app()->enableThumbsMenu(id == SQ_DirOperator::TypeThumbs); + dirop->enableThumbnailActions(id == SQ_DirOperator::TypeThumbs); + dirop->selectOld(); +} + +/* + * Selected items in currently visible diroperator. + */ +const KFileItemList* SQ_WidgetStack::selectedItems() const +{ + return dirop->view()->selectedItems(); +} + +/* + * All items in currently visible diroperator. + */ +const KFileItemList* SQ_WidgetStack::items() const +{ + return dirop->view()->items(); +} + +void SQ_WidgetStack::emitNextSelected() +{ + if(moveTo(SQ_WidgetStack::Next) == SQ_WidgetStack::moveSuccess) + { + KFileItem *fi = dirop->view()->currentFileItem(); + SQ_GLWidget::window()->setExpectedURL(fi->url()); + dirop->execute(fi); + } +} + +void SQ_WidgetStack::emitPreviousSelected() +{ + if(moveTo(SQ_WidgetStack::Previous) == SQ_WidgetStack::moveSuccess) + { + KFileItem *fi = dirop->view()->currentFileItem(); + SQ_GLWidget::window()->setExpectedURL(fi->url()); + dirop->execute(fi); + } +} + +void SQ_WidgetStack::slotSelectFirstFile() +{ + moveToFirstLast(SQ_WidgetStack::Next, false); +} + +void SQ_WidgetStack::slotSelectLastFile() +{ + moveToFirstLast(SQ_WidgetStack::Previous, false); +} + +// Go to first file +void SQ_WidgetStack::firstFile() +{ + moveToFirstLast(SQ_WidgetStack::Next); +} + +// Go to last file +void SQ_WidgetStack::lastFile() +{ + moveToFirstLast(SQ_WidgetStack::Previous); +} + +void SQ_WidgetStack::moveToFirstLast(Direction direct, bool exec) +{ + KFileView *local_view = dirop->view(); + KFileItemList *list = const_cast<KFileItemList*>(local_view->items()); + + if(list) + { + KFileItem *item = (direct == SQ_WidgetStack::Next) ? list->first() : list->last(); + + if(!item || moveTo(direct, item) == moveFailed) + return; + + item = local_view->currentFileItem(); + + if(item) + { + dirop->setCurrentItem(item); + SQ_GLWidget::window()->setExpectedURL(item->url()); + if(exec) dirop->execute(item); + } + } +} + +/* + * Update grid for thumbnail view. New grid is calcalated from item + * margins (from Options). + */ +void SQ_WidgetStack::updateGrid(bool arrange) +{ + if(dirop->viewType() != SQ_DirOperator::TypeThumbs) + return; + + SQ_Config::instance()->setGroup("Thumbnails"); + int newgrid = SQ_ThumbnailSize::instance()->extended() ? + SQ_ThumbnailSize::instance()->extendedSize().width() + : SQ_ThumbnailSize::instance()->pixelSize(); + + newgrid += (SQ_Config::instance()->readNumEntry("margin", 2) + 2); + + SQ_FileThumbView *tv = dynamic_cast<SQ_FileThumbView *>(dirop->view()); + + // different grid ? + if(tv->gridX() != newgrid) + { + tv->setGridX(newgrid); + + if(arrange) + tv->arrangeItemsInGrid(); + } +} + +void SQ_WidgetStack::thumbnailsUpdateEnded() +{ + if(dirop->viewType() != SQ_DirOperator::TypeThumbs) + return; + + SQ_FileThumbView *tv = dynamic_cast<SQ_FileThumbView *>(dirop->view()); + + if(!tv) return; + + timerShowProgress->stop(); + tv->progressBox()->hide(); + tv->progressBox()->flush(); + tv->progressBox()->startButtonPixmap(); +} + +void SQ_WidgetStack::thumbnailUpdateStart(int count) +{ + SQ_FileThumbView *tv = dynamic_cast<SQ_FileThumbView *>(dirop->view()); + + if(!tv) return; + + tv->progressBox()->setTotalSteps(count); + tv->progressBox()->stopButtonPixmap(); + + timerShowProgress->start(1000, true); +} + +void SQ_WidgetStack::slotDelayedShowProgress() +{ + SQ_FileThumbView *tv = dynamic_cast<SQ_FileThumbView *>(dirop->view()); + + if(tv) + tv->progressBox()->show(); +} + +void SQ_WidgetStack::thumbnailProcess() +{ + SQ_FileThumbView *tv = dynamic_cast<SQ_FileThumbView *>(dirop->view()); + + if(tv) + tv->progressBox()->advance(); +} + +void SQ_WidgetStack::setURLForCurrent(const TQString &path, bool parseTree) +{ + KURL url = KURL::fromPathOrURL(path); + + setURLForCurrent(url, parseTree); +} + +void SQ_WidgetStack::setURLForCurrent(const KURL &url, bool parseTree) +{ + setURL(url, parseTree); + dirop->setURL(url, true); +} + +void SQ_WidgetStack::updateView() +{ + dirop->actionCollection()->action("reload")->activate(); +} + +void SQ_WidgetStack::slotRunSeparately() +{ + const KFileItemList *selected = selectedItems(); + KFileItemListIterator it(*selected); + + KFileItem *item; + + while((item = it.current())) + { + if(item) + item->run(); + + ++it; + } +} + +// recreate selected thumbnails +void SQ_WidgetStack::slotRecreateThumbnail() +{ + // oops, not a thumbnail view + if(dirop->viewType() != SQ_DirOperator::TypeThumbs) + return; + + SQ_FileThumbView *tv = dynamic_cast<SQ_FileThumbView *>(dirop->view()); + + if(tv->updateRunning()) + return; + + tv->progressBox()->show(); + + TQTimer::singleShot(1, this, TQ_SLOT(slotDelayedRecreateThumbnail())); +} + +void SQ_WidgetStack::slotDelayedRecreateThumbnail() +{ + SQ_Thumbnail thumb; + + KFileItemList *list = const_cast<KFileItemList *>(selectedItems()); + SQ_FileThumbView *tv = dynamic_cast<SQ_FileThumbView *>(dirop->view()); + + if(!list || !tv) + return; + + KFileItemListIterator it(*list); + KFileItem *item; + + while((item = it.current())) + { + SQ_PixmapCache::instance()->removeEntryFull(item->url()); + ++it; + } + + tv->doStartThumbnailUpdate(*list); +} + +/* + * Save currently selected items' paths, if any. + * + * Return true, if at least one url was saved. + */ +bool SQ_WidgetStack::prepare() +{ + // clear old files + files.clear(); + + KFileItemList *items = const_cast<KFileItemList *>(selectedItems()); + KFileItem *i; + + if(!items || items->isEmpty()) + { + KMessageBox::information(dirop, i18n("No files to copy or move")); + return false; + } + + i = items->first(); + + while(i) + { + files.append(i->url()); + i = items->next(); + } + + return true; +} + +/* + * Slots for file actions: copy, move, cut... + */ +void SQ_WidgetStack::slotFileCopy() +{ + fileaction = (prepare()) ? SQ_WidgetStack::Copy : SQ_WidgetStack::Unknown; +} + +void SQ_WidgetStack::slotFileCut() +{ + fileaction = (prepare()) ? SQ_WidgetStack::Cut : SQ_WidgetStack::Unknown; +} + +// Paste files +void SQ_WidgetStack::slotFilePaste() +{ + // No files to copy ? + if(files.isEmpty() || fileaction == SQ_WidgetStack::Unknown) + { + KMessageBox::information(dirop, i18n("No files to copy or move")); + return; + } + + // get current url + KURL _url = url(); + emitNewLastURL(_url); + TDEIO::Job *job; + + // now copy or move files to current url + job = (fileaction == SQ_WidgetStack::Copy) ? TDEIO::copy(files, _url) : TDEIO::move(files, _url); + connect(job, TQ_SIGNAL(result(TDEIO::Job *)), this, TQ_SLOT(slotJobResult(TDEIO::Job *))); +} + +void SQ_WidgetStack::slotJobResult(TDEIO::Job *job) +{ + if(job && job->error()) + job->showErrorDialog(KSquirrel::app()); +} + +void SQ_WidgetStack::emitNewLastURL(const KURL &u) +{ + lastURL = u; + TQString text; + + TQString targ = KStringHandler::csqueeze(u.isLocalFile() ? u.path() : u.prettyURL(), 25); + + if(fileaction == SQ_WidgetStack::Copy) + text = i18n("Repeat (copy to %1)").arg(targ); + else if(fileaction == SQ_WidgetStack::Cut) + text = i18n("Repeat (move to %1)").arg(targ); + else if(fileaction == SQ_WidgetStack::Link) + text = i18n("Repeat (link to %1)").arg(targ); + + if(!text.isEmpty()) + emit newLastURL(text); +} + +void SQ_WidgetStack::repeat() +{ + if(fileaction == SQ_WidgetStack::Copy || fileaction == SQ_WidgetStack::Cut) + prepare(); + else + return; + + // No files to copy ? + if(lastURL.isEmpty() || files.isEmpty()) + return; + + TDEIO::Job *job = (fileaction == SQ_WidgetStack::Copy) ? TDEIO::copy(files, lastURL) : TDEIO::move(files, lastURL); + connect(job, TQ_SIGNAL(result(TDEIO::Job *)), this, TQ_SLOT(slotJobResult(TDEIO::Job *))); +} + +// Create links +void SQ_WidgetStack::slotFileLinkTo() +{ + if(!prepare()) + return; + + // select a directory + KURL url = KFileDialog::getExistingURL(lastURL.url(), dirop); + + if(url.isEmpty()) + return; + + fileaction = SQ_WidgetStack::Link; + emitNewLastURL(url); + + // create symlinks + TDEIO::link(files, url); +} + +// Copy to... +void SQ_WidgetStack::slotFileCopyTo() +{ + if(!prepare()) + return; + + // select a directory + KURL url = KFileDialog::getExistingURL(lastURL.url(), dirop); + + if(url.isEmpty()) + return; + + fileaction = SQ_WidgetStack::Copy; + emitNewLastURL(url); + + // copy files to selected directory + TDEIO::copy(files, url); +} + +// Move to... +void SQ_WidgetStack::slotFileMoveTo() +{ + if(!prepare()) + return; + + // select a directory + KURL url = KFileDialog::getExistingURL(lastURL.url(), dirop); + + if(url.isEmpty()) + return; + + fileaction = SQ_WidgetStack::Cut; + emitNewLastURL(url); + + // move files to selected directory + TDEIO::move(files, url); +} + +/* + * User wants to select to deselect some files. + */ +void SQ_WidgetStack::slotSelectGroup() +{ + selectDeselectGroup(true); +} + +void SQ_WidgetStack::slotDeselectGroup() +{ + selectDeselectGroup(false); +} + +/* + * Execute SQ_SelectDeselectGroup dialog, and select or + * deselect files after it has been closed. + */ +void SQ_WidgetStack::selectDeselectGroup(bool select) +{ + TQString mask; + + KFileView *local = dirop->view(); + + SQ_SelectDeselectGroup sd(KSquirrel::app()); + + sd.setCaption(select ? i18n("Select a group of files") : i18n("Deselect a group of files")); + sd.pushMask->setText(select ? i18n("Select !") : i18n("Deselect !")); + + if(sd.exec(mask) == TQDialog::Accepted) + { + if(select) + local->clearSelection(); + + KFileItemList *sd_files = const_cast<KFileItemList *>(items()); + KFileItem *i; + TQRegExp exp(mask); + exp.setWildcard(true); + + if(!sd_files) + return; + + i = sd_files->first(); + + // go through all files + while(i) + { + // name matched + if(exp.exactMatch(i->name())) + local->setSelected(i, select); + + // next file + i = sd_files->next(); + } + } +} + +/* + * Deselect all files. + */ +void SQ_WidgetStack::slotDeselectAll() +{ + dirop->view()->clearSelection(); +} + +/* + * Select all files. + */ +void SQ_WidgetStack::slotSelectAll() +{ + KFileItemList *sd_files = const_cast<KFileItemList *>(items()); + KFileView *local = dirop->view(); + KFileItem *i; + + if(!sd_files) + return; + + i = sd_files->first(); + + // go through files and select them all + while(i) + { + local->setSelected(i, true); + i = sd_files->next(); + } +} + +TDEAction* SQ_WidgetStack::action(const TQString &name) +{ + return dirop->actionCollection()->action(name); +} + +bool SQ_WidgetStack::updateRunning() const +{ + if(dirop->viewType() != SQ_DirOperator::TypeThumbs) + return false; + + SQ_FileThumbView *tv = dynamic_cast<SQ_FileThumbView *>(dirop->view()); + + if(!tv) + return false; + + return tv->updateRunning(); +} + +void SQ_WidgetStack::saveState() +{ + SQ_Config::instance()->writeEntry("last visited", dirop->url().prettyURL()); + SQ_Config::instance()->writeEntry("last_action", static_cast<int>(fileaction)); + SQ_Config::instance()->writeEntry("last_url", lastURL.prettyURL()); + + dirop->saveConfig(); +} + +#include "sq_widgetstack.moc" |