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.
657 lines
24 KiB
657 lines
24 KiB
/*
|
|
|
|
Copyright (C) 2013 Hong Jen Yee (PCMan) <pcman.tw@gmail.com>
|
|
|
|
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.
|
|
*/
|
|
|
|
|
|
#include "tabpage.h"
|
|
#include "launcher.h"
|
|
#include <libfm-qt/filemenu.h>
|
|
#include <libfm-qt/mountoperation.h>
|
|
#include <libfm-qt/proxyfoldermodel.h>
|
|
#include <libfm-qt/cachedfoldermodel.h>
|
|
#include <libfm-qt/core/fileinfo.h>
|
|
#include <libfm-qt/utilities.h>
|
|
#include <QApplication>
|
|
#include <QCursor>
|
|
#include <QMessageBox>
|
|
#include <QScrollBar>
|
|
#include <QDir>
|
|
#include "settings.h"
|
|
#include "application.h"
|
|
#include <QTimer>
|
|
#include <QTextStream>
|
|
#include <QDebug>
|
|
|
|
using namespace Fm;
|
|
|
|
namespace PCManFM {
|
|
|
|
bool ProxyFilter::filterAcceptsRow(const Fm::ProxyFolderModel* model, const std::shared_ptr<const Fm::FileInfo>& info) const {
|
|
if(!model || !info) {
|
|
return true;
|
|
}
|
|
QString baseName = QString::fromStdString(info->name());
|
|
if(!virtHiddenList_.isEmpty() && !model->showHidden() && virtHiddenList_.contains(baseName)) {
|
|
return false;
|
|
}
|
|
if(!filterStr_.isEmpty() && !baseName.contains(filterStr_, Qt::CaseInsensitive)) {
|
|
return false;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
void ProxyFilter::setVirtHidden(const std::shared_ptr<Fm::Folder> &folder) {
|
|
virtHiddenList_ = QStringList(); // reset the list
|
|
if(!folder) {
|
|
return;
|
|
}
|
|
auto path = folder->path();
|
|
if(path) {
|
|
auto pathStr = path.localPath();
|
|
if(pathStr) {
|
|
QString dotHidden = QString::fromUtf8(pathStr.get()) + QString("/.hidden");
|
|
// FIXME: this does not work for non-local filesystems
|
|
QFile file(dotHidden);
|
|
if(file.open(QIODevice::ReadOnly | QIODevice::Text)) {
|
|
QTextStream in(&file);
|
|
while(!in.atEnd()) {
|
|
virtHiddenList_.append(in.readLine());
|
|
}
|
|
file.close();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
TabPage::TabPage(QWidget* parent):
|
|
QWidget(parent),
|
|
folderView_{nullptr},
|
|
folderModel_{nullptr},
|
|
proxyModel_{nullptr},
|
|
proxyFilter_{nullptr},
|
|
verticalLayout{nullptr},
|
|
overrideCursor_(false) {
|
|
|
|
Settings& settings = static_cast<Application*>(qApp)->settings();
|
|
|
|
// create proxy folder model to do item filtering
|
|
proxyModel_ = new ProxyFolderModel();
|
|
proxyModel_->setShowHidden(settings.showHidden());
|
|
proxyModel_->setShowThumbnails(settings.showThumbnails());
|
|
connect(proxyModel_, &ProxyFolderModel::sortFilterChanged, this, &TabPage::sortFilterChanged);
|
|
|
|
verticalLayout = new QVBoxLayout(this);
|
|
verticalLayout->setContentsMargins(0, 0, 0, 0);
|
|
|
|
folderView_ = new View(settings.viewMode(), this);
|
|
folderView_->setMargins(settings.folderViewCellMargins());
|
|
// newView->setColumnWidth(Fm::FolderModel::ColumnName, 200);
|
|
connect(folderView_, &View::openDirRequested, this, &TabPage::openDirRequested);
|
|
connect(folderView_, &View::selChanged, this, &TabPage::onSelChanged);
|
|
connect(folderView_, &View::clickedBack, this, &TabPage::backwardRequested);
|
|
connect(folderView_, &View::clickedForward, this, &TabPage::forwardRequested);
|
|
|
|
proxyFilter_ = new ProxyFilter();
|
|
proxyModel_->addFilter(proxyFilter_);
|
|
|
|
// FIXME: this is very dirty
|
|
folderView_->setModel(proxyModel_);
|
|
verticalLayout->addWidget(folderView_);
|
|
}
|
|
|
|
TabPage::~TabPage() {
|
|
freeFolder();
|
|
if(proxyFilter_) {
|
|
delete proxyFilter_;
|
|
}
|
|
if(proxyModel_) {
|
|
delete proxyModel_;
|
|
}
|
|
disconnect(folderModel_, &Fm::FolderModel::fileSizeChanged, this, &TabPage::onFileSizeChanged);
|
|
if(folderModel_) {
|
|
folderModel_->unref();
|
|
}
|
|
|
|
if(overrideCursor_) {
|
|
QApplication::restoreOverrideCursor(); // remove busy cursor
|
|
}
|
|
}
|
|
|
|
void TabPage::freeFolder() {
|
|
if(folder_) {
|
|
if(folderSettings_.isCustomized()) {
|
|
// save custom view settings for this folder
|
|
static_cast<Application*>(qApp)->settings().saveFolderSettings(folder_->path(), folderSettings_);
|
|
}
|
|
disconnect(folder_.get(), nullptr, this, nullptr); // disconnect from all signals
|
|
folder_ = nullptr;
|
|
}
|
|
}
|
|
|
|
void TabPage::onFolderStartLoading() {
|
|
if(!overrideCursor_) {
|
|
// FIXME: sometimes FmFolder of libfm generates unpaired "start-loading" and
|
|
// "finish-loading" signals of uncertain reasons. This should be a bug in libfm.
|
|
// Until it's fixed in libfm, we need to workaround the problem here, not to
|
|
// override the cursor twice.
|
|
QApplication::setOverrideCursor(QCursor(Qt::WaitCursor));
|
|
overrideCursor_ = true;
|
|
}
|
|
#if 0
|
|
#if FM_CHECK_VERSION(1, 0, 2) && 0 // disabled
|
|
if(fm_folder_is_incremental(_folder)) {
|
|
/* create a model for the folder and set it to the view
|
|
it is delayed for non-incremental folders since adding rows into
|
|
model is much faster without handlers connected to its signals */
|
|
FmFolderModel* model = fm_folder_model_new(folder, FALSE);
|
|
fm_folder_view_set_model(fv, model);
|
|
fm_folder_model_set_sort(model, app_config->sort_by,
|
|
(app_config->sort_type == GTK_SORT_ASCENDING) ?
|
|
FM_SORT_ASCENDING : FM_SORT_DESCENDING);
|
|
g_object_unref(model);
|
|
}
|
|
else
|
|
#endif
|
|
fm_folder_view_set_model(fv, nullptr);
|
|
#endif
|
|
}
|
|
|
|
void TabPage::onUiUpdated() {
|
|
// scroll to recorded position
|
|
folderView_->childView()->verticalScrollBar()->setValue(browseHistory().currentScrollPos());
|
|
|
|
// if the current folder is the parent folder of the last browsed folder,
|
|
// select the folder item in current view.
|
|
if(lastFolderPath_ && lastFolderPath_.parent() == path()) {
|
|
QModelIndex index = folderView_->indexFromFolderPath(lastFolderPath_);
|
|
if(index.isValid()) {
|
|
folderView_->childView()->scrollTo(index, QAbstractItemView::EnsureVisible);
|
|
folderView_->childView()->setCurrentIndex(index);
|
|
}
|
|
}
|
|
// update selection statusbar info when needed
|
|
connect(folderModel_, &Fm::FolderModel::fileSizeChanged, this, &TabPage::onFileSizeChanged);
|
|
}
|
|
|
|
void TabPage::onFileSizeChanged(const QModelIndex& index) {
|
|
if(folderView_->hasSelection()) {
|
|
QModelIndexList indexes = folderView_->selectionModel()->selectedIndexes();
|
|
if(indexes.contains(proxyModel_->mapFromSource(index))) {
|
|
onSelChanged();
|
|
}
|
|
}
|
|
}
|
|
|
|
void TabPage::onFolderFinishLoading() {
|
|
auto fi = folder_->info();
|
|
if(fi) { // if loading of the folder fails, it's possible that we don't have FmFileInfo.
|
|
setWindowTitle(fi->displayName());
|
|
Q_EMIT titleChanged(fi->displayName());
|
|
}
|
|
|
|
folder_->queryFilesystemInfo(); // FIXME: is this needed?
|
|
#if 0
|
|
FmFolderView* fv = folder_view;
|
|
const FmNavHistoryItem* item;
|
|
GtkScrolledWindow* scroll = GTK_SCROLLED_WINDOW(fv);
|
|
|
|
/* Note: most of the time, we delay the creation of the
|
|
* folder model and do it after the whole folder is loaded.
|
|
* That is because adding rows into model is much faster when no handlers
|
|
* are connected to its signals. So we detach the model from folder view
|
|
* and create the model again when it's fully loaded.
|
|
* This optimization, however, is not used for FmFolder objects
|
|
* with incremental loading (search://) */
|
|
if(fm_folder_view_get_model(fv) == nullptr) {
|
|
/* create a model for the folder and set it to the view */
|
|
FmFolderModel* model = fm_folder_model_new(folder, app_config->show_hidden);
|
|
fm_folder_view_set_model(fv, model);
|
|
#if FM_CHECK_VERSION(1, 0, 2)
|
|
/* since 1.0.2 sorting should be applied on model instead of view */
|
|
fm_folder_model_set_sort(model, app_config->sort_by,
|
|
(app_config->sort_type == GTK_SORT_ASCENDING) ?
|
|
FM_SORT_ASCENDING : FM_SORT_DESCENDING);
|
|
#endif
|
|
g_object_unref(model);
|
|
}
|
|
|
|
#endif
|
|
|
|
// update status text
|
|
QString& text = statusText_[StatusTextNormal];
|
|
text = formatStatusText();
|
|
Q_EMIT statusChanged(StatusTextNormal, text);
|
|
|
|
if(overrideCursor_) {
|
|
QApplication::restoreOverrideCursor(); // remove busy cursor
|
|
overrideCursor_ = false;
|
|
}
|
|
|
|
// After finishing loading the folder, the model is updated, but Qt delays the UI update
|
|
// for performance reasons. Therefore at this point the UI is not up to date.
|
|
// For example, the scrollbar ranges are not updated yet. We solve this by installing an Qt timeout handler.
|
|
QTimer::singleShot(10, this, SLOT(onUiUpdated()));
|
|
}
|
|
|
|
void TabPage::onFolderError(const Fm::GErrorPtr& err, Fm::Job::ErrorSeverity severity, Fm::Job::ErrorAction& response) {
|
|
if(err.domain() == G_IO_ERROR) {
|
|
if(err.code() == G_IO_ERROR_NOT_MOUNTED && severity < Fm::Job::ErrorSeverity::CRITICAL) {
|
|
auto& path = folder_->path();
|
|
MountOperation* op = new MountOperation(this);
|
|
op->mount(path);
|
|
if(op->wait()) { // blocking event loop, wait for mount operation to finish.
|
|
// This will reload the folder, which generates a new "start-loading"
|
|
// signal, so we get more "start-loading" signals than "finish-loading"
|
|
// signals. FIXME: This is a bug of libfm.
|
|
// Because the two signals are not correctly paired, we need to
|
|
// remove busy cursor here since "finish-loading" is not emitted.
|
|
QApplication::restoreOverrideCursor(); // remove busy cursor
|
|
overrideCursor_ = false;
|
|
response = Fm::Job::ErrorAction::RETRY;
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
if(severity >= Fm::Job::ErrorSeverity::MODERATE) {
|
|
/* Only show more severe errors to the users and
|
|
* ignore milder errors. Otherwise too many error
|
|
* message boxes can be annoying.
|
|
* This fixes bug #3411298- Show "Permission denied" when switching to super user mode.
|
|
* https://sourceforge.net/tracker/?func=detail&aid=3411298&group_id=156956&atid=801864
|
|
* */
|
|
|
|
// FIXME: consider replacing this modal dialog with an info bar to improve usability
|
|
QMessageBox::critical(this, tr("Error"), err.message());
|
|
}
|
|
response = Fm::Job::ErrorAction::CONTINUE;
|
|
}
|
|
|
|
void TabPage::onFolderFsInfo() {
|
|
guint64 free, total;
|
|
QString& msg = statusText_[StatusTextFSInfo];
|
|
if(folder_->getFilesystemInfo(&total, &free)) {
|
|
char total_str[64];
|
|
char free_str[64];
|
|
fm_file_size_to_str(free_str, sizeof(free_str), free, fm_config->si_unit);
|
|
fm_file_size_to_str(total_str, sizeof(total_str), total, fm_config->si_unit);
|
|
msg = tr("Free space: %1 (Total: %2)")
|
|
.arg(QString::fromUtf8(free_str))
|
|
.arg(QString::fromUtf8(total_str));
|
|
}
|
|
else {
|
|
msg.clear();
|
|
}
|
|
Q_EMIT statusChanged(StatusTextFSInfo, msg);
|
|
}
|
|
|
|
QString TabPage::formatStatusText() {
|
|
if(proxyModel_ && folder_) {
|
|
// FIXME: this is very inefficient
|
|
auto files = folder_->files();
|
|
int total_files = files.size();
|
|
int shown_files = proxyModel_->rowCount();
|
|
int hidden_files = total_files - shown_files;
|
|
QString text = tr("%n item(s)", "", shown_files);
|
|
if(hidden_files > 0) {
|
|
text += tr(" (%n hidden)", "", hidden_files);
|
|
}
|
|
return text;
|
|
}
|
|
return QString();
|
|
}
|
|
|
|
void TabPage::onFolderRemoved() {
|
|
// the folder we're showing is removed, destroy the widget
|
|
qDebug("folder removed");
|
|
Settings& settings = static_cast<Application*>(qApp)->settings();
|
|
// NOTE: call deleteLater() directly from this GObject signal handler
|
|
// does not work but I don't know why.
|
|
// Maybe it's the problem of glib mainloop integration?
|
|
// Call it when idle works, though.
|
|
if(settings.closeOnUnmount()) {
|
|
QTimer::singleShot(0, this, SLOT(deleteLater()));
|
|
}
|
|
else {
|
|
chdir(Fm::FilePath::homeDir());
|
|
}
|
|
}
|
|
|
|
void TabPage::onFolderUnmount() {
|
|
// the folder we're showing is unmounted, destroy the widget
|
|
qDebug("folder unmount");
|
|
// NOTE: call deleteLater() directly from this GObject signal handler
|
|
// does not work but I don't know why.
|
|
// Maybe it's the problem of glib mainloop integration?
|
|
// Call it when idle works, though.
|
|
Settings& settings = static_cast<Application*>(qApp)->settings();
|
|
// NOTE: call deleteLater() directly from this GObject signal handler
|
|
// does not work but I don't know why.
|
|
// Maybe it's the problem of glib mainloop integration?
|
|
// Call it when idle works, though.
|
|
if(settings.closeOnUnmount()) {
|
|
QTimer::singleShot(0, this, SLOT(deleteLater()));
|
|
}
|
|
else {
|
|
chdir(Fm::FilePath::homeDir());
|
|
}
|
|
}
|
|
|
|
void TabPage::onFolderContentChanged() {
|
|
/* update status text */
|
|
statusText_[StatusTextNormal] = formatStatusText();
|
|
Q_EMIT statusChanged(StatusTextNormal, statusText_[StatusTextNormal]);
|
|
}
|
|
|
|
QString TabPage::pathName() {
|
|
// auto disp_path = path().displayName();
|
|
// FIXME: displayName() returns invalid path sometimes.
|
|
auto disp_path = path().toString();
|
|
return QString::fromUtf8(disp_path.get());
|
|
}
|
|
|
|
void TabPage::chdir(Fm::FilePath newPath, bool addHistory) {
|
|
// qDebug() << "TABPAGE CHDIR:" << newPath.toString().get();
|
|
if(folder_) {
|
|
// we're already in the specified dir
|
|
if(newPath == folder_->path()) {
|
|
return;
|
|
}
|
|
|
|
// reset the status selected text
|
|
statusText_[StatusTextSelectedFiles] = QString();
|
|
|
|
// remember the previous folder path that we have browsed.
|
|
lastFolderPath_ = folder_->path();
|
|
|
|
if(addHistory) {
|
|
// store current scroll pos in the browse history
|
|
BrowseHistoryItem& item = history_.currentItem();
|
|
QAbstractItemView* childView = folderView_->childView();
|
|
item.setScrollPos(childView->verticalScrollBar()->value());
|
|
}
|
|
|
|
// free the previous model
|
|
if(folderModel_) {
|
|
disconnect(folderModel_, &Fm::FolderModel::fileSizeChanged, this, &TabPage::onFileSizeChanged);
|
|
proxyModel_->setSourceModel(nullptr);
|
|
folderModel_->unref(); // unref the cached model
|
|
folderModel_ = nullptr;
|
|
}
|
|
|
|
freeFolder();
|
|
}
|
|
|
|
Q_EMIT titleChanged(newPath.baseName().get()); // FIXME: display name
|
|
|
|
folder_ = Fm::Folder::fromPath(newPath);
|
|
proxyFilter_->setVirtHidden(folder_);
|
|
if(addHistory) {
|
|
// add current path to browse history
|
|
history_.add(path());
|
|
}
|
|
connect(folder_.get(), &Fm::Folder::startLoading, this, &TabPage::onFolderStartLoading);
|
|
connect(folder_.get(), &Fm::Folder::finishLoading, this, &TabPage::onFolderFinishLoading);
|
|
|
|
// FIXME: Fm::Folder::error() is a bad design and might be removed in the future.
|
|
connect(folder_.get(), &Fm::Folder::error, this, &TabPage::onFolderError);
|
|
connect(folder_.get(), &Fm::Folder::fileSystemChanged, this, &TabPage::onFolderFsInfo);
|
|
/* destroy the page when the folder is unmounted or deleted. */
|
|
connect(folder_.get(), &Fm::Folder::removed, this, &TabPage::onFolderRemoved);
|
|
connect(folder_.get(), &Fm::Folder::unmount, this, &TabPage::onFolderUnmount);
|
|
connect(folder_.get(), &Fm::Folder::contentChanged, this, &TabPage::onFolderContentChanged);
|
|
|
|
folderModel_ = CachedFolderModel::modelFromFolder(folder_);
|
|
|
|
// set sorting, considering customized folders
|
|
Settings& settings = static_cast<Application*>(qApp)->settings();
|
|
folderSettings_ = settings.loadFolderSettings(path());
|
|
proxyModel_->sort(folderSettings_.sortColumn(), folderSettings_.sortOrder());
|
|
proxyModel_->setFolderFirst(folderSettings_.sortFolderFirst());
|
|
proxyModel_->setShowHidden(folderSettings_.showHidden());
|
|
proxyModel_->setSortCaseSensitivity(folderSettings_.sortCaseSensitive() ? Qt::CaseSensitive : Qt::CaseInsensitive);
|
|
proxyModel_->setSourceModel(folderModel_);
|
|
|
|
folderView_->setViewMode(folderSettings_.viewMode());
|
|
|
|
if(folder_->isLoaded()) {
|
|
onFolderStartLoading();
|
|
onFolderFinishLoading();
|
|
onFolderFsInfo();
|
|
}
|
|
else {
|
|
onFolderStartLoading();
|
|
}
|
|
}
|
|
|
|
void TabPage::selectAll() {
|
|
folderView_->selectAll();
|
|
}
|
|
|
|
void TabPage::invertSelection() {
|
|
folderView_->invertSelection();
|
|
}
|
|
|
|
void TabPage::reload() {
|
|
if(folder_) {
|
|
proxyFilter_->setVirtHidden(folder_); // reread ".hidden"
|
|
// don't select or scroll to the previous folder after reload
|
|
lastFolderPath_ = Fm::FilePath();
|
|
// but remember the current scroll position
|
|
BrowseHistoryItem& item = history_.currentItem();
|
|
QAbstractItemView* childView = folderView_->childView();
|
|
item.setScrollPos(childView->verticalScrollBar()->value());
|
|
|
|
folder_->reload();
|
|
}
|
|
}
|
|
|
|
// when the current selection in the folder view is changed
|
|
void TabPage::onSelChanged() {
|
|
QString msg;
|
|
if(folderView_->hasSelection()) {
|
|
auto files = folderView_->selectedFiles();
|
|
int numSel = files.size();
|
|
/* FIXME: display total size of all selected files. */
|
|
if(numSel == 1) { /* only one file is selected */
|
|
auto& fi = files.front();
|
|
if(!fi->isDir()) {
|
|
msg = QString("\"%1\" (%2) %3")
|
|
.arg(fi->displayName())
|
|
.arg(Fm::formatFileSize(fi->size(), fm_config->si_unit)) // FIXME: deprecate fm_config
|
|
.arg(fi->mimeType()->desc());
|
|
}
|
|
else {
|
|
msg = QString("\"%1\" %2")
|
|
.arg(fi->displayName())
|
|
.arg(fi->mimeType()->desc());
|
|
}
|
|
/* FIXME: should we support statusbar plugins as in the gtk+ version? */
|
|
}
|
|
else {
|
|
goffset sum;
|
|
GList* l;
|
|
msg = tr("%n item(s) selected", nullptr, numSel);
|
|
/* don't count if too many files are selected, that isn't lightweight */
|
|
if(numSel < 1000) {
|
|
sum = 0;
|
|
for(auto& fi: files) {
|
|
if(fi->isDir()) {
|
|
/* if we got a directory then we cannot tell it's size
|
|
unless we do deep count but we cannot afford it */
|
|
sum = -1;
|
|
break;
|
|
}
|
|
sum += fi->size();
|
|
}
|
|
if(sum >= 0) {
|
|
msg += QString(" (%1)").arg(Fm::formatFileSize(sum, fm_config->si_unit)); // FIXME: deprecate fm_config
|
|
}
|
|
/* FIXME: should we support statusbar plugins as in the gtk+ version? */
|
|
}
|
|
/* FIXME: can we show some more info on selection?
|
|
that isn't lightweight if a lot of files are selected */
|
|
}
|
|
}
|
|
statusText_[StatusTextSelectedFiles] = msg;
|
|
Q_EMIT statusChanged(StatusTextSelectedFiles, msg);
|
|
}
|
|
|
|
|
|
void TabPage::backward() {
|
|
// remember current scroll position
|
|
BrowseHistoryItem& item = history_.currentItem();
|
|
QAbstractItemView* childView = folderView_->childView();
|
|
item.setScrollPos(childView->verticalScrollBar()->value());
|
|
|
|
history_.backward();
|
|
chdir(history_.currentPath(), false);
|
|
}
|
|
|
|
void TabPage::forward() {
|
|
// remember current scroll position
|
|
BrowseHistoryItem& item = history_.currentItem();
|
|
QAbstractItemView* childView = folderView_->childView();
|
|
item.setScrollPos(childView->verticalScrollBar()->value());
|
|
|
|
history_.forward();
|
|
chdir(history_.currentPath(), false);
|
|
}
|
|
|
|
void TabPage::jumpToHistory(int index) {
|
|
if(index >= 0 && index < history_.size()) {
|
|
// remember current scroll position
|
|
BrowseHistoryItem& item = history_.currentItem();
|
|
QAbstractItemView* childView = folderView_->childView();
|
|
item.setScrollPos(childView->verticalScrollBar()->value());
|
|
|
|
history_.setCurrentIndex(index);
|
|
chdir(history_.currentPath(), false);
|
|
}
|
|
}
|
|
|
|
bool TabPage::canUp() {
|
|
auto _path = path();
|
|
return (_path && _path.hasParent());
|
|
}
|
|
|
|
void TabPage::up() {
|
|
auto _path = path();
|
|
if(_path) {
|
|
auto parent = _path.parent();
|
|
if(parent) {
|
|
chdir(parent, true);
|
|
}
|
|
}
|
|
}
|
|
|
|
void TabPage::updateFromSettings(Settings& settings) {
|
|
folderView_->updateFromSettings(settings);
|
|
}
|
|
|
|
void TabPage::setViewMode(Fm::FolderView::ViewMode mode) {
|
|
if(folderSettings_.viewMode() != mode) {
|
|
folderSettings_.setViewMode(mode);
|
|
if(folderSettings_.isCustomized()) {
|
|
static_cast<Application*>(qApp)->settings().saveFolderSettings(path(), folderSettings_);
|
|
}
|
|
}
|
|
folderView_->setViewMode(mode);
|
|
}
|
|
|
|
void TabPage::sort(int col, Qt::SortOrder order) {
|
|
if(folderSettings_.sortColumn() != col || folderSettings_.sortOrder() != order) {
|
|
folderSettings_.setSortColumn(Fm::FolderModel::ColumnId(col));
|
|
folderSettings_.setSortOrder(order);
|
|
if(folderSettings_.isCustomized()) {
|
|
static_cast<Application*>(qApp)->settings().saveFolderSettings(path(), folderSettings_);
|
|
}
|
|
}
|
|
if(proxyModel_) {
|
|
proxyModel_->sort(col, order);
|
|
}
|
|
}
|
|
|
|
void TabPage::setSortFolderFirst(bool value) {
|
|
if(folderSettings_.sortFolderFirst() != value) {
|
|
folderSettings_.setSortFolderFirst(value);
|
|
if(folderSettings_.isCustomized()) {
|
|
static_cast<Application*>(qApp)->settings().saveFolderSettings(path(), folderSettings_);
|
|
}
|
|
}
|
|
proxyModel_->setFolderFirst(value);
|
|
}
|
|
|
|
void TabPage::setSortCaseSensitive(bool value) {
|
|
if(folderSettings_.sortCaseSensitive() != value) {
|
|
folderSettings_.setSortCaseSensitive(value);
|
|
if(folderSettings_.isCustomized()) {
|
|
static_cast<Application*>(qApp)->settings().saveFolderSettings(path(), folderSettings_);
|
|
}
|
|
}
|
|
proxyModel_->setSortCaseSensitivity(value ? Qt::CaseSensitive : Qt::CaseInsensitive);
|
|
}
|
|
|
|
|
|
void TabPage::setShowHidden(bool showHidden) {
|
|
if(folderSettings_.showHidden() != showHidden) {
|
|
folderSettings_.setShowHidden(showHidden);
|
|
if(folderSettings_.isCustomized()) {
|
|
static_cast<Application*>(qApp)->settings().saveFolderSettings(path(), folderSettings_);
|
|
}
|
|
}
|
|
if(!proxyModel_) {
|
|
return;
|
|
}
|
|
if(showHidden != proxyModel_->showHidden()) {
|
|
proxyModel_->setShowHidden(showHidden);
|
|
}
|
|
// this may also be called by MainWindow::onTabPageSortFilterChanged to set status message
|
|
statusText_[StatusTextNormal] = formatStatusText();
|
|
Q_EMIT statusChanged(StatusTextNormal, statusText_[StatusTextNormal]);
|
|
}
|
|
|
|
void TabPage::applyFilter() {
|
|
if(!proxyModel_) {
|
|
return;
|
|
}
|
|
proxyModel_->updateFilters();
|
|
statusText_[StatusTextNormal] = formatStatusText();
|
|
Q_EMIT statusChanged(StatusTextNormal, statusText_[StatusTextNormal]);
|
|
}
|
|
|
|
void TabPage::setCustomizedView(bool value) {
|
|
if(folderSettings_.isCustomized() == value) {
|
|
return;
|
|
}
|
|
|
|
Settings& settings = static_cast<Application*>(qApp)->settings();
|
|
folderSettings_.setCustomized(value);
|
|
if(value) { // save customized folder view settings
|
|
settings.saveFolderSettings(path(), folderSettings_);
|
|
}
|
|
else { // use default folder view settings
|
|
settings.clearFolderSettings(path());
|
|
setShowHidden(settings.showHidden());
|
|
setSortCaseSensitive(settings.sortCaseSensitive());
|
|
setSortFolderFirst(settings.sortFolderFirst());
|
|
sort(settings.sortColumn(), settings.sortOrder());
|
|
}
|
|
}
|
|
|
|
} // namespace PCManFM
|