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
This commit is contained in:
parent
6c761062c5
commit
0bb15fb1bf
17
.gitignore
vendored
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
|
||||
|
2
AUTHORS
2
AUTHORS
@ -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:
|
||||
|
54
CHANGELOG
54
CHANGELOG
@ -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)
|
||||
|
51
README.md
51
README.md
@ -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
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><html><head/><body><p><a href="http://lxqt.org/"><span style=" text-decoration: underline; color:#0000ff;">http://lxqt.org/</span></a></p></body></html></string>
|
||||
<string><html><head/><body><p><a href="https://lxqt.org/"><span style=" text-decoration: underline; color:#0000ff;">https://lxqt.org/</span></a></p></body></html></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"
|
||||
|
92
pcmanfm/bulk-rename.ui
Normal file
92
pcmanfm/bulk-rename.ui
Normal file
@ -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>
|
103
pcmanfm/bulkrename.cpp
Normal file
103
pcmanfm/bulkrename.cpp
Normal file
@ -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
|
57
pcmanfm/bulkrename.h
Normal file
57
pcmanfm/bulkrename.h
Normal file
@ -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>&Path Buttons</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionBulkRename">
|
||||
<property name="text">
|
||||
<string>&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) {
|
||||
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);
|
||||
|
||||
if(path) {
|
||||
page->chdir(path, true);
|
||||
}
|
||||
ui.tabBar->insertTab(index, page->windowTitle());
|
||||
|
||||
Settings& settings = static_cast<Application*>(qApp)->settings();
|
||||
|
||||
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(!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::mouseReleaseEvent(QMouseEvent *event) {
|
||||
if (event->button() == Qt::MiddleButton) {
|
||||
int index = tabAt(event->pos());
|
||||
if (index != -1) {
|
||||
Q_EMIT tabCloseRequested(index);
|
||||
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);
|
||||
}
|
||||
}
|
||||
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_;
|
||||
};
|
||||
|
||||
}
|
||||
|
3
pcmanfm/translations/pcmanfm-qt-desktop-pref_es.desktop
Normal file
3
pcmanfm/translations/pcmanfm-qt-desktop-pref_es.desktop
Normal file
@ -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]=Περιήγηση του συστήματος αρχείων και διαχείριση των αρχείων
|
||||
|
||||
|
3
pcmanfm/translations/pcmanfm-qt_es.desktop
Normal file
3
pcmanfm/translations/pcmanfm-qt_es.desktop
Normal file
@ -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]=Просматривайте файловую систему и управляйте файлами
|
4
pcmanfm/translations/pcmanfm-qt_zh_CN.desktop
Normal file
4
pcmanfm/translations/pcmanfm-qt_zh_CN.desktop
Normal file
@ -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…
x
Reference in New Issue
Block a user