Cherry-picking upstream release 0.13.0.

* Bumped build dependency libfm-qt-dev to >= 0.13.0~
* Bumped build dependency lxqt-build-tools to >= 0.5.0~
* Added papirus-icon-theme as default alternative for icon-themes
* Bumped year in copyright
* Removed ported back upstream patches.
* Moved debian/.gitignore -> ./.gitignore
ubuntu/disco debian/0.13.0-1
Alf Gaida 6 years ago
parent 6c761062c5
commit 0bb15fb1bf

17
.gitignore vendored

@ -1,11 +1,8 @@
/*.debhelper
/*.log
/*.substvars
/debhelper-build-stamp
/files
/mangled
debian/*.debhelper
debian/*.log
debian/*.substvars
debian/debhelper-build-stamp
debian/files
debian/pcmanfm-qt/
/pcmanfm-qt/
/libfm-qt5-2/
/libfm-qt5-dev/
/tmp

@ -1,5 +1,5 @@
Upstream Authors:
LXQt team: http://lxqt.org
LXQt team: https://lxqt.org
Hong Jen Yee (PCMan) <pcman.tw@gmail.com>
Copyright:

@ -1,7 +1,59 @@
pcmanfm-qt-0.12.0 / 2017-10-21
pcmanfm-qt-0.13.0 / 2018-05-21
==============================
* Check minimum version of libfm-qt
* Bumped minor version to 13
* Spanish translation update
* Avoid using the old FmPath struct in libfm and use libfm-qt Fm::FilePath instead.
* Just changed a label in Preferences
* Replace the deprecated Fm::MountOperation::mount() with Fm::MountOperation::mountEnclosingVolume().
* Cleanup
* Migrate to the new libfm-qt Fm::FileLauncher API.
* CMake: Prevent in-source builds
* Use new libfm-qt Fm::Archiver API. (#660)
* Fixed tab close button setting
* Optionally select newly created files
* fixes http -> https
* Fixed some lxde mentions
* Drop usage of Fm::IconTheme
* Add symlink target info to statusbar
* Add Simplified Chinese desktop entries (#640)
* Follow GLib to know if a file is hidden
* Remember hidden Places items between sessions
* Drop Qt foreach
* Use QString Use multi-arg
* Prevent a possible c++11 range-loop detach container (QList)
* Don't call QList::first() on temporary
* Warnings (#625)
* move config to /usr/share/pcmanfm-qt/lxqt
* Fixed the setting for "backup as hidden"" (#614)
* Sweep a desktop mess under the carpet
* cmake: Don't set CMP0063
* cmake: Handle CMP0071 - Mark DBus files with SKIP_AUTOGEN
* cmake: Handle CMP0071 related to UI files.
* Refer to PCManFM-Qt in desktop entries
* Add Spanish desktop entries
* Use QChars
* Simplify if statements
* Const it
* Fix typos, move encloseWithBidiMarks to private and fix its behaviour
* Fix direction of statusbar message
* Give context to singleShot()
* Added a short comment
* Wait for events to be processed before chdir
* Rename progress dialog
* Basic bulk rename
* Really cancel multiple renaming on cancelling
* Initialize dragStarted_ in constructor
* Compact disconnection format
* Tab DND
* View tool-buttons
0.12.0 / 2017-10-21
===================
* Release 0.12.0: Update changelog
* Set Version
* removed dangeling symlink to debian dir
* Text eliding, long texts and newline

@ -1,39 +1,38 @@
cmake_minimum_required(VERSION 3.0.2)
project(pcmanfm-qt)
# CMP0063: Honor visibility properties for all target types.
if (POLICY CMP0063)
cmake_policy (SET CMP0063 NEW)
endif (POLICY CMP0063)
# PcmanFm-Qt Version
set(PCMANFM_QT_VERSION_MAJOR 0)
set(PCMANFM_QT_VERSION_MINOR 12)
set(PCMANFM_QT_VERSION_MINOR 13)
set(PCMANFM_QT_VERSION_PATCH 0)
set(PCMANFM_QT_VERSION ${PCMANFM_QT_VERSION_MAJOR}.${PCMANFM_QT_VERSION_MINOR}.${PCMANFM_QT_VERSION_PATCH})
set(LXQTBT_MINIMUM_VERSION "0.4.0")
set(QT_MINIMUM_VERSION "5.7.1")
set(LXQTBT_MINIMUM_VERSION "0.5.0")
set(LIBFMQT_MINIMUM_VERSION "5.0.0")
list(APPEND CMAKE_MODULE_PATH "${PROJECT_SOURCE_DIR}/cmake")
find_package(Qt5Widgets 5.2 REQUIRED)
find_package(Qt5DBus 5.2 REQUIRED)
find_package(Qt5LinguistTools 5.2 REQUIRED)
find_package(Qt5X11Extras 5.2 REQUIRED)
find_package(fm-qt REQUIRED)
find_package(Qt5Widgets ${QT_MINIMUM_VERSION} REQUIRED)
find_package(Qt5DBus ${QT_MINIMUM_VERSION} REQUIRED)
find_package(Qt5LinguistTools ${QT_MINIMUM_VERSION} REQUIRED)
find_package(Qt5X11Extras ${QT_MINIMUM_VERSION} REQUIRED)
find_package(fm-qt ${LIBFMQT_MINIMUM_VERSION} REQUIRED)
find_package(lxqt-build-tools ${LXQTBT_MINIMUM_VERSION} REQUIRED)
message(STATUS "Building ${PROJECT_NAME} with Qt ${Qt5Core_VERSION}")
option(UPDATE_TRANSLATIONS "Update source translation translations/*.ts files" OFF)
include(GNUInstallDirs)
include(LXQtPreventInSourceBuilds)
include(LXQtConfigVars)
include(LXQtTranslateTs)
include(LXQtTranslateDesktop)
include(LXQtCompilerSettings NO_POLICY_SCOPE)
set(CMAKE_AUTOMOC TRUE)
set(CMAKE_AUTOUIC ON)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
add_subdirectory(pcmanfm)

@ -2,38 +2,61 @@
## Overview
PCManFM-Qt is the Qt port of PCManFM, the file manager of [LXDE](http://lxde.org).
PCManFM-Qt is the Qt port of PCManFM, the file manager of [LXDE](https://lxde.org).
In LXQt sessions it is in addition used to handle the desktop. Nevertheless it can be used independently of LXQt as well.
In LXQt sessions it is in addition used to handle the desktop. Nevertheless it
can be used independently of LXQt as well.
PCManFM-Qt is licensed under the terms of the [GPLv2](https://www.gnu.org/licenses/gpl-2.0.en.html) or any later version. See file LICENSE for its full text.
PCManFM-Qt is licensed under the terms of the
[GPLv2](https://www.gnu.org/licenses/gpl-2.0.en.html) or any later version. See
file LICENSE for its full text.
## Installation
### Compiling source code
Runtime dependencies are qtx11extras, lxmenu-data, [liblxqt](https://github.com/lxde/liblxqt) and [libfm-qt](https://github.com/lxde/libfm-qt).
Additional build dependencies are CMake and optionally Git to pull latest VCS checkouts. The localization files were outsourced to repository [lxqt-l10n](https://github.com/lxde/lxqt-l10n) so the corresponding dependencies are needed, too. Please refer to this repository's `README.md` for further information.
Runtime dependencies are qtx11extras, lxmenu-data,
[liblxqt](https://github.com/lxqt/liblxqt) and
[libfm-qt](https://github.com/lxqt/libfm-qt).
Additional build dependencies are CMake and optionally Git to pull latest VCS
checkouts. The localization files were outsourced to repository
[lxqt-l10n](https://github.com/lxqt/lxqt-l10n) so the corresponding dependencies
are needed, too. Please refer to this repository's `README.md` for further information.
Code configuration is handled by CMake. CMake variable `CMAKE_INSTALL_PREFIX` has to be set to `/usr` on most operating systems, depending on the way library paths are dealt with on 64bit systems variables like `CMAKE_INSTALL_LIBDIR` may have to be set as well.
Code configuration is handled by CMake. CMake variable `CMAKE_INSTALL_PREFIX`
has to be set to `/usr` on most operating systems, depending on the way library
paths are dealt with on 64bit systems variables like `CMAKE_INSTALL_LIBDIR` may
have to be set as well.
To build run `make`, to install `make install` which accepts variable `DESTDIR` as usual.
To build run `make`, to install `make install` which accepts variable `DESTDIR`
as usual.
### Binary packages
Official binary packages are available in Arch Linux, Debian (as of Debian stretch), Fedora (version 0.10.0 only so far) and openSUSE (Leap 42.1 and Tumbleweed).
Official binary packages are available in Arch Linux, Debian (as of Debian stretch),
Fedora (version 0.10.0 only so far) and openSUSE (Leap 42.1 and Tumbleweed).
## Usage
The file manager functionality should be self-explanatory, handling of the desktop deserves some notes:
The file manager functionality should be self-explanatory, handling of the
desktop deserves some notes:
To handle the desktop binary `pcmanfm-qt` has to be launched with switch `--desktop` set. Optionally switch `--profile` can be used to safe settings specific to certain session types like the different desktop environments.
In LXQt sessions, PCManFM-Qt is launched with theses switches set as [LXQt Module](https://github.com/lxde/lxqt-session#lxqt-modules).
To handle the desktop binary `pcmanfm-qt` has to be launched with switch
`--desktop` set. Optionally switch `--profile` can be used to safe settings
specific to certain session types like the different desktop environments.
In LXQt sessions, PCManFM-Qt is launched with theses switches set as
[LXQt Module](https://github.com/lxqt/lxqt-session#lxqt-modules).
To configure the desktop there's a dialogue "Desktop Preferences". Technically it corresponds with launching `pcmanfm-qt` with switch `--desktop-pref` set. It is available in the desktop's context menu and included as topic "Desktop" in sub-menu Preferences - LXQt settings of the panel's main menu as well as the [Configuration Center](https://github.com/lxde/lxqt-config#configuration-center) of lxqt-config.
To configure the desktop there's a dialogue "Desktop Preferences". Technically
it corresponds with launching `pcmanfm-qt` with switch `--desktop-pref` set. It
is available in the desktop's context menu and included as topic "Desktop" in
sub-menu Preferences - LXQt settings of the panel's main menu as well as the
[Configuration Center](https://github.com/lxqt/lxqt-config#configuration-center)
of lxqt-config.
All switches (command line options) mentioned above are explained in detail in `man 1 pcmanfm-qt`.
All switches (command line options) mentioned above are explained in detail in
`man 1 pcmanfm-qt`.
## Development
Issues should go to the tracker of PCManFM-Qt at https://github.com/lxde/pcmanfm-qt/issues.
Issues should go to the tracker of PCManFM-Qt at https://github.com/lxqt/pcmanfm-qt/issues.

@ -1,2 +1 @@
# Translations
Name[es]=Escritorio

@ -3,6 +3,6 @@
configure_file(pcmanfm-qt/lxqt/settings.conf.in pcmanfm-qt/lxqt/settings.conf @ONLY)
install(FILES
"${CMAKE_CURRENT_BINARY_DIR}/pcmanfm-qt/lxqt/settings.conf"
DESTINATION "${LXQT_ETC_XDG_DIR}/pcmanfm-qt/lxqt"
DESTINATION "${CMAKE_INSTALL_DATADIR}/pcmanfm-qt/lxqt"
COMPONENT Runtime
)

10
debian/changelog vendored

@ -1,8 +1,14 @@
pcmanfm-qt (0.13.0-1) experimental; urgency=medium
*
* Cherry-picking upstream release 0.13.0.
* Bumped build dependency libfm-qt-dev to >= 0.13.0~
* Bumped build dependency lxqt-build-tools to >= 0.5.0~
* Added papirus-icon-theme as default alternative for icon-themes
* Bumped year in copyright
* Removed ported back upstream patches.
* Moved debian/.gitignore -> ./.gitignore
-- Alf Gaida <agaida@siduction.org> Mon, 21 May 2018 16:54:34 +0200
-- Alf Gaida <agaida@siduction.org> Sat, 26 May 2018 02:25:19 +0200
pcmanfm-qt (0.12.0-6) unstable; urgency=medium

@ -14,9 +14,10 @@ set(pcmanfm_SRCS
autorundialog.cpp
connectserverdialog.cpp
settings.cpp
bulkrename.cpp
)
qt5_add_dbus_adaptor(pcmanfm_SRCS
qt5_add_dbus_adaptor(pcmanfm_DBUS_SRCS
org.pcmanfm.Application.xml
application.h
PCManFM::Application
@ -24,6 +25,11 @@ qt5_add_dbus_adaptor(pcmanfm_SRCS
ApplicationAdaptor
)
# qt5_add_dbus_adaptor() already generated the moc files. It also marked the
# files with SKIP_AUTOMOC but we still need to mark them witk SKIP_AUTOGEN.
# TODO: Check if this behaviour is a CMake bug.
set_source_files_properties(${pcmanfm_DBUS_SRCS} PROPERTIES SKIP_AUTOGEN ON)
set(pcmanfm_UIS
main-win.ui
about.ui
@ -32,10 +38,9 @@ set(pcmanfm_UIS
desktop-folder.ui
autorun.ui
connect.ui
bulk-rename.ui
)
qt5_wrap_ui(pcmanfm_UIS_H ${pcmanfm_UIS})
# add translation for pcmanfm-qt
lxqt_translate_ts(QM_FILES
UPDATE_TRANSLATIONS ${UPDATE_TRANSLATIONS}
@ -56,7 +61,8 @@ lxqt_translate_desktop(DESKTOP_FILES
add_executable(pcmanfm-qt
${pcmanfm_SRCS}
${pcmanfm_UIS_H}
${pcmanfm_DBUS_SRCS}
${pcmanfm_UIS}
${QM_FILES}
${DESKTOP_FILES}
)
@ -66,6 +72,7 @@ target_compile_definitions(pcmanfm-qt
PCMANFM_DATA_DIR="${CMAKE_INSTALL_PREFIX}/share/pcmanfm-qt"
PCMANFM_QT_VERSION="${PCMANFM_QT_VERSION}"
LIBFM_DATA_DIR="${PKG_FM_PREFIX}/share/libfm"
QT_NO_FOREACH
)
target_include_directories(pcmanfm-qt

@ -55,7 +55,7 @@
<item>
<widget class="QLabel" name="label_3">
<property name="text">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;&lt;a href=&quot;http://lxqt.org/&quot;&gt;&lt;span style=&quot; text-decoration: underline; color:#0000ff;&quot;&gt;http://lxqt.org/&lt;/span&gt;&lt;/a&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;&lt;a href=&quot;https://lxqt.org/&quot;&gt;&lt;span style=&quot; text-decoration: underline; color:#0000ff;&quot;&gt;https://lxqt.org/&lt;/span&gt;&lt;/a&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="textFormat">
<enum>Qt::RichText</enum>

@ -42,7 +42,6 @@
#include <libfm-qt/mountoperation.h>
#include <libfm-qt/filesearchdialog.h>
#include <libfm-qt/path.h>
#include <libfm-qt/core/terminal.h>
#include "applicationadaptor.h"
@ -109,7 +108,6 @@ Application::Application(int& argc, char** argv):
if(settings_.useFallbackIconTheme()) {
QIcon::setThemeName(settings_.fallbackIconThemeName());
Fm::IconTheme::checkChanged();
}
// Check if LXQt Session is running. LXQt has it's own Desktop Folder
@ -379,7 +377,7 @@ void Application::onLastWindowClosed() {
}
void Application::onSaveStateRequest(QSessionManager& manager) {
void Application::onSaveStateRequest(QSessionManager& /*manager*/) {
}
@ -390,7 +388,8 @@ void Application::desktopManager(bool enabled) {
if(enabled) {
if(!enableDesktopManager_) {
// installNativeEventFilter(this);
Q_FOREACH(QScreen* screen, screens()) {
const auto allScreens = screens();
for(QScreen* screen : allScreens) {
connect(screen, &QScreen::virtualGeometryChanged, this, &Application::onVirtualGeometryChanged);
connect(screen, &QObject::destroyed, this, &Application::onScreenDestroyed);
}
@ -425,7 +424,8 @@ void Application::desktopManager(bool enabled) {
delete window;
}
desktopWindows_.clear();
Q_FOREACH(QScreen* screen, screens()) {
const auto allScreens = screens();
for(QScreen* screen : allScreens) {
disconnect(screen, &QScreen::virtualGeometryChanged, this, &Application::onVirtualGeometryChanged);
disconnect(screen, &QObject::destroyed, this, &Application::onScreenDestroyed);
}
@ -460,10 +460,8 @@ void Application::onFindFileAccepted() {
settings_.setSearchRecursive(dlg->recursive());
settings_.setSearchhHidden(dlg->searchhHidden());
Fm::Path uri = dlg->searchUri();
Fm::FilePathList paths;
Fm::GFilePtr gf{uri.toGfile(), false};
paths.push_back(Fm::FilePath{gf.get(), true});
paths.emplace_back(dlg->searchUri());
MainWindow* window = MainWindow::lastActive();
Launcher(window).launchPaths(nullptr, paths);
}
@ -500,11 +498,11 @@ void Application::connectToServer() {
dlg->show();
}
void Application::launchFiles(QString cwd, QStringList paths, bool inNewWindow) {
void Application::launchFiles(QString cwd, QStringList paths, bool /*inNewWindow*/) {
Fm::FilePathList pathList;
Fm::FilePath cwd_path;
QStringList::iterator it;
Q_FOREACH(const QString& it, paths) {
for(const QString& it : qAsConst(paths)) {
QByteArray pathName = it.toLocal8Bit();
Fm::FilePath path;
if(pathName == "~") { // special case for home dir
@ -588,7 +586,7 @@ void Application::setWallpaper(QString path, QString modeString) {
// update wallpaper
if(changed) {
if(enableDesktopManager_) {
Q_FOREACH(DesktopWindow* desktopWindow, desktopWindows_) {
for(DesktopWindow* desktopWindow : qAsConst(desktopWindows_)) {
if(!path.isEmpty()) {
desktopWindow->setWallpaperFile(path);
}
@ -760,7 +758,7 @@ bool Application::autoMountVolume(GVolume* volume, bool interactive) {
}
// static
void Application::onVolumeAdded(GVolumeMonitor* monitor, GVolume* volume, Application* pThis) {
void Application::onVolumeAdded(GVolumeMonitor* /*monitor*/, GVolume* volume, Application* pThis) {
if(pThis->settings_.mountRemovable()) {
pThis->autoMountVolume(volume, true);
}
@ -788,7 +786,7 @@ void Application::onScreenAdded(QScreen* newScreen) {
void Application::onScreenDestroyed(QObject* screenObj) {
// NOTE by PCMan: This is a workaround for Qt 5 bug #40681.
// With this very dirty workaround, we can fix lxde/lxde-qt bug #204, #205, and #206.
// With this very dirty workaround, we can fix lxqt/lxqt bug #204, #205, and #206.
// Qt 5 has two new regression bugs which breaks lxqt-panel in a multihead environment.
// #40681: Regression bug: QWidget::winId() returns old value and QEvent::WinIdChange event is not emitted sometimes. (multihead setup)
// #40791: Regression: QPlatformWindow, QWindow, and QWidget::winId() are out of sync.
@ -814,7 +812,7 @@ void Application::onScreenDestroyed(QObject* screenObj) {
if(enableDesktopManager_) {
bool reloadNeeded = false;
// FIXME: add workarounds for Qt5 bug #40681 and #40791 here.
Q_FOREACH(DesktopWindow* desktop, desktopWindows_) {
for(DesktopWindow* desktop : qAsConst(desktopWindows_)) {
if(desktop->windowHandle()->screen() == screenObj) {
desktop->destroy(); // destroy the underlying native window
reloadNeeded = true;
@ -829,7 +827,7 @@ void Application::onScreenDestroyed(QObject* screenObj) {
void Application::reloadDesktopsAsNeeded() {
if(enableDesktopManager_) {
// workarounds for Qt5 bug #40681 and #40791 here.
Q_FOREACH(DesktopWindow* desktop, desktopWindows_) {
for(DesktopWindow* desktop : qAsConst(desktopWindows_)) {
if(!desktop->windowHandle()) {
desktop->create(); // re-create the underlying native window
desktop->queueRelayout();
@ -841,7 +839,7 @@ void Application::reloadDesktopsAsNeeded() {
// This slot is for Qt 5 onlt, but the stupid Qt moc cannot do conditional compilation
// so we have to define it for Qt 4 as well.
void Application::onVirtualGeometryChanged(const QRect& rect) {
void Application::onVirtualGeometryChanged(const QRect& /*rect*/) {
// NOTE: the following is a workaround for Qt bug 32567.
// https://bugreports.qt-project.org/browse/QTBUG-32567
// Though the status of the bug report is closed, it's not yet fixed for X11.
@ -852,7 +850,7 @@ void Application::onVirtualGeometryChanged(const QRect& rect) {
// So we use it in Qt5.
if(enableDesktopManager_) {
// qDebug() << "onVirtualGeometryChanged";
Q_FOREACH(DesktopWindow* desktop, desktopWindows_) {
for(DesktopWindow* desktop : qAsConst(desktopWindows_)) {
desktop->queueRelayout();
}
}

@ -19,7 +19,6 @@
#include "autorundialog.h"
#include <libfm-qt/icontheme.h>
#include <QListWidgetItem>
#include "application.h"
#include "mainwindow.h"

@ -0,0 +1,92 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>BulkRenameDialog</class>
<widget class="QDialog" name="BulkRenameDialog">
<property name="windowTitle">
<string>Bulk Rename</string>
</property>
<layout class="QGridLayout" name="gridLayout">
<property name="verticalSpacing">
<number>4</number>
</property>
<item row="2" column="2">
<widget class="QSpinBox" name="spinBox">
<property name="minimum">
<number>-1000</number>
</property>
<property name="maximum">
<number>1000</number>
</property>
</widget>
</item>
<item row="3" column="2">
<spacer name="verticalSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeType">
<enum>QSizePolicy::MinimumExpanding</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>5</width>
<height>5</height>
</size>
</property>
</spacer>
</item>
<item row="4" column="1" colspan="2">
<widget class="QDialogButtonBox" name="buttonBox">
<property name="standardButtons">
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="QLabel" name="label2">
<property name="text">
<string># will be replaced by numbers starting with:</string>
</property>
</widget>
</item>
<item row="2" column="0">
<spacer name="horizontalSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeType">
<enum>QSizePolicy::MinimumExpanding</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>5</width>
<height>5</height>
</size>
</property>
</spacer>
</item>
<item row="0" column="0" colspan="3">
<widget class="QLabel" name="label1">
<property name="text">
<string>Rename selected files to:</string>
</property>
</widget>
</item>
<item row="1" column="0" colspan="3">
<widget class="QLineEdit" name="lineEdit">
<property name="sizePolicy">
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>Name#</string>
</property>
</widget>
</item>
</layout>
</widget>
<resources/>
<connections/>
</ui>

@ -0,0 +1,103 @@
/*
Copyright (C) 2017 Pedram Pourang (Tsu Jan) <tsujan2000@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 "bulkrename.h"
#include <QTimer>
#include <QPushButton>
#include <QMessageBox>
#include <QProgressDialog>
#include <libfm-qt/utilities.h>
namespace PCManFM {
BulkRenameDialog::BulkRenameDialog(QWidget* parent, Qt::WindowFlags flags) :
QDialog(parent, flags) {
ui.setupUi(this);
ui.lineEdit->setFocus();
connect(ui.buttonBox->button(QDialogButtonBox::Ok), &QAbstractButton::clicked, this, &QDialog::accept);
connect(ui.buttonBox->button(QDialogButtonBox::Cancel), &QAbstractButton::clicked, this, &QDialog::reject);
resize(minimumSize());
setMaximumHeight(minimumHeight()); // no vertical resizing
}
void BulkRenameDialog::showEvent(QShowEvent* event) {
QDialog::showEvent(event);
if(ui.lineEdit->text().endsWith(QLatin1Char('#'))) { // select what's before "#"
QTimer::singleShot(0, [this]() {
ui.lineEdit->setSelection(0, ui.lineEdit->text().size() - 1);
});
}
}
BulkRenamer::BulkRenamer(const Fm::FileInfoList& files, QWidget* parent) {
if(files.size() <= 1) { // no bulk rename with just one file
return;
}
QString baseName;
int start = 0;
BulkRenameDialog dlg(parent);
switch(dlg.exec()) {
case QDialog::Accepted:
baseName = dlg.getBaseName();
start = dlg.getStart();
break;
default:
return;
}
if(!baseName.contains(QLatin1Char('#'))) {
// insert "#" before the last dot
int end = baseName.lastIndexOf(QLatin1Char('.'));
if(end == -1) {
end = baseName.size();
}
baseName.insert(end, QLatin1Char('#'));
}
QProgressDialog progress(QObject::tr("Renaming files..."), QObject::tr("Abort"), 0, files.size(), parent);
progress.setWindowModality(Qt::WindowModal);
int i = 0, failed = 0;
for(auto& file: files) {
progress.setValue(i);
if(progress.wasCanceled()) {
progress.close();
QMessageBox::warning(parent, QObject::tr("Warning"), QObject::tr("Renaming is aborted."));
return;
}
auto fileName = QString::fromStdString(file->name());
QString newName = baseName;
newName.replace(QLatin1Char('#'), QString::number(start + i));
if (newName == fileName || !Fm::changeFileName(file->path(), newName, nullptr, false)) {
++failed;
}
++i;
}
progress.setValue(i);
if(failed == i) {
QMessageBox::critical(parent, QObject::tr("Error"), QObject::tr("No file could be renamed."));
}
else if(failed > 0) {
QMessageBox::critical(parent, QObject::tr("Error"), QObject::tr("Some files could not be renamed."));
}
}
BulkRenamer::~BulkRenamer() {
}
} //namespace PCManFM

@ -0,0 +1,57 @@
/*
Copyright (C) 2017 Pedram Pourang (Tsu Jan) <tsujan2000@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.
*/
#ifndef PCMANFM_BULKRENAME_H
#define PCMANFM_BULKRENAME_H
#include "ui_bulk-rename.h"
#include <QDialog>
#include <libfm-qt/core/fileinfo.h>
namespace PCManFM {
class BulkRenameDialog : public QDialog {
Q_OBJECT
public:
explicit BulkRenameDialog(QWidget* parent = nullptr, Qt::WindowFlags flags = 0);
QString getBaseName() const {
return ui.lineEdit->text();
}
int getStart() const {
return ui.spinBox->value();
}
protected:
virtual void showEvent(QShowEvent* event) override;
private:
Ui::BulkRenameDialog ui;
};
class BulkRenamer {
public:
BulkRenamer(const Fm::FileInfoList& files, QWidget* parent = nullptr);
~BulkRenamer();
};
}
#endif // PCMANFM_BULKRENAME_H

@ -21,8 +21,7 @@ ConnectServerDialog::ConnectServerDialog(QWidget *parent): QDialog(parent) {
connect(ui.host, &QLineEdit::textChanged, this, &ConnectServerDialog::checkInput);
connect(ui.userName, &QLineEdit::textChanged, this, &ConnectServerDialog::checkInput);
for(const auto& serverType: serverTypes) {
for(const auto& serverType : const_cast<const QList<ServerType>&>(serverTypes)) {
ui.serverType->addItem(serverType.name);
}
@ -62,7 +61,7 @@ QString ConnectServerDialog::uriText() {
return uri;
}
void ConnectServerDialog::onCurrentIndexChanged(int index) {
void ConnectServerDialog::onCurrentIndexChanged(int /*index*/) {
int serverTypeIdx = ui.serverType->currentIndex();
const auto& serverType = serverTypes[serverTypeIdx];
ui.port->setValue(serverType.defaultPort);

@ -203,8 +203,8 @@ void DesktopPreferencesDialog::onBrowseClicked() {
filter.reserve(256);
filter = tr("Image Files");
filter += " (";
QList<QByteArray> formats = QImageReader::supportedImageFormats();
Q_FOREACH(QByteArray format, formats) {
const QList<QByteArray> formats = QImageReader::supportedImageFormats();
for(const QByteArray& format : formats) {
filter += "*.";
filter += format.toLower();
filter += ' ';
@ -214,7 +214,7 @@ void DesktopPreferencesDialog::onBrowseClicked() {
dlg.setNameFilterDetailsVisible(false);
if(dlg.exec() == QDialog::Accepted) {
QString filename;
filename = dlg.selectedFiles().first();
filename = dlg.selectedFiles().constFirst();
ui.imageFile->setText(filename);
}
}
@ -227,7 +227,7 @@ void DesktopPreferencesDialog::onFolderBrowseClicked() {
dlg.setDirectory(QDir::home().path());
if(dlg.exec() == QDialog::Accepted) {
QString foldername;
foldername = dlg.selectedFiles().first();
foldername = dlg.selectedFiles().constFirst();
ui.imageFolder->setText(foldername);
}
}
@ -240,7 +240,7 @@ void DesktopPreferencesDialog::onBrowseDesktopFolderClicked()
dlg.setFileMode(QFileDialog::DirectoryOnly);
if (dlg.exec() == QDialog::Accepted) {
QString dir;
dir = dlg.selectedFiles().first();
dir = dlg.selectedFiles().constFirst();
uiDesktopFolder.desktopFolder->setText(dir);
}
}

@ -52,6 +52,7 @@
#include <libfm-qt/utilities.h>
#include <libfm-qt/core/fileinfo.h>
#include "xdgdir.h"
#include "bulkrename.h"
#include <QX11Info>
#include <QScreen>
@ -73,8 +74,10 @@ DesktopWindow::DesktopWindow(int screenNum):
wallpaperRandomize_(false),
fileLauncher_(nullptr),
showWmMenu_(false),
desktopHideItems_(false),
screenNum_(screenNum),
relayoutTimer_(nullptr) {
relayoutTimer_(nullptr),
selectionTimer_(nullptr) {
QDesktopWidget* desktopWidget = QApplication::desktop();
setWindowFlags(Qt::Window | Qt::FramelessWindowHint);
@ -108,6 +111,8 @@ DesktopWindow::DesktopWindow(int screenNum):
auto desktopPath = Fm::FilePath::fromLocalPath(XdgDir::readDesktopDir().toStdString().c_str());
model_ = Fm::CachedFolderModel::modelFromPath(desktopPath);
folder_ = model_->folder();
connect(folder_.get(), &Fm::Folder::startLoading, this, &DesktopWindow::onFolderStartLoading);
connect(folder_.get(), &Fm::Folder::finishLoading, this, &DesktopWindow::onFolderFinishLoading);
proxyModel_ = new Fm::ProxyFolderModel();
proxyModel_->setSourceModel(model_);
@ -147,7 +152,7 @@ DesktopWindow::DesktopWindow(int screenNum):
connect(shortcut, &QShortcut::activated, this, &DesktopWindow::onPasteActivated);
shortcut = new QShortcut(QKeySequence(Qt::CTRL + Qt::Key_A), this); // select all
connect(shortcut, &QShortcut::activated, this, &FolderView::selectAll);
connect(shortcut, &QShortcut::activated, this, &DesktopWindow::selectAll);
shortcut = new QShortcut(QKeySequence(Qt::Key_Delete), this); // delete
connect(shortcut, &QShortcut::activated, this, &DesktopWindow::onDeleteActivated);
@ -155,7 +160,10 @@ DesktopWindow::DesktopWindow(int screenNum):
shortcut = new QShortcut(QKeySequence(Qt::Key_F2), this); // rename
connect(shortcut, &QShortcut::activated, this, &DesktopWindow::onRenameActivated);
shortcut = new QShortcut(QKeySequence(Qt::ALT + Qt::Key_Return), this); // rename
shortcut = new QShortcut(QKeySequence(Qt::CTRL + Qt::Key_F2), this); // bulk rename
connect(shortcut, &QShortcut::activated, this, &DesktopWindow::onBulkRenameActivated);
shortcut = new QShortcut(QKeySequence(Qt::ALT + Qt::Key_Return), this); // properties
connect(shortcut, &QShortcut::activated, this, &DesktopWindow::onFilePropertiesActivated);
shortcut = new QShortcut(QKeySequence(Qt::SHIFT + Qt::Key_Delete), this); // force delete
@ -166,6 +174,8 @@ DesktopWindow::~DesktopWindow() {
listView_->viewport()->removeEventFilter(this);
listView_->removeEventFilter(this);
disconnect(folder_.get(), nullptr, this, nullptr);
if(relayoutTimer_) {
relayoutTimer_->stop();
delete relayoutTimer_;
@ -181,6 +191,7 @@ DesktopWindow::~DesktopWindow() {
}
if(model_) {
disconnect(model_, &Fm::FolderModel::filesAdded, this, &DesktopWindow::onFilesAdded);
model_->unref();
}
}
@ -224,9 +235,31 @@ void DesktopWindow::resizeEvent(QResizeEvent* event) {
}
void DesktopWindow::setDesktopFolder() {
if(folder_) {
// free the previous model and folder
if(model_) {
disconnect(model_, &Fm::FolderModel::filesAdded, this, &DesktopWindow::onFilesAdded);
proxyModel_->setSourceModel(nullptr);
model_->unref(); // unref the cached model
model_ = nullptr;
}
disconnect(folder_.get(), nullptr, this, nullptr);
folder_ = nullptr;
}
auto path = Fm::FilePath::fromLocalPath(XdgDir::readDesktopDir().toStdString().c_str());
model_ = Fm::CachedFolderModel::modelFromPath(path);
folder_ = model_->folder();
connect(folder_.get(), &Fm::Folder::startLoading, this, &DesktopWindow::onFolderStartLoading);
connect(folder_.get(), &Fm::Folder::finishLoading, this, &DesktopWindow::onFolderFinishLoading);
proxyModel_->setSourceModel(model_);
if(folder_->isLoaded()) {
onFolderStartLoading();
onFolderFinishLoading();
}
else {
onFolderStartLoading();
}
}
void DesktopWindow::setWallpaperFile(QString filename) {
@ -478,6 +511,13 @@ void DesktopWindow::updateFromSettings(Settings& settings, bool changeSlide) {
setBackground(settings.desktopBgColor());
setShadow(settings.desktopShadowColor());
showWmMenu_ = settings.showWmMenu();
desktopHideItems_ = settings.desktopHideItems();
if(desktopHideItems_) {
// hide all items by hiding the list view and also
// prevent the current item from being changed by arrow keys
listView_->clearFocus();
listView_->setVisible(false);
}
if(slideShowInterval_ > 0
&& QFileInfo(wallpaperDir_).isDir()) {
@ -516,7 +556,18 @@ void DesktopWindow::onFileClicked(int type, const std::shared_ptr<const Fm::File
if(!fileInfo && showWmMenu_) {
return; // do not show the popup if we want to use the desktop menu provided by the WM.
}
View::onFileClicked(type, fileInfo);
if(desktopHideItems_) { // only a context menu with desktop actions
if(type == Fm::FolderView::ActivatedClick) {
return;
}
QMenu* menu = new QMenu(this);
addDesktopActions(menu);
menu->exec(QCursor::pos());
delete menu;
}
else {
View::onFileClicked(type, fileInfo);
}
}
void DesktopWindow::prepareFileMenu(Fm::FileMenu* menu) {
@ -543,11 +594,42 @@ void DesktopWindow::prepareFolderMenu(Fm::FolderMenu* menu) {
PCManFM::View::prepareFolderMenu(menu);
// remove file properties action
menu->removeAction(menu->propertiesAction());
// add an action for desktop preferences instead
QAction* action = menu->addAction(tr("Desktop Preferences"));
// add desktop actions instead
addDesktopActions(menu);
}
void DesktopWindow::addDesktopActions(QMenu* menu) {
QAction* action = menu->addAction(tr("Hide Desktop Items"));
action->setCheckable(true);
action->setChecked(desktopHideItems_);
menu->addSeparator();
connect(action, &QAction::triggered, this, &DesktopWindow::toggleDesktop);
action = menu->addAction(tr("Desktop Preferences"));
connect(action, &QAction::triggered, this, &DesktopWindow::onDesktopPreferences);
}
void DesktopWindow::toggleDesktop() {
desktopHideItems_ = !desktopHideItems_;
Settings& settings = static_cast<Application*>(qApp)->settings();
settings.setDesktopHideItems(desktopHideItems_);
listView_->setVisible(!desktopHideItems_);
// a relayout is needed on showing the items for the first time
// because the positions aren't updated while the view is hidden
if(!desktopHideItems_) {
listView_->setFocus(); // refocus the view
queueRelayout();
}
else { // prevent the current item from being changed by arrow keys
listView_->clearFocus();
}
}
void DesktopWindow::selectAll() {
if(!desktopHideItems_) {
FolderView::selectAll();
}
}
void DesktopWindow::onDesktopPreferences() {
static_cast<Application* >(qApp)->desktopPrefrences(QString());
}
@ -570,9 +652,8 @@ void DesktopWindow::onRowsAboutToBeRemoved(const QModelIndex& parent, int start,
// Here we can't rely on ProxyFolderModel::fileInfoFromIndex() because, although rows
// aren't removed yet, files are already removed.
bool changed = false;
char* dektopPath = Fm::Path::getDesktop().toStr();
QString desktopDir = QString(dektopPath) + QString("/");
g_free(dektopPath);
QString desktopDir = QStandardPaths::writableLocation(QStandardPaths::DesktopLocation);
desktopDir += '/';
for(auto it = customItemPos_.cbegin(); it != customItemPos_.cend();) {
auto& name = it->first;
if(!QFile::exists(desktopDir + QString::fromStdString(name))) {
@ -599,7 +680,7 @@ void DesktopWindow::onModelSortFilterChanged() {
Settings& settings = static_cast<Application*>(qApp)->settings();
settings.setDesktopSortColumn(static_cast<Fm::FolderModel::ColumnId>(proxyModel_->sortColumn()));
settings.setDesktopSortOrder(proxyModel_->sortOrder());
settings.setSesktopSortFolderFirst(proxyModel_->folderFirst());
settings.setDesktopSortFolderFirst(proxyModel_->folderFirst());
}
void DesktopWindow::onDataChanged(const QModelIndex& topLeft, const QModelIndex& bottomRight) {
@ -633,7 +714,7 @@ void DesktopWindow::onIndexesMoved(const QModelIndexList& indexes) {
auto delegate = static_cast<Fm::FolderItemDelegate*>(listView_->itemDelegateForColumn(0));
auto itemSize = delegate->itemSize();
// remember the custom position for the items
Q_FOREACH(const QModelIndex& index, indexes) {
for(const QModelIndex& index : indexes) {
// Under some circumstances, Qt might emit indexMoved for
// every single cells in the same row. (when QAbstractItemView::SelectItems is set)
// So indexes list may contain several indixes for the same row.
@ -664,6 +745,35 @@ void DesktopWindow::onIndexesMoved(const QModelIndexList& indexes) {
queueRelayout();
}
void DesktopWindow::onFolderStartLoading() { // desktop may be reloaded
if(model_) {
disconnect(model_, &Fm::FolderModel::filesAdded, this, &DesktopWindow::onFilesAdded);
}
}
void DesktopWindow::onFolderFinishLoading() {
QTimer::singleShot(10, [this]() { // Qt delays the UI update (as in TabPage::onFolderFinishLoading)
if(model_) {
connect(model_, &Fm::FolderModel::filesAdded, this, &DesktopWindow::onFilesAdded);
}
});
}
void DesktopWindow::onFilesAdded(const Fm::FileInfoList files) {
if(static_cast<Application*>(qApp)->settings().selectNewFiles()) {
if(!selectionTimer_) {
selectFiles(files, false);
selectionTimer_ = new QTimer (this);
selectionTimer_->setSingleShot(true);
selectionTimer_->start(200);
}
else {
selectFiles(files, selectionTimer_->isActive());
selectionTimer_->start(200);
}
}
}
void DesktopWindow::removeBottomGap() {
/************************************************************
NOTE: Desktop is an area bounded from below while icons snap
@ -673,7 +783,7 @@ void DesktopWindow::removeBottomGap() {
************************************************************/
auto delegate = static_cast<Fm::FolderItemDelegate*>(listView_->itemDelegateForColumn(0));
auto itemSize = delegate->itemSize();
qDebug() << "delegate:" << delegate->itemSize();
//qDebug() << "delegate:" << delegate->itemSize();
QSize cellMargins = getMargins();
int workAreaHeight = qApp->desktop()->availableGeometry(screenNum_).height()
- 24; // a 12-pix margin will be considered everywhere
@ -828,17 +938,16 @@ void DesktopWindow::loadItemPositions() {
auto grid = delegate->itemSize();
QRect workArea = qApp->desktop()->availableGeometry(screenNum_);
workArea.adjust(12, 12, -12, -12);
char* dektopPath = Fm::Path::getDesktop().toStr();
QString desktopDir = QString(dektopPath) + QString("/");
g_free(dektopPath);
QString desktopDir = QStandardPaths::writableLocation(QStandardPaths::DesktopLocation);
desktopDir += '/';
std::vector<QPoint> usedPos;
for(auto& item: customItemPos_) {
usedPos.push_back(item.second);
}
// FIXME: this is inefficient
Q_FOREACH(const QString& name, file.childGroups()) {
const auto names = file.childGroups();
for(const QString& name : names) {
if(!QFile::exists(desktopDir + name.toUtf8())) {
// the file may have been removed from outside LXQT
continue;
@ -927,6 +1036,9 @@ void DesktopWindow::queueRelayout(int delay) {
// slots for file operations
void DesktopWindow::onCutActivated() {
if(desktopHideItems_) {
return;
}
auto paths = selectedFilePaths();
if(!paths.empty()) {
Fm::cutFilesToClipboard(paths);
@ -934,6 +1046,9 @@ void DesktopWindow::onCutActivated() {
}
void DesktopWindow::onCopyActivated() {
if(desktopHideItems_) {
return;
}
auto paths = selectedFilePaths();
if(!paths.empty()) {
Fm::copyFilesToClipboard(paths);
@ -941,10 +1056,16 @@ void DesktopWindow::onCopyActivated() {
}
void DesktopWindow::onPasteActivated() {
if(desktopHideItems_) {
return;
}
Fm::pasteFilesFromClipboard(path());
}
void DesktopWindow::onDeleteActivated() {
if(desktopHideItems_) {
return;
}
auto paths = selectedFilePaths();
if(!paths.empty()) {
Settings& settings = static_cast<Application*>(qApp)->settings();
@ -959,6 +1080,9 @@ void DesktopWindow::onDeleteActivated() {
}
void DesktopWindow::onRenameActivated() {
if(desktopHideItems_) {
return;
}
// do inline renaming if only one item is selected,
// otherwise use the renaming dialog
if(selectedIndexes().size() == 1) {
@ -971,12 +1095,24 @@ void DesktopWindow::onRenameActivated() {
auto files = selectedFiles();
if(!files.empty()) {
for(auto& info: files) {
Fm::renameFile(info, nullptr);
if(!Fm::renameFile(info, nullptr)) {
break;
}
}
}
}
void DesktopWindow::onBulkRenameActivated() {
if(desktopHideItems_) {
return;
}
BulkRenamer(selectedFiles(), this);
}
void DesktopWindow::onFilePropertiesActivated() {
if(desktopHideItems_) {
return;
}
auto files = selectedFiles();
if(!files.empty()) {
Fm::FilePropsDialog::showForFiles(std::move(files));
@ -1052,7 +1188,7 @@ static void forwardMouseEventToRoot(QMouseEvent* event) {
bool DesktopWindow::event(QEvent* event) {
switch(event->type()) {
case QEvent::WinIdChange: {
qDebug() << "winid change:" << effectiveWinId();
//qDebug() << "winid change:" << effectiveWinId();
if(effectiveWinId() == 0) {
break;
}

@ -105,6 +105,8 @@ protected:
protected Q_SLOTS:
void onOpenDirRequested(const Fm::FilePath& path, int target);
void onDesktopPreferences();
void selectAll();
void toggleDesktop();
void onRowsAboutToBeRemoved(const QModelIndex& parent, int start, int end);
void onRowsInserted(const QModelIndex& parent, int start, int end);
@ -112,6 +114,9 @@ protected Q_SLOTS:
void onModelSortFilterChanged();
void onIndexesMoved(const QModelIndexList& indexes);
void onDataChanged(const QModelIndex& topLeft, const QModelIndex& bottomRight);
void onFolderStartLoading();
void onFolderFinishLoading();
void onFilesAdded(const Fm::FileInfoList files);
void relayoutItems();
void onStickToCurrentPos(bool toggled);
@ -123,11 +128,13 @@ protected Q_SLOTS:
void onCopyActivated();
void onPasteActivated();
void onRenameActivated();
void onBulkRenameActivated();
void onDeleteActivated();
void onFilePropertiesActivated();
private:
void removeBottomGap();
void addDesktopActions(QMenu* menu);
void paintBackground(QPaintEvent* event);
static void alignToGrid(QPoint& pos, const QPoint& topLeft, const QSize& grid, const int spacing);
@ -150,11 +157,13 @@ private:
QPixmap wallpaperPixmap_;
Launcher fileLauncher_;
bool showWmMenu_;
bool desktopHideItems_;
int screenNum_;
std::unordered_map<std::string, QPoint> customItemPos_;
QHash<QModelIndex, QString> displayNames_; // only for desktop entries and shortcuts
QTimer* relayoutTimer_;
QTimer* selectionTimer_;
};
}

@ -37,12 +37,11 @@ Launcher::~Launcher() {
}
bool Launcher::openFolder(GAppLaunchContext* ctx, GList* folder_infos, GError** err) {
GList* l = folder_infos;
FmFileInfo* fi = FM_FILE_INFO(l->data);
bool Launcher::openFolder(GAppLaunchContext* /*ctx*/, const Fm::FileInfoList& folderInfos, Fm::GErrorPtr& /*err*/) {
auto fi = folderInfos[0];
Application* app = static_cast<Application*>(qApp);
MainWindow* mainWindow = mainWindow_;
Fm::FilePath path{fm_path_to_gfile(fm_file_info_get_path(fi)), false};
Fm::FilePath path = fi->path();
if(!mainWindow) {
mainWindow = new MainWindow(std::move(path));
mainWindow->resize(app->settings().windowWidth(), app->settings().windowHeight());
@ -54,10 +53,10 @@ bool Launcher::openFolder(GAppLaunchContext* ctx, GList* folder_infos, GError**
else {
mainWindow->chdir(std::move(path));
}
l = l->next;
for(; l; l = l->next) {
fi = FM_FILE_INFO(l->data);
path = Fm::FilePath{fm_path_to_gfile(fm_file_info_get_path(fi)), false};
for(size_t i = 1; i < folderInfos.size(); ++i) {
fi = folderInfos[i];
path = fi->path();
mainWindow->addTab(std::move(path));
}
mainWindow->show();

@ -33,7 +33,7 @@ public:
~Launcher();
protected:
virtual bool openFolder(GAppLaunchContext* ctx, GList* folder_infos, GError** err);
bool openFolder(GAppLaunchContext* ctx, const Fm::FileInfoList& folderInfos, Fm::GErrorPtr& err) override;
private:
MainWindow* mainWindow_;

@ -210,6 +210,9 @@
<addaction name="actionSelectAll"/>
<addaction name="actionInvertSelection"/>
<addaction name="separator"/>
<addaction name="separator"/>
<addaction name="actionBulkRename"/>
<addaction name="separator"/>
<addaction name="actionPreferences"/>
</widget>
<widget class="QMenu" name="menu_Bookmarks">
@ -278,6 +281,11 @@
<addaction name="actionGoUp"/>
<addaction name="actionReload"/>
<addaction name="separator"/>
<addaction name="actionIconView"/>
<addaction name="actionThumbnailView"/>
<addaction name="actionCompactView"/>
<addaction name="actionDetailedList"/>
<addaction name="separator"/>
<addaction name="actionGo"/>
<addaction name="actionMenu"/>
</widget>
@ -828,6 +836,17 @@
<string>&amp;Path Buttons</string>
</property>
</action>
<action name="actionBulkRename">
<property name="text">
<string>&amp;Bulk Rename</string>
</property>
<property name="toolTip">
<string>Bulk Rename</string>
</property>
<property name="shortcut">
<string>Ctrl+F2</string>
</property>
</action>
</widget>
<customwidgets>
<customwidget>

@ -30,6 +30,7 @@
#include <QShortcut>
#include <QKeySequence>
#include <QSettings>
#include <QMimeData>
#include <QStandardPaths>
#include <QDebug>
@ -45,6 +46,7 @@
#include <libfm-qt/core/fileinfo.h>
#include "ui_about.h"
#include "application.h"
#include "bulkrename.h"
using namespace Fm;
@ -57,10 +59,10 @@ MainWindow::MainWindow(Fm::FilePath path):
QMainWindow(),
pathEntry_(nullptr),
pathBar_(nullptr),
bookmarks_{Fm::Bookmarks::globalInstance()},
fileLauncher_(this),
rightClickIndex_(-1),
updatingViewMenu_(false),
bookmarks_{Fm::Bookmarks::globalInstance()} {
updatingViewMenu_(false) {
Settings& settings = static_cast<Application*>(qApp)->settings();
setAttribute(Qt::WA_DeleteOnClose);
@ -90,7 +92,7 @@ MainWindow::MainWindow(Fm::FilePath path):
// tabbed browsing interface
ui.tabBar->setDocumentMode(true);
ui.tabBar->setTabsClosable(true);
ui.tabBar->setTabsClosable(settings.showTabClose());
ui.tabBar->setElideMode(Qt::ElideRight);
ui.tabBar->setExpanding(false);
ui.tabBar->setMovable(true); // reorder the tabs by dragging
@ -114,6 +116,7 @@ MainWindow::MainWindow(Fm::FilePath path):
connect(ui.tabBar, &QTabBar::tabCloseRequested, this, &MainWindow::onTabBarCloseRequested);
connect(ui.tabBar, &QTabBar::tabMoved, this, &MainWindow::onTabBarTabMoved);
connect(ui.tabBar, &QTabBar::customContextMenuRequested, this, &MainWindow::tabContextMenu);
connect(ui.tabBar, &TabBar::tabDetached, this, &MainWindow::detachTab);
connect(ui.stackedWidget, &QStackedWidget::widgetRemoved, this, &MainWindow::onStackedWidgetWidgetRemoved);
// FIXME: should we make the filter bar a per-view configuration?
@ -124,12 +127,14 @@ MainWindow::MainWindow(Fm::FilePath path):
// side pane
ui.sidePane->setIconSize(QSize(settings.sidePaneIconSize(), settings.sidePaneIconSize()));
ui.sidePane->setMode(settings.sidePaneMode());
ui.sidePane->restoreHiddenPlaces(settings.getHiddenPlaces());
connect(ui.sidePane, &Fm::SidePane::chdirRequested, this, &MainWindow::onSidePaneChdirRequested);
connect(ui.sidePane, &Fm::SidePane::openFolderInNewWindowRequested, this, &MainWindow::onSidePaneOpenFolderInNewWindowRequested);
connect(ui.sidePane, &Fm::SidePane::openFolderInNewTabRequested, this, &MainWindow::onSidePaneOpenFolderInNewTabRequested);
connect(ui.sidePane, &Fm::SidePane::openFolderInTerminalRequested, this, &MainWindow::onSidePaneOpenFolderInTerminalRequested);
connect(ui.sidePane, &Fm::SidePane::createNewFolderRequested, this, &MainWindow::onSidePaneCreateNewFolderRequested);
connect(ui.sidePane, &Fm::SidePane::modeChanged, this, &MainWindow::onSidePaneModeChanged);
connect(ui.sidePane, &Fm::SidePane::hiddenPlaceSet, this, &MainWindow::onSettingHiddenPlace);
// detect change of splitter position
connect(ui.splitter, &QSplitter::splitterMoved, this, &MainWindow::onSplitterMoved);
@ -158,6 +163,12 @@ MainWindow::MainWindow(Fm::FilePath path):
connect(bookmarks_.get(), &Fm::Bookmarks::changed, this, &MainWindow::onBookmarksChanged);
loadBookmarksMenu();
// set generic icons for view actions
ui.actionIconView->setIcon(style()->standardIcon(QStyle::SP_FileDialogContentsView));
ui.actionThumbnailView->setIcon(style()->standardIcon(QStyle::SP_FileDialogInfoView));
ui.actionCompactView->setIcon(style()->standardIcon(QStyle::SP_FileDialogListView));
ui.actionDetailedList->setIcon(style()->standardIcon(QStyle::SP_FileDialogDetailedView));
// Fix the menu groups which is not done by Qt designer
// To my suprise, this was supported in Qt designer 3 :-(
QActionGroup* group = new QActionGroup(ui.menu_View);
@ -271,28 +282,31 @@ MainWindow::MainWindow(Fm::FilePath path):
}
// size from settings
if(settings.rememberWindowSize()) {
resize(settings.windowWidth(), settings.windowHeight());
if(settings.windowMaximized()) {
setWindowState(windowState() | Qt::WindowMaximized);
}
}
resize(settings.windowWidth(), settings.windowHeight());
if(settings.rememberWindowSize() && settings.windowMaximized()) {
setWindowState(windowState() | Qt::WindowMaximized);
}
if(QApplication::layoutDirection() == Qt::RightToLeft) {
setRTLIcons(true);
}
// we want tab dnd
setAcceptDrops(true);
}
MainWindow::~MainWindow() {
}
void MainWindow::chdir(Fm::FilePath path) {
TabPage* page = currentPage();
if(page) {
ui.filterBar->clear();
page->chdir(path, true);
updateUIForCurrentPage();
}
// wait until queued events are processed
QTimer::singleShot(0, this, [this, path] {
if(TabPage* page = currentPage()) {
ui.filterBar->clear();
page->chdir(path, true);
updateUIForCurrentPage();
}
});
}
void MainWindow::createPathBar(bool usePathButtons) {
@ -311,30 +325,38 @@ void MainWindow::createPathBar(bool usePathButtons) {
ui.actionGo->setVisible(!usePathButtons);
}
// add a new tab
int MainWindow::addTab(Fm::FilePath path) {
Settings& settings = static_cast<Application*>(qApp)->settings();
int MainWindow::addTabWithPage(TabPage* page, Fm::FilePath path) {
if(page == nullptr) {
return -1;
}
page->setFileLauncher(&fileLauncher_);
int index = ui.stackedWidget->addWidget(page);
connect(page, &TabPage::titleChanged, this, &MainWindow::onTabPageTitleChanged);
connect(page, &TabPage::statusChanged, this, &MainWindow::onTabPageStatusChanged);
connect(page, &TabPage::openDirRequested, this, &MainWindow::onTabPageOpenDirRequested);
connect(page, &TabPage::sortFilterChanged, this, &MainWindow::onTabPageSortFilterChanged);
connect(page, &TabPage::backwardRequested, this, &MainWindow::on_actionGoBack_triggered);
connect(page, &TabPage::forwardRequested, this, &MainWindow::on_actionGoForward_triggered);
TabPage* newPage = new TabPage(this);
newPage->setFileLauncher(&fileLauncher_);
int index = ui.stackedWidget->addWidget(newPage);
connect(newPage, &TabPage::titleChanged, this, &MainWindow::onTabPageTitleChanged);
connect(newPage, &TabPage::statusChanged, this, &MainWindow::onTabPageStatusChanged);
connect(newPage, &TabPage::openDirRequested, this, &MainWindow::onTabPageOpenDirRequested);
connect(newPage, &TabPage::sortFilterChanged, this, &MainWindow::onTabPageSortFilterChanged);
connect(newPage, &TabPage::backwardRequested, this, &MainWindow::on_actionGoBack_triggered);
connect(newPage, &TabPage::forwardRequested, this, &MainWindow::on_actionGoForward_triggered);
newPage->chdir(path, true);
ui.tabBar->insertTab(index, newPage->windowTitle());
if(path) {
page->chdir(path, true);
}
ui.tabBar->insertTab(index, page->windowTitle());
Settings& settings = static_cast<Application*>(qApp)->settings();
if(!settings.alwaysShowTabs()) {
ui.tabBar->setVisible(ui.tabBar->count() > 1);
}
return index;
}
void MainWindow::toggleMenuBar(bool checked) {
// add a new tab
int MainWindow::addTab(Fm::FilePath path) {
TabPage* newPage = new TabPage(this);
return addTabWithPage(newPage, path);
}
void MainWindow::toggleMenuBar(bool /*checked*/) {
Settings& settings = static_cast<Application*>(qApp)->settings();
bool showMenuBar = !settings.showMenuBar();
@ -375,33 +397,34 @@ void MainWindow::onPathBarMiddleClickChdir(const Fm::FilePath& dirPath) {
}
void MainWindow::on_actionGoUp_triggered() {
TabPage* page = currentPage();
if(page) {
ui.filterBar->clear();
page->up();
updateUIForCurrentPage();
}
QTimer::singleShot(0, this, [this] {
if(TabPage* page = currentPage()) {
ui.filterBar->clear();
page->up();
updateUIForCurrentPage();
}
});
}
void MainWindow::on_actionGoBack_triggered() {
TabPage* page = currentPage();
if(page) {
ui.filterBar->clear();
page->backward();
updateUIForCurrentPage();
}
QTimer::singleShot(0, this, [this] {
if(TabPage* page = currentPage()) {
ui.filterBar->clear();
page->backward();
updateUIForCurrentPage();
}
});
}
void MainWindow::on_actionGoForward_triggered() {
TabPage* page = currentPage();
QTimer::singleShot(0, this, [this] {
if(TabPage* page = currentPage()) {
ui.filterBar->clear();
page->forward();
updateUIForCurrentPage();
}
});
if(page) {
ui.filterBar->clear();
page->forward();
updateUIForCurrentPage();
}
}
void MainWindow::on_actionHome_triggered() {
@ -494,31 +517,31 @@ void MainWindow::on_actionShowHidden_triggered(bool checked) {
}
}
void MainWindow::on_actionByFileName_triggered(bool checked) {
void MainWindow::on_actionByFileName_triggered(bool /*checked*/) {
currentPage()->sort(Fm::FolderModel::ColumnFileName, currentPage()->sortOrder());
}
void MainWindow::on_actionByMTime_triggered(bool checked) {
void MainWindow::on_actionByMTime_triggered(bool /*checked*/) {
currentPage()->sort(Fm::FolderModel::ColumnFileMTime, currentPage()->sortOrder());
}
void MainWindow::on_actionByOwner_triggered(bool checked) {
void MainWindow::on_actionByOwner_triggered(bool /*checked*/) {
currentPage()->sort(Fm::FolderModel::ColumnFileOwner, currentPage()->sortOrder());
}
void MainWindow::on_actionByFileSize_triggered(bool checked) {
void MainWindow::on_actionByFileSize_triggered(bool /*checked*/) {
currentPage()->sort(Fm::FolderModel::ColumnFileSize, currentPage()->sortOrder());
}
void MainWindow::on_actionByFileType_triggered(bool checked) {
void MainWindow::on_actionByFileType_triggered(bool /*checked*/) {
currentPage()->sort(Fm::FolderModel::ColumnFileType, currentPage()->sortOrder());
}
void MainWindow::on_actionAscending_triggered(bool checked) {
void MainWindow::on_actionAscending_triggered(bool /*checked*/) {
currentPage()->sort(currentPage()->sortColumn(), Qt::AscendingOrder);
}
void MainWindow::on_actionDescending_triggered(bool checked) {
void MainWindow::on_actionDescending_triggered(bool /*checked*/) {
currentPage()->sort(currentPage()->sortColumn(), Qt::DescendingOrder);
}
@ -530,7 +553,7 @@ void MainWindow::on_actionFolderFirst_triggered(bool checked) {
currentPage()->setSortFolderFirst(checked);
}
void MainWindow::on_actionPreserveView_triggered(bool checked) {
void MainWindow::on_actionPreserveView_triggered(bool /*checked*/) {
TabPage* page = currentPage();
page->setCustomizedView(!page->hasCustomizedView());
}
@ -623,7 +646,7 @@ void MainWindow::on_actionAbout_triggered() {
// the about dialog
class AboutDialog : public QDialog {
public:
explicit AboutDialog(QWidget* parent = 0, Qt::WindowFlags f = 0) {
explicit AboutDialog(QWidget* parent = 0, Qt::WindowFlags f = 0) : QDialog(parent, f) {
ui.setupUi(this);
ui.version->setText(tr("Version: %1").arg(PCMANFM_QT_VERSION));
}
@ -816,7 +839,7 @@ void MainWindow::updateViewMenuForCurrentPage() {
void MainWindow::updateEditSelectedActions() {
bool hasAccessible(false);
bool hasDeletable(false);
bool hasRenamable(false);
int renamable(0);
if(TabPage* page = currentPage()) {
auto files = page->selectedFiles();
for(auto& file: files) {
@ -827,9 +850,9 @@ void MainWindow::updateEditSelectedActions() {
hasDeletable = true;
}
if(file->canSetName()) {
hasRenamable = true;
++renamable;
}
if (hasAccessible && hasDeletable && hasRenamable) {
if (hasAccessible && hasDeletable && renamable > 1) {
break;
}
}
@ -837,7 +860,8 @@ void MainWindow::updateEditSelectedActions() {
ui.actionCopy->setEnabled(hasAccessible);
ui.actionCut->setEnabled(hasDeletable);
ui.actionDelete->setEnabled(hasDeletable);
ui.actionRename->setEnabled(hasRenamable);
ui.actionRename->setEnabled(renamable > 0);
ui.actionBulkRename->setEnabled(renamable > 1);
}
void MainWindow::updateUIForCurrentPage() {
@ -1013,7 +1037,11 @@ void MainWindow::onSidePaneModeChanged(Fm::SidePane::Mode mode) {
static_cast<Application*>(qApp)->settings().setSidePaneMode(mode);
}
void MainWindow::onSplitterMoved(int pos, int index) {
void MainWindow::onSettingHiddenPlace(const QString& str, bool hide) {
static_cast<Application*>(qApp)->settings().setHiddenPlace(str, hide);
}
void MainWindow::onSplitterMoved(int pos, int /*index*/) {
Application* app = static_cast<Application*>(qApp);
app->settings().setSplitterPos(pos);
}
@ -1116,11 +1144,16 @@ void MainWindow::on_actionRename_triggered() {
}
if(!files.empty()) {
for(auto& file: files) {
Fm::renameFile(file, nullptr);
if(!Fm::renameFile(file, nullptr)) {
break;
}
}
}
}
void MainWindow::on_actionBulkRename_triggered() {
BulkRenamer(currentPage()->selectedFiles(), this);
}
void MainWindow::on_actionSelectAll_triggered() {
currentPage()->selectAll();
@ -1181,12 +1214,12 @@ void MainWindow::onBackForwardContextMenu(QPoint pos) {
Fm::BrowseHistory& history = page->browseHistory();
int current = history.currentIndex();
QMenu menu;
for(int i = 0; i < history.size(); ++i) {
for(size_t i = 0; i < history.size(); ++i) {
const BrowseHistoryItem& item = history.at(i);
auto path = item.path();
auto name = path.displayName();
QAction* action = menu.addAction(name.get());
if(i == current) {
if(i == static_cast<size_t>(current)) {
// make the current path bold and checked
action->setCheckable(true);
action->setChecked(true);
@ -1256,6 +1289,70 @@ void MainWindow::focusPathEntry() {
}
}
void MainWindow::dragEnterEvent(QDragEnterEvent* event) {
if(event->mimeData()->hasFormat("application/pcmanfm-qt-tab")) {
event->acceptProposedAction();
}
}
void MainWindow::dropEvent(QDropEvent* event) {
if(event->mimeData()->hasFormat("application/pcmanfm-qt-tab")) {
dropTab();
}
event->acceptProposedAction();
}
void MainWindow::dropTab() {
if(lastActive_ == nullptr // impossible
|| lastActive_ == this) { // don't drop on the same window
ui.tabBar->finishMouseMoveEvent();
return;
}
// close the tab in the first window and add
// its page to a new tab in the second window
TabPage* dropPage = lastActive_->currentPage();
if(dropPage) {
disconnect(dropPage, nullptr, lastActive_, nullptr);
// release mouse before tab removal because otherwise, the source tabbar
// might not be updated properly with tab reordering during a fast drag-and-drop
lastActive_->ui.tabBar->releaseMouse();
QWidget* page = lastActive_->ui.stackedWidget->currentWidget();
lastActive_->ui.stackedWidget->removeWidget(page);
int index = addTabWithPage(dropPage);
ui.tabBar->setCurrentIndex(index);
}
else {
ui.tabBar->finishMouseMoveEvent(); // impossible
}
}
void MainWindow::detachTab() {
if (ui.stackedWidget->count() == 1) { // don't detach a single tab
ui.tabBar->finishMouseMoveEvent();
return;
}
// close the tab and move its page to a new window
TabPage* dropPage = currentPage();
if(dropPage) {
disconnect(dropPage, nullptr, this, nullptr);
ui.tabBar->releaseMouse(); // as in dropTab()
QWidget* page = ui.stackedWidget->currentWidget();
ui.stackedWidget->removeWidget(page);
MainWindow* newWin = new MainWindow();
newWin->addTabWithPage(dropPage);
newWin->show();
}
else {
ui.tabBar->finishMouseMoveEvent(); // impossible
}
}
void MainWindow::updateFromSettings(Settings& settings) {
// apply settings
@ -1289,7 +1386,7 @@ void MainWindow::updateFromSettings(Settings& settings) {
}
}
static const char* su_cmd_subst(char opt, gpointer user_data) {
static const char* su_cmd_subst(char /*opt*/, gpointer user_data) {
return (const char*)user_data;
}

@ -32,7 +32,6 @@
#include <QStackedWidget>
#include <QSplitter>
#include "launcher.h"
#include <libfm-qt/path.h>
#include <libfm-qt/core/filepath.h>
#include <libfm-qt/core/bookmarks.h>
@ -85,6 +84,7 @@ protected Q_SLOTS:
void on_actionPaste_triggered();
void on_actionDelete_triggered();
void on_actionRename_triggered();
void on_actionBulkRename_triggered();
void on_actionSelectAll_triggered();
void on_actionInvertSelection_triggered();
void on_actionPreferences_triggered();
@ -173,15 +173,20 @@ protected Q_SLOTS:
}
void focusPathEntry();
void toggleMenuBar(bool checked);
void detachTab();
void onBookmarksChanged();
void onSettingHiddenPlace(const QString& str, bool hide);
protected:
bool event(QEvent* event) override;
void changeEvent(QEvent* event) override;
void closeTab(int index);
virtual void resizeEvent(QResizeEvent* event) override;
virtual void closeEvent(QCloseEvent* event) override;
virtual void dragEnterEvent(QDragEnterEvent* event) override;
virtual void dropEvent(QDropEvent* event) override;
private:
void loadBookmarksMenu();
@ -191,6 +196,8 @@ private:
void updateStatusBarForCurrentPage();
void setRTLIcons(bool isRTL);
void createPathBar(bool usePathButtons);
int addTabWithPage(TabPage* page, Fm::FilePath path = Fm::FilePath());
void dropTab();
private:
Ui::MainWindow ui;

@ -1,6 +1,6 @@
[Desktop Entry]
Type=Application
Name=PCManFM File Manager
Name=PCManFM-Qt File Manager
GenericName=File Manager
Comment=Browse the file system and manage the files
Exec=pcmanfm-qt %U

@ -4,7 +4,7 @@
int main(int argc, char** argv) {
// ensure that glib integration of Qt is not turned off
// This fixes #168: https://github.com/lxde/pcmanfm-qt/issues/168
// This fixes #168: https://github.com/lxqt/pcmanfm-qt/issues/168
qunsetenv("QT_NO_GLIB");
PCManFM::Application app(argc, argv);

@ -190,7 +190,15 @@
<item>
<widget class="QCheckBox" name="quickExec">
<property name="text">
<string>Don't ask options on launch executable file</string>
<string>Launch executable files without prompt
(Requires application restart to take effect)</string>
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="selectNewFiles">
<property name="text">
<string>Select newly created files</string>
</property>
</widget>
</item>

@ -28,6 +28,7 @@
#include <libfm-qt/folderview.h>
#include <libfm-qt/core/terminal.h>
#include <libfm-qt/core/archiver.h>
namespace PCManFM {
@ -52,9 +53,9 @@ PreferencesDialog::~PreferencesDialog() {
static void findIconThemesInDir(QHash<QString, QString>& iconThemes, QString dirName) {
QDir dir(dirName);
QStringList subDirs = dir.entryList(QDir::AllDirs);
const QStringList subDirs = dir.entryList(QDir::AllDirs);
GKeyFile* kf = g_key_file_new();
Q_FOREACH(QString subDir, subDirs) {
for(const QString& subDir : subDirs) {
QString indexFile = dirName % '/' % subDir % "/index.theme";
if(g_key_file_load_from_file(kf, indexFile.toLocal8Bit().constData(), GKeyFileFlags(0), nullptr)) {
// FIXME: skip hidden ones
@ -117,12 +118,11 @@ void PreferencesDialog::initIconThemes(Settings& settings) {
}
void PreferencesDialog::initArchivers(Settings& settings) {
const GList* allArchivers = fm_archiver_get_all();
int i = 0;
for(const GList* l = allArchivers; l; l = l->next, ++i) {
FmArchiver* archiver = reinterpret_cast<FmArchiver*>(l->data);
ui.archiver->addItem(archiver->program, QString(archiver->program));
if(archiver->program == settings.archiver()) {
auto& allArchivers = Fm::Archiver::allArchivers();
for(int i = 0; i < int(allArchivers.size()); ++i) {
auto& archiver = allArchivers[i];
ui.archiver->addItem(archiver->program(), QString(archiver->program()));
if(archiver->program() == settings.archiver()) {
ui.archiver->setCurrentIndex(i);
}
}
@ -220,6 +220,7 @@ void PreferencesDialog::initBehaviorPage(Settings& settings) {
ui.noUsbTrash->setChecked(settings.noUsbTrash());
ui.confirmTrash->setChecked(settings.confirmTrash());
ui.quickExec->setChecked(settings.quickExec());
ui.selectNewFiles->setChecked(settings.selectNewFiles());
}
void PreferencesDialog::initThumbnailPage(Settings& settings) {
@ -281,7 +282,8 @@ void PreferencesDialog::applyDisplayPage(Settings& settings) {
settings.setFallbackIconThemeName(newIconTheme);
QIcon::setThemeName(settings.fallbackIconThemeName());
// update the UI by emitting a style change event
Q_FOREACH(QWidget* widget, QApplication::allWidgets()) {
const auto widgets = QApplication::allWidgets();
for(QWidget* widget : widgets) {
QEvent event(QEvent::StyleChange);
QApplication::sendEvent(widget, &event);
}
@ -327,6 +329,7 @@ void PreferencesDialog::applyBehaviorPage(Settings& settings) {
settings.setNoUsbTrash(ui.noUsbTrash->isChecked());
settings.setConfirmTrash(ui.confirmTrash->isChecked());
settings.setQuickExec(ui.quickExec->isChecked());
settings.setSelectNewFiles(ui.selectNewFiles->isChecked());
}
void PreferencesDialog::applyThumbnailPage(Settings& settings) {

@ -73,6 +73,7 @@ Settings::Settings():
desktopIconSize_(48),
showWmMenu_(false),
desktopShowHidden_(false),
desktopHideItems_(false),
desktopSortOrder_(Qt::AscendingOrder),
desktopSortColumn_(Fm::FolderModel::ColumnFileMTime),
desktopSortFolderFirst_(true),
@ -104,6 +105,7 @@ Settings::Settings():
noUsbTrash_(false),
confirmTrash_(false),
quickExec_(false),
selectNewFiles_(false),
showThumbnails_(true),
archiver_(),
siUnit_(false),
@ -207,6 +209,7 @@ bool Settings::loadFile(QString filePath) {
setNoUsbTrash(settings.value("NoUsbTrash", false).toBool());
confirmTrash_ = settings.value("ConfirmTrash", false).toBool();
setQuickExec(settings.value("QuickExec", false).toBool());
selectNewFiles_ = settings.value("SelectNewFiles", false).toBool();
// bool thumbnailLocal_;
// bool thumbnailMax;
settings.endGroup();
@ -230,6 +233,7 @@ bool Settings::loadFile(QString filePath) {
desktopIconSize_ = settings.value("DesktopIconSize", 48).toInt();
showWmMenu_ = settings.value("ShowWmMenu", false).toBool();
desktopShowHidden_ = settings.value("ShowHidden", false).toBool();
desktopHideItems_ = settings.value("HideItems", false).toBool();
desktopSortOrder_ = sortOrderFromString(settings.value("SortOrder").toString());
desktopSortColumn_ = sortColumnFromString(settings.value("SortColumn").toString());
@ -283,6 +287,7 @@ bool Settings::loadFile(QString filePath) {
placesRoot_ = settings.value("PlacesRoot", true).toBool();
placesComputer_ = settings.value("PlacesComputer", true).toBool();
placesNetwork_ = settings.value("PlacesNetwork", true).toBool();
hiddenPlaces_ = settings.value("HiddenPlaces").toStringList().toSet();
settings.endGroup();
settings.beginGroup("Window");
@ -339,6 +344,7 @@ bool Settings::saveFile(QString filePath) {
settings.setValue("NoUsbTrash", noUsbTrash_);
settings.setValue("ConfirmTrash", confirmTrash_);
settings.setValue("QuickExec", quickExec_);
settings.setValue("SelectNewFiles", selectNewFiles_);
// bool thumbnailLocal_;
// bool thumbnailMax;
settings.endGroup();
@ -357,6 +363,7 @@ bool Settings::saveFile(QString filePath) {
settings.setValue("DesktopIconSize", desktopIconSize_);
settings.setValue("ShowWmMenu", showWmMenu_);
settings.setValue("ShowHidden", desktopShowHidden_);
settings.setValue("HideItems", desktopHideItems_);
settings.setValue("SortOrder", sortOrderToString(desktopSortOrder_));
settings.setValue("SortColumn", sortColumnToString(desktopSortColumn_));
settings.setValue("SortFolderFirst", desktopSortFolderFirst_);
@ -406,6 +413,13 @@ bool Settings::saveFile(QString filePath) {
settings.setValue("PlacesRoot", placesRoot_);
settings.setValue("PlacesComputer", placesComputer_);
settings.setValue("PlacesNetwork", placesNetwork_);
if (hiddenPlaces_.isEmpty()) { // don't save "@Invalid()"
settings.remove("HiddenPlaces");
}
else {
QStringList hiddenPlaces = hiddenPlaces_.toList();
settings.setValue("HiddenPlaces", hiddenPlaces);
}
settings.endGroup();
settings.beginGroup("Window");

@ -28,6 +28,7 @@
#include "desktopwindow.h"
#include <libfm-qt/sidepane.h>
#include <libfm-qt/core/thumbnailjob.h>
#include <libfm-qt/core/archiver.h>
namespace PCManFM {
@ -189,9 +190,7 @@ public:
void setArchiver(QString archiver) {
archiver_ = archiver;
// override libfm FmConfig
g_free(fm_config->archiver);
fm_config->archiver = g_strdup(archiver_.toLocal8Bit().constData());
Fm::Archiver::setDefaultArchiverByName(archiver_.toLocal8Bit().constData());
}
bool mountOnStartup() const {
@ -330,6 +329,14 @@ public:
desktopShowHidden_ = desktopShowHidden;
}
bool desktopHideItems() const {
return desktopHideItems_;
}
void setDesktopHideItems(bool hide) {
desktopHideItems_ = hide;
}
Qt::SortOrder desktopSortOrder() const {
return desktopSortOrder_;
}
@ -350,7 +357,7 @@ public:
return desktopSortFolderFirst_;
}
void setSesktopSortFolderFirst(bool desktopFolderFirst) {
void setDesktopSortFolderFirst(bool desktopFolderFirst) {
desktopSortFolderFirst_ = desktopFolderFirst;
}
@ -546,6 +553,19 @@ public:
placesNetwork_ = placesNetwork;
}
QSet<QString> getHiddenPlaces() const {
return hiddenPlaces_;
}
void setHiddenPlace(const QString& str, bool hide) {
if(hide) {
hiddenPlaces_ << str;
}
else {
hiddenPlaces_.remove(str);
}
}
Qt::SortOrder sortOrder() const {
return sortOrder_;
@ -649,6 +669,14 @@ public:
fm_config->quick_exec = quickExec_;
}
bool selectNewFiles() const {
return selectNewFiles_;
}
void setSelectNewFiles(bool value) {
selectNewFiles_ = value;
}
// bool thumbnailLocal_;
// bool thumbnailMax;
@ -874,6 +902,7 @@ private:
bool showWmMenu_;
bool desktopShowHidden_;
bool desktopHideItems_;
Qt::SortOrder desktopSortOrder_;
Fm::FolderModel::ColumnId desktopSortColumn_;
bool desktopSortFolderFirst_;
@ -908,6 +937,7 @@ private:
bool noUsbTrash_; // do not trash files on usb removable devices
bool confirmTrash_; // Confirm before moving files into "trash can"
bool quickExec_; // Don't ask options on launch executable file
bool selectNewFiles_;
bool showThumbnails_;
@ -924,6 +954,7 @@ private:
bool placesRoot_;
bool placesComputer_;
bool placesNetwork_;
QSet<QString> hiddenPlaces_;
int bigIconSize_;
int smallIconSize_;

@ -19,23 +19,92 @@
#include "tabbar.h"
#include <QPointer>
#include <QMouseEvent>
#include <QApplication>
#include <QDrag>
#include <QMimeData>
namespace PCManFM {
TabBar::TabBar(QWidget *parent):
QTabBar(parent)
QTabBar(parent),
dragStarted_(false)
{
}
void TabBar::mousePressEvent(QMouseEvent *event) {
QTabBar::mousePressEvent (event);
if(event->button() == Qt::LeftButton
&& tabAt(event->pos()) > -1) {
dragStartPosition_ = event->pos();
}
dragStarted_ = false;
}
void TabBar::mouseMoveEvent(QMouseEvent *event)
{
if(!dragStartPosition_.isNull()
&& (event->pos() - dragStartPosition_).manhattanLength() < QApplication::startDragDistance()) {
dragStarted_ = true;
}
if((event->buttons() & Qt::LeftButton)
&& dragStarted_
&& !window()->geometry().contains(event->globalPos())) {
if(currentIndex() == -1) {
return;
}
QPointer<QDrag> drag = new QDrag(this);
QMimeData *mimeData = new QMimeData;
mimeData->setData("application/pcmanfm-qt-tab", QByteArray());
drag->setMimeData(mimeData);
Qt::DropAction dragged = drag->exec();
if(dragged == Qt::IgnoreAction) { // a tab is dropped outside all windows
if(count() > 1) {
Q_EMIT tabDetached();
}
else {
finishMouseMoveEvent();
}
event->accept();
}
else if(dragged == Qt::MoveAction) { // a tab is dropped into another window
event->accept();
}
drag->deleteLater();
}
else {
QTabBar::mouseMoveEvent(event);
}
}
void TabBar::finishMouseMoveEvent() {
QMouseEvent finishingEvent(QEvent::MouseMove, QPoint(), Qt::NoButton, Qt::NoButton, Qt::NoModifier);
mouseMoveEvent(&finishingEvent);
}
void TabBar::releaseMouse() {
QMouseEvent releasingEvent(QEvent::MouseButtonRelease, QPoint(), Qt::LeftButton, Qt::NoButton, Qt::NoModifier);
mouseReleaseEvent(&releasingEvent);
}
void TabBar::mouseReleaseEvent(QMouseEvent *event) {
if (event->button() == Qt::MiddleButton) {
int index = tabAt(event->pos());
if (index != -1) {
Q_EMIT tabCloseRequested(index);
if (event->button() == Qt::MiddleButton) {
int index = tabAt(event->pos());
if (index != -1) {
Q_EMIT tabCloseRequested(index);
}
}
QTabBar::mouseReleaseEvent(event);
}
// Let the main window receive dragged tabs!
void TabBar::dragEnterEvent(QDragEnterEvent *event) {
if(event->mimeData()->hasFormat("application/pcmanfm-qt-tab")) {
event->ignore();
}
}
QTabBar::mouseReleaseEvent(event);
}
}

@ -31,10 +31,23 @@ class TabBar : public QTabBar {
Q_OBJECT
public:
explicit TabBar(QWidget *parent = 0);
explicit TabBar(QWidget *parent = 0);
void finishMouseMoveEvent();
void releaseMouse();
Q_SIGNALS:
void tabDetached();
protected:
void mouseReleaseEvent(QMouseEvent *event);
void mouseReleaseEvent(QMouseEvent *event);
// from qtabbar.cpp
virtual void mousePressEvent(QMouseEvent *event);
virtual void mouseMoveEvent(QMouseEvent *event);
virtual void dragEnterEvent(QDragEnterEvent *event);
private:
QPoint dragStartPosition_;
bool dragStarted_;
};
}

@ -46,38 +46,12 @@ bool ProxyFilter::filterAcceptsRow(const Fm::ProxyFolderModel* model, const std:
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},
@ -85,13 +59,15 @@ TabPage::TabPage(QWidget* parent):
proxyModel_{nullptr},
proxyFilter_{nullptr},
verticalLayout{nullptr},
overrideCursor_(false) {
overrideCursor_(false),
selectionTimer_(nullptr) {
Settings& settings = static_cast<Application*>(qApp)->settings();
// create proxy folder model to do item filtering
proxyModel_ = new ProxyFolderModel();
proxyModel_->setShowHidden(settings.showHidden());
proxyModel_->setBackupAsHidden(settings.backupAsHidden());
proxyModel_->setShowThumbnails(settings.showThumbnails());
connect(proxyModel_, &ProxyFolderModel::sortFilterChanged, this, &TabPage::sortFilterChanged);
@ -122,8 +98,9 @@ TabPage::~TabPage() {
if(proxyModel_) {
delete proxyModel_;
}
disconnect(folderModel_, &Fm::FolderModel::fileSizeChanged, this, &TabPage::onFileSizeChanged);
if(folderModel_) {
disconnect(folderModel_, &Fm::FolderModel::fileSizeChanged, this, &TabPage::onFileSizeChanged);
disconnect(folderModel_, &Fm::FolderModel::filesAdded, this, &TabPage::onFilesAdded);
folderModel_->unref();
}
@ -144,6 +121,9 @@ void TabPage::freeFolder() {
}
void TabPage::onFolderStartLoading() {
if(folderModel_){
disconnect(folderModel_, &Fm::FolderModel::filesAdded, this, &TabPage::onFilesAdded);
}
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.
@ -184,8 +164,12 @@ void TabPage::onUiUpdated() {
folderView_->childView()->setCurrentIndex(index);
}
}
// update selection statusbar info when needed
connect(folderModel_, &Fm::FolderModel::fileSizeChanged, this, &TabPage::onFileSizeChanged);
if(folderModel_) {
// update selection statusbar info when needed
connect(folderModel_, &Fm::FolderModel::fileSizeChanged, this, &TabPage::onFileSizeChanged);
// get ready to select files that may be added later
connect(folderModel_, &Fm::FolderModel::filesAdded, this, &TabPage::onFilesAdded);
}
}
void TabPage::onFileSizeChanged(const QModelIndex& index) {
@ -197,6 +181,22 @@ void TabPage::onFileSizeChanged(const QModelIndex& index) {
}
}
// slot
void TabPage::onFilesAdded(Fm::FileInfoList files) {
if(static_cast<Application*>(qApp)->settings().selectNewFiles()) {
if(!selectionTimer_) {
folderView_->selectFiles(files, false);
selectionTimer_ = new QTimer (this);
selectionTimer_->setSingleShot(true);
selectionTimer_->start(200);
}
else {
folderView_->selectFiles(files, selectionTimer_->isActive());
selectionTimer_->start(200);
}
}
}
void TabPage::onFolderFinishLoading() {
auto fi = folder_->info();
if(fi) { // if loading of the folder fails, it's possible that we don't have FmFileInfo.
@ -252,8 +252,8 @@ void TabPage::onFolderError(const Fm::GErrorPtr& err, Fm::Job::ErrorSeverity sev
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);
MountOperation* op = new MountOperation(true);
op->mountEnclosingVolume(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"
@ -290,8 +290,8 @@ void TabPage::onFolderFsInfo() {
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));
.arg(QString::fromUtf8(free_str),
QString::fromUtf8(total_str));
}
else {
msg.clear();
@ -310,6 +310,12 @@ QString TabPage::formatStatusText() {
if(hidden_files > 0) {
text += tr(" (%n hidden)", "", hidden_files);
}
auto fi = folder_->info();
if (fi && fi->isSymlink()) {
text += QString(" %2(%1)")
.arg(encloseWithBidiMarks(tr("Link to") + QChar(QChar::Space) + QString::fromStdString(fi->target())),
(layoutDirection() == Qt::RightToLeft) ? QChar(0x200f) : QChar(0x200e));
}
return text;
}
return QString();
@ -388,6 +394,7 @@ void TabPage::chdir(Fm::FilePath newPath, bool addHistory) {
// free the previous model
if(folderModel_) {
disconnect(folderModel_, &Fm::FolderModel::fileSizeChanged, this, &TabPage::onFileSizeChanged);
disconnect(folderModel_, &Fm::FolderModel::filesAdded, this, &TabPage::onFilesAdded);
proxyModel_->setSourceModel(nullptr);
folderModel_->unref(); // unref the cached model
folderModel_ = nullptr;
@ -399,7 +406,6 @@ void TabPage::chdir(Fm::FilePath newPath, bool addHistory) {
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());
@ -448,7 +454,6 @@ void TabPage::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
@ -460,6 +465,17 @@ void TabPage::reload() {
}
}
// 200e LEFT-TO-RIGHT MARK
// 200f RIGHT-TO-LEFT MARK
// 202a LEFT-TO-RIGHT EMBEDDING
// 202b RIGHT-TO-LEFT EMBEDDING
// 202c POP DIRECTIONAL FORMATTING
QString TabPage::encloseWithBidiMarks(const QString& text) {
QChar bidiMark = text.isRightToLeft() ? QChar(0x200f) : QChar(0x200e);
QChar embedBidiMark = text.isRightToLeft() ? QChar(0x202b) : QChar(0x202a);
return embedBidiMark+text+bidiMark+QChar(0x202c);
}
// when the current selection in the folder view is changed
void TabPage::onSelChanged() {
QString msg;
@ -467,24 +483,44 @@ void TabPage::onSelChanged() {
auto files = folderView_->selectedFiles();
int numSel = files.size();
/* FIXME: display total size of all selected files. */
if(numSel == 1) { /* only one file is selected */
if(numSel == 1) { /* only one file is selected (also, tell if it is a symlink)*/
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());
if(fi->isSymlink()) {
msg = QString("%5\"%1\" %5(%2) %5%3 %5(%4)")
.arg(encloseWithBidiMarks(fi->displayName()),
encloseWithBidiMarks(Fm::formatFileSize(fi->size(), fm_config->si_unit)),
encloseWithBidiMarks(fi->mimeType()->desc()),
encloseWithBidiMarks(tr("Link to") + QChar(QChar::Space) + QString::fromStdString(fi->target())),
(layoutDirection() == Qt::RightToLeft) ? QChar(0x200f) : QChar(0x200e));
}
else {
msg = QString("%4\"%1\" %4(%2) %4%3")
.arg(encloseWithBidiMarks(fi->displayName()),
encloseWithBidiMarks(Fm::formatFileSize(fi->size(), fm_config->si_unit)), // FIXME: deprecate fm_config
encloseWithBidiMarks(fi->mimeType()->desc()),
(layoutDirection() == Qt::RightToLeft) ? QChar(0x200f) : QChar(0x200e));
}
}
else {
msg = QString("\"%1\" %2")
.arg(fi->displayName())
.arg(fi->mimeType()->desc());
if(fi->isSymlink()) {
msg = QString("%4\"%1\" %4%2 %4(%3)")
.arg(encloseWithBidiMarks(fi->displayName()),
encloseWithBidiMarks(fi->mimeType()->desc()),
encloseWithBidiMarks(tr("Link to") + QChar(QChar::Space) + QString::fromStdString(fi->target())),
(layoutDirection() == Qt::RightToLeft) ? QChar(0x200f) : QChar(0x200e));
}
else {
msg = QString("%3\"%1\" %3%2")
.arg(encloseWithBidiMarks(fi->displayName()),
encloseWithBidiMarks(fi->mimeType()->desc()),
(layoutDirection() == Qt::RightToLeft) ? QChar(0x200f) : QChar(0x200e));
}
}
/* 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) {
@ -533,7 +569,7 @@ void TabPage::forward() {
}
void TabPage::jumpToHistory(int index) {
if(index >= 0 && index < history_.size()) {
if(index >= 0 && static_cast<size_t>(index) < history_.size()) {
// remember current scroll position
BrowseHistoryItem& item = history_.currentItem();
QAbstractItemView* childView = folderView_->childView();

@ -26,7 +26,6 @@
#include <libfm/fm.h>
#include <libfm-qt/browsehistory.h>
#include "view.h"
#include <libfm-qt/path.h>
#include "settings.h"
#include <libfm-qt/core/fileinfo.h>
@ -48,7 +47,6 @@ class ProxyFilter : public Fm::ProxyFolderModelFilter {
public:
bool filterAcceptsRow(const Fm::ProxyFolderModel* model, const std::shared_ptr<const Fm::FileInfo>& info) const;
virtual ~ProxyFilter() {}
void setVirtHidden(const std::shared_ptr<Fm::Folder>& folder);
QString getFilterStr() {
return filterStr_;
}
@ -58,7 +56,6 @@ public:
private:
QString filterStr_;
QStringList virtHiddenList_;
};
class TabPage : public QWidget {
@ -212,11 +209,15 @@ protected Q_SLOTS:
void onSelChanged();
void onUiUpdated();
void onFileSizeChanged(const QModelIndex& index);
void onFilesAdded(const Fm::FileInfoList files);
private:
void freeFolder();
QString formatStatusText();
// Adds bidi marks (RLM/LRM/RLE/LRE/POP) around the text for the statusbar.
QString encloseWithBidiMarks(const QString& text);
void onFolderStartLoading();
void onFolderFinishLoading();
@ -240,6 +241,7 @@ private:
Fm::FilePath lastFolderPath_; // last browsed folder
bool overrideCursor_;
FolderSettings folderSettings_;
QTimer* selectionTimer_;
};
}

@ -0,0 +1,3 @@
Name[es]=Escritorio
GenericName[es]=Configuración del escritorio
Comment[es]=Cambiar el fondo de pantalla y el comportamiento del escritorio

@ -1,4 +1,4 @@
#Translations / translated by tulliana <tulliana@yandex.com>
Name[tr]=Dosya Yöneticisi (pcmanfm-qt)
Name[tr]=Dosya Yöneticisi (PCManFM-Qt)
GenericName[tr]=Dosya ve masaüstü yönetim uygulaması
Comment[tr]=Dosya Yöneticisi ve Masaüstü Ayarları (duvarkağıtları, menüler vs..)

@ -0,0 +1,4 @@
#Translations
Name[zh_CN]=桌面
GenericName[zh_CN]=桌面设置
Comment[zh_CN]=更改墙纸与桌面管理器的行为。

@ -1,4 +1,4 @@
#Translations
Name[ar]=مدير الملفّات PCManFM
Name[ar]=مدير الملفّات PCManFM-Qt
GenericName[ar]=مدير ملفّات
Comment[ar]=تصفّح نظام الملفّات وأدر ملفّاتك

@ -1,4 +1,4 @@
#Translations
Name[ca]=Gestor de fitxers PCManFM
Name[ca]=Gestor de fitxers PCManFM-Qt
GenericName[ca]=Gestor de fitxers
Comment[ca]=Navegueu pel sistema de fitxers i gestioneu els fitxers

@ -1,3 +1,3 @@
Name[da]=PCManFM-filhåndtering
Name[da]=PCManFM-Qt-filhåndtering
GenericName[da]=Filhåndtering
Comment[da]=Gennemse filsystemet og håndtér filerne

@ -1,4 +1,4 @@
Name[el]=Διαχειριστής αρχείων PCManFM
Name[el]=Διαχειριστής αρχείων PCManFM-Qt
GenericName[el]=Διαχειριστής αρχείων
Comment[el]=Περιήγηση του συστήματος αρχείων και διαχείριση των αρχείων

@ -0,0 +1,3 @@
Name[es]=Gestor de archivos PCManFM-Qt
GenericName[es]=Gestor de archivos
Comment[es]=Explorar el sistema de archivos y gestionar los archivos

@ -1,4 +1,4 @@
#Translations
Name[it]=Gestore file PCmanFM
Name[it]=Gestore file PCManFM-Qt
GenericName[it]=Gestore file
Comment[it]=Esplora e organizza file e cartelle

@ -1,4 +1,4 @@
#Translations
Name[lt]=PCManFM failų tvarkytuvė
Name[lt]=PCManFM-Qt failų tvarkytuvė
GenericName[lt]=Failų tvarkytuvė
Comment[lt]=Naršyti failų sistemą ir tvarkyti failus

@ -1,4 +1,4 @@
#Translations
Name[pl]=Menedżer plików PCManFM
Name[pl]=Menedżer plików PCManFM-Qt
GenericName[pl]=Menedżer plików
Comment[pl]=Przegląd systemu plików i zarządzanie plikami

@ -1,4 +1,4 @@
#Translations
Name[pt]=Gestor de ficheiros PCManFM
Name[pt]=Gestor de ficheiros PCManFM-Qt
GenericName[pt]=Gestor de ficheiros
Comment[pt]=Explorar o sistema de ficheiros e gerir os seus ficheiros e pastas

@ -1,4 +1,4 @@
#Translations
Name[pt_BR]=Gerenciador de Arquivos PCManFM
Name[pt_BR]=Gerenciador de Arquivos PCManFM-Qt
GenericName[pt_BR]=Gerenciador de Arquivos
Comment[pt_BR]=Navegue pelo sistema de arquivos e gerencie arquivos e pastas

@ -1,4 +1,4 @@
#Translations
Name[ru]=Диспетчер файлов PCManFM
Name[ru]=Диспетчер файлов PCManFM-Qt
GenericName[ru]=Диспетчер файлов
Comment[ru]=Просматривайте файловую систему и управляйте файлами

@ -0,0 +1,4 @@
#Translations
Name[zh_CN]=PCManFM-Qt 文件管理器
GenericName[zh_CN]=文件管理器
Comment[zh_CN]=浏览文件系统并管理文件。

@ -126,7 +126,7 @@ void View::prepareFileMenu(Fm::FileMenu* menu) {
}
}
void View::prepareFolderMenu(Fm::FolderMenu* menu) {
void View::prepareFolderMenu(Fm::FolderMenu* /*menu*/) {
}
void View::updateFromSettings(Settings& settings) {
@ -143,6 +143,7 @@ void View::updateFromSettings(Settings& settings) {
Fm::ProxyFolderModel* proxyModel = model();
if(proxyModel) {
proxyModel->setShowThumbnails(settings.showThumbnails());
proxyModel->setBackupAsHidden(settings.backupAsHidden());
}
}

Loading…
Cancel
Save