Compare commits

...

81 Commits

Author SHA1 Message Date
Aaron Rainbolt
aa64408b59
Update build deps 2025-08-01 11:27:25 -05:00
Aaron Rainbolt
a50857afe9
Bump Standards-Version 2025-08-01 11:26:19 -05:00
Aaron Rainbolt
14a3980790
Update copyright file 2025-08-01 11:25:55 -05:00
Aaron Rainbolt
a728549560
Bump version for new upstream release 2025-08-01 11:23:43 -05:00
0748caa591 Update Standards-Version to 4.7.1, no changes needed. 2025-02-21 17:09:30 -06:00
299d23ae1b No-change rebuild for lxqt-build-tools C++17 -> C++20. 2025-02-21 16:58:52 -06:00
15c2e1269b Upload to Plucky 2024-11-15 15:34:45 -06:00
cfc7276549 Make Lintian happy 2024-11-05 18:34:59 -06:00
0c050f1ed9 Bump build dependencies. 2024-11-05 18:30:49 -06:00
9d4a47c1e1 New upstream release. 2024-11-05 18:29:24 -06:00
Aaron Rainbolt
0ff7e381a6 Release to Oracular 2024-08-15 16:45:52 -05:00
Aaron Rainbolt
8af637bfa3 PPA build 2024-06-27 23:16:39 -05:00
Aaron Rainbolt
3c8298485f Adjust dependencies 2024-06-27 23:14:44 -05:00
Aaron Rainbolt
d8437b3e4f Bump Standards-Version 2024-06-27 23:13:57 -05:00
Aaron Rainbolt
8a01ad88c1 Update copyright file 2024-06-27 23:13:47 -05:00
Aaron Rainbolt
c3a20795a0 Bump version for new upstream release 2024-06-27 23:12:28 -05:00
be20a285df Overhaul copyright file 2023-11-12 12:47:31 -06:00
fccfe824c7 Bump version for new upstream release 2023-11-12 12:21:08 -06:00
cc03cc8630 Upload to Mantic. 2023-08-03 10:43:32 -05:00
d5c19dc50a Bump build dependencies. 2023-07-27 17:01:28 -05:00
735d894f41 New upstream release. 2023-07-27 16:59:44 -05:00
Aaron Rainbolt
d3aea648e2 Swap pulseaudio and pipewire-pulse dependencies 2023-04-02 15:20:22 -05:00
Aaron Rainbolt
8ac437506d Bump version number 2023-02-12 17:41:03 -06:00
Aaron Rainbolt
80154abf01 Updated copyright file. 2023-02-10 13:52:11 -06:00
Debian Janitor
cb48c5b8db Set upstream metadata fields: Repository-Browse. 2023-02-10 13:52:08 -06:00
Aaron Rainbolt
47fad3fafb Bumped Standards-Version. 2023-02-10 13:31:15 -06:00
Aaron Rainbolt
bd6c953fdf Revert a sync from Debian.
This reverts commit 3fcf6e56d11eb205a0fc1ab331dfbfe8e301940d.
2023-02-10 13:30:44 -06:00
Aaron Rainbolt
3fcf6e56d1 Sync with archive. 2023-02-10 13:28:48 -06:00
b55e967956 Upload to Lunar. 2022-11-17 16:43:25 -06:00
064bd7edf1 Bump build dependencies in debian/control. 2022-11-17 16:37:42 -06:00
f26d70ceb7 Lubuntuify the package slightly, to make debhelper happy. 2022-11-17 16:35:19 -06:00
daa1c2de24 Fix the watch file, for real this time. 2022-11-17 16:31:46 -06:00
bdb166a982 New upstream release. 2022-11-17 16:30:09 -06:00
f1c4688096 Sync with Debian version 1.1.0-1. 2022-11-17 16:27:10 -06:00
6542fceb76 Upload to Kinetic. 2022-06-02 10:42:30 -05:00
a3b8864f6a Bump build dependencies. 2022-06-02 10:39:53 -05:00
5fc5a01f1b New upstream release. 2022-06-02 10:39:23 -05:00
Rik Mills
db661ecfe1 Allow pipewire-pulse as an alternate depends. 2022-06-02 10:38:46 -05:00
apt-ghetto
fad72048d0 New upstream release for pavucontrol-qt (Closes D137)
Packaged new upstream version 0.17.0 of pavucontrol-qt
Updated changelog, control and copyright
Renamed tag for lintian override
2021-08-19 10:37:43 -05:00
Rik Mills
9662277ed9 release to hirsute 2021-02-21 19:48:55 +00:00
Rik Mills
5784bf15c6 restore correct upstream signing key 2021-02-21 19:48:20 +00:00
Rik Mills
2a597afc67 merge from debian unstable 2021-01-31 17:17:18 +00:00
57854a4f5d Upload to Groovy. 2020-06-04 00:17:34 -05:00
e2b5dade29 Run wrap-and-sort. 2020-04-30 23:56:34 -05:00
9a8446f01a Update LXQt build dependencies. 2020-04-30 23:56:20 -05:00
280671b531 Update Standards-version to 4.5.0, no changes needed. 2020-04-30 23:56:01 -05:00
59b9c462c1 Update upstream signing key. 2020-04-30 23:55:49 -05:00
d988018c6c New upstream release. 2020-04-30 23:55:14 -05:00
Simon Quigley
8a17a95390 Lubuntuify the package. 2019-03-30 17:54:27 -05:00
Alf Gaida
9ae1574941 Cherry-picking upstream release 0.14.1.
* Bumped minimum version libfm-qt-dev (>= 0.14.1~)
* Depend now on libfm-qt6 (>= 0.14.1~)
* Improved the description of the language package
2019-02-25 00:03:33 +01:00
Alf Gaida
2e4ab0a73b Cherry-picking upstream release 0.14.0.
* Bumped Standards to 4.3.0, no changes needed
* Dropped d/compat, use debhelper-compat = 12, no changes needed
* Fixed years in d/copyright
* Bumped minimum version libfm-qt-dev (>= 0.14.0~)
* Bumped minimum version lxqt-build-tools (>= 0.6.0~)
* Depend now on libfm-qt6 (>= 0.14.0~)
* Removed obsolete PULL_TRANSLATIONS= OFF from dh_auto_configure
* Added Build-Depends-Package field to symbols
* Added l10n-package, moved from lxqt-l10n
* Added d/upstream/metadata
2019-01-27 19:40:59 +01:00
Alf Gaida
1e04a14cf3 Switch to unstable
* Bumped build dependency libfm-qt-dev to >= 0.13.1~
* Bumped Standards to 4.1.5, no changes needed
2018-07-07 14:37:55 +02:00
Alf Gaida
0bb15fb1bf 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
2018-05-26 02:28:29 +02:00
Alf Gaida
6c761062c5 prep 0.13.0 2018-05-22 03:30:49 +02:00
Alf Gaida
6b4ff33f89 Some updates in debian $foo
* Bumped compat to 11
* Bumped debhelper to >= 11~
* Bumped Standards to 4.1.4, no changes needed
* Fixed a glitch in VCS fields
* Changed Homepage, Source and watch to lxqt
* Bumped year in copyright
2018-04-28 18:44:22 +02:00
Alf Gaida
9958fa6b82 Moved git to salsa, changed the VCS fields that way
* Bumped Standards to 4.1.3, no changes needed
* Added gfvs-fuse to recommends, thanks robert <maxl1234@gmx.at>
  (Closes: #886166)
2018-01-05 19:12:57 +01:00
Alf Gaida
675cbb7210 Really bumped Standards. 2017-12-16 03:48:46 +01:00
Alf Gaida
44b4e33961 Cleanup debian/*
* Bumped Standards to 4.1.2, no changes needed
* Move config to /usr/share/pcmanfm-qt/lxqt
* Removed branch from VCS fields
* Removed debian/gbp.conf
2017-12-15 00:49:30 +01:00
Alf Gaida
e60a20c17e Transition to sid 2017-12-05 01:54:16 +01:00
Alf Gaida
bb042458e5 Merge branch 'debian/experimental' into debian/sid 2017-12-05 01:50:50 +01:00
Alf Gaida
49eb8afa56 Cherry-picking upstream version 0.12.0. 2017-12-05 01:48:48 +01:00
Alf Gaida
2f23742571 remove the forgotten quilt 2017-12-05 01:47:37 +01:00
Alf Gaida
5fba8b840b Cherry-picking upstream release 0.12.0.
* Bumped Standards to 4.1.1
* Bumped build-tools >= 0.4.0
* Bumped libfm-qt-dev >= 0.12.0
* Bumped years in copyright
* Added  build dependency libexif-dev
* Added Breaks and Replaces for lxqt-common << 0.12.0
2017-10-24 21:54:10 +02:00
Alf Gaida
307faf782b Make dependencies and recommends more useful
* Depend on desktop-file-utils (Closes: #866900)
* Recommend ffmpegthumbnailer (Closes: #867460)
* Removed the alternative dependency gksu.  Reason: #867236
2017-07-06 20:02:32 +02:00
Alf Gaida
e34ee74853 Improved dependencies and recommends and bumped Standards
* Bumped Standards to 4.0.0
* Depend on lxqt-sudo | gksu we need at least one UI for sudo
* Added Recommends: lximage-qt, lxqt-policykit, lxqt-qtplugin (Closes: #866347)
* pcmanfm-qt allow multiple file selections with mouse, the implementation is
  horrible in some places, but it works. (Closes: #853201)
2017-07-02 18:05:23 +02:00
Alf Gaida
11e85f2a87 set oxygen-icon-theme as default alternative recommendation
(Closes: #851411)
2017-01-15 01:40:14 +01:00
Alf Gaida
6fc1ada88a Cherry-picking upstream release 0.11.3. 2017-01-14 03:55:07 +01:00
Alf Gaida
3194275f96 Cherry-picking upstream release 0.11.2.
* Removed build dependencies:
  - libfm-dev
  - liblxqt0-dev
* Bumped minimum versions
  - libfm-qt-dev (>= 0.11.2)
  - lxqt-build-tools (>= 0.3.0)
  - libfm-qt3 (>= 0.11.2)
* Suggests: cdtool -> cdtool [linux-any]
2016-12-22 02:02:45 +01:00
Alf Gaida
c8fa152f29 Some fixes in debian/control
* Added versioned dependency libfm-qt3 (>= 0.11.1), dh detect only
  a minimum version of 0.11.0 - false because some symbols are added
  which are needed for pcmanfm-qt (>= 0.11.1) (Closes: #842080)
* Removed build dependencies
  - libqt5xdg-dev
  - pkg-config,
  - qttools5-dev,
  - qttools5-dev-tools
* Added build dependency lxqt-build-tools
2016-11-05 02:47:46 +01:00
Alf Gaida
90f60f818b Added versioned dependency libfm-qt3 (>= 0.11.1)
dh detect only a minimum version of 0.11.0 - false because some symbols
are added which are needed for pcmanfm-qt (>= 0.11.1) (Closes: #842080)
2016-10-26 03:03:22 +02:00
Alf Gaida
98bdec9473 Cherry-picking upstream release 0.11.1.
* Synced debian foo with experimental
* Removed --parallel from rules, standard compat 10
* New dep. default-dbus-session-bus | dbus-session-bus | dbus-x11
  (Closes: #836284)
* Fixed Crashes while copying (Closes: #823753)
* Bumped minimum version libfm-qt-dev (>= 0.11.1)
* Bumped minimum version libqt5xdg-dev (>= 2.0.0)
* Added build dependency libkf5windowsystem-dev
* Added build dependency libqt5svg5-dev
* Added build dependency liblxqt0-dev (>= 0.11.0)
* Added Recommends pcmanfm-qt-l10n
* Fixed VCS fields, using plain /git/
* Fixed copyright Format field, using https
* Dropped patches, applied upstream
* Added translation controls
* Set CMAKE_BUILD_TYPE=RelWithDebInfo
2016-10-18 22:59:50 +02:00
Alf Gaida
49f999091b prepare 0.11.1 import
added current upstream signing key
fixed watch file
2016-09-24 06:32:59 +02:00
Alf Gaida
11102b8d08 Fixed typo in Recommends: oyxgen-icon-theme -> oxygen-icon-theme 2016-09-19 21:50:19 +02:00
Alf Gaida
c4f67c3906 Bumped compat to 10
Bumped build dependency debhelper (>=10)
Fixed typo in Recommends: faenza--icon-theme > faenza-icon-theme
2016-09-19 04:24:00 +02:00
Alf Gaida
b9b8a01b55 Replace dep. dbus-x11 with default-dbus-session-bus | dbus-session-bus (Closes: #836284)
Set CMAKE_BUILD_TYPE=RelWithDebInfo
2016-09-01 22:56:44 +02:00
Alf Gaida
78f7986504 Fixed VCS fields, use plain /git/
Reworked icon-theme recommends (Closes: #833590)
 Thanks Pino Toscano <pino@debian.org>
2016-08-07 11:15:54 +02:00
ChangZhuo Chen (陳昌倬)
4e4a9b3908 Update changelog 2016-07-16 11:16:45 +08:00
ChangZhuo Chen (陳昌倬)
e5d8da79c0 Set LC_ALL for reproducible builds 2016-07-16 11:11:24 +08:00
Alf Gaida
326f8dd6f9 Backported temporary upstream fix for #826311
(https://github.com/lxde/pcmanfm-qt/pull/359)
Bumped standards version to 3.9.8 - no changes needed
2016-06-04 19:39:41 +02:00
Alf Gaida
15d47c8e57 Added oxygen-icon-theme | oxygen5-icon-theme | gnome-icon-theme
to recommends. (Closes: #826311)
2016-06-04 15:54:40 +02:00
Yuan CHAO
62151a370b Adding Depends: dbus-x11. Closes: #820079 2016-04-19 20:32:58 +08:00
96 changed files with 395 additions and 36772 deletions

10
.gitignore vendored
View File

@ -1,2 +1,8 @@
build
*.kdev4
debian/*.debhelper
debian/*.log
debian/*.substvars
debian/debhelper-build-stamp
debian/files
debian/pcmanfm-qt/

View File

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

View File

@ -1,102 +0,0 @@
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)
set(PCMANFM_QT_VERSION_MAJOR 0)
set(PCMANFM_QT_VERSION_MINOR 11)
set(PCMANFM_QT_VERSION_PATCH 0)
set(PCMANFM_QT_VERSION ${PCMANFM_QT_VERSION_MAJOR}.${PCMANFM_QT_VERSION_MINOR}.${PCMANFM_QT_VERSION_PATCH})
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(PkgConfig REQUIRED)
pkg_check_modules(LIB_XCB REQUIRED xcb)
option(UPDATE_TRANSLATIONS "Update source translation translations/*.ts files" OFF)
include(GNUInstallDirs)
include(LXQtTranslateTs)
include(LXQtTranslateDesktop)
# set visibility to hidden to hide symbols, unless they're exported manually in the code
set(CMAKE_CXX_VISIBILITY_PRESET hidden)
set(CMAKE_VISIBILITY_INLINES_HIDDEN 1)
if (CMAKE_VERSION VERSION_LESS "3.1")
include(CheckCXXCompilerFlag)
CHECK_CXX_COMPILER_FLAG("-std=c++11" COMPILER_SUPPORTS_CXX11)
if(COMPILER_SUPPORTS_CXX11)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
else()
CHECK_CXX_COMPILER_FLAG("-std=c++0x" COMPILER_SUPPORTS_CXX0X)
# -std=c++0x is deprecated but some tools e.g. qmake or older gcc are still using it
if(COMPILER_SUPPORTS_CXX0X)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++0x")
else()
message(FATAL_ERROR "Compiler ${CMAKE_CXX_COMPILER} does not support c++11/c++0x")
endif()
endif()
else()
set(CMAKE_CXX_STANDARD 11)
endif()
if (CMAKE_COMPILER_IS_GNUCXX OR CMAKE_CXX_COMPILER_ID STREQUAL "Clang")
# set visibility to hidden to hide symbols, unless they're exported manually in the code
set(CMAKE_CXX_FLAGS "-fno-exceptions ${CMAKE_CXX_FLAGS}")
endif()
set(CMAKE_AUTOMOC TRUE)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
add_subdirectory(pcmanfm)
# manpage for pcmanfm-qt
configure_file(
"${CMAKE_CURRENT_SOURCE_DIR}/pcmanfm-qt.1.in"
"${CMAKE_CURRENT_BINARY_DIR}/pcmanfm-qt.1"
@ONLY
)
install(FILES
"${CMAKE_CURRENT_BINARY_DIR}/pcmanfm-qt.1"
DESTINATION "${CMAKE_INSTALL_MANDIR}/man1"
)
# add Doxygen support to generate API docs
# References:
# http://majewsky.wordpress.com/2010/08/14/tip-of-the-day-cmake-and-doxygen/
# http://www.bluequartz.net/projects/EIM_Segmentation/SoftwareDocumentation/html/usewithcmakeproject.html
option(BUILD_DOCUMENTATION "Use Doxygen to create the HTML based API documentation" OFF)
if(BUILD_DOCUMENTATION)
find_package(Doxygen REQUIRED)
configure_file("${CMAKE_CURRENT_SOURCE_DIR}/Doxyfile.in" "${CMAKE_CURRENT_BINARY_DIR}/Doxyfile" @ONLY)
add_custom_target(doc ALL
${DOXYGEN_EXECUTABLE} "${CMAKE_CURRENT_BINARY_DIR}/Doxyfile"
WORKING_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}"
COMMENT "Generating API documentation with Doxygen" VERBATIM
)
install(DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/docs" DESTINATION "${CMAKE_INSTALL_DOCDIR}")
endif()
# building tarball with CPack -------------------------------------------------
# To create a source distribution, type:
# make package_source
include(InstallRequiredSystemLibraries)
set(CPACK_RESOURCE_FILE_LICENSE "${CMAKE_CURRENT_SOURCE_DIR}/LICENSE")
set(CPACK_RESOURCE_FILE_README "${CMAKE_CURRENT_SOURCE_DIR}/README.md")
set(CPACK_PACKAGE_VENDOR "")
set(CPACK_PACKAGE_VERSION_MAJOR ${PCMANFM_QT_VERSION_MAJOR})
set(CPACK_PACKAGE_VERSION_MINOR ${PCMANFM_QT_VERSION_MINOR})
set(CPACK_PACKAGE_VERSION_PATCH ${PCMANFM_QT_VERSION_PATCH})
set(CPACK_GENERATOR TBZ2)
set(CPACK_SOURCE_GENERATOR TBZ2)
set(CPACK_SOURCE_IGNORE_FILES /build/;.gitignore;.*~;.git;.kdev4;temp)
include(CPack)

File diff suppressed because it is too large Load Diff

280
LICENSE
View File

@ -1,280 +0,0 @@
GNU GENERAL PUBLIC LICENSE
Version 2, June 1991
Copyright (C) 1989, 1991 Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
Preamble
The licenses for most software are designed to take away your
freedom to share and change it. By contrast, the GNU General Public
License is intended to guarantee your freedom to share and change free
software--to make sure the software is free for all its users. This
General Public License applies to most of the Free Software
Foundation's software and to any other program whose authors commit to
using it. (Some other Free Software Foundation software is covered by
the GNU Lesser General Public License instead.) You can apply it to
your programs, too.
When we speak of free software, we are referring to freedom, not
price. Our General Public Licenses are designed to make sure that you
have the freedom to distribute copies of free software (and charge for
this service if you wish), that you receive source code or can get it
if you want it, that you can change the software or use pieces of it
in new free programs; and that you know you can do these things.
To protect your rights, we need to make restrictions that forbid
anyone to deny you these rights or to ask you to surrender the rights.
These restrictions translate to certain responsibilities for you if you
distribute copies of the software, or if you modify it.
For example, if you distribute copies of such a program, whether
gratis or for a fee, you must give the recipients all the rights that
you have. You must make sure that they, too, receive or can get the
source code. And you must show them these terms so they know their
rights.
We protect your rights with two steps: (1) copyright the software, and
(2) offer you this license which gives you legal permission to copy,
distribute and/or modify the software.
Also, for each author's protection and ours, we want to make certain
that everyone understands that there is no warranty for this free
software. If the software is modified by someone else and passed on, we
want its recipients to know that what they have is not the original, so
that any problems introduced by others will not reflect on the original
authors' reputations.
Finally, any free program is threatened constantly by software
patents. We wish to avoid the danger that redistributors of a free
program will individually obtain patent licenses, in effect making the
program proprietary. To prevent this, we have made it clear that any
patent must be licensed for everyone's free use or not licensed at all.
The precise terms and conditions for copying, distribution and
modification follow.
GNU GENERAL PUBLIC LICENSE
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
0. This License applies to any program or other work which contains
a notice placed by the copyright holder saying it may be distributed
under the terms of this General Public License. The "Program", below,
refers to any such program or work, and a "work based on the Program"
means either the Program or any derivative work under copyright law:
that is to say, a work containing the Program or a portion of it,
either verbatim or with modifications and/or translated into another
language. (Hereinafter, translation is included without limitation in
the term "modification".) Each licensee is addressed as "you".
Activities other than copying, distribution and modification are not
covered by this License; they are outside its scope. The act of
running the Program is not restricted, and the output from the Program
is covered only if its contents constitute a work based on the
Program (independent of having been made by running the Program).
Whether that is true depends on what the Program does.
1. You may copy and distribute verbatim copies of the Program's
source code as you receive it, in any medium, provided that you
conspicuously and appropriately publish on each copy an appropriate
copyright notice and disclaimer of warranty; keep intact all the
notices that refer to this License and to the absence of any warranty;
and give any other recipients of the Program a copy of this License
along with the Program.
You may charge a fee for the physical act of transferring a copy, and
you may at your option offer warranty protection in exchange for a fee.
2. You may modify your copy or copies of the Program or any portion
of it, thus forming a work based on the Program, and copy and
distribute such modifications or work under the terms of Section 1
above, provided that you also meet all of these conditions:
a) You must cause the modified files to carry prominent notices
stating that you changed the files and the date of any change.
b) You must cause any work that you distribute or publish, that in
whole or in part contains or is derived from the Program or any
part thereof, to be licensed as a whole at no charge to all third
parties under the terms of this License.
c) If the modified program normally reads commands interactively
when run, you must cause it, when started running for such
interactive use in the most ordinary way, to print or display an
announcement including an appropriate copyright notice and a
notice that there is no warranty (or else, saying that you provide
a warranty) and that users may redistribute the program under
these conditions, and telling the user how to view a copy of this
License. (Exception: if the Program itself is interactive but
does not normally print such an announcement, your work based on
the Program is not required to print an announcement.)
These requirements apply to the modified work as a whole. If
identifiable sections of that work are not derived from the Program,
and can be reasonably considered independent and separate works in
themselves, then this License, and its terms, do not apply to those
sections when you distribute them as separate works. But when you
distribute the same sections as part of a whole which is a work based
on the Program, the distribution of the whole must be on the terms of
this License, whose permissions for other licensees extend to the
entire whole, and thus to each and every part regardless of who wrote it.
Thus, it is not the intent of this section to claim rights or contest
your rights to work written entirely by you; rather, the intent is to
exercise the right to control the distribution of derivative or
collective works based on the Program.
In addition, mere aggregation of another work not based on the Program
with the Program (or with a work based on the Program) on a volume of
a storage or distribution medium does not bring the other work under
the scope of this License.
3. You may copy and distribute the Program (or a work based on it,
under Section 2) in object code or executable form under the terms of
Sections 1 and 2 above provided that you also do one of the following:
a) Accompany it with the complete corresponding machine-readable
source code, which must be distributed under the terms of Sections
1 and 2 above on a medium customarily used for software interchange; or,
b) Accompany it with a written offer, valid for at least three
years, to give any third party, for a charge no more than your
cost of physically performing source distribution, a complete
machine-readable copy of the corresponding source code, to be
distributed under the terms of Sections 1 and 2 above on a medium
customarily used for software interchange; or,
c) Accompany it with the information you received as to the offer
to distribute corresponding source code. (This alternative is
allowed only for noncommercial distribution and only if you
received the program in object code or executable form with such
an offer, in accord with Subsection b above.)
The source code for a work means the preferred form of the work for
making modifications to it. For an executable work, complete source
code means all the source code for all modules it contains, plus any
associated interface definition files, plus the scripts used to
control compilation and installation of the executable. However, as a
special exception, the source code distributed need not include
anything that is normally distributed (in either source or binary
form) with the major components (compiler, kernel, and so on) of the
operating system on which the executable runs, unless that component
itself accompanies the executable.
If distribution of executable or object code is made by offering
access to copy from a designated place, then offering equivalent
access to copy the source code from the same place counts as
distribution of the source code, even though third parties are not
compelled to copy the source along with the object code.
4. You may not copy, modify, sublicense, or distribute the Program
except as expressly provided under this License. Any attempt
otherwise to copy, modify, sublicense or distribute the Program is
void, and will automatically terminate your rights under this License.
However, parties who have received copies, or rights, from you under
this License will not have their licenses terminated so long as such
parties remain in full compliance.
5. You are not required to accept this License, since you have not
signed it. However, nothing else grants you permission to modify or
distribute the Program or its derivative works. These actions are
prohibited by law if you do not accept this License. Therefore, by
modifying or distributing the Program (or any work based on the
Program), you indicate your acceptance of this License to do so, and
all its terms and conditions for copying, distributing or modifying
the Program or works based on it.
6. Each time you redistribute the Program (or any work based on the
Program), the recipient automatically receives a license from the
original licensor to copy, distribute or modify the Program subject to
these terms and conditions. You may not impose any further
restrictions on the recipients' exercise of the rights granted herein.
You are not responsible for enforcing compliance by third parties to
this License.
7. If, as a consequence of a court judgment or allegation of patent
infringement or for any other reason (not limited to patent issues),
conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License. If you cannot
distribute so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you
may not distribute the Program at all. For example, if a patent
license would not permit royalty-free redistribution of the Program by
all those who receive copies directly or indirectly through you, then
the only way you could satisfy both it and this License would be to
refrain entirely from distribution of the Program.
If any portion of this section is held invalid or unenforceable under
any particular circumstance, the balance of the section is intended to
apply and the section as a whole is intended to apply in other
circumstances.
It is not the purpose of this section to induce you to infringe any
patents or other property right claims or to contest validity of any
such claims; this section has the sole purpose of protecting the
integrity of the free software distribution system, which is
implemented by public license practices. Many people have made
generous contributions to the wide range of software distributed
through that system in reliance on consistent application of that
system; it is up to the author/donor to decide if he or she is willing
to distribute software through any other system and a licensee cannot
impose that choice.
This section is intended to make thoroughly clear what is believed to
be a consequence of the rest of this License.
8. If the distribution and/or use of the Program is restricted in
certain countries either by patents or by copyrighted interfaces, the
original copyright holder who places the Program under this License
may add an explicit geographical distribution limitation excluding
those countries, so that distribution is permitted only in or among
countries not thus excluded. In such case, this License incorporates
the limitation as if written in the body of this License.
9. The Free Software Foundation may publish revised and/or new versions
of the General Public License from time to time. Such new versions will
be similar in spirit to the present version, but may differ in detail to
address new problems or concerns.
Each version is given a distinguishing version number. If the Program
specifies a version number of this License which applies to it and "any
later version", you have the option of following the terms and conditions
either of that version or of any later version published by the Free
Software Foundation. If the Program does not specify a version number of
this License, you may choose any version ever published by the Free Software
Foundation.
10. If you wish to incorporate parts of the Program into other free
programs whose distribution conditions are different, write to the author
to ask for permission. For software which is copyrighted by the Free
Software Foundation, write to the Free Software Foundation; we sometimes
make exceptions for this. Our decision will be guided by the two goals
of preserving the free status of all derivatives of our free software and
of promoting the sharing and reuse of software generally.
NO WARRANTY
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
REPAIR OR CORRECTION.
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
POSSIBILITY OF SUCH DAMAGES.
END OF TERMS AND CONDITIONS

View File

@ -1,20 +0,0 @@
# PCManFM-Qt
The Qt port of the LXDE file manager PCManFM.
Issue tracker:
https://github.com/lxde/pcmanfm-qt/issues
LXQt website:
http://lxqt.org
LXDE website:
http://lxde.org
# License
PCManFM is licensed under the terms of the
[GPLv2](https://www.gnu.org/licenses/gpl-2.0.en.html) or any later version.
See the LICENSE file for the full text of the license.

View File

@ -1,107 +0,0 @@
#=============================================================================
# The lxqt_translate_desktop() function was copied from the the
# LXQt LxQtTranste.cmake
#
# Original Author: Alexander Sokolov <sokoloff.a@gmail.com>
#
# funtion lxqt_translate_desktop(_RESULT
# SOURCES <sources>
# [TRANSLATION_DIR] translation_directory
# )
# Output:
# _RESULT The generated .desktop (.desktop) files
#
# Input:
#
# SOURCES List of input desktop files (.destktop.in) to be translated
# (merged), relative to the CMakeList.txt.
#
# TRANSLATION_DIR Optional path to the directory with the .ts files,
# relative to the CMakeList.txt. Defaults to
# "translations".
#
#=============================================================================
function(lxqt_translate_desktop _RESULT)
# Parse arguments ***************************************
set(oneValueArgs TRANSLATION_DIR)
set(multiValueArgs SOURCES)
cmake_parse_arguments(_ARGS "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN})
# check for unknown arguments
set(_UNPARSED_ARGS ${_ARGS_UNPARSED_ARGUMENTS})
if (NOT ${_UNPARSED_ARGS} STREQUAL "")
MESSAGE(FATAL_ERROR
"Unknown arguments '${_UNPARSED_ARGS}'.\n"
"See lxqt_translate_desktop() documenation for more information.\n"
)
endif()
if (NOT DEFINED _ARGS_SOURCES)
set(${_RESULT} "" PARENT_SCOPE)
return()
else()
set(_sources ${_ARGS_SOURCES})
endif()
if (NOT DEFINED _ARGS_TRANSLATION_DIR)
set(_translationDir "translations")
else()
set(_translationDir ${_ARGS_TRANSLATION_DIR})
endif()
get_filename_component (_translationDir ${_translationDir} ABSOLUTE)
foreach (_inFile ${_sources})
get_filename_component(_inFile ${_inFile} ABSOLUTE)
get_filename_component(_fileName ${_inFile} NAME_WE)
#Extract the real extension ............
get_filename_component(_fileExt ${_inFile} EXT)
string(REPLACE ".in" "" _fileExt ${_fileExt})
#.......................................
set(_outFile "${CMAKE_CURRENT_BINARY_DIR}/${_fileName}${_fileExt}")
file(GLOB _translations
${_translationDir}/${_fileName}_*${_fileExt}
${_translationDir}/local/${_fileName}_*${_fileExt}
)
set(_pattern "'\\[.*]\\s*='")
if (_translations)
add_custom_command(OUTPUT ${_outFile}
COMMAND grep -a -v "'#TRANSLATIONS_DIR='" ${_inFile} > ${_outFile}
COMMAND grep -a -h ${_pattern} ${_translations} >> ${_outFile}
COMMENT "Generating ${_fileName}${_fileExt}"
)
else()
add_custom_command(OUTPUT ${_outFile}
COMMAND grep -a -v "'#TRANSLATIONS_DIR='" ${_inFile} > ${_outFile}
COMMENT "Generating ${_fileName}${_fileExt}"
)
endif()
set(__result ${__result} ${_outFile})
# TX file ***********************************************
set(_txFile "${CMAKE_BINARY_DIR}/tx/${_fileName}${_fileExt}.tx.sh")
string(REPLACE "${CMAKE_SOURCE_DIR}/" "" _tx_translationDir ${_translationDir})
string(REPLACE "${CMAKE_SOURCE_DIR}/" "" _tx_inFile ${_inFile})
string(REPLACE "." "" _fileType ${_fileExt})
file(WRITE ${_txFile}
"[ -f ${_inFile} ] || exit 0\n"
"echo '[lxde-qt.${_fileName}_${_fileType}]'\n"
"echo 'type = DESKTOP'\n"
"echo 'source_lang = en'\n"
"echo 'source_file = ${_tx_inFile}'\n"
"echo 'file_filter = ${_tx_translationDir}/${_fileName}_<lang>${_fileExt}'\n"
"echo ''\n"
)
endforeach()
set(${_RESULT} ${__result} PARENT_SCOPE)
endfunction(lxqt_translate_desktop)

View File

@ -1,131 +0,0 @@
#=============================================================================
# Copyright 2014 Luís Pereira <luis.artur.pereira@gmail.com>
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
#
# 1. Redistributions of source code must retain the copyright
# notice, this list of conditions and the following disclaimer.
# 2. Redistributions in binary form must reproduce the copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution.
# 3. The name of the author may not be used to endorse or promote products
# derived from this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
# OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
# IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
# NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#=============================================================================
#
# funtion lxqt_translate_ts(qmFiles
# [USE_QT5 [Yes | No]]
# [UPDATE_TRANSLATIONS [Yes | No]]
# SOURCES <sources>
# [TEMPLATE] translation_template
# [TRANSLATION_DIR] translation_directory
# [INSTALL_DIR] install_directory
# )
# Output:
# qmFiles The generated compiled translations (.qm) files
#
# Input:
# USE_QT5 Optional flag to choose between Qt4 and Qt5. Defaults to Qt5
#
# UPDATE_TRANSLATIONS Optional flag. Setting it to Yes, extracts and
# compiles the translations. Setting it No, only
# compiles them.
#
# TEMPLATE Optional translations files base name. Defaults to
# ${PROJECT_NAME}. An .ts extensions is added.
#
# TRANSLATION_DIR Optional path to the directory with the .ts files,
# relative to the CMakeList.txt. Defaults to
# "translations".
#
# INSTALL_DIR Optional destination of the file compiled files (qmFiles).
# If not present no installation is performed
# CMake v2.8.3 needed to use the CMakeParseArguments module
cmake_minimum_required(VERSION 2.8.3 FATAL_ERROR)
# We use our patched version to round a annoying bug.
include(Qt5PatchedLinguistToolsMacros)
function(lxqt_translate_ts qmFiles)
set(oneValueArgs USE_QT5 UPDATE_TRANSLATIONS TEMPLATE TRANSLATION_DIR INSTALL_DIR)
set(multiValueArgs SOURCES)
cmake_parse_arguments(TR "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN})
if (NOT DEFINED TR_UPDATE_TRANSLATIONS)
set(TR_UPDATE_TRANSLATIONS "No")
endif()
if (NOT DEFINED TR_USE_QT5)
set(TR_USE_QT5 "Yes")
endif()
if(NOT DEFINED TR_TEMPLATE)
set(TR_TEMPLATE "${PROJECT_NAME}")
endif()
if (NOT DEFINED TR_TRANSLATION_DIR)
set(TR_TRANSLATION_DIR "translations")
endif()
file(GLOB tsFiles "${TR_TRANSLATION_DIR}/${TR_TEMPLATE}_*.ts")
set(templateFile "${TR_TRANSLATION_DIR}/${TR_TEMPLATE}.ts")
if(TR_USE_QT5)
# Qt5
if (TR_UPDATE_TRANSLATIONS)
qt5_patched_create_translation(QMS
${TR_SOURCES}
${templateFile}
OPTIONS -locations absolute
)
qt5_patched_create_translation(QM
${TR_SOURCES}
${tsFiles}
OPTIONS -locations absolute
)
else()
qt5_patched_add_translation(QM ${tsFiles})
endif()
else()
# Qt4
if(TR_UPDATE_TRANSLATIONS)
qt4_create_translation(QMS
${TR_SOURCES}
${templateFile}
OPTIONS -locations absolute
)
qt4_create_translation(QM
${TR_SOURCES}
${tsFiles}
OPTIONS -locations absolute
)
else()
qt4_add_translation(QM ${tsFiles})
endif()
endif()
if(TR_UPDATE_TRANSLATIONS)
add_custom_target("update_${TR_TEMPLATE}_ts" ALL DEPENDS ${QMS})
endif()
if(DEFINED TR_INSTALL_DIR)
install(FILES ${QM} DESTINATION ${TR_INSTALL_DIR})
endif()
set(${qmFiles} ${QM} PARENT_SCOPE)
endfunction()

View File

@ -1,112 +0,0 @@
#=============================================================================
# Copyright 2005-2011 Kitware, Inc.
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
#
# * Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
#
# * Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution.
#
# * Neither the name of Kitware, Inc. nor the names of its
# contributors may be used to endorse or promote products derived
# from this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
# HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#=============================================================================
include(CMakeParseArguments)
function(QT5_PATCHED_CREATE_TRANSLATION _qm_files)
set(options)
set(oneValueArgs)
set(multiValueArgs OPTIONS)
cmake_parse_arguments(_LUPDATE "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN})
set(_lupdate_files ${_LUPDATE_UNPARSED_ARGUMENTS})
set(_lupdate_options ${_LUPDATE_OPTIONS})
set(_my_sources)
set(_my_tsfiles)
foreach(_file ${_lupdate_files})
get_filename_component(_ext ${_file} EXT)
get_filename_component(_abs_FILE ${_file} ABSOLUTE)
if(_ext MATCHES "ts")
list(APPEND _my_tsfiles ${_abs_FILE})
else()
list(APPEND _my_sources ${_abs_FILE})
endif()
endforeach()
foreach(_ts_file ${_my_tsfiles})
if(_my_sources)
# make a list file to call lupdate on, so we don't make our commands too
# long for some systems
# get_filename_component(_ts_name ${_ts_file} NAME_WE)
get_filename_component(_name ${_ts_file} NAME)
string(REGEX REPLACE "^(.+)(\\.[^.]+)$" "\\1" _ts_name ${_name})
set(_ts_lst_file "${CMAKE_CURRENT_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/${_ts_name}_lst_file")
set(_lst_file_srcs)
foreach(_lst_file_src ${_my_sources})
set(_lst_file_srcs "${_lst_file_src}\n${_lst_file_srcs}")
endforeach()
get_directory_property(_inc_DIRS INCLUDE_DIRECTORIES)
foreach(_pro_include ${_inc_DIRS})
get_filename_component(_abs_include "${_pro_include}" ABSOLUTE)
set(_lst_file_srcs "-I${_pro_include}\n${_lst_file_srcs}")
endforeach()
file(WRITE ${_ts_lst_file} "${_lst_file_srcs}")
endif()
add_custom_command(OUTPUT ${_ts_file}
COMMAND ${Qt5_LUPDATE_EXECUTABLE}
ARGS ${_lupdate_options} "@${_ts_lst_file}" -ts ${_ts_file}
DEPENDS ${_my_sources} ${_ts_lst_file} VERBATIM)
endforeach()
qt5_patched_add_translation(${_qm_files} ${_my_tsfiles})
set(${_qm_files} ${${_qm_files}} PARENT_SCOPE)
endfunction()
function(QT5_PATCHED_ADD_TRANSLATION _qm_files)
foreach(_current_FILE ${ARGN})
get_filename_component(_abs_FILE ${_current_FILE} ABSOLUTE)
# get_filename_component(qm ${_abs_FILE} NAME_WE)
get_filename_component(_name ${_abs_FILE} NAME)
string(REGEX REPLACE "^(.+)(\\.[^.]+)$" "\\1" qm ${_name})
get_source_file_property(output_location ${_abs_FILE} OUTPUT_LOCATION)
if(output_location)
file(MAKE_DIRECTORY "${output_location}")
set(qm "${output_location}/${qm}.qm")
else()
set(qm "${CMAKE_CURRENT_BINARY_DIR}/${qm}.qm")
endif()
add_custom_command(OUTPUT ${qm}
COMMAND ${Qt5_LRELEASE_EXECUTABLE}
ARGS ${_abs_FILE} -qm ${qm}
DEPENDS ${_abs_FILE} VERBATIM
)
list(APPEND ${_qm_files} ${qm})
endforeach()
set(${_qm_files} ${${_qm_files}} PARENT_SCOPE)
endfunction()

12
debian/.gitignore vendored
View File

@ -1,12 +0,0 @@
/*.debhelper
/*.log
/*.substvars
/files
/mangled
/pcmanfm-qt/
/pcmanfm-qt-dbg/
/libfm-qt5-2/
/libfm-qt5-dev/
/libfm-qt5-dbg/
/tmp

328
debian/changelog vendored
View File

@ -1,153 +1,207 @@
pcmanfm-qt (0.11.0-2) unstable; urgency=medium
* Merge experimental to unstable
-- Alf Gaida <agaida@siduction.org> Thu, 31 Mar 2016 22:07:11 +0200
pcmanfm-qt (0.11.0-1) experimental; urgency=medium
* New upstream release
* Removed grep patch
* Bump libfm-qt-dev (>= 0.11.0)
-- Alf Gaida <agaida@siduction.org> Mon, 28 Mar 2016 18:12:27 +0200
pcmanfm-qt (0.10.1-2) unstable; urgency=medium
* Bump Standards to 3.9.7
* Fix years in copyright
* Add hardending=+all
* simplify rules
* make pcmanfm-qt reproducible again, thanks to Eduard Sanou for the
bugreport and the patch, but it was fixed before (Closes: #815818)
-- Alf Gaida <agaida@siduction.org> Fri, 26 Feb 2016 00:16:22 +0100
pcmanfm-qt (0.10.1-1) unstable; urgency=medium
pavucontrol-qt (2.2.0-0ubuntu1) questing; urgency=medium
* New upstream release.
* Remove libfm-qt as upstream moved it into another source repository.
* Remove dbg package in favor of dbgsym.
* Update Vcs-Browser.
- Update build dependencies.
* Update copyright file.
* Update Standards-Version to 4.7.2, no changes needed.
-- ChangZhuo Chen (陳昌倬) <czchen@debian.org> Sun, 07 Feb 2016 16:13:27 +0800
-- Aaron Rainbolt <arraybolt3@ubuntu.com> Fri, 01 Aug 2025 11:23:16 -0500
pcmanfm-qt (0.10.0-2) unstable; urgency=medium
pavucontrol-qt (2.1.0-0ubuntu3) plucky; urgency=medium
* Update Standards-Version to 4.7.1, no changes needed.
-- Simon Quigley <tsimonq2@ubuntu.com> Fri, 21 Feb 2025 16:58:59 -0600
pavucontrol-qt (2.1.0-0ubuntu2) plucky; urgency=medium
* No-change rebuild for lxqt-build-tools C++17 -> C++20.
-- Simon Quigley <tsimonq2@ubuntu.com> Fri, 03 Jan 2025 04:00:32 -0600
pavucontrol-qt (2.1.0-0ubuntu1) plucky; urgency=medium
* Merge from experimental.
* New upstream release.
* Update minimum version of liblxqt.
* Update symbols.
* Remove menu file, see CTTE #741573.
- Bump build dependencies.
-- ChangZhuo Chen (陳昌倬) <czchen@debian.org> Sun, 15 Nov 2015 21:14:41 +0800
-- Simon Quigley <tsimonq2@ubuntu.com> Fri, 15 Nov 2024 15:33:29 -0600
pcmanfm-qt (0.9.0+20150908-2) unstable; urgency=medium
pavucontrol-qt (2.0.0-0ubuntu1) oracular; urgency=medium
* Menufile deleted
* debian/rules --fail-missing included --list-missig, so
--list-missing deleted
* New upstream release.
* Updated copyright file.
* Bump Standards-Version to 4.7.0, no changes necessary.
* Adjust dependencies.
-- Alf Gaida <agaida@siduction.org> Fri, 13 Nov 2015 02:37:53 +0100
-- Aaron Rainbolt <arraybolt3@ubuntu.com> Thu, 27 Jun 2024 23:12:01 -0500
pcmanfm-qt (0.9.0+20150908-1) unstable; urgency=medium
pavucontrol-qt (1.4.0-0ubuntu1) noble; urgency=medium
* New upstream release.
* Overhauled copyright file.
-- Aaron Rainbolt <arraybolt3@gmail.com> Sun, 12 Nov 2023 12:20:37 -0600
pavucontrol-qt (1.3.0-0ubuntu1) mantic; urgency=medium
* New upstream release.
* Bump build dependencies.
-- Simon Quigley <tsimonq2@ubuntu.com> Thu, 03 Aug 2023 10:43:30 -0500
pavucontrol-qt (1.2.0-1ubuntu3) lunar; urgency=medium
* Swap "pulseaudio | pipewire-pulse" to "pipewire-pulse | pulseaudio" in
debian/control to convince Germinate to grab the right package when the
Lubuntu ISO builds.
-- Aaron Rainbolt <arraybolt3@ubuntu.com> Sun, 02 Apr 2023 15:10:28 -0500
pavucontrol-qt (1.2.0-1ubuntu2) lunar; urgency=medium
[ Debian Janitor ]
* Set upstream metadata fields: Repository-Browse.
[ Aaron Rainbolt ]
* Revert a sync from Debian.
* Bumped Standards-Version to 4.6.2, no changes necessary.
* Updated copyright file.
-- Aaron Rainbolt <arraybolt3@ubuntu.com> Sun, 12 Feb 2023 17:33:26 -0600
pavucontrol-qt (1.2.0-0ubuntu1) lunar; urgency=medium
* New upstream release.
* Fix the watch file, for real this time.
* Lubuntuify the package slightly, to make debhelper happy.
* Bump build dependencies in debian/control.
-- Simon Quigley <tsimonq2@ubuntu.com> Thu, 17 Nov 2022 16:43:15 -0600
pavucontrol-qt (1.1.0-1) experimental; urgency=medium
* New upstream release 1.1.0.
* Removed obsolete debian/compat file.
* Switched to GBP.
* Upstreamed non-Ubuntu-specific packaging changes from Ubuntu, modifying
the following files:
- control
- copyright
- lintian-overrides
- *.install
- rules
- upstream/*
-- Aaron Rainbolt <arraybolt3@gmail.com> Sun, 10 Jul 2022 04:35:38 -0500
pavucontrol-qt (0.16.0-2) unstable; urgency=medium
* Depend on either pulseaudio or pipewire-pulse (Closes: #995690)
-- Arto Jantunen <viiru@debian.org> Wed, 03 Nov 2021 12:41:14 +0200
pavucontrol-qt (0.16.0-1) unstable; urgency=medium
[ Alf Gaida ]
* Cherry-picked upstream version 0.9.0+20150908.
* Tar-ignore .gitignore
* Fixed control with cme fix
* Added upstream signing-key and use it in watch file
* Removed automoc build dependency - not needed with Qt5
* Fixed symbols for i386 and amd64
[ ChangZhuo Chen (陳昌倬) ]
* Use arch-bits to fix 32 bit architecture symbols.
* Add Shih-Yuan Lee (FourDollars) as Uploaders.
-- ChangZhuo Chen (陳昌倬) <czchen@debian.org> Tue, 15 Sep 2015 23:30:13 +0800
pcmanfm-qt (0.9.0+20150816-1) unstable; urgency=medium
[ ChangZhuo Chen (陳昌倬) ]
* Import debian directory from Wen.Liao.
* Initial release (Closes: #747605)
* Merge debian directory.
* Backup *.ts.
* Fix package-contains-empty-directory.
* Don't use variable for command.
* Add libfm-qt1 and libfm-qt-dev.
* Update copyright.
* Add Pre-Depends: ${misc:Pre-Depends} to libfm-qt1.
* Create manpage for pcmanfm-qt.
* add libfm-qt1.symbols.
* Revert "Create manpage for pcmanfm-qt".
* Add pcmanfm-qt.manpages.
* Fix manpage.
* Install include to libfm-qt-dev.
* Update package description.
* Use patch to install manpage.
* Migrate to QT5.
* Update d/copyright.
* Fix copyright typo.
* Revert accidiently ts changed.
[ Alf Gaida ]
* gitignore added.
* new upstream translation files.
* some cleanup in debian rules.
* two missed symbols added.
* they need a little bit of beautyfing.
* we should not save translations in debian/bak. if there is a real
problem with the translations this should be fixed upstream.
* add two symbols @czchen - would you be so kind and clean them up.
* catch up with upstream Patch descriptions changed.
* Imported Upstream version 0.8.0
* Min Qt version 5.3.2.
* bump standards to 3.9.6.
* removed all patches, integrated in upstream.
* fix symbols (two symbols added).
* fix prefs desktop file.
* fix arch for dbg packages.
* Imported Upstream version 0.8.0.
* Min Qt version 5.3.2.
* bump standards to 3.9.6.
* removed all patches, integrated in upstream.
* fix symbols (two symbols added).
* fix prefs desktop file.
* fix arch for dbg packages.
* patch added released.
* fixing arch dependent symbols.
* recommend gfvs-backends.
* Some cleanup in debian $foo.
* some changes in debian $foo.
* drop transitional packages.
[ ChangZhuo Chen (陳昌倬) ]
* Unapply Debian patch.
* Add debian/source/local-options.
* Backup / Restore translations.
* Fix override_dh_clean.
* Use override_dh_auto_clean to restore translations.
* Update symbol control file.
* Quote in symbol control file.
* Restore upstream file.
* Imported Upstream version 0.9.0+20150816.
* Add (c++) to symbol control file.
* Update changelog.
* Update symbol control file.
* Fix symbol control file.
* Fix Architecture.
* Add Multi-Arch: same.
[ Shih-Yuan Lee (FourDollars) ]
* Polish debian/control by 'cme fix dpkg-control'.
* Update package description.
* Switched to gbp
* Bumped Standards-Version to 4.4.0, no changes needed
[ Andrew Lee (李健秋) ]
* Added myself as Uploader.
* Removing whitespaces at EOL and EOF.
* Refine descriptions.
* Don't need to backup/restore translation files, this fixed upstream.
* Warpped lines in copyright.
* New upstream release. (Closes: #978181)
-- Andrew Lee (李健秋) <ajqlee@debian.org> Mon, 17 Aug 2015 21:04:54 +0800
-- Andrew Lee (李健秋) <ajqlee@debian.org> Thu, 07 Jan 2021 16:48:22 +0800
pavucontrol-qt (0.14.1-1) unstable; urgency=medium
* Cherry-picked upstream release 0.14.1.
-- Alf Gaida <agaida@siduction.org> Tue, 26 Feb 2019 00:51:28 +0100
pavucontrol-qt (0.14.0-1) unstable; urgency=medium
* Cherry-picked upstream release 0.14.0.
* Bumped Standards to 4.3.0, no changes needed
* Dropped d/compat, use debhelper-compat = 12, no changes needed
* Fixed years in d/copyright
* Bumped minimum version lxqt-build-tools (>= 0.6.0~)
* Removed obsolete PULL_TRANSLATIONS= OFF from dh_auto_configure
* Added l10n-package, moved from lxqt-l10n
* Added d/upstream/metadata
-- Alf Gaida <agaida@siduction.org> Sun, 27 Jan 2019 15:25:30 +0100
pavucontrol-qt (0.4.0-1) unstable; urgency=medium
* Cherry-picked upstream release 0.4.0
* Bump lxqt-build-tools to >= 0.5.0~
* Fixed watch file lxde -> lxqt
* Moved .gitignore from debian to ./
* Cleaned up debian/source/options
-- Alf Gaida <agaida@siduction.org> Wed, 23 May 2018 20:29:30 +0200
pavucontrol-qt (0.3.0-4) unstable; urgency=medium
* Bumped compat to 11
* Bumped debhelper to >= 11~
* Bumped Standards to 4.1.4, no changes needed
* Changed VCS fields for salsa
* Changed Homepage, Source and watch to lxqt
* Bumped years in copyright
* Removed trailing whitespaces in changelog
-- Alf Gaida <agaida@siduction.org> Sat, 28 Apr 2018 18:21:55 +0200
pavucontrol-qt (0.3.0-3) unstable; urgency=medium
* Bumped Standards to 4.1.2, no changes needed
* Removed branch from VCS fields
* Removed debian/gbp.conf
-- Alf Gaida <agaida@siduction.org> Thu, 14 Dec 2017 23:51:12 +0100
pavucontrol-qt (0.3.0-2) unstable; urgency=medium
* Transition to unstable
-- Alf Gaida <agaida@siduction.org> Mon, 04 Dec 2017 20:00:17 +0100
pavucontrol-qt (0.3.0-1) experimental; urgency=medium
* Cherry-picking new upstream release 0.3.0.
* Switched to experimental
* Bumped Standards to 0.4.0, no changes needed
* Bumped minimum version lxqt-build-tools (>= 0.4.0)
* Bumped years in copyright
-- Alf Gaida <agaida@siduction.org> Sun, 24 Sep 2017 15:19:13 +0200
pavucontrol-qt (0.2.0-1) unstable; urgency=medium
* Cherry-picking upstream release 0.2.0.
* Removed some no longer needed build dependencies:
- cmake
- liblxqt0-dev
- libqt5xdg-dev
- libqt5xdgiconloader-dev
- pkg-config
- qttools5-dev
- qttools5-dev-tools
* Added build dependency lxqt-build-tools (>= 0.3.0)
* Added dependency pulseaudio (Closes: #847373)
* Fixed Recommends: obconf-qt-l10n -> pavucontrol-qt-l10n
-- Alf Gaida <agaida@siduction.org> Mon, 12 Dec 2016 18:56:14 +0100
pavucontrol-qt (0.1.0-2) unstable; urgency=medium
* Moved to unstable
* Fixed signing-key, thanks Rohan Garg <rohan@kde.org>
-- Alf Gaida <agaida@siduction.org> Tue, 18 Oct 2016 20:34:41 +0200
pavucontrol-qt (0.1.0-1) experimental; urgency=medium
* Initial release (Closes: #838724)
-- Alf Gaida <agaida@siduction.org> Sat, 24 Sep 2016 16:18:14 +0200

1
debian/compat vendored
View File

@ -1 +0,0 @@
9

78
debian/control vendored
View File

@ -1,38 +1,52 @@
Source: pcmanfm-qt
Maintainer: LXQt Packaging Team <pkg-lxqt-devel@lists.alioth.debian.org>
Source: pavucontrol-qt
Maintainer: Lubuntu Developers <lubuntu-devel@lists.ubuntu.com>
Original-Maintainer: LXQt Packaging Team <pkg-lxqt-devel@lists.alioth.debian.org>
Uploaders: Alf Gaida <agaida@siduction.org>,
ChangZhuo Chen (陳昌倬) <czchen@debian.org>,
Andrew Lee (李健秋) <ajqlee@debian.org>,
Shih-Yuan Lee (FourDollars) <fourdollars@gmail.com>
Section: x11
ChangZhuo Chen (陳昌倬) <czchen@debian.org>,
Simon Quigley <tsimonq2@debian.org>,
Aaron Rainbolt <arraybolt3@gmail.com>
Section: utils
Priority: optional
Build-Depends: debhelper (>= 9.20151219),
cmake (>= 3.0.2),
libfm-dev (>= 1.2.0),
libfm-qt-dev (>= 0.11.0),
libglib2.0-dev,
liblxqt0-dev (>= 0.10.0),
libmenu-cache-dev,
libqt5x11extras5-dev,
libqt5xdg-dev (>= 1.3.0),
libx11-dev,
pkg-config,
qttools5-dev,
qttools5-dev-tools
Standards-Version: 3.9.7
Vcs-Browser: https://anonscm.debian.org/cgit/pkg-lxqt/pcmanfm-qt.git/?h=debian/sid
Vcs-Git: https://anonscm.debian.org/cgit/pkg-lxqt/pcmanfm-qt.git -b debian/sid
Homepage: https://github.com/lxde/pcmanfm-qt
Build-Depends: debhelper-compat (= 13),
libkf6windowsystem-dev,
libpulse-dev,
lxqt-build-tools (>= 2.2.0),
qt6-svg-dev (>= 6.6.0),
xdg-user-dirs
Standards-Version: 4.7.2
Vcs-Browser: https://git.lubuntu.me/Lubuntu/pavucontrol-qt-packaging
Vcs-Git: https://git.lubuntu.me/Lubuntu/pavucontrol-qt-packaging.git
Debian-Vcs-Browser: https://salsa.debian.org/lxqt-team/pavucontrol-qt
Debian-Vcs-Git: https://salsa.debian.org/lxqt-team/pavucontrol-qt.git
Homepage: https://github.com/lxqt/pavucontrol-qt
Rules-Requires-Root: no
Package: pcmanfm-qt
Package: pavucontrol-qt
Architecture: any
Depends: ${misc:Depends},
${shlibs:Depends},
libfm-modules
Recommends: gvfs-backends,
lxqt-sudo | gksu
Description: extremely fast and lightweight file and desktop icon manager
PCManFM-Qt is the Qt port of the LXDE file manager PCManFM.
Depends: pipewire-pulse | pulseaudio, ${misc:Depends}, ${shlibs:Depends}
Recommends: pavucontrol-qt-l10n
Description: Qt port of volume control pavucontrol
Qt port of volume control pavucontrol of sound server PulseAudio. As such it
can be used to adjust all controls provided by PulseAudio as well as some
additional settings.
.
Libfm-Qt is a companion library providing components to build desktop file
managers.
The software belongs to the LXQt project but its usage isn't limited to this
desktop environment.
.
This package contain the application files.
Package: pavucontrol-qt-l10n
Architecture: all
Multi-Arch: foreign
Section: localization
Depends: qt6-translations-l10n, ${misc:Depends}
Description: Language package for pavucontrol-qt
Qt port of volume control pavucontrol of sound server PulseAudio. As such it
can be used to adjust all controls provided by PulseAudio as well as some
additional settings.
.
The software belongs to the LXQt project but its usage isn't limited to this
desktop environment.
.
This package contains the l10n files needed by the pavucontrol-qt.

87
debian/copyright vendored
View File

@ -1,32 +1,81 @@
Format: http://www.debian.org/doc/packaging-manuals/copyright-format/1.0/
Upstream-Name: pcmanfm-qt
Source: https://github.com/lxde/pcmanfm-qt
Format: https://www.debian.org/doc/packaging-manuals/copyright-format/1.0/
Upstream-Name: pavucontrol-qt
Source: https://github.com/lxqt/pavucontrol-qt
Files: *
Copyright: 2013-2016 LXQt team
2013-2016 Hong Jen Yee (PCMan) <pcman.tw@gmail.com>
2012-2013 Andriy Grytsenko (LStranger) <andrej@rep.kiev.ua>
2014 Kuzma Shapran <kuzma.shapran@gmail.com>
Copyright: 2016-2025 LXQt team
License: GPL-2.0
Files: src/elidinglabel.cc
src/elidinglabel.h
Copyright: 2016-2023 LXQt team
License: GPL-2.0+
Files: src/cardwidget.cc
src/cardwidget.h
src/channel.cc
src/channel.h
src/devicewidget.cc
src/devicewidget.h
src/mainwindow.cc
src/mainwindow.h
src/minimalstreamwidget.cc
src/minimalstreamwidget.h
src/pavucontrol.cc
src/pavucontrol.h
src/rolewidget.cc
src/rolewidget.h
src/sinkinputwidget.cc
src/sinkinputwidget.h
src/sinkwidget.cc
src/sinkwidget.h
src/sourceoutputwidget.cc
src/sourceoutputwidget.h
src/sourcewidget.cc
src/sourcewidget.h
src/streamwidget.cc
src/streamwidget.h
Copyright: 2008 Sjoerd Simons <sjoerd@luon.net>
2006-2009 Lennart Poettering
2009-2011 Colin Guthrie <mzcnihpbageby@0pointer.de>
2016 Hong Jen Yee (PCMan) <pcman.tw@gmail.com>
License: GPL-2.0+
Files: debian/*
Copyright: 2014-2015 Wen Liao <wen.cf83@gmail.com>
2014-2016 ChangZhuo Chen (陳昌倬) <czchen@debian.org>
2013-2016 Alf Gaida <agaida@siduction.org>
2015 Andrew Lee (李健秋) <ajqlee@debian.org>
Copyright: 2015 Andrew Lee <ajqlee@debian.org>
2015 Shih-Yuan Lee (FourDollars) <fourdollars@gmail.com>
2014-2016 ChangZhuo Chen <czchen@gmail.com>
2016 Yuan CHAO <yuanchao@gmail.com>
2014-2019 Alf Gaida <agaida@siduction.org>
2021 apt-ghetto <apt-ghetto@protonmail.com>
2021-2022 Rik Mills <rikmills@kde.org>
2019-2025 Simon Quigley <tsimonq2@ubuntu.com>
2023-2025 Aaron Rainbolt <arraybolt3@gmail.com>
License: GPL-2.0+
License: GPL-2.0+
This package is free software; you can redistribute it and/or modify
License: GPL-2.0
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.
the Free Software Foundation; version 2 of the License.
.
This package is distributed in the hope that it will be useful,
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.
.
On Debian systems, the complete text of the GNU General
Public License version 2 can be found in
"/usr/share/common-licenses/GPL-2".
On Debian systems, the complete text of the GNU General Public License
version 2 can be found in "/usr/share/common-licenses/GPL-2".
License: GPL-2.0+
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.
.
On Debian systems, the complete text of the GNU General Public License
version 2 can be found in "/usr/share/common-licenses/GPL-2".

5
debian/gbp.conf vendored
View File

@ -2,7 +2,4 @@
debian-branch = debian/sid
upstream-branch = upstream/latest
pristine-tar = True
[import-orig]
# Use git cherrypick -n upstream instead.
merge = False
compression = xz

4
debian/lintian-overrides vendored Normal file
View File

@ -0,0 +1,4 @@
# yes, we know
pavucontrol-qt: no-manual-page [usr/bin/pavucontrol-qt]
pavucontrol-qt: desktop-entry-lacks-keywords-entry [usr/share/applications/pavucontrol-qt.desktop]

1
debian/pavucontrol-qt-l10n.install vendored Normal file
View File

@ -0,0 +1 @@
usr/share/pavucontrol-qt/translations/

2
debian/pavucontrol-qt.install vendored Normal file
View File

@ -0,0 +1,2 @@
usr/bin/pavucontrol-qt
usr/share/applications/pavucontrol-qt.desktop

15
debian/rules vendored
View File

@ -1,9 +1,16 @@
#!/usr/bin/make -f
#DH_VERBOSE = 1
# export DH_VERBOSE=1
export LC_ALL=C.UTF-8
export DEB_BUILD_MAINT_OPTIONS = hardening=+all
export DEB_LDFLAGS_MAINT_APPEND = -Wl,--as-needed
%:
dh ${@} --buildsystem cmake \
--parallel
dh ${@} --buildsystem cmake
override_dh_missing:
dh_missing --fail-missing
override_dh_auto_configure:
dh_auto_configure -- \
-DUPDATE_TRANSLATIONS=OFF \
-DCMAKE_BUILD_TYPE=RelWithDebInfo

2
debian/source/lintian-overrides vendored Normal file
View File

@ -0,0 +1,2 @@
# Translations files can be long
pavucontrol-qt source: very-long-line-length-in-source-file * > 512 [*.ts:*]

View File

@ -1 +1 @@
tar-ignore = .gitignore
tar-ignore=.gitignore

6
debian/upstream/metadata vendored Normal file
View File

@ -0,0 +1,6 @@
Name: pavucontrol-qt
Bug-Database: https://github.com/lxqt/pavucontrol-qt/issues
Bug-Submit: https://github.com/lxqt/pavucontrol-qt/issues/new
Changelog: https://github.com/lxqt/pavucontrol-qt/blob/master/CHANGELOG
Repository: https://github.com/lxqt/pavucontrol-qt
Repository-Browse: https://github.com/lxqt/pavucontrol-qt

View File

@ -1,63 +1,52 @@
-----BEGIN PGP PUBLIC KEY BLOCK-----
Version: GnuPG v2.0.22 (GNU/Linux)
mQINBFJevCYBEACx+Hvy+Vsuf+V5jeLUnzjAmHoy8DfTeGWr3ts30IapLHrfi0+U
WpzNnISO77yTr4VNboVZH+GHM/rnPfieODfB4ZW6CZLlInMSKUXcgQsEqXpyBZhA
Ib/SPy2bOfHly1uRJes0uRDsH5+v/hD74sByfnjQlrvI68O6wvGZmDFMNNPVO8+/
OWBSBNkBuVrrZOMSPsLwQGJ4UtUQ4whburaPJG4VZJc5DLbzJGbEuACc0IAEYJS3
7AfXVXn4j4Gc9F3o1xTUnbOBnwGPquWwUIm3FM7Ec2OdkvMt3EwvnkMAfeVrq3iE
FDD/KZTxdL0BZH3QD8gB7Jm4v4f3Nkobg6JCvCbcH3wBdZW4mASbwWzfRaDC2zHb
ErTglD7PpShLKZZ0pr9okWZEGw4Ku3q8ALi1JXK/ePTmsBlvkVskOJ3Nnd0avgH4
+Q/vZoKfH8EhNY745rI+8CE9iv6V9XiSUt4CKEWAENt4A8hq6U2vV+jZv3B6AgD7
ZjiI59yD4YuYubu8rCnNizTgh1voVw3ietknn/x2H5yH8fByWZ5uL87C0ky/uma6
ZGbiiAtM4kdkyDMrfRV5nlEG9EKAGPVu5mjeSCrfkETwZ9OFPz1AuDye4ZEXrrcC
iRQ7RX6/GtW18aHER0kzGnfwx5KJzkDrRBY8A2PdXLBcrsN4WpK9EX01PQARAQAB
tCNKZXJvbWUgTGVjbGFuY2hlIDxqZXJvbWVAbGVjbGFuLmNoPokCPwQTAQIAKQUC
Ul68JgIbAwUJAeEzgAcLCQgHAwIBBhUIAgkKCwQWAgMBAh4BAheAAAoJEDfgrx/a
SPNzSHIP/1ewXcC0TFBcvDD7MrIP7anyNfiWfW7cxkR8GSamkg6HTa6Ndyr1FFjJ
OoDFUP37jWhu59CsHxs2D0zRWJktezfvElscRgqbHcdpIznqsGdI8hXCZafhBGVb
sdAB2LRawcXGxnXt7XajPcSVwLWRE62caBqohznU2iWvI780WNjEbZoA0LhZwaFF
UUPJm8ea9v0IkZVKUyg9WONZ1U7FEG9SaEiSpI8kJdx1fvCwZVDV/NRO5GqnJaho
P1LCne4YdwS6pt1/fRgk32IHxxZfHlLzLHxb6v1JmIg72x28qCmGyK9oFBDbbnYu
6Aq8XbHogOrD5vJM2Pfm2IhV0+JHOjfQbddv8tsAH1M+LI+tToXmg5st1AU3wnTn
pda3hjA1avKwkfBPW/osHc8782ViyS9iX2e9iDtMv608guij4NjpGExzGCypHOd8
+VXRwJDjvgDynkL206MZ+wn0j5wHsIE8F3Y5Bp1thQOrdDli5MYNQoXhjFmH46XT
bcr84IgW0+AiXZdoFUqvwtzrWy2Onuw5R3k4OyV4skN4DkWXyAk/V+Y4K39JvTKf
H9YuiQ9blNzCu8WiAnjKnh9kNl9E/TyEwI6cHFmIPqF8ST9tJytWHtrKvU9csvXX
n8XNJmpcv2R1e6N+VuWWm5zUPTouv3AxCacLbm8Lh3ymGsk7ZEyhiQIcBBABAgAG
BQJSsFYyAAoJEBMY76xfu9vO6v0P/3wSj3/kE4nP4HfgcVJSzi+lm1ycpbLDZtgh
P1G+zJLVmA+E41vEZimeiYQxBAelatJz+CHzQo3LZ2oVChzVrZcVHn9k4P3pib69
qCVif3/y0Wmecn+u2TWbOvJ7mthfO7T3W7rkW1/9ES7bUaXcXWQ2sjUBVqFkFsVt
xgJDo8wcxA+K4Yf06GCbxFwrB7X5GraWIkzqGnyse3XAQn8aORAXmE8Yd0FHOjEZ
Beb9shChnkYc3lEvNY8ioCaYSF9xr/Iz9cwpfPkpqFiVYWadtb+Gqeh6zC7vPmcT
zHxrgkq1WwQlSBm724tPt9xuGQoOglqEa23vlQZfv20nyrYjLeYUy6pMCRq7vn/n
nkQOcXF7yQlnqR6xKk0tWsM4e6du0ZvbjBbhHV/kBFVGCLm/upTwoMVm0WJTbr4T
5XfIZo7eA0lvGtUhe1PgcOidBikHfAIfYxu0BoMXoL4jbcQdR5+YBDEfsS0jPhCl
mew2ScW/R/UhUknJUVFTma0KHXzEmKiqeeUCDtwEi6fxdicAYkbcekgkfFiD/w8N
Lk3Uf+0x2MdKA36nUobFkk38oU+GW37kFWJs3f1YRuQFao896eNW/E8ekVMLNxOl
nCjnSbabaxDnxPTyW2KlNjf/QUEK4pT6S5QmuCSrle3PQpaSbAZDHzLBIL9gd3m6
MH7+SvV4uQINBFJevCYBEADiXDUqstSdhIyuionS2KtE3IeEBIqS7GY8QPRBylIZ
ACVHFI/1HxChBqYVGFaDEQn3gj5lUUQPubfWaxzjF6+UNVQW4+cxmTocndAwfDbI
+E5BLdieFUzbAA05MV5ZjPhTNbSk1jpy4bNy0FILwNqc89Y6SoCbv1r3tZLCrBas
1+AfWknBynx0siGMbLFxtzR6hUkNz9URxt13FrzpUWMpAL8ZQGczOTSaWLrZA5l9
xLzJ9ww8uM+C2Xej3/sANxi+kQE2GVMKurPS0TICwVWZxbdW/ytIkO67Rhse0q3t
vzjdawfCFRxv7XQB2ZJ6irDxbpHiJoojSWCHJadIyCG03iOiaqsSVvi4KnxtUck+
udOEJUV5sxdzgeRrsDpeaN//KCWW9WjfsSkvOqP6S1gmWpNFdzF5XrzcgvqvSNqo
XejfakUTJqsIIEHO0zGuJFVzJNh2hQ/9dhjIspUORhtNKaljNvePiBrj2yqmd9PY
FlH1KMHe4H+YVIwPiyeNA87Pu+1yNo8gT7mXhGRfibgWjbt146WUJ7+l2StJMApn
eNSCartNaUNPnw96i2l5c9AsJ3SWC6XWpWzOLVj+9XceeA11lu/ogqEMHzx81NjH
2TePxwKTKxZnAvDmqryp++IgY2/OgIoIk3ZRdYu/dPijTOYWfCet/9/9kAFr9PeJ
KwARAQABiQIlBBgBAgAPBQJSXrwmAhsMBQkB4TOAAAoJEDfgrx/aSPNzJv0QAKkx
lCKEZ6ahAUuNWslsHnNWaHFHNawEO3NIEtQZGVFk2BYISupizvjZF6MnymO/9UFM
pzV6fp3xNdqaKWQBjScOgMgCASRixW2tMAKbJGHZKp3dBixpHgXxy2oOGMS+mQ5m
gWy07usq2YesoMD0K/SG6EnoRPHBvrJihArzMFVUY9hD3hk8bhiy8w9bCYFe+gkm
zpQl3/KN01kyt5LjzEBcIOw8qIBQe9Pk8PyOK75lPoNME714LatgOsyw2kaSQ9Sv
hziRGC5z/fV3PmH7XhSjENPKnCJU51GUMMLaL28t9o7Afh6Q8UV31/JO36vmQXQV
+b+0BoGqEmf3AKBASb2Cr2q4pZFjywwSUXHZ9hQyu1tpbE1dS6aI01kM0y270pk7
W/ajuzuOxAVL1bJAanL/5+DWM03esZPVdEWhxpWEM40Z6Rhq+Xb2a5xfwCN9PmaQ
o9fez0I+yh53s7Ypv0tBj05FPe5L48+pDi6pz5nddN1B0FzF58jVfsBZUjBlY24+
VwQeAaWkRXZrSEdtBS5ufsi80x/cNCSTJBWqtborKL1iGgf5MDPYRMSvmZXAeIld
pyL/0pbW7iokewyKzpFfo7KEbwLxB+flWaBZ867JpF4yyRj3b4qcvcyV8QnsoB7Z
KhxTl3gGwD/t0HUcu85zcfs4GkealYhIWfGaAso2
=fF8P
mQINBF6cxrwBEADfl3ydxNfLBbWGPesXty2baQgixZ3D6aCxadI2kX+aikmT8rd0
ttDKN18cXV52Ssxnj0qhgf4hwnu/b0be6BzqSEyGM+UQR3X2CYpxrMakfW32Q18K
X5ec0RPR2ucBq9G0r9t6FYC8FkJ4uQUU3xxrLW3z302S0Makjgzm8BV9WrFQ7oFF
uJQj0BHbHYC4RyaZb2AfxY4Y92BPGTjtGekWqgw6vEXCCnvAbGYVQzvxZt3nw21/
1YmV4g7xhGFQPbOf9v3ejFUJeJIGzuJf5NAh7kvfCdUBAGYH0gnj0GpOve4ftnaG
sAId2CQwm3oYF4Tu7yBPTOBpkaKkNaT+UdwTyeKERuCZ9ocZWX++/YF9ItRkJ5mM
zoP1GluWn2atNWpRh/K97gyAGgr2fSmrAA4d1JrVbMujZAHoHAOKwJKqX9jPziPZ
BFHfhcIOzG3ZhXAuumHsd7uwfPBVt20g+G+cOjBghbSSu9EOtMkAZl1g3ybvZixu
Jtxa5exZWEmU7vtytEb8eq9Dj5XcGoTDbErE2RpJ/20HPzhyRKg9RN4iGS+0OiHS
oRbDi5IEOizvQjp2bsBmfa3rsoDSOqF2pevp+u8I56I6bU1GFpxxNC5IGvgo2Q79
quz0oIk5hs3eLlUdEYsLGwR6pWJaJyf36vuDsq7iLrLyvHI5irAowO4r1QARAQAB
tCVQZWRyYW0gUG91cmFuZyA8dHN1amFuMjAwMEBnbWFpbC5jb20+iQJOBBMBCAA4
FiEEGd/fOleb1QnbtXLYvnkwB60i334FAl6cxrwCGwMFCwkIBwIGFQoJCAsCBBYC
AwECHgECF4AACgkQvnkwB60i335f9RAAgRpn8gUa/l10UkVAnpM2Cz0MuNMwwCOq
IfVnuZuPBtYYiTU5Su++/aPZe3fF5B4v61F+XjNi7qeVL2t52X3jZ/iIx9Syasb+
vDAIfQ5t6lKXvOptWxf6vteOg6CHbXwpGHbPjUkUS2vQwRikjBnR0SnkrMoXtgSX
amPFqsitNrOhEJfeDfo0NzKESZuliWrCFt2v8c5q18G8cCZAvPLBlGuwRl58cDep
3EIibMI/9MUSJbKoiHlK+LcHtG7BQTNis/e7Pe1PkRmExfhxe1lNajtOx8FO72Tq
B6zY6drippM9VaIc1M+zp9BRpsFu8whOmapCqlXHRgAK8xTdQRIGInQFqLWPOxSC
f0B6N+EvQvgkyFQ1rW+u91OJBma46uKkhrwf+mDttVRncaIAkgE6e6pqm18yIPFk
D42rt/yHcOl+2qkcJS3gPcg5UvlCzqOwg1rKZQIk+TcPuDx3r2UghDEYZN9X6vw3
zCBufr7ygZNf4tkbnVARFWTR4GzyCseFkWgOVZL9DccAhs8NeMy1WLkUzB75adeR
3LONmEL7xOI8FuknKY4e6EcWhmstNIDgXfRe0hwO0VBdW3unoZC/K2ZM/ZuZyMdK
TFjvYJrNewmymKge68wo0054bGZn8oz17i2AosJz7kW+ITsxmxhVcpfl4bav9Neq
RpQwhnhK9bC5Ag0EXpzGvAEQANbeRHFbpgQVIqV9WVOVnTj4FIqrTPTPKKa02vJA
7tGpgFapgvjdxnMxJfV6wuwOBUUFLR7DrXlV8EVFAYc5qTIeSQXvJsWw6gQ3+f0D
z13oGOhZPBIzIKnV/MZI/jhIio8kSPWAuM5hR2X9Hvw3/CLo+H+hZZ6cFYoCxrQS
tTzcKMkdQizLLa+WNbqUSxg6I/P5k/smUDY9gKW7RtI5t/PupA3WTnsVD6CYWa3Q
c1O/1mUgqT6nQ5N9KCPpjZQRT6D6eIMmePtS85z4PPeYMJxPsKRYWPGRxKhCSdZl
/0wsC8aRtmwYT729e0ZgTAmUnj+rQp5hboF/ZPFjIoXR9G+0HnoY0a/nqVO4lUON
AV25GnMFGVyiHHlbH/0gboywwnzEg8BZbk+Z/61oOzBIW09sfG8fn8bsbkpL+nHf
Mi/Vauge6wSfw7I5AfSiwrSDNHmKVsu39koWV6JGxEeFr2MffF+CuaoJCNOr/ZII
SYR5ku3Y/lMKyUH1Oas0RWzFrdRcInqYK90A0x083zP4V445MvCwbRPzQAkm9wOP
kILLhE5FW+9/O0/9bpx4joJUDLV4d3hFZy7GSHKiZUs1QW6BV75JQKqoi+cVt+/L
+o1S8CMNekjqdC2mWRosM3doo51zT/FWNzQA1QcoZP2hORJDfw66y+4wPq6o8y1W
jR35ABEBAAGJAjYEGAEIACAWIQQZ3986V5vVCdu1cti+eTAHrSLffgUCXpzGvAIb
DAAKCRC+eTAHrSLffgbJD/4qW5YOo/BayBhaUh2L7VP7JNlECb/2xNNOFKI1NjNr
nOmgSJLzf74Uhmt5W+iVjmJBHrDceprIPkizmPrn90kIsPIMtHIDNxzUgKZHbnza
j1vZyAeC+JV79X1hOVpprj1TJwy65lpxXNyYnGqeIOgyFokn9fOHXv8aMQwpNuUr
bdUJ1C75jYrvwy/NR1DczIFFYgsbkDGDtjVBjyMc5JAgvUBz37/iVPJfWP6dKVnf
abRnUVzHgvgK7bnab00SA1TiWvjHURGjo+5rnRtv8X/AgStc2Phjq68TMIgMn0F2
kjUVvfQotNqzo9madNshvUDmsGtAzKh4e0dS1ear7u3nRp4Z7fqSrTEtXKNbEPwZ
wdWrWmmQLacNQBSe/FtcMzGF6xIVr4lnrL0bFjqBdQpdTC7vns3QSKk8/GFiEfpv
kzXrDbGV7jX2OWDjNHKcmXX2+E1CsNaJgS7zOgZw5jvbvlTLJUwyYNlM1VLI2OFW
Oa86l8pqli+B7rpTbsAE9Ut8qUaWjm87oUNSJbaKgqNnMaE+b/8VJaEeWHgQJwsD
bJSJ/O/vzlRtDjOJ1JDlMRLs7TnOFeUh5pgwyaJoidYbJEiGlMGJbI6BjwhDTBFO
NLJtd3SsRjc7ICtGdCvej59IvCDTjxtkhx5okF03APi1aXpHQrE18/arFD7BpoGO
sw==
=gSIv
-----END PGP PUBLIC KEY BLOCK-----

8
debian/watch vendored
View File

@ -1,3 +1,5 @@
version=3
opts="pgpsigurlmangle=s/$/.asc/" \
https://github.com/lxde/pcmanfm-qt/releases .*/([\d\.]+).tar.gz
version=4
opts="searchmode=plain, \
pgpsigurlmangle=s/$/.asc/, \
uversionmangle=s/(\d+\.\d+\.\d+).*/$1/" \
https://api.github.com/repos/lxqt/@PACKAGE@/releases https:\/\/github.com\/lxqt\/@PACKAGE@\/releases\/download\/@ANY_VERSION@\/@PACKAGE@-@ANY_VERSION@.tar.xz

View File

@ -1,51 +0,0 @@
.TH PCManFM-Qt "1" "September 2014" "@CMAKE_PROJECT_NAME@ @PCMANFM_QT_VERSION@" "User Commands"
.SH NAME
PCManFM-Qt \- A lightweight Qt-based file manager for X Window.
.SH SYNOPSIS
pcmanfm\-qt [OPTION...] [FILE1, FILE2,...]
.SH DESCRIPTION
PCMan File Manager Qt (\fBPCManFM-Qt\fP) is an extremely fast, lightweight, yet
feature-rich file manager with tabbed browsing. It is the default file manager
for the lightweight desktop environment \fBLXQt\fP.
.SH OPTIONS
.SS "Help Options:"
.TP
\fB\-h\fR, \fB\-\-help\fR
Show help options
.SS "Application Options:"
.TP
\fB\-p\fR, \fB\-\-profile\fR=\fI\,PROFILE\/\fR
Set name of configuration profile
.TP
\fB\-d\fR, \fB\-\-daemon\-mode\fR
Run PCManFM as a daemon
.TP
\fB\-\-quit\fR
Quit PCManFM
.TP
\fB\-\-desktop\fR
Launch desktop manager
.TP
\fB\-\-desktop\-off\fR
Turn off desktop manager if it's running
.TP
\fB\-\-desktop\-pref\fR=\fI\,NAME\/\fR
Open desktop preference dialog on the page with the specified name
.TP
\fB\-w\fR, \fB\-\-set\-wallpaper\fR=\fI\,FILE\/\fR
Set desktop wallpaper from image FILE
.TP
\fB\-\-wallpaper\-mode\fR=\fI\,MODE\/\fR
Set mode of desktop wallpaper. MODE=(color|stretch|fit|center|tile)
.TP
\fB\-\-show\-pref\fR=\fI\,NAME\/\fR
Open Preferences dialog on the page with the specified name
.TP
\fB\-n\fR, \fB\-\-new\-window\fR
Open new window
.TP
\fB\-f\fR, \fB\-\-find\-files\fR
Open Find Files utility
.SH "AUTHORS"
.B pcmanfm-qt
was primarily written by Hong Jen Yee (PCMan) <pcman.tw@gmail.com>.

View File

@ -1,85 +0,0 @@
set(pcmanfm_SRCS
application.cpp
pcmanfm.cpp
mainwindow.cpp
tabpage.cpp
tabbar.cpp
view.cpp
launcher.cpp
preferencesdialog.cpp
xdgdir.cpp
desktoppreferencesdialog.cpp
desktopwindow.cpp
desktopitemdelegate.cpp
autorundialog.cpp
settings.cpp
)
qt5_add_dbus_adaptor(pcmanfm_SRCS
org.pcmanfm.Application.xml
application.h
PCManFM::Application
applicationadaptor
ApplicationAdaptor
)
set(pcmanfm_UIS
main-win.ui
about.ui
preferences.ui
desktop-preferences.ui
desktop-folder.ui
autorun.ui
)
qt5_wrap_ui(pcmanfm_UIS_H ${pcmanfm_UIS})
# add translation for pcmanfm-qt
lxqt_translate_ts(QM_FILES
UPDATE_TRANSLATIONS ${UPDATE_TRANSLATIONS}
SOURCES ${pcmanfm_SRCS} ${pcmanfm_UIS}
)
# translate desktop entry files for pcmanfm-qt and desktop preferences
lxqt_translate_desktop(DESKTOP_FILES
SOURCES
pcmanfm-qt.desktop.in
pcmanfm-qt-desktop-pref.desktop.in
)
add_executable(pcmanfm-qt
${pcmanfm_SRCS}
${pcmanfm_UIS_H}
${QM_FILES}
${DESKTOP_FILES}
)
set_property(
TARGET pcmanfm-qt APPEND
PROPERTY COMPILE_DEFINITIONS
PCMANFM_DATA_DIR="${CMAKE_INSTALL_PREFIX}/share/pcmanfm-qt"
PCMANFM_QT_VERSION="${PCMANFM_QT_VERSION}"
)
target_include_directories(pcmanfm-qt
PRIVATE "${LIB_XCB_INDLUDE_DIRS}"
"${Qt5Gui_PRIVATE_INCLUDE_DIRS}"
)
target_link_libraries(pcmanfm-qt
Qt5::X11Extras
Qt5::Widgets
Qt5::DBus
fm-qt
"${LIB_XCB_LIBRARIES}"
)
install(TARGETS pcmanfm-qt RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR})
# install a desktop entry file for pcmanfm-qt and desktop preferences
install(FILES ${DESKTOP_FILES} DESTINATION "${CMAKE_INSTALL_DATADIR}/applications"
)
install(FILES ${QM_FILES} DESTINATION "${CMAKE_INSTALL_DATADIR}/pcmanfm-qt/translations")
# prevent the generated files from being deleted during make clean
set_directory_properties(PROPERTIES CLEAN_NO_CUSTOM true)

View File

@ -1,180 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>AboutDialog</class>
<widget class="QDialog" name="AboutDialog">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>430</width>
<height>325</height>
</rect>
</property>
<property name="windowTitle">
<string>About</string>
</property>
<property name="windowIcon">
<iconset theme="help-about">
<normaloff/>
</iconset>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<widget class="QLabel" name="label">
<property name="text">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;&lt;span style=&quot; font-size:16pt; font-weight:600;&quot;&gt;PCManFM&lt;/span&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="textFormat">
<enum>Qt::RichText</enum>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="version">
<property name="text">
<string/>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="label_2">
<property name="text">
<string>Lightweight file manager</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="label_3">
<property name="text">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;&lt;a href=&quot;http://lxqt.org/&quot;&gt;&lt;span style=&quot; text-decoration: underline; color:#0000ff;&quot;&gt;http://lxqt.org/&lt;/span&gt;&lt;/a&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="textFormat">
<enum>Qt::RichText</enum>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
<item>
<widget class="QTabWidget" name="tabWidget">
<property name="currentIndex">
<number>0</number>
</property>
<property name="tabsClosable">
<bool>false</bool>
</property>
<widget class="QWidget" name="tab">
<attribute name="title">
<string>Authors</string>
</attribute>
<layout class="QVBoxLayout" name="verticalLayout_4">
<item>
<widget class="QPlainTextEdit" name="plainTextEdit_2">
<property name="readOnly">
<bool>true</bool>
</property>
<property name="plainText">
<string>Programming:
* Hong Jen Yee (PCMan) &lt;pcman.tw@gmail.com&gt;
</string>
</property>
<property name="backgroundVisible">
<bool>false</bool>
</property>
</widget>
</item>
</layout>
</widget>
<widget class="QWidget" name="tab_2">
<attribute name="title">
<string>License</string>
</attribute>
<layout class="QVBoxLayout" name="verticalLayout_3">
<item>
<widget class="QPlainTextEdit" name="plainTextEdit">
<property name="readOnly">
<bool>true</bool>
</property>
<property name="plainText">
<string>PCMan File Manager
Copyright (C) 2009 - 2014 洪任諭 (Hong Jen Yee)
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.</string>
</property>
</widget>
</item>
</layout>
</widget>
</widget>
</item>
<item>
<widget class="QDialogButtonBox" name="buttonBox">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="standardButtons">
<set>QDialogButtonBox::Close</set>
</property>
</widget>
</item>
</layout>
</widget>
<resources/>
<connections>
<connection>
<sender>buttonBox</sender>
<signal>accepted()</signal>
<receiver>AboutDialog</receiver>
<slot>accept()</slot>
<hints>
<hint type="sourcelabel">
<x>248</x>
<y>254</y>
</hint>
<hint type="destinationlabel">
<x>157</x>
<y>274</y>
</hint>
</hints>
</connection>
<connection>
<sender>buttonBox</sender>
<signal>rejected()</signal>
<receiver>AboutDialog</receiver>
<slot>reject()</slot>
<hints>
<hint type="sourcelabel">
<x>316</x>
<y>260</y>
</hint>
<hint type="destinationlabel">
<x>286</x>
<y>274</y>
</hint>
</hints>
</connection>
</connections>
</ui>

View File

@ -1,844 +0,0 @@
/*
Copyright (C) 2013 Hong Jen Yee (PCMan) <pcman.tw@gmail.com>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#include "application.h"
#include "mainwindow.h"
#include "desktopwindow.h"
#include <QDBusConnection>
#include <QDBusInterface>
#include <QDir>
#include <QDesktopWidget>
#include <QVector>
#include <QLocale>
#include <QLibraryInfo>
#include <QPixmapCache>
#include <QFile>
#include <QMessageBox>
#include <QCommandLineParser>
#include <QSocketNotifier>
#include <gio/gio.h>
#include <sys/socket.h>
#include "applicationadaptor.h"
#include "preferencesdialog.h"
#include "desktoppreferencesdialog.h"
#include <libfm-qt/mountoperation.h>
#include "autorundialog.h"
#include "launcher.h"
#include <libfm-qt/filesearchdialog.h>
#include <QScreen>
#include <QWindow>
#include <X11/Xlib.h>
#include "xdgdir.h"
#include <QFileSystemWatcher>
namespace PCManFM {
static const char* serviceName = "org.pcmanfm.PCManFM";
static const char* ifaceName = "org.pcmanfm.Application";
int ProxyStyle::styleHint(StyleHint hint, const QStyleOption* option, const QWidget* widget, QStyleHintReturn* returnData) const {
Application* app = static_cast<Application*>(qApp);
if(hint == QStyle::SH_ItemView_ActivateItemOnSingleClick)
return app->settings().singleClick();
return QProxyStyle::styleHint(hint, option, widget, returnData);
}
Application::Application(int& argc, char** argv):
QApplication(argc, argv),
libFm_(),
settings_(),
profileName_("default"),
daemonMode_(false),
desktopWindows_(),
enableDesktopManager_(false),
preferencesDialog_(),
volumeMonitor_(NULL),
userDirsWatcher_(NULL),
lxqtRunning_(false),
editBookmarksialog_() {
argc_ = argc;
argv_ = argv;
setApplicationVersion(PCMANFM_QT_VERSION);
// QDBusConnection::sessionBus().registerObject("/org/pcmanfm/Application", this);
QDBusConnection dbus = QDBusConnection::sessionBus();
if(dbus.registerService(serviceName)) {
// we successfully registered the service
isPrimaryInstance = true;
setStyle(new ProxyStyle());
desktop()->installEventFilter(this);
new ApplicationAdaptor(this);
dbus.registerObject("/Application", this);
connect(this, &Application::aboutToQuit, this, &Application::onAboutToQuit);
// aboutToQuit() is not signalled on SIGTERM, install signal handler
installSigtermHandler();
settings_.load(profileName_);
// decrease the cache size to reduce memory usage
QPixmapCache::setCacheLimit(2048);
if(settings_.useFallbackIconTheme()) {
QIcon::setThemeName(settings_.fallbackIconThemeName());
Fm::IconTheme::checkChanged();
}
// Check if LXQt Session is running. LXQt has it's own Desktop Folder
// editor. We just hide our editor when LXQt is running.
QDBusInterface* lxqtSessionIface = new QDBusInterface(
QStringLiteral("org.lxqt.session"),
QStringLiteral("/LXQtSession"));
if (lxqtSessionIface) {
if (lxqtSessionIface->isValid()) {
lxqtRunning_ = true;
userDesktopFolder_ = XdgDir::readDesktopDir();
initWatch();
}
delete lxqtSessionIface;
lxqtSessionIface = 0;
}
}
else {
// an service of the same name is already registered.
// we're not the first instance
isPrimaryInstance = false;
}
}
Application::~Application() {
desktop()->removeEventFilter(this);
if(volumeMonitor_) {
g_signal_handlers_disconnect_by_func(volumeMonitor_, gpointer(onVolumeAdded), this);
g_object_unref(volumeMonitor_);
}
// if(enableDesktopManager_)
// removeNativeEventFilter(this);
}
void Application::initWatch()
{
QFile file_ (QStandardPaths::writableLocation(QStandardPaths::ConfigLocation) + QStringLiteral("/user-dirs.dirs"));
if(! file_.open(QIODevice::ReadOnly | QIODevice::Text)) {
qDebug() << Q_FUNC_INFO << "Could not read: " << userDirsFile_;
userDirsFile_ = QString();
} else {
userDirsFile_ = file_.fileName();
}
userDirsWatcher_ = new QFileSystemWatcher(this);
userDirsWatcher_->addPath(userDirsFile_);
connect(userDirsWatcher_, &QFileSystemWatcher::fileChanged, this, &Application::onUserDirsChanged);
}
bool Application::parseCommandLineArgs() {
bool keepRunning = false;
QCommandLineParser parser;
parser.addHelpOption();
parser.addVersionOption();
QCommandLineOption profileOption(QStringList() << "p" << "profile", tr("Name of configuration profile"), tr("PROFILE"));
parser.addOption(profileOption);
QCommandLineOption daemonOption(QStringList() << "d" << "daemon-mode", tr("Run PCManFM as a daemon"));
parser.addOption(daemonOption);
QCommandLineOption quitOption(QStringList() << "q" << "quit", tr("Quit PCManFM"));
parser.addOption(quitOption);
QCommandLineOption desktopOption("desktop", tr("Launch desktop manager"));
parser.addOption(desktopOption);
QCommandLineOption desktopOffOption("desktop-off", tr("Turn off desktop manager if it's running"));
parser.addOption(desktopOffOption);
QCommandLineOption desktopPrefOption("desktop-pref", tr("Open desktop preference dialog on the page with the specified name"), tr("NAME"));
parser.addOption(desktopPrefOption);
QCommandLineOption newWindowOption(QStringList() << "n" << "new-window", tr("Open new window"));
parser.addOption(newWindowOption);
QCommandLineOption findFilesOption(QStringList() << "f" << "find-files", tr("Open Find Files utility"));
parser.addOption(findFilesOption);
QCommandLineOption setWallpaperOption(QStringList() << "w" << "set-wallpaper", tr("Set desktop wallpaper from image FILE"), tr("FILE"));
parser.addOption(setWallpaperOption);
QCommandLineOption wallpaperModeOption("wallpaper-mode", tr("Set mode of desktop wallpaper. MODE=(%1)").arg("color|stretch|fit|center|tile"), tr("MODE"));
parser.addOption(wallpaperModeOption);
QCommandLineOption showPrefOption("show-pref", tr("Open Preferences dialog on the page with the specified name"), tr("NAME"));
parser.addOption(showPrefOption);
parser.addPositionalArgument("files", tr("Files or directories to open"), tr("[FILE1, FILE2,...]"));
parser.process(arguments());
if(isPrimaryInstance) {
qDebug("isPrimaryInstance");
if(parser.isSet(daemonOption))
daemonMode_ = true;
if(parser.isSet(profileOption))
profileName_ = parser.value(profileOption);
// load settings
settings_.load(profileName_);
// desktop icon management
if(parser.isSet(desktopOption)) {
desktopManager(true);
keepRunning = true;
}
else if(parser.isSet(desktopOffOption))
desktopManager(false);
if(parser.isSet(desktopPrefOption)) { // desktop preference dialog
desktopPrefrences(parser.value(desktopPrefOption));
keepRunning = true;
}
else if(parser.isSet(findFilesOption)) { // file searching utility
findFiles(parser.positionalArguments());
keepRunning = true;
}
else if(parser.isSet(showPrefOption)) { // preferences dialog
preferences(parser.value(showPrefOption));
keepRunning = true;
}
else if(parser.isSet(setWallpaperOption) || parser.isSet(wallpaperModeOption)) // set wall paper
setWallpaper(parser.value(setWallpaperOption), parser.value(wallpaperModeOption));
else {
if(!parser.isSet(desktopOption) && !parser.isSet(desktopOffOption)) {
QStringList paths = parser.positionalArguments();
if(paths.isEmpty()) {
// if no path is specified and we're using daemon mode,
// don't open current working directory
if(!daemonMode_)
paths.push_back(QDir::currentPath());
}
if(!paths.isEmpty())
launchFiles(QDir::currentPath(), paths, parser.isSet(newWindowOption));
keepRunning = true;
}
}
}
else {
QDBusConnection dbus = QDBusConnection::sessionBus();
QDBusInterface iface(serviceName, "/Application", ifaceName, dbus, this);
if(parser.isSet(quitOption)) {
iface.call("quit");
return false;
}
if(parser.isSet(desktopOption))
iface.call("desktopManager", true);
else if(parser.isSet(desktopOffOption))
iface.call("desktopManager", false);
if(parser.isSet(desktopPrefOption)) { // desktop preference dialog
iface.call("desktopPrefrences", parser.value(desktopPrefOption));
}
else if(parser.isSet(findFilesOption)) { // file searching utility
iface.call("findFiles", parser.positionalArguments());
}
else if(parser.isSet(showPrefOption)) { // preferences dialog
iface.call("preferences", parser.value(showPrefOption));
}
else if(parser.isSet(setWallpaperOption) || parser.isSet(wallpaperModeOption)) { // set wall paper
iface.call("setWallpaper", parser.value(setWallpaperOption), parser.value(wallpaperModeOption));
}
else {
if(!parser.isSet(desktopOption) && !parser.isSet(desktopOffOption)) {
QStringList paths = parser.positionalArguments();
if(paths.isEmpty()) {
paths.push_back(QDir::currentPath());
}
iface.call("launchFiles", QDir::currentPath(), paths, parser.isSet(newWindowOption));
}
}
}
return keepRunning;
}
void Application::init() {
// install the translations built-into Qt itself
qtTranslator.load("qt_" + QLocale::system().name(), QLibraryInfo::location(QLibraryInfo::TranslationsPath));
installTranslator(&qtTranslator);
// install libfm-qt translator
installTranslator(libFm_.translator());
// install our own tranlations
translator.load("pcmanfm-qt_" + QLocale::system().name(), PCMANFM_DATA_DIR "/translations");
installTranslator(&translator);
}
int Application::exec() {
if(!parseCommandLineArgs())
return 0;
if(daemonMode_) // keep running even when there is no window opened.
setQuitOnLastWindowClosed(false);
volumeMonitor_ = g_volume_monitor_get();
// delay the volume manager a little because in newer versions of glib/gio there's a problem.
// when the first volume monitor object is created, it discovers volumes asynchonously.
// g_volume_monitor_get() immediately returns while the monitor is still discovering devices.
// So initially g_volume_monitor_get_volumes() returns nothing, but shortly after that
// we get volume-added signals for all of the volumes. This is not what we want.
// So, we wait for 3 seconds here to let it finish device discovery.
QTimer::singleShot(3000, this, SLOT(initVolumeManager()));
return QCoreApplication::exec();
}
void Application::onUserDirsChanged()
{
qDebug() << Q_FUNC_INFO;
bool file_deleted = !userDirsWatcher_->files().contains(userDirsFile_);
if(file_deleted) {
// if our config file is already deleted, reinstall a new watcher
userDirsWatcher_->addPath(userDirsFile_);
}
const QString d = XdgDir::readDesktopDir();
if (d != userDesktopFolder_) {
userDesktopFolder_ = d;
const QDir dir(d);
if (dir.exists()) {
const int N = desktopWindows_.size();
for(int i = 0; i < N; ++i) {
desktopWindows_.at(i)->setDesktopFolder();
}
} else {
qWarning("Application::onUserDirsChanged: %s doesn't exist",
userDesktopFolder_.toUtf8().constData());
}
}
}
void Application::onAboutToQuit() {
qDebug("aboutToQuit");
settings_.save();
}
bool Application::eventFilter(QObject* watched, QEvent* event) {
if(watched == desktop()) {
switch(event->type()) {
case QEvent::StyleChange:
case QEvent::ThemeChange:
setStyle(new ProxyStyle());
};
}
return QObject::eventFilter(watched, event);
}
void Application::onLastWindowClosed() {
}
void Application::onSaveStateRequest(QSessionManager& manager) {
}
void Application::desktopManager(bool enabled) {
// TODO: turn on or turn off desktpo management (desktop icons & wallpaper)
qDebug("desktopManager: %d", enabled);
QDesktopWidget* desktopWidget = desktop();
if(enabled) {
if(!enableDesktopManager_) {
// installNativeEventFilter(this);
Q_FOREACH(QScreen* screen, screens()) {
connect(screen, &QScreen::virtualGeometryChanged, this, &Application::onVirtualGeometryChanged);
connect(screen, &QObject::destroyed, this, &Application::onScreenDestroyed);
}
connect(this, &QApplication::screenAdded, this, &Application::onScreenAdded);
connect(desktopWidget, &QDesktopWidget::resized, this, &Application::onScreenResized);
connect(desktopWidget, &QDesktopWidget::screenCountChanged, this, &Application::onScreenCountChanged);
// NOTE: there are two modes
// When virtual desktop is used (all screens are combined to form a large virtual desktop),
// we only create one DesktopWindow. Otherwise, we create one for each screen.
if(desktopWidget->isVirtualDesktop()) {
DesktopWindow* window = createDesktopWindow(-1);
desktopWindows_.push_back(window);
}
else {
int n = desktopWidget->numScreens();
desktopWindows_.reserve(n);
for(int i = 0; i < n; ++i) {
DesktopWindow* window = createDesktopWindow(i);
desktopWindows_.push_back(window);
}
}
}
}
else {
if(enableDesktopManager_) {
disconnect(desktopWidget, &QDesktopWidget::resized, this, &Application::onScreenResized);
disconnect(desktopWidget, &QDesktopWidget::screenCountChanged, this, &Application::onScreenCountChanged);
int n = desktopWindows_.size();
for(int i = 0; i < n; ++i) {
DesktopWindow* window = desktopWindows_.at(i);
delete window;
}
desktopWindows_.clear();
Q_FOREACH(QScreen* screen, screens()) {
disconnect(screen, &QScreen::virtualGeometryChanged, this, &Application::onVirtualGeometryChanged);
disconnect(screen, &QObject::destroyed, this, &Application::onScreenDestroyed);
}
disconnect(this, &QApplication::screenAdded, this, &Application::onScreenAdded);
// removeNativeEventFilter(this);
}
}
enableDesktopManager_ = enabled;
}
void Application::desktopPrefrences(QString page) {
// show desktop preference window
if(!desktopPreferencesDialog_) {
desktopPreferencesDialog_ = new DesktopPreferencesDialog();
// Should be used only one time
desktopPreferencesDialog_->setEditDesktopFolder(!lxqtRunning_);
}
desktopPreferencesDialog_.data()->selectPage(page);
desktopPreferencesDialog_.data()->show();
desktopPreferencesDialog_.data()->raise();
desktopPreferencesDialog_.data()->activateWindow();
}
void Application::onFindFileAccepted() {
Fm::FileSearchDialog* dlg = static_cast<Fm::FileSearchDialog*>(sender());
Fm::Path uri = dlg->searchUri();
// FIXME: we should be able to open it in an existing window
FmPathList* paths = fm_path_list_new();
fm_path_list_push_tail(paths, uri.data());
Launcher(NULL).launchPaths(NULL, paths);
fm_path_list_unref(paths);
}
void Application::findFiles(QStringList paths) {
// launch file searching utility.
Fm::FileSearchDialog* dlg = new Fm::FileSearchDialog(paths);
connect(dlg, &QDialog::accepted, this, &Application::onFindFileAccepted);
dlg->setAttribute(Qt::WA_DeleteOnClose);
dlg->show();
}
void Application::launchFiles(QString cwd, QStringList paths, bool inNewWindow) {
FmPathList* pathList = fm_path_list_new();
FmPath* cwd_path = NULL;
QStringList::iterator it;
Q_FOREACH(const QString& it, paths) {
QByteArray pathName = it.toLocal8Bit();
FmPath* path = NULL;
if(pathName[0] == '/') // absolute path
path = fm_path_new_for_path(pathName.constData());
else if(pathName.contains(":/")) // URI
path = fm_path_new_for_uri(pathName.constData());
else if(pathName == "~") // special case for home dir
path = fm_path_ref(fm_path_get_home());
else // basename
{
if(Q_UNLIKELY(!cwd_path))
cwd_path = fm_path_new_for_str(cwd.toLocal8Bit().constData());
path = fm_path_new_relative(cwd_path, pathName.constData());
}
fm_path_list_push_tail(pathList, path);
fm_path_unref(path);
}
if(cwd_path)
fm_path_unref(cwd_path);
Launcher(NULL).launchPaths(NULL, pathList);
fm_path_list_unref(pathList);
}
void Application::openFolders(FmFileInfoList* files) {
Launcher(NULL).launchFiles(NULL, files);
}
void Application::openFolderInTerminal(FmPath* path) {
if(!settings_.terminal().isEmpty()) {
char* cwd_str;
if(fm_path_is_native(path))
cwd_str = fm_path_to_str(path);
else { // gio will map remote filesystems to local FUSE-mounted paths here.
GFile* gf = fm_path_to_gfile(path);
cwd_str = g_file_get_path(gf);
g_object_unref(gf);
}
GError* err = NULL;
if(!fm_terminal_launch(cwd_str, &err)) {
QMessageBox::critical(NULL, tr("Error"), QString::fromUtf8(err->message));
g_error_free(err);
}
g_free(cwd_str);
}
else {
// show an error message and ask the user to set the command
QMessageBox::critical(NULL, tr("Error"), tr("Terminal emulator is not set."));
preferences("advanced");
}
}
void Application::preferences(QString page) {
// open preference dialog
if(!preferencesDialog_) {
preferencesDialog_ = new PreferencesDialog(page);
}
else {
preferencesDialog_.data()->selectPage(page);
}
preferencesDialog_.data()->show();
preferencesDialog_.data()->raise();
preferencesDialog_.data()->activateWindow();
}
void Application::setWallpaper(QString path, QString modeString) {
static const char* valid_wallpaper_modes[] = {"color", "stretch", "fit", "center", "tile"};
DesktopWindow::WallpaperMode mode = settings_.wallpaperMode();
bool changed = false;
if(!path.isEmpty() && path != settings_.wallpaper()) {
if(QFile(path).exists()) {
settings_.setWallpaper(path);
changed = true;
}
}
// convert mode string to value
for(int i = 0; i < G_N_ELEMENTS(valid_wallpaper_modes); ++i) {
if(modeString == valid_wallpaper_modes[i]) {
mode = (DesktopWindow::WallpaperMode)i;
if(mode != settings_.wallpaperMode())
changed = true;
break;
}
}
// FIXME: support different wallpapers on different screen.
// update wallpaper
if(changed) {
if(enableDesktopManager_) {
Q_FOREACH(DesktopWindow * desktopWindow, desktopWindows_) {
if(!path.isEmpty())
desktopWindow->setWallpaperFile(path);
if(mode != settings_.wallpaperMode())
desktopWindow->setWallpaperMode(mode);
desktopWindow->updateWallpaper();
}
settings_.save(); // save the settings to the config file
}
}
}
void Application::onScreenResized(int num) {
if(desktop()->isVirtualDesktop()) {
// in virtual desktop mode, we only have one desktop window. that is the first one.
DesktopWindow* window = desktopWindows_.at(0);
window->setGeometry(desktop()->geometry());
}
else {
DesktopWindow* window = desktopWindows_.at(num);
QRect rect = desktop()->screenGeometry(num);
window->setGeometry(rect);
}
}
DesktopWindow* Application::createDesktopWindow(int screenNum) {
DesktopWindow* window = new DesktopWindow(screenNum);
if(screenNum == -1) { // one large virtual desktop only
QRect rect = desktop()->geometry();
window->setGeometry(rect);
}
else {
QRect rect = desktop()->screenGeometry(screenNum);
window->setGeometry(rect);
}
window->updateFromSettings(settings_);
window->show();
return window;
}
void Application::onScreenCountChanged(int newCount) {
QDesktopWidget* desktopWidget = desktop();
bool oldVirtual = (desktopWindows_.size() == 1 && desktopWindows_.at(0)->screenNum() == -1);
bool isVirtual = desktopWidget->isVirtualDesktop();
if(oldVirtual && isVirtual) {
// if we are using virtual desktop mode previously, and the new mode is sitll virtual
// no further change is needed, only do relayout.
desktopWindows_.at(0)->queueRelayout();
return;
}
// we used non-virtual mode originally, but now we're switched to virtual mode
if(isVirtual)
newCount = 1; // we only want one desktop window for all screens in virtual mode
if(newCount > desktopWindows_.size()) {
// add more desktop windows
for(int i = desktopWindows_.size(); i < newCount; ++i) {
DesktopWindow* desktop = createDesktopWindow(i);
desktopWindows_.push_back(desktop);
}
}
else if(newCount < desktopWindows_.size()) {
// delete excessive desktop windows
for(int i = newCount; i < desktopWindows_.size(); ++i) {
DesktopWindow* desktop = desktopWindows_.at(i);
delete desktop;
}
desktopWindows_.resize(newCount);
}
if(newCount == 1) { // now only 1 screen is in use
DesktopWindow* desktop = desktopWindows_.at(0);
if(isVirtual)
desktop->setScreenNum(-1);
else // non-virtual mode, and we only have 1 screen
desktop->setScreenNum(0);
desktop->updateWallpaper();
}
}
// called when Settings is changed to update UI
void Application::updateFromSettings() {
// if(iconTheme.isEmpty())
// Fm::IconTheme::setThemeName(settings_.fallbackIconThemeName());
// update main windows and desktop windows
QWidgetList windows = this->topLevelWidgets();
QWidgetList::iterator it;
for(it = windows.begin(); it != windows.end(); ++it) {
QWidget* window = *it;
if(window->inherits("PCManFM::MainWindow")) {
MainWindow* mainWindow = static_cast<MainWindow*>(window);
mainWindow->updateFromSettings(settings_);
}
}
if(desktopManagerEnabled())
updateDesktopsFromSettings();
}
void Application::updateDesktopsFromSettings() {
QVector<DesktopWindow*>::iterator it;
for(it = desktopWindows_.begin(); it != desktopWindows_.end(); ++it) {
DesktopWindow* desktopWindow = static_cast<DesktopWindow*>(*it);
desktopWindow->updateFromSettings(settings_);
}
}
void Application::editBookmarks() {
if(!editBookmarksialog_) {
FmBookmarks* bookmarks = fm_bookmarks_dup();
editBookmarksialog_ = new Fm::EditBookmarksDialog(bookmarks);
g_object_unref(bookmarks);
}
editBookmarksialog_.data()->show();
}
void Application::initVolumeManager() {
g_signal_connect(volumeMonitor_, "volume-added", G_CALLBACK(onVolumeAdded), this);
if(settings_.mountOnStartup()) {
/* try to automount all volumes */
GList* vols = g_volume_monitor_get_volumes(volumeMonitor_);
for(GList* l = vols; l; l = l->next) {
GVolume* volume = G_VOLUME(l->data);
if(g_volume_should_automount(volume))
autoMountVolume(volume, false);
g_object_unref(volume);
}
g_list_free(vols);
}
}
bool Application::autoMountVolume(GVolume* volume, bool interactive) {
if(!g_volume_should_automount(volume) || !g_volume_can_mount(volume))
return FALSE;
GMount* mount = g_volume_get_mount(volume);
if(!mount) { // not mounted, automount is needed
// try automount
Fm::MountOperation* op = new Fm::MountOperation(interactive);
op->mount(volume);
if(!op->wait())
return false;
if(!interactive)
return true;
mount = g_volume_get_mount(volume);
}
if(mount) {
if(interactive && settings_.autoRun()) { // show autorun dialog
AutoRunDialog* dlg = new AutoRunDialog(volume, mount);
dlg->show();
}
g_object_unref(mount);
}
return true;
}
// static
void Application::onVolumeAdded(GVolumeMonitor* monitor, GVolume* volume, Application* pThis) {
if(pThis->settings_.mountRemovable())
pThis->autoMountVolume(volume, true);
}
#if 0
bool Application::nativeEventFilter(const QByteArray & eventType, void * message, long * result) {
if(eventType == "xcb_generic_event_t") { // XCB event
// filter all native X11 events (xcb)
xcb_generic_event_t* generic_event = reinterpret_cast<xcb_generic_event_t*>(message);
// qDebug("XCB event: %d", generic_event->response_type & ~0x80);
Q_FOREACH(DesktopWindow * window, desktopWindows_) {
}
}
return false;
}
#endif
void Application::onScreenAdded(QScreen* newScreen) {
if(enableDesktopManager_) {
connect(newScreen, &QScreen::virtualGeometryChanged, this, &Application::onVirtualGeometryChanged);
connect(newScreen, &QObject::destroyed, this, &Application::onScreenDestroyed);
}
}
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.
// 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.
// Explanations for the workaround:
// Internally, Qt mantains a list of QScreens and update it when XRandR configuration changes.
// When the user turn off an monitor with xrandr --output <xxx> --off, this will destroy the QScreen
// object which represent the output. If the QScreen being destroyed contains our panel widget,
// Qt will call QWindow::setScreen(0) on the internal windowHandle() of our panel widget to move it
// to the primary screen. However, moving a window to a different screen is more than just changing
// its position. With XRandR, all screens are actually part of the same virtual desktop. However,
// this is not the case in other setups, such as Xinerama and moving a window to another screen is
// not possible unless you destroy the widget and create it again for a new screen.
// Therefore, Qt destroy the widget and re-create it when moving our panel to a new screen.
// Unfortunately, destroying the window also destroy the child windows embedded into it,
// using XEMBED such as the tray icons. (#206)
// Second, when the window is re-created, the winId of the QWidget is changed, but Qt failed to
// generate QEvent::WinIdChange event so we have no way to know that. We have to set
// some X11 window properties using the native winId() to make it a dock, but this stop working
// because we cannot get the correct winId(), so this causes #204 and #205.
//
// The workaround is very simple. Just completely destroy the window before Qt has a chance to do
// QWindow::setScreen() for it. Later, we recreate the window ourselves. So this can bypassing the Qt bugs.
if(enableDesktopManager_) {
bool reloadNeeded = false;
// FIXME: add workarounds for Qt5 bug #40681 and #40791 here.
Q_FOREACH(DesktopWindow* desktop, desktopWindows_) {
if(desktop->windowHandle()->screen() == screenObj) {
desktop->destroy(); // destroy the underlying native window
reloadNeeded = true;
}
}
if(reloadNeeded)
QTimer::singleShot(0, this, SLOT(reloadDesktopsAsNeeded()));
}
}
void Application::reloadDesktopsAsNeeded() {
if(enableDesktopManager_) {
// workarounds for Qt5 bug #40681 and #40791 here.
Q_FOREACH(DesktopWindow* desktop, desktopWindows_) {
if(!desktop->windowHandle()) {
desktop->create(); // re-create the underlying native window
desktop->queueRelayout();
desktop->show();
}
}
}
}
// 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) {
// 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.
// In theory, QDesktopWidget should emit "workAreaResized()" signal when the work area
// of any screen is changed, but in fact it does not do it.
// However, QScreen provided since Qt5 does not have the bug and
// virtualGeometryChanged() is emitted correctly when the workAreas changed.
// So we use it in Qt5.
if(enableDesktopManager_) {
// qDebug() << "onVirtualGeometryChanged";
Q_FOREACH(DesktopWindow* desktop, desktopWindows_) {
desktop->queueRelayout();
}
}
}
static int sigterm_fd[2];
static void sigtermHandler(int) {
char c = 1;
::write(sigterm_fd[0], &c, sizeof(c));
}
void Application::installSigtermHandler() {
if(::socketpair(AF_UNIX, SOCK_STREAM, 0, sigterm_fd) == 0) {
QSocketNotifier* notifier = new QSocketNotifier(sigterm_fd[1], QSocketNotifier::Read, this);
connect(notifier, &QSocketNotifier::activated, this, &Application::onSigtermNotified);
struct sigaction action;
action.sa_handler = sigtermHandler;
::sigemptyset(&action.sa_mask);
action.sa_flags = SA_RESTART;
if(::sigaction(SIGTERM, &action, 0) != 0) {
qWarning("Couldn't install SIGTERM handler");
}
} else {
qWarning("Couldn't create SIGTERM socketpair");
}
}
void Application::onSigtermNotified() {
if (QSocketNotifier* notifier = qobject_cast<QSocketNotifier*>(sender())) {
notifier->setEnabled(false);
char c;
::read(sigterm_fd[1], &c, sizeof(c));
quit();
notifier->setEnabled(true);
}
}
} // namespace PCManFM

View File

@ -1,151 +0,0 @@
/*
Copyright (C) 2013 Hong Jen Yee (PCMan) <pcman.tw@gmail.com>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#ifndef PCMANFM_APPLICATION_H
#define PCMANFM_APPLICATION_H
#include <QApplication>
#include "settings.h"
#include <libfm-qt/libfmqt.h>
#include <libfm-qt/editbookmarksdialog.h>
#include <QVector>
#include <QPointer>
#include <QProxyStyle>
#include <QTranslator>
#include <gio/gio.h>
class QScreen;
class QFileSystemWatcher;
namespace PCManFM {
class DesktopWindow;
class PreferencesDialog;
class DesktopPreferencesDialog;
class ProxyStyle: public QProxyStyle {
Q_OBJECT
public:
ProxyStyle() : QProxyStyle() {}
virtual ~ProxyStyle() {}
virtual int styleHint(StyleHint hint, const QStyleOption * option = 0, const QWidget * widget = 0, QStyleHintReturn * returnData = 0) const;
};
class Application : public QApplication {
Q_OBJECT
Q_PROPERTY(bool desktopManagerEnabled READ desktopManagerEnabled)
public:
Application(int& argc, char** argv);
virtual ~Application();
void init();
int exec();
Settings& settings() {
return settings_;
}
Fm::LibFmQt& libFm() {
return libFm_;
}
// public interface exported via dbus
void launchFiles(QString cwd, QStringList paths, bool inNewWindow);
void setWallpaper(QString path, QString modeString);
void preferences(QString page);
void desktopPrefrences(QString page);
void editBookmarks();
void desktopManager(bool enabled);
void findFiles(QStringList paths = QStringList());
bool desktopManagerEnabled() {
return enableDesktopManager_;
}
void updateFromSettings();
void updateDesktopsFromSettings();
void openFolderInTerminal(FmPath* path);
void openFolders(FmFileInfoList* files);
QString profileName() {
return profileName_;
}
protected Q_SLOTS:
void onAboutToQuit();
void onSigtermNotified();
void onLastWindowClosed();
void onSaveStateRequest(QSessionManager & manager);
void onScreenResized(int num);
void onScreenCountChanged(int newCount);
void initVolumeManager();
void onVirtualGeometryChanged(const QRect& rect);
void onScreenDestroyed(QObject* screenObj);
void onScreenAdded(QScreen* newScreen);
void reloadDesktopsAsNeeded();
void onFindFileAccepted();
protected:
virtual bool eventFilter(QObject* watched, QEvent* event);
bool parseCommandLineArgs();
DesktopWindow* createDesktopWindow(int screenNum);
bool autoMountVolume(GVolume* volume, bool interactive = true);
static void onVolumeAdded(GVolumeMonitor* monitor, GVolume* volume, Application* pThis);
private Q_SLOTS:
void onUserDirsChanged();
private:
void initWatch();
void installSigtermHandler();
bool isPrimaryInstance;
Fm::LibFmQt libFm_;
Settings settings_;
QString profileName_;
bool daemonMode_;
bool enableDesktopManager_;
QVector<DesktopWindow*> desktopWindows_;
QPointer<PreferencesDialog> preferencesDialog_;
QPointer<DesktopPreferencesDialog> desktopPreferencesDialog_;
QPointer<Fm::EditBookmarksDialog> editBookmarksialog_;
QTranslator translator;
QTranslator qtTranslator;
GVolumeMonitor* volumeMonitor_;
QFileSystemWatcher *userDirsWatcher_;
QString userDirsFile_;
QString userDesktopFolder_;
bool lxqtRunning_;
int argc_;
char** argv_;
};
}
#endif // PCMANFM_APPLICATION_H

View File

@ -1,117 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>AutoRunDialog</class>
<widget class="QDialog" name="AutoRunDialog">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>334</width>
<height>312</height>
</rect>
</property>
<property name="windowTitle">
<string>Removable medium is inserted</string>
</property>
<property name="windowIcon">
<iconset theme="drive-removable-media">
<normaloff>../../../.designer/backup</normaloff>../../../.designer/backup</iconset>
</property>
<layout class="QFormLayout" name="formLayout_2">
<item row="0" column="0">
<widget class="QLabel" name="icon">
<property name="text">
<string/>
</property>
</widget>
</item>
<item row="0" column="1">
<layout class="QFormLayout" name="formLayout">
<item row="0" column="0" colspan="2">
<widget class="QLabel" name="label">
<property name="text">
<string>&lt;b&gt;Removable medium is inserted&lt;/b&gt;</string>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QLabel" name="label_2">
<property name="text">
<string>Type of medium:</string>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QLabel" name="mediumType">
<property name="text">
<string>Detecting...</string>
</property>
</widget>
</item>
</layout>
</item>
<item row="1" column="0" colspan="2">
<widget class="QLabel" name="label_3">
<property name="text">
<string>Please select the action you want to perform:</string>
</property>
</widget>
</item>
<item row="2" column="0" colspan="2">
<widget class="QListWidget" name="listWidget">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Expanding">
<horstretch>0</horstretch>
<verstretch>1</verstretch>
</sizepolicy>
</property>
</widget>
</item>
<item row="3" column="0" colspan="2">
<widget class="QDialogButtonBox" name="buttonBox">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="standardButtons">
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
</property>
</widget>
</item>
</layout>
</widget>
<resources/>
<connections>
<connection>
<sender>buttonBox</sender>
<signal>accepted()</signal>
<receiver>AutoRunDialog</receiver>
<slot>accept()</slot>
<hints>
<hint type="sourcelabel">
<x>248</x>
<y>254</y>
</hint>
<hint type="destinationlabel">
<x>157</x>
<y>274</y>
</hint>
</hints>
</connection>
<connection>
<sender>buttonBox</sender>
<signal>rejected()</signal>
<receiver>AutoRunDialog</receiver>
<slot>reject()</slot>
<hints>
<hint type="sourcelabel">
<x>316</x>
<y>260</y>
</hint>
<hint type="destinationlabel">
<x>286</x>
<y>274</y>
</hint>
</hints>
</connection>
</connections>
</ui>

View File

@ -1,139 +0,0 @@
/*
Copyright (C) 2013 Hong Jen Yee (PCMan) <pcman.tw@gmail.com>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#include "autorundialog.h"
#include <libfm-qt/icontheme.h>
#include <QListWidgetItem>
#include "application.h"
#include "mainwindow.h"
namespace PCManFM {
AutoRunDialog::AutoRunDialog(GVolume* volume, GMount* mount, QWidget* parent, Qt::WindowFlags f):
cancellable(g_cancellable_new()),
applications(NULL),
mount_(G_MOUNT(g_object_ref(mount))),
QDialog(parent, f) {
setAttribute(Qt::WA_DeleteOnClose);
ui.setupUi(this);
GIcon* gicon = g_volume_get_icon(volume);
QIcon icon = Fm::IconTheme::icon(gicon);
ui.icon->setPixmap(icon.pixmap(QSize(48, 48)));
// add actions
QListWidgetItem* item = new QListWidgetItem(QIcon::fromTheme("system-file-manager"), tr("Open in file manager"));
ui.listWidget->addItem(item);
g_mount_guess_content_type(mount, TRUE, cancellable, (GAsyncReadyCallback)onContentTypeFinished, this);
}
AutoRunDialog::~AutoRunDialog() {
g_list_foreach(applications, (GFunc)g_object_unref, NULL);
g_list_free(applications);
if(mount_)
g_object_unref(mount_);
if(cancellable) {
g_cancellable_cancel(cancellable);
g_object_unref(cancellable);
}
}
void AutoRunDialog::accept() {
QListWidgetItem* item = ui.listWidget->selectedItems().first();
if(item) {
GFile* gf = g_mount_get_root(mount_);
void* p = item->data(Qt::UserRole).value<void*>();
if(p) { // run the selected application
GAppInfo* app = G_APP_INFO(p);
GList* filelist = g_list_prepend(NULL, gf);
g_app_info_launch(app, filelist, NULL, NULL);
g_list_free(filelist);
}
else {
// the default action, open the mounted folder in the file manager
Application* app = static_cast<Application*>(qApp);
Settings& settings = app->settings();
FmPath* path = fm_path_new_for_gfile(gf);
// open the path in a new window
// FIXME: or should we open it in a new tab? Make this optional later
MainWindow* win = new MainWindow(path);
fm_path_unref(path);
win->resize(settings.windowWidth(), settings.windowHeight());
if(settings.windowMaximized()) {
win->setWindowState(win->windowState() | Qt::WindowMaximized);
}
win->show();
}
g_object_unref(gf);
}
QDialog::accept();
}
// static
void AutoRunDialog::onContentTypeFinished(GMount* mount, GAsyncResult* res, AutoRunDialog* pThis) {
if(pThis->cancellable) {
g_object_unref(pThis->cancellable);
pThis->cancellable = NULL;
}
char** types = g_mount_guess_content_type_finish(mount, res, NULL);
char* desc = NULL;
if(types) {
if(types[0]) {
for(char** type = types; *type; ++type) {
GList* l = g_app_info_get_all_for_type(*type);
if(l)
pThis->applications = g_list_concat(pThis->applications, l);
}
desc = g_content_type_get_description(types[0]);
}
g_strfreev(types);
if(pThis->applications) {
int pos = 0;
for(GList* l = pThis->applications; l; l = l->next, ++pos) {
GAppInfo* app = G_APP_INFO(l->data);
GIcon* gicon = g_app_info_get_icon(app);
QIcon icon = Fm::IconTheme::icon(gicon);
QString text = QString::fromUtf8(g_app_info_get_name(app));
QListWidgetItem* item = new QListWidgetItem(icon, text);
item->setData(Qt::UserRole, qVariantFromValue<void*>(app));
pThis->ui.listWidget->insertItem(pos, item);
}
}
}
if(desc) {
pThis->ui.mediumType->setText(QString::fromUtf8(desc));
g_free(desc);
}
else
pThis->ui.mediumType->setText(tr("Removable Disk"));
// select the first item
pThis->ui.listWidget->item(0)->setSelected(true);
}
} // namespace PCManFM

View File

@ -1,54 +0,0 @@
/*
Copyright (C) 2013 Hong Jen Yee (PCMan) <pcman.tw@gmail.com>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#ifndef PCMANFM_AUTORUNDIALOG_H
#define PCMANFM_AUTORUNDIALOG_H
#include <QDialog>
#include "ui_autorun.h"
#include <gio/gio.h>
namespace PCManFM {
class AutoRunDialog : public QDialog {
Q_OBJECT
public:
explicit AutoRunDialog(GVolume* volume, GMount* mount, QWidget* parent = 0, Qt::WindowFlags f = 0);
virtual ~AutoRunDialog();
virtual void accept();
private Q_SLOTS:
private:
static void onContentTypeFinished(GMount* mount, GAsyncResult* res, AutoRunDialog* pThis);
private:
Ui::AutoRunDialog ui;
GCancellable* cancellable;
GList* applications;
GMount* mount_;
};
}
#endif // PCMANFM_AUTORUNDIALOG_H

View File

@ -1,60 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>DesktopFolder</class>
<widget class="QWidget" name="DesktopFolder">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>352</width>
<height>81</height>
</rect>
</property>
<property name="windowTitle">
<string>Form</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<widget class="QGroupBox" name="groupBox_3">
<property name="enabled">
<bool>true</bool>
</property>
<property name="title">
<string>Desktop</string>
</property>
<layout class="QHBoxLayout" name="horizontalLayout_4">
<item>
<widget class="QLabel" name="label_7">
<property name="text">
<string>Desktop folder:</string>
</property>
</widget>
</item>
<item>
<widget class="QLineEdit" name="desktopFolder">
<property name="toolTip">
<string>Image file</string>
</property>
<property name="statusTip">
<string/>
</property>
<property name="placeholderText">
<string>Folder path</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="browseDesktopFolder">
<property name="text">
<string>&amp;Browse</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
</layout>
</widget>
<resources/>
<connections/>
</ui>

View File

@ -1,391 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>DesktopPreferencesDialog</class>
<widget class="QDialog" name="DesktopPreferencesDialog">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>534</width>
<height>434</height>
</rect>
</property>
<property name="windowTitle">
<string>Desktop Preferences</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<widget class="QTabWidget" name="tabWidget">
<property name="currentIndex">
<number>0</number>
</property>
<widget class="QWidget" name="generalPage">
<attribute name="title">
<string>General</string>
</attribute>
<layout class="QVBoxLayout" name="verticalLayout_2">
<item>
<widget class="QGroupBox" name="groupBox_2">
<property name="title">
<string>Background</string>
</property>
<layout class="QGridLayout" name="gridLayout">
<item row="2" column="1" colspan="2">
<widget class="QComboBox" name="wallpaperMode">
<property name="sizePolicy">
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
</widget>
</item>
<item row="2" column="0">
<widget class="QLabel" name="label">
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>Wallpaper mode:</string>
</property>
</widget>
</item>
<item row="3" column="0">
<widget class="QLabel" name="label_6">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>Wallpaper image file:</string>
</property>
</widget>
</item>
<item row="5" column="1">
<widget class="Fm::ColorButton" name="backgroundColor">
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string/>
</property>
</widget>
</item>
<item row="5" column="0">
<widget class="QLabel" name="label_5">
<property name="text">
<string>Select background color:</string>
</property>
</widget>
</item>
<item row="4" column="0" colspan="3">
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<widget class="QLineEdit" name="imageFile">
<property name="toolTip">
<string>Image file</string>
</property>
<property name="statusTip">
<string/>
</property>
<property name="placeholderText">
<string>Image file path</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="browse">
<property name="text">
<string>&amp;Browse</string>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QGroupBox" name="groupBox">
<property name="title">
<string>Label Text</string>
</property>
<layout class="QGridLayout" name="gridLayout_2">
<item row="1" column="1">
<widget class="Fm::ColorButton" name="textColor">
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string/>
</property>
</widget>
</item>
<item row="3" column="1">
<widget class="Fm::ColorButton" name="shadowColor">
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string/>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QLabel" name="label_3">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>Select text color:</string>
</property>
</widget>
</item>
<item row="3" column="0">
<widget class="QLabel" name="label_4">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>Select shadow color:</string>
</property>
</widget>
</item>
<item row="0" column="0">
<widget class="QLabel" name="label_2">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>Select font:</string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="Fm::FontButton" name="font">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string/>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QGroupBox" name="groupBox_3">
<property name="title">
<string>Spacing</string>
</property>
<layout class="QGridLayout" name="gridLayout_3">
<item row="0" column="0">
<widget class="QLabel" name="label_7">
<property name="text">
<string>Minimum item margins:</string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QSpinBox" name="hMargin">
<property name="toolTip">
<string>3 px by default.</string>
</property>
<property name="suffix">
<string> px</string>
</property>
<property name="maximum">
<number>48</number>
</property>
<property name="value">
<number>3</number>
</property>
</widget>
</item>
<item row="0" column="2">
<widget class="QLabel" name="label_8">
<property name="text">
<string>x</string>
</property>
</widget>
</item>
<item row="0" column="3">
<widget class="QSpinBox" name="vMargin">
<property name="toolTip">
<string>1 px by default.
A space is also reserved for 3 lines of text.</string>
</property>
<property name="suffix">
<string> px</string>
</property>
<property name="maximum">
<number>48</number>
</property>
<property name="value">
<number>1</number>
</property>
</widget>
</item>
<item row="0" column="4">
<widget class="QCheckBox" name="lockMargins">
<property name="text">
<string>Lock</string>
</property>
</widget>
</item>
<item row="0" column="5">
<spacer name="horizontalSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>5</height>
</size>
</property>
</spacer>
</item>
</layout>
</widget>
</item>
<item>
<spacer name="verticalSpacer_2">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>10</height>
</size>
</property>
</spacer>
</item>
</layout>
</widget>
<widget class="QWidget" name="advancedPage">
<attribute name="title">
<string>Advanced</string>
</attribute>
<layout class="QVBoxLayout" name="advancedPageLayout">
<item>
<widget class="QGroupBox" name="groupBox_4">
<property name="title">
<string>Window Manager</string>
</property>
<layout class="QHBoxLayout" name="horizontalLayout_3">
<item>
<widget class="QCheckBox" name="showWmMenu">
<property name="text">
<string>Show menus provided by window managers when desktop is clicked</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<spacer name="verticalSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
</size>
</property>
</spacer>
</item>
</layout>
</widget>
</widget>
</item>
<item>
<widget class="QDialogButtonBox" name="buttonBox">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="standardButtons">
<set>QDialogButtonBox::Apply|QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
</property>
</widget>
</item>
</layout>
</widget>
<customwidgets>
<customwidget>
<class>Fm::ColorButton</class>
<extends>QPushButton</extends>
<header location="global">libfm-qt/colorbutton.h</header>
</customwidget>
<customwidget>
<class>Fm::FontButton</class>
<extends>QPushButton</extends>
<header location="global">libfm-qt/fontbutton.h</header>
</customwidget>
</customwidgets>
<resources/>
<connections>
<connection>
<sender>buttonBox</sender>
<signal>accepted()</signal>
<receiver>DesktopPreferencesDialog</receiver>
<slot>accept()</slot>
<hints>
<hint type="sourcelabel">
<x>248</x>
<y>254</y>
</hint>
<hint type="destinationlabel">
<x>157</x>
<y>274</y>
</hint>
</hints>
</connection>
<connection>
<sender>buttonBox</sender>
<signal>rejected()</signal>
<receiver>DesktopPreferencesDialog</receiver>
<slot>reject()</slot>
<hints>
<hint type="sourcelabel">
<x>316</x>
<y>260</y>
</hint>
<hint type="destinationlabel">
<x>286</x>
<y>274</y>
</hint>
</hints>
</connection>
</connections>
</ui>

View File

@ -1,206 +0,0 @@
/*
Copyright (C) 2013 Hong Jen Yee (PCMan) <pcman.tw@gmail.com>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#include "desktopitemdelegate.h"
#include <libfm-qt/foldermodel.h>
#include <QApplication>
#include <QListView>
#include <QPainter>
#include <QIcon>
#include <QTextLayout>
#include <QTextOption>
#include <QTextLine>
namespace PCManFM {
DesktopItemDelegate::DesktopItemDelegate(QListView* view, QObject* parent):
QStyledItemDelegate(parent ? parent : view),
view_(view),
symlinkIcon_(QIcon::fromTheme("emblem-symbolic-link")),
shadowColor_(0, 0, 0),
margins_(QSize(3, 3)) {
}
// FIXME: we need to figure out a way to derive from Fm::FolderItemDelegate to avoid code duplication.
void DesktopItemDelegate::paint(QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index) const {
Q_ASSERT(index.isValid());
QStyleOptionViewItemV4 opt = option;
initStyleOption(&opt, index);
painter->save();
painter->setClipRect(option.rect);
opt.decorationAlignment = Qt::AlignHCenter | Qt::AlignTop;
opt.displayAlignment = Qt::AlignTop | Qt::AlignHCenter;
// draw the icon
QIcon::Mode iconMode;
if(opt.state & QStyle::State_Enabled) {
if(opt.state & QStyle::State_Selected)
iconMode = QIcon::Selected;
else {
iconMode = QIcon::Normal;
}
}
else
iconMode = QIcon::Disabled;
QPoint iconPos(opt.rect.x() + (opt.rect.width() - opt.decorationSize.width()) / 2, opt.rect.y());
QPixmap pixmap = opt.icon.pixmap(opt.decorationSize, iconMode);
painter->drawPixmap(iconPos, pixmap);
// draw some emblems for the item if needed
// we only support symlink emblem at the moment
FmFileInfo* file = static_cast<FmFileInfo*>(index.data(Fm::FolderModel::FileInfoRole).value<void*>());
if(file) {
if(fm_file_info_is_symlink(file)) {
painter->drawPixmap(iconPos, symlinkIcon_.pixmap(opt.decorationSize / 2, iconMode));
}
}
// draw text
QSize gridSize = view_->gridSize() - 2 * margins_;
QRectF textRect(opt.rect.x() - (gridSize.width() - opt.rect.width()) / 2,
opt.rect.y() + opt.decorationSize.height(),
gridSize.width(),
gridSize.height() - opt.decorationSize.height());
drawText(painter, opt, textRect);
if(opt.state & QStyle::State_HasFocus) {
// FIXME: draw focus rect
}
painter->restore();
}
void DesktopItemDelegate::drawText(QPainter* painter, QStyleOptionViewItemV4& opt, QRectF& textRect) const {
QTextLayout layout(opt.text, opt.font);
QTextOption textOption;
textOption.setAlignment(opt.displayAlignment);
textOption.setWrapMode(QTextOption::WrapAtWordBoundaryOrAnywhere);
textOption.setTextDirection(opt.direction);
layout.setTextOption(textOption);
qreal height = 0;
qreal width = 0;
int visibleLines = 0;
layout.beginLayout();
QString elidedText;
textRect.adjust(2, 2, -2, -2); // a 2-px margin is considered at FolderView::updateGridSize()
for(;;) {
QTextLine line = layout.createLine();
if(!line.isValid())
break;
line.setLineWidth(textRect.width());
height += opt.fontMetrics.leading();
line.setPosition(QPointF(0, height));
if((height + line.height() + textRect.y()) > textRect.bottom()) {
// if part of this line falls outside the textRect, ignore it and quit.
QTextLine lastLine = layout.lineAt(visibleLines - 1);
elidedText = opt.text.mid(lastLine.textStart());
elidedText = opt.fontMetrics.elidedText(elidedText, opt.textElideMode, textRect.width());
break;
}
height += line.height();
width = qMax(width, line.naturalTextWidth());
++ visibleLines;
}
layout.endLayout();
width = qMax(width, (qreal)opt.fontMetrics.width(elidedText));
QRectF boundRect = layout.boundingRect();
boundRect.setWidth(width);
boundRect.setHeight(height);
boundRect.moveTo(textRect.x() + (textRect.width() - width)/2, textRect.y());
QRectF selRect = boundRect.adjusted(-2, -2, 2, 2);
if(!painter) { // no painter, calculate the bounding rect only
textRect = selRect;
return;
}
if (opt.state & QStyle::State_Selected || opt.state & QStyle::State_MouseOver) {
if (const QWidget* widget = opt.widget) { // let the style engine do it
QStyle* style = widget->style() ? widget->style() : qApp->style();
QStyleOptionViewItemV4 o(opt);
o.text = QString();
o.rect = selRect.toAlignedRect().intersected(opt.rect); // due to clipping and rounding, we might lose 1px
o.showDecorationSelected = true;
style->drawPrimitive(QStyle::PE_PanelItemViewItem, &o, painter, widget);
}
}
if((opt.state & QStyle::State_Selected)) {
// qDebug("w: %f, h:%f, m:%f", boundRect.width(), boundRect.height(), layout.minimumWidth());
if(!opt.widget)
painter->fillRect(selRect, opt.palette.highlight());
painter->setPen(opt.palette.color(QPalette::Normal, QPalette::HighlightedText));
}
else { // only draw shadow for non-selected items
// draw shadow, FIXME: is it possible to use QGraphicsDropShadowEffect here?
QPen prevPen = painter->pen();
painter->setPen(QPen(shadowColor_));
for(int i = 0; i < visibleLines; ++i) {
QTextLine line = layout.lineAt(i);
if(i == (visibleLines - 1) && !elidedText.isEmpty()) { // the last line, draw elided text
QPointF pos(boundRect.x() + line.position().x() + 1, boundRect.y() + line.y() + line.ascent() + 1);
painter->drawText(pos, elidedText);
}
else {
line.draw(painter, textRect.topLeft() + QPointF(1, 1));
}
}
painter->setPen(prevPen);
}
// draw text
for(int i = 0; i < visibleLines; ++i) {
QTextLine line = layout.lineAt(i);
if(i == (visibleLines - 1) && !elidedText.isEmpty()) { // the last line, draw elided text
QPointF pos(boundRect.x() + line.position().x(), boundRect.y() + line.y() + line.ascent());
painter->drawText(pos, elidedText);
}
else {
line.draw(painter, textRect.topLeft());
}
}
}
QSize DesktopItemDelegate::sizeHint(const QStyleOptionViewItem& option, const QModelIndex& index) const {
QVariant value = index.data(Qt::SizeHintRole);
if(value.isValid())
return qvariant_cast<QSize>(value);
QStyleOptionViewItemV4 opt = option;
initStyleOption(&opt, index);
opt.decorationAlignment = Qt::AlignHCenter|Qt::AlignTop;
opt.displayAlignment = Qt::AlignTop|Qt::AlignHCenter;
QSize gridSize = view_->gridSize() - 2 * margins_;
Q_ASSERT(gridSize != QSize());
QRectF textRect(0, 0, gridSize.width(), gridSize.height() - opt.decorationSize.height());
drawText(NULL, opt, textRect); // passing NULL for painter will calculate the bounding rect only.
int width = qMax((int)textRect.width(), opt.decorationSize.width());
int height = opt.decorationSize.height() + textRect.height();
return QSize(width, height);
}
DesktopItemDelegate::~DesktopItemDelegate() {
}
} // namespace PCManFM

View File

@ -1,64 +0,0 @@
/*
Copyright (C) 2013 Hong Jen Yee (PCMan) <pcman.tw@gmail.com>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#ifndef PCMANFM_DESKTOPITEMDELEGATE_H
#define PCMANFM_DESKTOPITEMDELEGATE_H
#include <QStyledItemDelegate>
#include <QColor>
class QListView;
class QTextOption;
class QTextLayout;
namespace PCManFM {
class DesktopItemDelegate : public QStyledItemDelegate
{
Q_OBJECT
public:
explicit DesktopItemDelegate(QListView* view, QObject* parent = 0);
virtual void paint(QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index) const;
virtual QSize sizeHint(const QStyleOptionViewItem& option, const QModelIndex& index) const;
virtual ~DesktopItemDelegate();
void setShadowColor(const QColor& shadowColor) {
shadowColor_ = shadowColor;
}
const QColor& shadowColor() const {
return shadowColor_;
}
void setMargins(QSize margins) {
margins_ = margins.expandedTo(QSize(0, 0));
}
private:
void drawText(QPainter* painter, QStyleOptionViewItemV4& opt, QRectF& textRect) const;
private:
QListView* view_;
QIcon symlinkIcon_;
QColor shadowColor_;
QSize margins_;
};
}
#endif // PCMANFM_DESKTOPITEMDELEGATE_H

View File

@ -1,216 +0,0 @@
/*
Copyright (C) 2013 Hong Jen Yee (PCMan) <pcman.tw@gmail.com>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#include "desktoppreferencesdialog.h"
#include "desktopwindow.h"
#include "settings.h"
#include "application.h"
#include "xdgdir.h"
#include <QFileDialog>
#include <QImageReader>
#include <QFile>
#include <QDir>
#include <QSaveFile>
#include <QRegExp>
#include <QDebug>
#include <QStandardPaths>
namespace PCManFM {
DesktopPreferencesDialog::DesktopPreferencesDialog(QWidget* parent, Qt::WindowFlags f):
QDialog(parent, f),
editDesktopFolderEnabled(false),
desktopFolderWidget(0),
desktopFolder() {
setAttribute(Qt::WA_DeleteOnClose);
Settings& settings = static_cast<Application*>(qApp)->settings();
ui.setupUi(this);
// setup wallpaper modes
connect(ui.wallpaperMode, static_cast<void (QComboBox::*)(int)>(&QComboBox::currentIndexChanged), this, &DesktopPreferencesDialog::onWallpaperModeChanged);
ui.wallpaperMode->addItem(tr("Fill with background color only"), DesktopWindow::WallpaperNone);
ui.wallpaperMode->addItem(tr("Stretch to fill the entire screen"), DesktopWindow::WallpaperStretch);
ui.wallpaperMode->addItem(tr("Stretch to fit the screen"), DesktopWindow::WallpaperFit);
ui.wallpaperMode->addItem(tr("Center on the screen"), DesktopWindow::WallpaperCenter);
ui.wallpaperMode->addItem(tr("Tile the image to fill the entire screen"), DesktopWindow::WallpaperTile);
int i;
switch(settings.wallpaperMode()) {
case DesktopWindow::WallpaperNone:
i = 0;
break;
case DesktopWindow::WallpaperStretch:
i = 1;
break;
case DesktopWindow::WallpaperFit:
i = 2;
break;
case DesktopWindow::WallpaperCenter:
i = 3;
break;
case DesktopWindow::WallpaperTile:
i = 4;
break;
default:
i = 0;
}
ui.wallpaperMode->setCurrentIndex(i);
connect(ui.browse, &QPushButton::clicked, this, &DesktopPreferencesDialog::onBrowseClicked);
qDebug("wallpaper: %s", settings.wallpaper().toUtf8().data());
ui.imageFile->setText(settings.wallpaper());
ui.font->setFont(settings.desktopFont());
ui.backgroundColor->setColor(settings.desktopBgColor());
ui.textColor->setColor(settings.desktopFgColor());
ui.shadowColor->setColor(settings.desktopShadowColor());
ui.showWmMenu->setChecked(settings.showWmMenu());
connect(ui.buttonBox->button(QDialogButtonBox::Apply), &QPushButton::clicked,
this, &DesktopPreferencesDialog::onApplyClicked);
ui.hMargin->setValue(settings.desktopCellMargins().width());
ui.vMargin->setValue(settings.desktopCellMargins().height());
connect(ui.lockMargins, &QAbstractButton::clicked, this, &DesktopPreferencesDialog::lockMargins);
}
DesktopPreferencesDialog::~DesktopPreferencesDialog() {
}
void DesktopPreferencesDialog::setupDesktopFolderUi()
{
desktopFolderWidget = new QWidget();
uiDesktopFolder.setupUi(desktopFolderWidget);
ui.advancedPageLayout->insertWidget(1, desktopFolderWidget);
uiDesktopFolder.verticalLayout->setMargin(0);
desktopFolder = XdgDir::readDesktopDir();
qDebug("desktop folder: %s", desktopFolder.toStdString().c_str());
uiDesktopFolder.desktopFolder->setText(desktopFolder);
connect(uiDesktopFolder.browseDesktopFolder, &QPushButton::clicked,
this, &DesktopPreferencesDialog::onBrowseDesktopFolderClicked);
}
void DesktopPreferencesDialog::lockMargins(bool lock) {
ui.vMargin->setDisabled(lock);
if(lock) {
ui.vMargin->setValue(ui.hMargin->value());
connect(ui.hMargin, static_cast<void (QSpinBox::*)(int)>(&QSpinBox::valueChanged), ui.vMargin, &QSpinBox::setValue);
}
else
disconnect(ui.hMargin, static_cast<void (QSpinBox::*)(int)>(&QSpinBox::valueChanged), ui.vMargin, &QSpinBox::setValue);
}
void DesktopPreferencesDialog::applySettings()
{
Settings& settings = static_cast<Application*>(qApp)->settings();
if (editDesktopFolderEnabled)
XdgDir::setDesktopDir(uiDesktopFolder.desktopFolder->text());
settings.setWallpaper(ui.imageFile->text());
int mode = ui.wallpaperMode->itemData(ui.wallpaperMode->currentIndex()).toInt();
settings.setWallpaperMode(mode);
settings.setDesktopFont(ui.font->font());
settings.setDesktopBgColor(ui.backgroundColor->color());
settings.setDesktopFgColor(ui.textColor->color());
settings.setDesktopShadowColor(ui.shadowColor->color());
settings.setShowWmMenu(ui.showWmMenu->isChecked());
settings.setDesktopCellMargins(QSize(ui.hMargin->value(), ui.vMargin->value()));
settings.save();
}
void DesktopPreferencesDialog::onApplyClicked()
{
applySettings();
static_cast<Application*>(qApp)->updateDesktopsFromSettings();
}
void DesktopPreferencesDialog::accept() {
applySettings();
static_cast<Application*>(qApp)->updateDesktopsFromSettings();
QDialog::accept();
}
void DesktopPreferencesDialog::onWallpaperModeChanged(int index) {
int mode = ui.wallpaperMode->itemData(index).toInt();
bool enable = (mode != DesktopWindow::WallpaperNone);
ui.imageFile->setEnabled(enable);
ui.browse->setEnabled(enable);
}
void DesktopPreferencesDialog::onBrowseClicked() {
QFileDialog dlg;
dlg.setAcceptMode(QFileDialog::AcceptOpen);
dlg.setFileMode(QFileDialog::ExistingFile);
// compose a name fileter from QImageReader
QString filter;
filter.reserve(256);
filter = tr("Image Files");
filter += " (";
QList<QByteArray> formats = QImageReader::supportedImageFormats();
Q_FOREACH(QByteArray format, formats) {
filter += "*.";
filter += format.toLower();
filter += ' ';
}
filter += ')';
dlg.setNameFilter(filter);
dlg.setNameFilterDetailsVisible(false);
if(dlg.exec() == QDialog::Accepted) {
QString filename;
filename = dlg.selectedFiles().first();
ui.imageFile->setText(filename);
}
}
void DesktopPreferencesDialog::onBrowseDesktopFolderClicked()
{
QFileDialog dlg;
dlg.setAcceptMode(QFileDialog::AcceptOpen);
dlg.setAcceptMode(QFileDialog::AcceptOpen);
dlg.setFileMode(QFileDialog::DirectoryOnly);
if (dlg.exec() == QDialog::Accepted) {
QString dir;
dir = dlg.selectedFiles().first();
uiDesktopFolder.desktopFolder->setText(dir);
}
}
void DesktopPreferencesDialog::selectPage(QString name) {
QWidget* page = findChild<QWidget*>(name + "Page");
if(page)
ui.tabWidget->setCurrentWidget(page);
}
void DesktopPreferencesDialog::setEditDesktopFolder(const bool enabled)
{
editDesktopFolderEnabled = enabled;
if (editDesktopFolderEnabled)
setupDesktopFolderUi();
}
} // namespace PCManFM

View File

@ -1,67 +0,0 @@
/*
Copyright (C) 2013 Hong Jen Yee (PCMan) <pcman.tw@gmail.com>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#ifndef PCMANFM_DESKTOPPREFERENCESDIALOG_H
#define PCMANFM_DESKTOPPREFERENCESDIALOG_H
#include <QDialog>
#include "ui_desktop-preferences.h"
#include "ui_desktop-folder.h"
namespace PCManFM {
class DesktopPreferencesDialog : public QDialog {
Q_OBJECT
public:
explicit DesktopPreferencesDialog(QWidget* parent = 0, Qt::WindowFlags f = 0);
virtual ~DesktopPreferencesDialog();
virtual void accept();
void selectPage(QString name);
// Should only be used one time.
void setEditDesktopFolder(const bool enabled);
protected Q_SLOTS:
void onApplyClicked();
void onWallpaperModeChanged(int index);
void onBrowseClicked();
void onBrowseDesktopFolderClicked();
void lockMargins(bool lock);
void applySettings();
private:
Ui::DesktopPreferencesDialog ui;
Ui::DesktopFolder uiDesktopFolder;
bool editDesktopFolderEnabled;
QWidget* desktopFolderWidget;
QString desktopFolder;
void setupDesktopFolderUi();
};
}
#endif // PCMANFM_DESKTOPPREFERENCESDIALOG_H

View File

@ -1,897 +0,0 @@
/*
Copyright (C) 2013 Hong Jen Yee (PCMan) <pcman.tw@gmail.com>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#include "desktopwindow.h"
#include <QWidget>
#include <QDesktopWidget>
#include <QPainter>
#include <QImage>
#include <QImageReader>
#include <QFile>
#include <QPixmap>
#include <QPalette>
#include <QBrush>
#include <QLayout>
#include <QDebug>
#include <QTimer>
#include <QSettings>
#include <QStringBuilder>
#include <QDir>
#include <QShortcut>
#include <QDropEvent>
#include <QMimeData>
#include "./application.h"
#include "mainwindow.h"
#include "desktopitemdelegate.h"
#include <libfm-qt/foldermenu.h>
#include <libfm-qt/filemenu.h>
#include <libfm-qt/cachedfoldermodel.h>
#include <libfm-qt/folderview_p.h>
#include <libfm-qt/fileoperation.h>
#include <libfm-qt/filepropsdialog.h>
#include <libfm-qt/utilities.h>
#include <libfm-qt/path.h>
#include "xdgdir.h"
#include <QX11Info>
#include <QScreen>
#include <xcb/xcb.h>
#include <X11/Xlib.h>
namespace PCManFM {
DesktopWindow::DesktopWindow(int screenNum):
View(Fm::FolderView::IconMode),
screenNum_(screenNum),
folder_(NULL),
model_(NULL),
proxyModel_(NULL),
fileLauncher_(NULL),
showWmMenu_(false),
wallpaperMode_(WallpaperNone),
relayoutTimer_(NULL) {
QDesktopWidget* desktopWidget = QApplication::desktop();
setWindowFlags(Qt::Window | Qt::FramelessWindowHint);
setAttribute(Qt::WA_X11NetWmWindowTypeDesktop);
setAttribute(Qt::WA_DeleteOnClose);
// set our custom file launcher
View::setFileLauncher(&fileLauncher_);
listView_ = static_cast<Fm::FolderViewListView*>(childView());
listView_->setMovement(QListView::Snap);
listView_->setResizeMode(QListView::Adjust);
listView_->setFlow(QListView::TopToBottom);
// NOTE: When XRnadR is in use, the all screens are actually combined to form a
// large virtual desktop and only one DesktopWindow needs to be created and screenNum is -1.
// In some older multihead setups, such as xinerama, every physical screen
// is treated as a separate desktop so many instances of DesktopWindow may be created.
// In this case we only want to show desktop icons on the primary screen.
if(desktopWidget->isVirtualDesktop() || screenNum_ == desktopWidget->primaryScreen()) {
loadItemPositions();
Settings& settings = static_cast<Application* >(qApp)->settings();
model_ = Fm::CachedFolderModel::modelFromPath(fm_path_get_desktop());
folder_ = reinterpret_cast<FmFolder*>(g_object_ref(model_->folder()));
proxyModel_ = new Fm::ProxyFolderModel();
proxyModel_->setSourceModel(model_);
proxyModel_->setShowThumbnails(settings.showThumbnails());
proxyModel_->sort(Fm::FolderModel::ColumnFileMTime);
setModel(proxyModel_);
connect(proxyModel_, &Fm::ProxyFolderModel::rowsInserted, this, &DesktopWindow::onRowsInserted);
connect(proxyModel_, &Fm::ProxyFolderModel::rowsAboutToBeRemoved, this, &DesktopWindow::onRowsAboutToBeRemoved);
connect(proxyModel_, &Fm::ProxyFolderModel::layoutChanged, this, &DesktopWindow::onLayoutChanged);
connect(listView_, &QListView::indexesMoved, this, &DesktopWindow::onIndexesMoved);
}
// set our own delegate
delegate_ = new DesktopItemDelegate(listView_);
listView_->setItemDelegateForColumn(Fm::FolderModel::ColumnFileName, delegate_);
// remove frame
listView_->setFrameShape(QFrame::NoFrame);
// inhibit scrollbars FIXME: this should be optional in the future
listView_->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
listView_->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
connect(this, &DesktopWindow::openDirRequested, this, &DesktopWindow::onOpenDirRequested);
listView_->installEventFilter(this);
// setup shortcuts
QShortcut* shortcut;
shortcut = new QShortcut(QKeySequence(Qt::CTRL + Qt::Key_X), this); // cut
connect(shortcut, &QShortcut::activated, this, &DesktopWindow::onCutActivated);
shortcut = new QShortcut(QKeySequence(Qt::CTRL + Qt::Key_C), this); // copy
connect(shortcut, &QShortcut::activated, this, &DesktopWindow::onCopyActivated);
shortcut = new QShortcut(QKeySequence(Qt::CTRL + Qt::Key_V), this); // paste
connect(shortcut, &QShortcut::activated, this, &DesktopWindow::onPasteActivated);
shortcut = new QShortcut(QKeySequence(Qt::CTRL + Qt::Key_A), this); // select all
connect(shortcut, &QShortcut::activated, listView_, &QListView::selectAll);
shortcut = new QShortcut(QKeySequence(Qt::Key_Delete), this); // delete
connect(shortcut, &QShortcut::activated, this, &DesktopWindow::onDeleteActivated);
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
connect(shortcut, &QShortcut::activated, this, &DesktopWindow::onFilePropertiesActivated);
shortcut = new QShortcut(QKeySequence(Qt::SHIFT + Qt::Key_Delete), this); // force delete
connect(shortcut, &QShortcut::activated, this, &DesktopWindow::onDeleteActivated);
}
DesktopWindow::~DesktopWindow() {
listView_->removeEventFilter(this);
if(relayoutTimer_)
delete relayoutTimer_;
if(proxyModel_)
delete proxyModel_;
if(model_)
model_->unref();
if(folder_)
g_object_unref(folder_);
}
void DesktopWindow::setBackground(const QColor& color) {
bgColor_ = color;
}
void DesktopWindow::setForeground(const QColor& color) {
QPalette p = listView_->palette();
p.setBrush(QPalette::Text, color);
listView_->setPalette(p);
fgColor_ = color;
}
void DesktopWindow::setShadow(const QColor& color) {
shadowColor_ = color;
delegate_->setShadowColor(color);
}
void DesktopWindow::onOpenDirRequested(FmPath* path, int target) {
// open in new window unconditionally.
Application* app = static_cast<Application*>(qApp);
MainWindow* newWin = new MainWindow(path);
// apply window size from app->settings
newWin->resize(app->settings().windowWidth(), app->settings().windowHeight());
newWin->show();
}
void DesktopWindow::resizeEvent(QResizeEvent* event) {
QWidget::resizeEvent(event);
// resize wall paper if needed
if(isVisible() && wallpaperMode_ != WallpaperNone && wallpaperMode_ != WallpaperTile) {
updateWallpaper();
update();
}
queueRelayout(100); // Qt use a 100 msec delay for relayout internally so we use it, too.
}
void DesktopWindow::setDesktopFolder() {
FmPath *path = fm_path_new_for_path(XdgDir::readDesktopDir().toStdString().c_str());
model_ = Fm::CachedFolderModel::modelFromPath(path);
proxyModel_->setSourceModel(model_);
}
void DesktopWindow::setWallpaperFile(QString filename) {
wallpaperFile_ = filename;
}
void DesktopWindow::setWallpaperMode(WallpaperMode mode) {
wallpaperMode_ = mode;
}
QImage DesktopWindow::loadWallpaperFile(QSize requiredSize) {
// NOTE: for ease of programming, we only use the cache for the primary screen.
bool useCache = (screenNum_ == -1 || screenNum_ == 0);
QFile info;
QString cacheFileName;
if(useCache) {
// see if we have a scaled version cached on disk
cacheFileName = QString::fromLocal8Bit(qgetenv("XDG_CACHE_HOME"));
if(cacheFileName.isEmpty())
cacheFileName = QDir::homePath() % QLatin1String("/.cache");
Application* app = static_cast<Application*>(qApp);
cacheFileName += QLatin1String("/pcmanfm-qt/") % app->profileName();
QDir().mkpath(cacheFileName); // ensure that the cache dir exists
cacheFileName += QLatin1String("/wallpaper.cache");
// read info file
QString origin;
info.setFileName(cacheFileName % ".info");
if(info.open(QIODevice::ReadOnly)) {
// FIXME: we need to compare mtime to see if the cache is out of date
origin = QString::fromLocal8Bit(info.readLine());
info.close();
if(!origin.isEmpty()) {
// try to see if we can get the size of the cached image.
QImageReader reader(cacheFileName);
reader.setAutoDetectImageFormat(true);
QSize cachedSize = reader.size();
qDebug() << "size of cached file" << cachedSize << ", requiredSize:" << requiredSize;
if(cachedSize.isValid()) {
if(cachedSize == requiredSize) { // see if the cached wallpaper has the size we want
QImage image = reader.read(); // return the loaded image
qDebug() << "origin" << origin;
if(origin == wallpaperFile_)
return image;
}
}
}
}
qDebug() << "no cached wallpaper. generate a new one!";
}
// we don't have a cached scaled image, load the original file
QImage image(wallpaperFile_);
qDebug() << "size of original image" << image.size();
if(image.isNull() || image.size() == requiredSize) // if the original size is what we want
return image;
// scale the original image
QImage scaled = image.scaled(requiredSize.width(), requiredSize.height(), Qt::IgnoreAspectRatio, Qt::SmoothTransformation);
// FIXME: should we save the scaled image if its size is larger than the original image?
if(useCache) {
// write the path of the original image to the .info file
if(info.open(QIODevice::WriteOnly)) {
info.write(wallpaperFile_.toLocal8Bit());
info.close();
// write the scaled cache image to disk
const char* format; // we keep jpg format for *.jpg files, and use png format for others.
if(wallpaperFile_.endsWith(QLatin1String(".jpg"), Qt::CaseInsensitive) || wallpaperFile_.endsWith(QLatin1String(".jpeg"), Qt::CaseInsensitive))
format = "JPG";
else
format = "PNG";
scaled.save(cacheFileName, format);
}
qDebug() << "wallpaper cached saved to " << cacheFileName;
// FIXME: we might delay the write of the cached image?
}
return scaled;
}
// really generate the background pixmap according to current settings and apply it.
void DesktopWindow::updateWallpaper() {
// reset the brush
// QPalette palette(listView_->palette());
QPalette palette(Fm::FolderView::palette());
if(wallpaperMode_ == WallpaperNone) { // use background color only
palette.setBrush(QPalette::Base, bgColor_);
}
else { // use wallpaper
QPixmap pixmap;
QImage image;
if(wallpaperMode_ == WallpaperTile) { // use the original size
image = QImage(wallpaperFile_);
pixmap = QPixmap::fromImage(image);
}
else if(wallpaperMode_ == WallpaperStretch) {
image = loadWallpaperFile(size());
pixmap = QPixmap::fromImage(image);
}
else { // WallpaperCenter || WallpaperFit
if(wallpaperMode_ == WallpaperCenter) {
image = QImage(wallpaperFile_); // load original image
}
else if(wallpaperMode_ == WallpaperFit) {
// calculate the desired size
QSize origSize = QImageReader(wallpaperFile_).size(); // get the size of the original file
if(origSize.isValid()) {
QSize desiredSize = origSize;
desiredSize.scale(width(), height(), Qt::KeepAspectRatio);
image = loadWallpaperFile(desiredSize); // load the scaled image
}
}
if(!image.isNull()) {
pixmap = QPixmap(size());
QPainter painter(&pixmap);
pixmap.fill(bgColor_);
int x = (width() - image.width()) / 2;
int y = (height() - image.height()) / 2;
painter.drawImage(x, y, image);
}
}
wallpaperPixmap_ = pixmap;
if(!pixmap.isNull()) {
QBrush brush(pixmap);
palette.setBrush(QPalette::Base, brush);
}
else // if the image is not loaded, fallback to use background color only
palette.setBrush(QPalette::Base, bgColor_);
}
//FIXME: we should set the pixmap to X11 root window?
setPalette(palette);
}
void DesktopWindow::updateFromSettings(Settings& settings) {
setDesktopFolder();
setWallpaperFile(settings.wallpaper());
setWallpaperMode(settings.wallpaperMode());
setFont(settings.desktopFont());
setIconSize(Fm::FolderView::IconMode, QSize(settings.bigIconSize(), settings.bigIconSize()));
setMargins(settings.desktopCellMargins());
// setIconSize and setMargins may trigger relayout of items by QListView, so we need to do the layout again.
queueRelayout();
setForeground(settings.desktopFgColor());
setBackground(settings.desktopBgColor());
setShadow(settings.desktopShadowColor());
showWmMenu_ = settings.showWmMenu();
updateWallpaper();
update();
}
void DesktopWindow::onFileClicked(int type, FmFileInfo* fileInfo) {
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);
}
void DesktopWindow::prepareFileMenu(Fm::FileMenu* menu) {
// qDebug("DesktopWindow::prepareFileMenu");
PCManFM::View::prepareFileMenu(menu);
QAction* action = new QAction(tr("Stic&k to Current Position"), menu);
action->setCheckable(true);
menu->insertSeparator(menu->separator2());
menu->insertAction(menu->separator2(), action);
FmFileInfoList* files = menu->files();
// select exactly one item
if(fm_file_info_list_get_length(files) == 1) {
FmFileInfo* file = menu->firstFile();
if(customItemPos_.find(fm_file_info_get_name(file)) != customItemPos_.end()) {
// the file item has a custom position
action->setChecked(true);
}
}
connect(action, &QAction::toggled, this, &DesktopWindow::onStickToCurrentPos);
}
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"));
connect(action, &QAction::triggered, this, &DesktopWindow::onDesktopPreferences);
}
void DesktopWindow::onDesktopPreferences() {
static_cast<Application* >(qApp)->desktopPrefrences(QString());
}
void DesktopWindow::onRowsInserted(const QModelIndex& parent, int start, int end) {
queueRelayout();
}
void DesktopWindow::onRowsAboutToBeRemoved(const QModelIndex& parent, int start, int end) {
Q_UNUSED(parent);
Q_UNUSED(start);
Q_UNUSED(end);
if(!customItemPos_.isEmpty()) {
// also delete stored custom item positions for the items currently being removed.
// Here we can't rely on ProxyFolderModel::fileInfoFromIndex() because, although rows
// aren't removed yet, files are already removed.
QHash<QByteArray, QPoint> _customItemPos = customItemPos_;
char* dektopPath = fm_path_to_str(fm_path_get_desktop());
QString desktopDir = QString(dektopPath) + QString("/");
g_free(dektopPath);
QHash<QByteArray, QPoint>::iterator it;
for(it = _customItemPos.begin(); it != _customItemPos.end(); ++it) {
const QByteArray& name = it.key();
if(!QFile::exists(desktopDir + QString::fromUtf8(name, name.length())))
customItemPos_.remove(it.key());
}
if(customItemPos_ != _customItemPos)
saveItemPositions();
}
queueRelayout();
}
void DesktopWindow::onLayoutChanged() {
queueRelayout();
}
void DesktopWindow::onIndexesMoved(const QModelIndexList& indexes) {
// remember the custom position for the items
Q_FOREACH(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.
// Since we only care about rows, not individual cells,
// let's handle column 0 of every row here.
if(index.column() == 0) {
FmFileInfo* file = proxyModel_->fileInfoFromIndex(index);
QRect itemRect = listView_->rectForIndex(index);
QPoint tl = itemRect.topLeft();
QRect workArea = qApp->desktop()->availableGeometry(screenNum_);
workArea.adjust(12, 12, -12, -12);
if(customItemPos_.keys(tl).isEmpty() // don't put items on each other
&& tl.x() >= workArea.x() && tl.y() >= workArea.y()
&& tl.x() + listView_->gridSize().width() <= workArea.right() + 1 // for historical reasons (-> Qt doc)
&& tl.y() + listView_->gridSize().height() <= workArea.bottom() + 1) { // as above
QByteArray name = fm_file_info_get_name(file);
customItemPos_[name] = tl;
// qDebug() << "indexMoved:" << name << index << itemRect;
}
}
}
saveItemPositions();
queueRelayout();
}
void DesktopWindow::removeBottomGap() {
/************************************************************
NOTE: Desktop is an area bounded from below while icons snap
to its grid srarting from above. Therefore, we try to adjust
the vertical cell margin to prevent relatively large gaps
from taking shape at the desktop bottom.
************************************************************/
QSize cellMargins = getMargins();
int workAreaHeight = qApp->desktop()->availableGeometry(screenNum_).height()
- 24; // a 12-pix margin will be considered everywhere
int cellHeight = listView_->gridSize().height() + listView_->spacing();
int iconNumber = workAreaHeight / cellHeight;
int bottomGap = workAreaHeight % cellHeight;
/*******************************************
First try to make room for an extra icon...
*******************************************/
// If one pixel is subtracted from the vertical margin, cellHeight
// will decrease by 2 while bottomGap will increase by 2*iconNumber.
// So, we can add an icon to the bottom once this inequality holds:
// bottomGap + 2*n*iconNumber >= cellHeight - 2*n
// From here, we get our "subtrahend":
qreal exactNumber = ((qreal)cellHeight - (qreal)bottomGap)
/ (2.0 * (qreal)iconNumber + 2.0);
int subtrahend = (int)exactNumber + ((int)exactNumber == exactNumber ? 0 : 1);
Settings& settings = static_cast<Application*>(qApp)->settings();
int minCellHeight = settings.desktopCellMargins().height();
if(subtrahend > 0
&& cellMargins.height() - subtrahend >= minCellHeight) {
cellMargins -= QSize(0, subtrahend);
}
/***************************************************
... but if that can't be done, try to spread icons!
***************************************************/
else
cellMargins += QSize(0, (bottomGap / iconNumber) / 2);
// set the new margins (if they're changed)
delegate_->setMargins(cellMargins);
setMargins(cellMargins);
// in case the text shadow is reset to (0,0,0,0)
setShadow(settings.desktopShadowColor());
}
// QListView does item layout in a very inflexible way, so let's do our custom layout again.
// FIXME: this is very inefficient, but due to the design flaw of QListView, this is currently the only workaround.
void DesktopWindow::relayoutItems() {
loadItemPositions(); // something may have changed
// qDebug("relayoutItems()");
if(relayoutTimer_) {
// this slot might be called from the timer, so we cannot delete it directly here.
relayoutTimer_->deleteLater();
relayoutTimer_ = NULL;
}
QDesktopWidget* desktop = qApp->desktop();
int screen = 0;
int row = 0;
int rowCount = proxyModel_->rowCount();
for(;;) {
if(desktop->isVirtualDesktop()) {
if(screen >= desktop->numScreens())
break;
}else {
screen = screenNum_;
}
QRect workArea = desktop->availableGeometry(screen);
workArea.adjust(12, 12, -12, -12); // add a 12 pixel margin to the work area
// qDebug() << "workArea" << screen << workArea;
// FIXME: we use an internal class declared in a private header here, which is pretty bad.
QSize grid = listView_->gridSize();
QPoint pos = workArea.topLeft();
for(; row < rowCount; ++row) {
QModelIndex index = proxyModel_->index(row, 0);
int itemWidth = delegate_->sizeHint(listView_->getViewOptions(), index).width();
FmFileInfo* file = proxyModel_->fileInfoFromIndex(index);
QByteArray name = fm_file_info_get_name(file);
QHash<QByteArray, QPoint>::iterator it = customItemPos_.find(name);
if(it != customItemPos_.end()) { // the item has a custom position
QPoint customPos = *it;
// center the contents vertically
listView_->setPositionForIndex(customPos + QPoint((grid.width() - itemWidth) / 2, 0), index);
// qDebug() << "set custom pos:" << name << row << index << customPos;
continue;
}
// check if the current pos is alredy occupied by a custom item
bool used = false;
for(it = customItemPos_.begin(); it != customItemPos_.end(); ++it) {
QPoint customPos = *it;
if(QRect(customPos, grid).contains(pos)) {
used = true;
break;
}
}
if(used) { // go to next pos
--row;
}
else {
// center the contents vertically
listView_->setPositionForIndex(pos + QPoint((grid.width() - itemWidth) / 2, 0), index);
// qDebug() << "set pos" << name << row << index << pos;
}
// move to next cell in the column
pos.setY(pos.y() + grid.height() + listView_->spacing());
if(pos.y() + grid.height() > workArea.bottom() + 1) {
// if the next position may exceed the bottom of work area, go to the top of next column
pos.setX(pos.x() + grid.width() + listView_->spacing());
pos.setY(workArea.top());
// check if the new column exceeds the right margin of work area
if(pos.x() + grid.width() > workArea.right() + 1) {
if(desktop->isVirtualDesktop()) {
// in virtual desktop mode, go to next screen
++screen;
break;
}
}
}
}
if(row >= rowCount)
break;
}
}
void DesktopWindow::loadItemPositions() {
// load custom item positions
customItemPos_.clear();
Settings& settings = static_cast<Application*>(qApp)->settings();
QString configFile = QString("%1/desktop-items-%2.conf").arg(settings.profileDir(settings.profileName())).arg(screenNum_);
QSettings file(configFile, QSettings::IniFormat);
QSize grid = listView_->gridSize();
QRect workArea = qApp->desktop()->availableGeometry(screenNum_);
workArea.adjust(12, 12, -12, -12);
char* dektopPath = fm_path_to_str(fm_path_get_desktop());
QString desktopDir = QString(dektopPath) + QString("/");
g_free(dektopPath);
Q_FOREACH(const QString& name, file.childGroups()) {
if(!QFile::exists(desktopDir + name.toUtf8())) {
// the file may have been removed from outside LXQT
continue;
}
file.beginGroup(name);
QVariant var = file.value("pos");
if(var.isValid()) {
QPoint customPos = var.toPoint();
if (customPos.x() >= workArea.x() && customPos.y() >= workArea.y()
&& customPos.x() + listView_->gridSize().width() <= workArea.right() + 1
&& customPos.y() + listView_->gridSize().height() <= workArea.bottom() + 1)
{
// correct positions that are't aligned to the grid
qreal w = qAbs((qreal)customPos.x() - (qreal)workArea.x())
/ (qreal)(grid.width() + listView_->spacing());
qreal h = qAbs(customPos.y() - (qreal)workArea.y())
/ (qreal)(grid.height() + listView_->spacing());
customPos.setX(workArea.x() + qRound(w) * (grid.width() + listView_->spacing()));
customPos.setY(workArea.y() + qRound(h) * (grid.height() + listView_->spacing()));
while(customItemPos_.values().contains(customPos)) {
customPos.setY(customPos.y() + grid.height() + listView_->spacing());
if(customPos.y() + grid.height() > workArea.bottom() + 1) {
customPos.setX(customPos.x() + grid.width() + listView_->spacing());
customPos.setY(workArea.top());
}
}
customItemPos_[name.toUtf8()] = customPos;
}
}
file.endGroup();
}
}
void DesktopWindow::saveItemPositions() {
Settings& settings = static_cast<Application*>(qApp)->settings();
// store custom item positions
QString configFile = QString("%1/desktop-items-%2.conf").arg(settings.profileDir(settings.profileName())).arg(screenNum_);
// FIXME: using QSettings here is inefficient and it's not friendly to UTF-8.
QSettings file(configFile, QSettings::IniFormat);
file.clear(); // remove all existing entries
// FIXME: we have to remove dead entries not associated to any files?
QHash<QByteArray, QPoint>::iterator it;
for(it = customItemPos_.begin(); it != customItemPos_.end(); ++it) {
const QByteArray& name = it.key();
QPoint pos = it.value();
file.beginGroup(QString::fromUtf8(name, name.length()));
file.setValue("pos", pos);
file.endGroup();
}
}
void DesktopWindow::onStickToCurrentPos(bool toggled) {
QAction* action = static_cast<QAction*>(sender());
Fm::FileMenu* menu = static_cast<Fm::FileMenu*>(action->parent());
QModelIndexList indexes = listView_->selectionModel()->selectedIndexes();
if(!indexes.isEmpty()) {
FmFileInfo* file = menu->firstFile();
QByteArray name = fm_file_info_get_name(file);
QModelIndex index = indexes.first();
if(toggled) { // remember to current custom position
QRect itemRect = listView_->rectForIndex(index);
customItemPos_[name] = itemRect.topLeft();
saveItemPositions();
}
else { // cancel custom position and perform relayout
QHash<QByteArray, QPoint>::iterator it = customItemPos_.find(name);
if(it != customItemPos_.end()) {
customItemPos_.erase(it);
saveItemPositions();
relayoutItems();
}
}
}
}
void DesktopWindow::queueRelayout(int delay) {
// qDebug() << "queueRelayout";
removeBottomGap();
if(!relayoutTimer_) {
relayoutTimer_ = new QTimer();
relayoutTimer_->setSingleShot(true);
connect(relayoutTimer_, &QTimer::timeout, this, &DesktopWindow::relayoutItems);
relayoutTimer_->start(delay);
}
}
// slots for file operations
void DesktopWindow::onCutActivated() {
if(FmPathList* paths = selectedFilePaths()) {
Fm::cutFilesToClipboard(paths);
fm_path_list_unref(paths);
}
}
void DesktopWindow::onCopyActivated() {
if(FmPathList* paths = selectedFilePaths()) {
Fm::copyFilesToClipboard(paths);
fm_path_list_unref(paths);
}
}
void DesktopWindow::onPasteActivated() {
Fm::pasteFilesFromClipboard(path());
}
void DesktopWindow::onDeleteActivated() {
if(FmPathList* paths = selectedFilePaths()) {
Settings& settings = static_cast<Application*>(qApp)->settings();
bool shiftPressed = (qApp->keyboardModifiers() & Qt::ShiftModifier ? true : false);
if(settings.useTrash() && !shiftPressed)
Fm::FileOperation::trashFiles(paths, settings.confirmTrash());
else
Fm::FileOperation::deleteFiles(paths, settings.confirmDelete());
fm_path_list_unref(paths);
}
}
void DesktopWindow::onRenameActivated() {
if(FmFileInfoList* files = selectedFiles()) {
for(GList* l = fm_file_info_list_peek_head_link(files); l; l = l->next) {
FmFileInfo* info = FM_FILE_INFO(l->data);
Fm::renameFile(info, NULL);
fm_file_info_list_unref(files);
}
}
}
void DesktopWindow::onFilePropertiesActivated() {
if(FmFileInfoList* files = selectedFiles()) {
Fm::FilePropsDialog::showForFiles(files);
fm_file_info_list_unref(files);
}
}
static void forwardMouseEventToRoot(QMouseEvent* event) {
xcb_ungrab_pointer(QX11Info::connection(), event->timestamp());
// forward the event to the root window
xcb_button_press_event_t xcb_event;
uint32_t mask = 0;
xcb_event.state = 0;
switch(event->type()) {
case QEvent::MouseButtonPress:
xcb_event.response_type = XCB_BUTTON_PRESS;
mask = XCB_EVENT_MASK_BUTTON_PRESS;
break;
case QEvent::MouseButtonRelease:
xcb_event.response_type = XCB_BUTTON_RELEASE;
mask = XCB_EVENT_MASK_BUTTON_RELEASE;
break;
default:
return;
}
// convert Qt button to XCB button
switch(event->button()) {
case Qt::LeftButton:
xcb_event.detail = 1;
xcb_event.state |= XCB_BUTTON_MASK_1;
break;
case Qt::MiddleButton:
xcb_event.detail = 2;
xcb_event.state |= XCB_BUTTON_MASK_2;
break;
case Qt::RightButton:
xcb_event.detail = 3;
xcb_event.state |= XCB_BUTTON_MASK_3;
break;
default:
xcb_event.detail = 0;
}
// convert Qt modifiers to XCB states
if(event->modifiers() & Qt::ShiftModifier)
xcb_event.state |= XCB_MOD_MASK_SHIFT;
if(event->modifiers() & Qt::ControlModifier)
xcb_event.state |= XCB_MOD_MASK_SHIFT;
if(event->modifiers() & Qt::AltModifier)
xcb_event.state |= XCB_MOD_MASK_1;
xcb_event.sequence = 0;
xcb_event.time = event->timestamp();
WId root = QX11Info::appRootWindow(QX11Info::appScreen());
xcb_event.event = root;
xcb_event.root = root;
xcb_event.child = 0;
xcb_event.root_x = event->globalX();
xcb_event.root_y = event->globalY();
xcb_event.event_x = event->x();
xcb_event.event_y = event->y();
xcb_event.same_screen = 1;
xcb_send_event(QX11Info::connection(), 0, root, mask, (char*)&xcb_event);
xcb_flush(QX11Info::connection());
}
bool DesktopWindow::event(QEvent* event)
{
switch(event->type()) {
case QEvent::WinIdChange: {
qDebug() << "winid change:" << effectiveWinId();
if(effectiveWinId() == 0)
break;
// set freedesktop.org EWMH hints properly
if(QX11Info::isPlatformX11() && QX11Info::connection()) {
xcb_connection_t* con = QX11Info::connection();
const char* atom_name = "_NET_WM_WINDOW_TYPE_DESKTOP";
xcb_atom_t atom = xcb_intern_atom_reply(con, xcb_intern_atom(con, 0, strlen(atom_name), atom_name), NULL)->atom;
const char* prop_atom_name = "_NET_WM_WINDOW_TYPE";
xcb_atom_t prop_atom = xcb_intern_atom_reply(con, xcb_intern_atom(con, 0, strlen(prop_atom_name), prop_atom_name), NULL)->atom;
xcb_atom_t XA_ATOM = 4;
xcb_change_property(con, XCB_PROP_MODE_REPLACE, effectiveWinId(), prop_atom, XA_ATOM, 32, 1, &atom);
}
break;
}
#undef FontChange // FontChange is defined in the headers of XLib and clashes with Qt, let's undefine it.
case QEvent::StyleChange:
case QEvent::FontChange:
queueRelayout();
break;
default:
break;
}
return QWidget::event(event);
}
#undef FontChange // this seems to be defined in Xlib headers as a macro, undef it!
bool DesktopWindow::eventFilter(QObject * watched, QEvent * event) {
if(watched == listView_) {
switch(event->type()) {
case QEvent::StyleChange:
case QEvent::FontChange:
if(model_)
queueRelayout();
break;
default:
break;
}
}
else if(watched == listView_->viewport()) {
switch(event->type()) {
case QEvent::MouseButtonPress:
case QEvent::MouseButtonRelease:
if(showWmMenu_) {
QMouseEvent* e = static_cast<QMouseEvent*>(event);
// If we want to show the desktop menus provided by the window manager instead of ours,
// we have to forward the mouse events we received to the root window.
// check if the user click on blank area
QModelIndex index = listView_->indexAt(e->pos());
if(!index.isValid() && e->button() != Qt::LeftButton) {
forwardMouseEventToRoot(e);
}
}
break;
default:
break;
}
}
return false;
}
void DesktopWindow::childDropEvent(QDropEvent* e) {
bool moveItem = false;
if(e->source() == listView_ && e->keyboardModifiers() == Qt::NoModifier) {
// drag source is our list view, and no other modifier keys are pressed
// => we're dragging desktop items
const QMimeData *mimeData = e->mimeData();
if(mimeData->hasFormat("application/x-qabstractitemmodeldatalist")) {
QModelIndex dropIndex = listView_->indexAt(e->pos());
if(dropIndex.isValid()) { // drop on an item
QModelIndexList selected = selectedIndexes(); // the dragged items
if(selected.contains(dropIndex)) { // drop on self, ignore
moveItem = true;
}
}
else { // drop on a blank area
moveItem = true;
}
}
}
if(moveItem)
e->accept();
else
Fm::FolderView::childDropEvent(e);
}
void DesktopWindow::closeEvent(QCloseEvent *event) {
// prevent the desktop window from being closed.
event->ignore();
}
void DesktopWindow::setScreenNum(int num) {
if(screenNum_ != num) {
screenNum_ = num;
queueRelayout();
}
}
} // namespace PCManFM

View File

@ -1,142 +0,0 @@
/*
Copyright (C) 2013 Hong Jen Yee (PCMan) <pcman.tw@gmail.com>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#ifndef PCMANFM_DESKTOPWINDOW_H
#define PCMANFM_DESKTOPWINDOW_H
#include "view.h"
#include "launcher.h"
#include <QHash>
#include <QPoint>
#include <QByteArray>
#include <xcb/xcb.h>
namespace Fm {
class CachedFolderModel;
class ProxyFolderModel;
class FolderViewListView;
}
namespace PCManFM {
class DesktopItemDelegate;
class Settings;
class DesktopWindow : public View {
Q_OBJECT
public:
friend class Application;
enum WallpaperMode {
WallpaperNone,
WallpaperStretch,
WallpaperFit,
WallpaperCenter,
WallpaperTile
};
explicit DesktopWindow(int screenNum);
virtual ~DesktopWindow();
void setForeground(const QColor& color);
void setShadow(const QColor& color);
void setBackground(const QColor& color);
void setDesktopFolder();
void setWallpaperFile(QString filename);
void setWallpaperMode(WallpaperMode mode = WallpaperStretch);
// void setWallpaperAlpha(qreal alpha);
void updateWallpaper();
void updateFromSettings(Settings& settings);
void queueRelayout(int delay = 0);
int screenNum() const {
return screenNum_;
}
void setScreenNum(int num);
protected:
virtual void prepareFolderMenu(Fm::FolderMenu* menu);
virtual void prepareFileMenu(Fm::FileMenu* menu);
virtual void resizeEvent(QResizeEvent* event);
virtual void onFileClicked(int type, FmFileInfo* fileInfo);
void loadItemPositions();
void saveItemPositions();
QImage loadWallpaperFile(QSize requiredSize);
virtual bool event(QEvent* event);
virtual bool eventFilter(QObject * watched, QEvent * event);
virtual void childDropEvent(QDropEvent* e);
virtual void closeEvent(QCloseEvent *event);
protected Q_SLOTS:
void onOpenDirRequested(FmPath* path, int target);
void onDesktopPreferences();
void onRowsAboutToBeRemoved(const QModelIndex& parent, int start, int end);
void onRowsInserted(const QModelIndex& parent, int start, int end);
void onLayoutChanged();
void onIndexesMoved(const QModelIndexList& indexes);
void relayoutItems();
void onStickToCurrentPos(bool toggled);
// void updateWorkArea();
// file operations
void onCutActivated();
void onCopyActivated();
void onPasteActivated();
void onRenameActivated();
void onDeleteActivated();
void onFilePropertiesActivated();
private:
void removeBottomGap();
private:
Fm::ProxyFolderModel* proxyModel_;
Fm::CachedFolderModel* model_;
FmFolder* folder_;
Fm::FolderViewListView* listView_;
QColor fgColor_;
QColor bgColor_;
QColor shadowColor_;
QString wallpaperFile_;
WallpaperMode wallpaperMode_;
QPixmap wallpaperPixmap_;
DesktopItemDelegate* delegate_;
Launcher fileLauncher_;
bool showWmMenu_;
int screenNum_;
QHash<QByteArray, QPoint> customItemPos_;
QTimer* relayoutTimer_;
};
}
#endif // PCMANFM_DESKTOPWINDOW_H

View File

@ -1,517 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>FindFilesDialog</class>
<widget class="QDialog" name="FindFilesDialog">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>431</width>
<height>416</height>
</rect>
</property>
<property name="windowTitle">
<string>Find Files</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<widget class="QTabWidget" name="tabWidget">
<property name="currentIndex">
<number>0</number>
</property>
<widget class="QWidget" name="tab">
<attribute name="title">
<string>Name/Location</string>
</attribute>
<layout class="QVBoxLayout" name="verticalLayout_4">
<item>
<widget class="QGroupBox" name="groupBox">
<property name="title">
<string>File name patterns</string>
</property>
<layout class="QFormLayout" name="formLayout">
<item row="0" column="0">
<widget class="QLabel" name="label">
<property name="text">
<string>Pattern:</string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QLineEdit" name="lineEdit"/>
</item>
<item row="1" column="0" colspan="2">
<widget class="QCheckBox" name="checkBox">
<property name="text">
<string>Case insensitive</string>
</property>
</widget>
</item>
<item row="2" column="0" colspan="2">
<widget class="QCheckBox" name="checkBox_2">
<property name="text">
<string>Use regular expression</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QGroupBox" name="groupBox_2">
<property name="title">
<string>Places to search</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout_3">
<item>
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<widget class="QListWidget" name="listWidget"/>
</item>
<item>
<layout class="QVBoxLayout" name="verticalLayout_2">
<item>
<widget class="QPushButton" name="pushButton">
<property name="text">
<string>Add</string>
</property>
<property name="icon">
<iconset theme="list-add">
<normaloff/>
</iconset>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="pushButton_2">
<property name="text">
<string>Remove</string>
</property>
<property name="icon">
<iconset theme="list-remove">
<normaloff/>
</iconset>
</property>
</widget>
</item>
<item>
<spacer name="verticalSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
</size>
</property>
</spacer>
</item>
</layout>
</item>
</layout>
</item>
<item>
<widget class="QCheckBox" name="checkBox_3">
<property name="text">
<string>Search in sub directories</string>
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="checkBox_4">
<property name="text">
<string>Search hidden files</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
</layout>
</widget>
<widget class="QWidget" name="tab_2">
<attribute name="title">
<string>File Type</string>
</attribute>
<layout class="QVBoxLayout" name="verticalLayout_6">
<item>
<widget class="QGroupBox" name="groupBox_3">
<property name="title">
<string>File Type</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout_5">
<item>
<widget class="QLabel" name="label_2">
<property name="text">
<string>Only search for files of following types:</string>
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="checkBox_5">
<property name="text">
<string>Text files</string>
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="checkBox_6">
<property name="text">
<string>Image files</string>
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="checkBox_7">
<property name="text">
<string>Audio files</string>
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="checkBox_8">
<property name="text">
<string>Video files</string>
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="checkBox_9">
<property name="text">
<string>Documents</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<spacer name="verticalSpacer_2">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
</size>
</property>
</spacer>
</item>
</layout>
</widget>
<widget class="QWidget" name="tab_4">
<attribute name="title">
<string>Content</string>
</attribute>
<layout class="QVBoxLayout" name="verticalLayout_8">
<item>
<widget class="QGroupBox" name="groupBox_4">
<property name="title">
<string>File contains</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout_7">
<item>
<widget class="QLineEdit" name="lineEdit_2"/>
</item>
<item>
<widget class="QCheckBox" name="checkBox_10">
<property name="text">
<string>Case insensitive</string>
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="checkBox_11">
<property name="text">
<string>Use regular expression</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<spacer name="verticalSpacer_3">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
</size>
</property>
</spacer>
</item>
</layout>
</widget>
<widget class="QWidget" name="tab_3">
<attribute name="title">
<string>Properties</string>
</attribute>
<layout class="QVBoxLayout" name="verticalLayout_9">
<item>
<widget class="QGroupBox" name="groupBox_5">
<property name="title">
<string>File Size</string>
</property>
<layout class="QFormLayout" name="formLayout_3">
<item row="0" column="0">
<widget class="QCheckBox" name="checkBox_12">
<property name="text">
<string>Bigger than:</string>
</property>
</widget>
</item>
<item row="0" column="1">
<layout class="QHBoxLayout" name="horizontalLayout_2">
<item>
<widget class="QSpinBox" name="spinBox">
<property name="enabled">
<bool>false</bool>
</property>
</widget>
</item>
<item>
<widget class="QComboBox" name="comboBox">
<property name="enabled">
<bool>false</bool>
</property>
</widget>
</item>
</layout>
</item>
<item row="1" column="0">
<widget class="QCheckBox" name="checkBox_13">
<property name="text">
<string>Smaller than:</string>
</property>
</widget>
</item>
<item row="1" column="1">
<layout class="QHBoxLayout" name="horizontalLayout_3">
<item>
<widget class="QSpinBox" name="spinBox_2">
<property name="enabled">
<bool>false</bool>
</property>
</widget>
</item>
<item>
<widget class="QComboBox" name="comboBox_2">
<property name="enabled">
<bool>false</bool>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QGroupBox" name="groupBox_6">
<property name="title">
<string>Last Modified Time</string>
</property>
<layout class="QFormLayout" name="formLayout_2">
<item row="0" column="0">
<widget class="QCheckBox" name="checkBox_14">
<property name="text">
<string>Earlier than:</string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QDateTimeEdit" name="dateTimeEdit">
<property name="enabled">
<bool>false</bool>
</property>
<property name="calendarPopup">
<bool>true</bool>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QCheckBox" name="checkBox_15">
<property name="text">
<string>Later than:</string>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QDateTimeEdit" name="dateTimeEdit_2">
<property name="enabled">
<bool>false</bool>
</property>
<property name="calendarPopup">
<bool>true</bool>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<spacer name="verticalSpacer_4">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
</size>
</property>
</spacer>
</item>
</layout>
</widget>
</widget>
</item>
<item>
<widget class="QDialogButtonBox" name="buttonBox">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="standardButtons">
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
</property>
</widget>
</item>
</layout>
</widget>
<resources/>
<connections>
<connection>
<sender>buttonBox</sender>
<signal>accepted()</signal>
<receiver>FindFilesDialog</receiver>
<slot>accept()</slot>
<hints>
<hint type="sourcelabel">
<x>222</x>
<y>344</y>
</hint>
<hint type="destinationlabel">
<x>157</x>
<y>274</y>
</hint>
</hints>
</connection>
<connection>
<sender>buttonBox</sender>
<signal>rejected()</signal>
<receiver>FindFilesDialog</receiver>
<slot>reject()</slot>
<hints>
<hint type="sourcelabel">
<x>290</x>
<y>350</y>
</hint>
<hint type="destinationlabel">
<x>286</x>
<y>274</y>
</hint>
</hints>
</connection>
<connection>
<sender>checkBox_14</sender>
<signal>toggled(bool)</signal>
<receiver>dateTimeEdit</receiver>
<slot>setEnabled(bool)</slot>
<hints>
<hint type="sourcelabel">
<x>129</x>
<y>166</y>
</hint>
<hint type="destinationlabel">
<x>294</x>
<y>170</y>
</hint>
</hints>
</connection>
<connection>
<sender>checkBox_15</sender>
<signal>toggled(bool)</signal>
<receiver>dateTimeEdit_2</receiver>
<slot>setEnabled(bool)</slot>
<hints>
<hint type="sourcelabel">
<x>91</x>
<y>188</y>
</hint>
<hint type="destinationlabel">
<x>302</x>
<y>195</y>
</hint>
</hints>
</connection>
<connection>
<sender>checkBox_12</sender>
<signal>toggled(bool)</signal>
<receiver>spinBox</receiver>
<slot>setEnabled(bool)</slot>
<hints>
<hint type="sourcelabel">
<x>102</x>
<y>73</y>
</hint>
<hint type="destinationlabel">
<x>184</x>
<y>77</y>
</hint>
</hints>
</connection>
<connection>
<sender>checkBox_12</sender>
<signal>toggled(bool)</signal>
<receiver>comboBox</receiver>
<slot>setEnabled(bool)</slot>
<hints>
<hint type="sourcelabel">
<x>49</x>
<y>72</y>
</hint>
<hint type="destinationlabel">
<x>357</x>
<y>76</y>
</hint>
</hints>
</connection>
<connection>
<sender>checkBox_13</sender>
<signal>toggled(bool)</signal>
<receiver>spinBox_2</receiver>
<slot>setEnabled(bool)</slot>
<hints>
<hint type="sourcelabel">
<x>123</x>
<y>101</y>
</hint>
<hint type="destinationlabel">
<x>186</x>
<y>104</y>
</hint>
</hints>
</connection>
<connection>
<sender>checkBox_13</sender>
<signal>toggled(bool)</signal>
<receiver>comboBox_2</receiver>
<slot>setEnabled(bool)</slot>
<hints>
<hint type="sourcelabel">
<x>53</x>
<y>98</y>
</hint>
<hint type="destinationlabel">
<x>339</x>
<y>108</y>
</hint>
</hints>
</connection>
</connections>
</ui>

View File

@ -1,64 +0,0 @@
/*
* <one line to give the library's name and an idea of what it does.>
* Copyright (C) 2014 <copyright holder> <email>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
*/
#include "launcher.h"
#include "mainwindow.h"
#include "application.h"
namespace PCManFM {
Launcher::Launcher(PCManFM::MainWindow* mainWindow):
Fm::FileLauncher(),
mainWindow_(mainWindow) {
Application* app = static_cast<Application*>(qApp);
setQuickExec(app->settings().quickExec());
}
Launcher::~Launcher() {
}
bool Launcher::openFolder(GAppLaunchContext* ctx, GList* folder_infos, GError** err) {
GList* l = folder_infos;
FmFileInfo* fi = FM_FILE_INFO(l->data);
Application* app = static_cast<Application*>(qApp);
MainWindow* mainWindow = mainWindow_;
if(!mainWindow) {
mainWindow = new MainWindow(fm_file_info_get_path(fi));
mainWindow->resize(app->settings().windowWidth(), app->settings().windowHeight());
if(app->settings().windowMaximized()) {
mainWindow->setWindowState(mainWindow->windowState() | Qt::WindowMaximized);
}
}
else
mainWindow->chdir(fm_file_info_get_path(fi));
l = l->next;
for(; l; l = l->next) {
fi = FM_FILE_INFO(l->data);
mainWindow->addTab(fm_file_info_get_path(fi));
}
mainWindow->show();
mainWindow->raise();
return true;
}
} //namespace PCManFM

View File

@ -1,44 +0,0 @@
/*
* <one line to give the library's name and an idea of what it does.>
* Copyright (C) 2014 <copyright holder> <email>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
*/
#ifndef PCMANFM_LAUNCHER_H
#define PCMANFM_LAUNCHER_H
#include <libfm-qt/filelauncher.h>
namespace PCManFM {
class MainWindow;
class Launcher : public Fm::FileLauncher {
public:
Launcher(MainWindow* mainWindow = NULL);
~Launcher();
protected:
virtual bool openFolder(GAppLaunchContext* ctx, GList* folder_infos, GError** err);
private:
MainWindow* mainWindow_;
};
}
#endif // PCMANFM_LAUNCHER_H

View File

@ -1,780 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>MainWindow</class>
<widget class="QMainWindow" name="MainWindow">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>460</width>
<height>369</height>
</rect>
</property>
<property name="windowTitle">
<string>File Manager</string>
</property>
<property name="windowIcon">
<iconset theme="folder">
<normaloff>.</normaloff>.</iconset>
</property>
<widget class="QWidget" name="centralwidget">
<layout class="QVBoxLayout" name="verticalLayout">
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item>
<widget class="PCManFM::TabBar" name="tabBar" native="true">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="acceptDrops">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<widget class="QSplitter" name="splitter">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<widget class="Fm::SidePane" name="sidePane" native="true">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Expanding">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
</widget>
<widget class="QFrame" name="frame">
<layout class="QVBoxLayout" name="verticalLayout_2">
<property name="spacing">
<number>2</number>
</property>
<property name="leftMargin">
<number>1</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item>
<widget class="QStackedWidget" name="stackedWidget">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Expanding">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
</widget>
</item>
<item>
<widget class="QLineEdit" name="filterBar">
<property name="placeholderText">
<string>Filter by string...</string>
</property>
<property name="clearButtonEnabled">
<bool>true</bool>
</property>
<property name="toolTip">
<string>Focus with Ctrl+I</string>
</property>
</widget>
</item>
</layout>
</widget>
</widget>
</item>
</layout>
</widget>
<widget class="QMenuBar" name="menubar">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>460</width>
<height>23</height>
</rect>
</property>
<widget class="QMenu" name="menu_File">
<property name="title">
<string>&amp;File</string>
</property>
<widget class="QMenu" name="menuCreateNew">
<property name="title">
<string>C&amp;reate New</string>
</property>
<addaction name="actionNewFolder"/>
<addaction name="actionNewBlankFile"/>
</widget>
<addaction name="actionNewTab"/>
<addaction name="actionNewWin"/>
<addaction name="separator"/>
<addaction name="menuCreateNew"/>
<addaction name="separator"/>
<addaction name="actionFileProperties"/>
<addaction name="actionFolderProperties"/>
<addaction name="separator"/>
<addaction name="actionCloseTab"/>
<addaction name="actionCloseWindow"/>
</widget>
<widget class="QMenu" name="menu_Help">
<property name="title">
<string>&amp;Help</string>
</property>
<addaction name="actionAbout"/>
</widget>
<widget class="QMenu" name="menu_View">
<property name="title">
<string>&amp;View</string>
</property>
<widget class="QMenu" name="menuSorting">
<property name="title">
<string>&amp;Sorting</string>
</property>
<addaction name="actionByFileName"/>
<addaction name="actionByMTime"/>
<addaction name="actionByFileSize"/>
<addaction name="actionByFileType"/>
<addaction name="actionByOwner"/>
<addaction name="separator"/>
<addaction name="actionAscending"/>
<addaction name="actionDescending"/>
<addaction name="separator"/>
<addaction name="actionFolderFirst"/>
<addaction name="actionCaseSensitive"/>
</widget>
<addaction name="actionReload"/>
<addaction name="actionShowHidden"/>
<addaction name="separator"/>
<addaction name="actionIconView"/>
<addaction name="actionThumbnailView"/>
<addaction name="actionCompactView"/>
<addaction name="actionDetailedList"/>
<addaction name="separator"/>
<addaction name="menuSorting"/>
<addaction name="actionFilter"/>
<addaction name="actionMenu_bar"/>
</widget>
<widget class="QMenu" name="menu_Editw">
<property name="title">
<string>&amp;Edit</string>
</property>
<addaction name="actionCut"/>
<addaction name="actionCopy"/>
<addaction name="actionPaste"/>
<addaction name="actionRename"/>
<addaction name="actionDelete"/>
<addaction name="separator"/>
<addaction name="actionSelectAll"/>
<addaction name="actionInvertSelection"/>
<addaction name="separator"/>
<addaction name="actionPreferences"/>
</widget>
<widget class="QMenu" name="menu_Bookmarks">
<property name="title">
<string>&amp;Bookmarks</string>
</property>
<addaction name="actionAddToBookmarks"/>
<addaction name="actionEditBookmarks"/>
</widget>
<widget class="QMenu" name="menu_Go">
<property name="title">
<string>&amp;Go</string>
</property>
<addaction name="actionHome"/>
<addaction name="actionDesktop"/>
<addaction name="actionComputer"/>
<addaction name="actionTrash"/>
<addaction name="actionNetwork"/>
<addaction name="actionApplications"/>
<addaction name="separator"/>
<addaction name="actionGoBack"/>
<addaction name="actionGoForward"/>
<addaction name="actionGoUp"/>
</widget>
<widget class="QMenu" name="menu_Tool">
<property name="title">
<string>&amp;Tool</string>
</property>
<addaction name="actionOpenTerminal"/>
<addaction name="actionOpenAsRoot"/>
<addaction name="actionFindFiles"/>
</widget>
<addaction name="menu_File"/>
<addaction name="menu_Editw"/>
<addaction name="menu_View"/>
<addaction name="menu_Go"/>
<addaction name="menu_Bookmarks"/>
<addaction name="menu_Tool"/>
<addaction name="menu_Help"/>
</widget>
<widget class="QStatusBar" name="statusbar"/>
<widget class="QToolBar" name="toolBar">
<property name="windowTitle">
<string>Main Toolbar</string>
</property>
<property name="movable">
<bool>false</bool>
</property>
<property name="floatable">
<bool>false</bool>
</property>
<attribute name="toolBarArea">
<enum>TopToolBarArea</enum>
</attribute>
<attribute name="toolBarBreak">
<bool>false</bool>
</attribute>
<addaction name="actionNewTab"/>
<addaction name="actionGoBack"/>
<addaction name="actionGoForward"/>
<addaction name="actionGoUp"/>
<addaction name="actionReload"/>
<addaction name="actionGo"/>
<addaction name="separator"/>
<addaction name="actionMenu"/>
</widget>
<action name="actionGoUp">
<property name="icon">
<iconset theme="go-up">
<normaloff>.</normaloff>.</iconset>
</property>
<property name="text">
<string>Go &amp;Up</string>
</property>
<property name="toolTip">
<string>Go Up</string>
</property>
<property name="shortcut">
<string>Alt+Up</string>
</property>
</action>
<action name="actionHome">
<property name="icon">
<iconset theme="user-home">
<normaloff>.</normaloff>.</iconset>
</property>
<property name="text">
<string>&amp;Home</string>
</property>
<property name="shortcut">
<string>Alt+Home</string>
</property>
</action>
<action name="actionReload">
<property name="icon">
<iconset theme="view-refresh">
<normaloff>.</normaloff>.</iconset>
</property>
<property name="text">
<string>&amp;Reload</string>
</property>
<property name="shortcut">
<string>F5</string>
</property>
</action>
<action name="actionGo">
<property name="icon">
<iconset theme="go-jump">
<normaloff>.</normaloff>.</iconset>
</property>
<property name="text">
<string>Go</string>
</property>
</action>
<action name="actionQuit">
<property name="icon">
<iconset theme="application-exit">
<normaloff>.</normaloff>.</iconset>
</property>
<property name="text">
<string>Quit</string>
</property>
</action>
<action name="actionAbout">
<property name="icon">
<iconset theme="help-about">
<normaloff>.</normaloff>.</iconset>
</property>
<property name="text">
<string>&amp;About</string>
</property>
</action>
<action name="actionNewWin">
<property name="icon">
<iconset theme="window-new">
<normaloff>.</normaloff>.</iconset>
</property>
<property name="text">
<string>&amp;New Window</string>
</property>
<property name="toolTip">
<string>New Window</string>
</property>
<property name="shortcut">
<string>Ctrl+N</string>
</property>
</action>
<action name="actionShowHidden">
<property name="checkable">
<bool>true</bool>
</property>
<property name="text">
<string>Show &amp;Hidden</string>
</property>
<property name="shortcut">
<string>Ctrl+H</string>
</property>
</action>
<action name="actionComputer">
<property name="icon">
<iconset theme="computer">
<normaloff>.</normaloff>.</iconset>
</property>
<property name="text">
<string>&amp;Computer</string>
</property>
</action>
<action name="actionTrash">
<property name="icon">
<iconset theme="user-trash">
<normaloff>.</normaloff>.</iconset>
</property>
<property name="text">
<string>&amp;Trash</string>
</property>
</action>
<action name="actionNetwork">
<property name="text">
<string>&amp;Network</string>
</property>
</action>
<action name="actionDesktop">
<property name="icon">
<iconset theme="user-desktop">
<normaloff>.</normaloff>.</iconset>
</property>
<property name="text">
<string>&amp;Desktop</string>
</property>
</action>
<action name="actionAddToBookmarks">
<property name="icon">
<iconset theme="list-add">
<normaloff>.</normaloff>.</iconset>
</property>
<property name="text">
<string>&amp;Add to Bookmarks</string>
</property>
</action>
<action name="actionApplications">
<property name="text">
<string>&amp;Applications</string>
</property>
</action>
<action name="actionReload_2">
<property name="text">
<string>Reload</string>
</property>
</action>
<action name="actionIconView">
<property name="checkable">
<bool>true</bool>
</property>
<property name="text">
<string>&amp;Icon View</string>
</property>
</action>
<action name="actionCompactView">
<property name="checkable">
<bool>true</bool>
</property>
<property name="text">
<string>&amp;Compact View</string>
</property>
</action>
<action name="actionDetailedList">
<property name="checkable">
<bool>true</bool>
</property>
<property name="text">
<string>&amp;Detailed List</string>
</property>
</action>
<action name="actionThumbnailView">
<property name="checkable">
<bool>true</bool>
</property>
<property name="text">
<string>&amp;Thumbnail View</string>
</property>
</action>
<action name="actionCut">
<property name="icon">
<iconset theme="edit-cut">
<normaloff>.</normaloff>.</iconset>
</property>
<property name="text">
<string>Cu&amp;t</string>
</property>
<property name="shortcut">
<string>Ctrl+X</string>
</property>
</action>
<action name="actionCopy">
<property name="icon">
<iconset theme="edit-copy">
<normaloff>.</normaloff>.</iconset>
</property>
<property name="text">
<string>&amp;Copy</string>
</property>
<property name="shortcut">
<string>Ctrl+C</string>
</property>
</action>
<action name="actionPaste">
<property name="icon">
<iconset theme="edit-paste">
<normaloff>.</normaloff>.</iconset>
</property>
<property name="text">
<string>&amp;Paste</string>
</property>
<property name="shortcut">
<string>Ctrl+V</string>
</property>
</action>
<action name="actionSelectAll">
<property name="text">
<string>Select &amp;All</string>
</property>
<property name="shortcut">
<string>Ctrl+A</string>
</property>
</action>
<action name="actionPreferences">
<property name="text">
<string>Pr&amp;eferences</string>
</property>
</action>
<action name="actionAscending">
<property name="checkable">
<bool>true</bool>
</property>
<property name="text">
<string>&amp;Ascending</string>
</property>
</action>
<action name="actionDescending">
<property name="checkable">
<bool>true</bool>
</property>
<property name="text">
<string>&amp;Descending</string>
</property>
</action>
<action name="actionByFileName">
<property name="checkable">
<bool>true</bool>
</property>
<property name="text">
<string>&amp;By File Name</string>
</property>
</action>
<action name="actionByMTime">
<property name="checkable">
<bool>true</bool>
</property>
<property name="text">
<string>By &amp;Modification Time</string>
</property>
</action>
<action name="actionByFileType">
<property name="checkable">
<bool>true</bool>
</property>
<property name="text">
<string>By File &amp;Type</string>
</property>
</action>
<action name="actionByOwner">
<property name="checkable">
<bool>true</bool>
</property>
<property name="text">
<string>By &amp;Owner</string>
</property>
</action>
<action name="actionFolderFirst">
<property name="checkable">
<bool>true</bool>
</property>
<property name="text">
<string>&amp;Folder First</string>
</property>
</action>
<action name="actionNewTab">
<property name="icon">
<iconset theme="window-new">
<normaloff>.</normaloff>.</iconset>
</property>
<property name="text">
<string>New &amp;Tab</string>
</property>
<property name="toolTip">
<string>New Tab</string>
</property>
<property name="shortcut">
<string>Ctrl+T</string>
</property>
</action>
<action name="actionGoBack">
<property name="icon">
<iconset theme="go-previous">
<normaloff>.</normaloff>.</iconset>
</property>
<property name="text">
<string>Go &amp;Back</string>
</property>
<property name="toolTip">
<string>Go Back</string>
</property>
<property name="shortcut">
<string>Alt+Left</string>
</property>
</action>
<action name="actionGoForward">
<property name="icon">
<iconset theme="go-next">
<normaloff>.</normaloff>.</iconset>
</property>
<property name="text">
<string>Go &amp;Forward</string>
</property>
<property name="toolTip">
<string>Go Forward</string>
</property>
<property name="shortcut">
<string>Alt+Right</string>
</property>
</action>
<action name="actionInvertSelection">
<property name="text">
<string>&amp;Invert Selection</string>
</property>
</action>
<action name="actionDelete">
<property name="icon">
<iconset theme="edit-delete">
<normaloff>.</normaloff>.</iconset>
</property>
<property name="text">
<string>&amp;Delete</string>
</property>
<property name="shortcut">
<string>Del</string>
</property>
</action>
<action name="actionRename">
<property name="text">
<string>&amp;Rename</string>
</property>
<property name="shortcut">
<string>F2</string>
</property>
</action>
<action name="actionCloseTab">
<property name="text">
<string>C&amp;lose Tab</string>
</property>
<property name="shortcut">
<string>Ctrl+W</string>
</property>
</action>
<action name="actionFileProperties">
<property name="text">
<string>File &amp;Properties</string>
</property>
<property name="shortcut">
<string>Alt+Return</string>
</property>
</action>
<action name="actionFolderProperties">
<property name="text">
<string>&amp;Folder Properties</string>
</property>
</action>
<action name="actionCaseSensitive">
<property name="checkable">
<bool>true</bool>
</property>
<property name="text">
<string>&amp;Case Sensitive</string>
</property>
</action>
<action name="actionByFileSize">
<property name="checkable">
<bool>true</bool>
</property>
<property name="text">
<string>By File &amp;Size</string>
</property>
</action>
<action name="actionCloseWindow">
<property name="text">
<string>&amp;Close Window</string>
</property>
<property name="shortcut">
<string>Ctrl+Q</string>
</property>
</action>
<action name="actionEdit_Bookmarks">
<property name="text">
<string>Edit Bookmarks</string>
</property>
</action>
<action name="actionOpenTerminal">
<property name="text">
<string>Open &amp;Terminal</string>
</property>
<property name="shortcut">
<string>F4</string>
</property>
</action>
<action name="actionOpenAsRoot">
<property name="text">
<string>Open as &amp;Root</string>
</property>
</action>
<action name="actionEditBookmarks">
<property name="text">
<string>&amp;Edit Bookmarks</string>
</property>
</action>
<action name="actionNewFolder">
<property name="icon">
<iconset theme="folder-new">
<normaloff>.</normaloff>.</iconset>
</property>
<property name="text">
<string>&amp;Folder</string>
</property>
<property name="shortcut">
<string>Ctrl+Shift+N</string>
</property>
</action>
<action name="actionNewBlankFile">
<property name="icon">
<iconset theme="document-new">
<normaloff>.</normaloff>.</iconset>
</property>
<property name="text">
<string>&amp;Blank File</string>
</property>
<property name="shortcut">
<string>Ctrl+Alt+N</string>
</property>
</action>
<action name="actionFindFiles">
<property name="text">
<string>&amp;Find Files</string>
</property>
<property name="shortcut">
<string>F3</string>
</property>
</action>
<action name="actionFilter">
<property name="checkable">
<bool>true</bool>
</property>
<property name="text">
<string>&amp;Filter</string>
</property>
<property name="shortcut">
<string>Ctrl+B</string>
</property>
</action>
<action name="actionCloseLeft">
<property name="icon">
<iconset theme="go-previous">
<normaloff>.</normaloff>.</iconset>
</property>
<property name="text">
<string>Close &amp;left tabs</string>
</property>
</action>
<action name="actionCloseRight">
<property name="icon">
<iconset theme="go-next">
<normaloff>.</normaloff>.</iconset>
</property>
<property name="text">
<string>Close &amp;right tabs</string>
</property>
</action>
<action name="actionCloseOther">
<property name="text">
<string>Close &amp;other tabs</string>
</property>
</action>
<action name="actionMenu_bar">
<property name="checkable">
<bool>true</bool>
</property>
<property name="text">
<string>Menu bar</string>
</property>
<property name="toolTip">
<string>Menu bar</string>
</property>
<property name="shortcut">
<string>Ctrl+M</string>
</property>
</action>
<action name="actionMenu">
<property name="icon">
<iconset theme="application-menu"/>
</property>
<property name="text">
<string>Menu</string>
</property>
<property name="toolTip">
<string>Menu</string>
</property>
</action>
</widget>
<customwidgets>
<customwidget>
<class>PCManFM::TabBar</class>
<extends>QWidget</extends>
<header>tabbar.h</header>
<container>1</container>
</customwidget>
<customwidget>
<class>Fm::SidePane</class>
<extends>QWidget</extends>
<header location="global">libfm-qt/sidepane.h</header>
<container>1</container>
</customwidget>
</customwidgets>
<resources/>
<connections/>
</ui>

File diff suppressed because it is too large Load Diff

View File

@ -1,182 +0,0 @@
/*
Copyright (C) 2013 Hong Jen Yee (PCMan) <pcman.tw@gmail.com>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#ifndef FM_MAIN_WINDOW_H
#define FM_MAIN_WINDOW_H
#include "ui_main-win.h"
#include <QMainWindow>
#include <QListView>
#include <QSortFilterProxyModel>
#include <QLineEdit>
#include <QTabWidget>
#include <libfm/fm.h>
#include <QMessageBox>
#include <QTabBar>
#include <QStackedWidget>
#include <QSplitter>
#include "launcher.h"
namespace PCManFM {
class TabPage;
class Settings;
class MainWindow : public QMainWindow {
Q_OBJECT
public:
MainWindow(FmPath* path = NULL);
virtual ~MainWindow();
void chdir(FmPath* path);
int addTab(FmPath* path);
TabPage* currentPage() {
return reinterpret_cast<TabPage*>(ui.stackedWidget->currentWidget());
}
void updateFromSettings(Settings& settings);
protected Q_SLOTS:
void onPathEntryReturnPressed();
void on_actionNewTab_triggered();
void on_actionNewWin_triggered();
void on_actionNewFolder_triggered();
void on_actionNewBlankFile_triggered();
void on_actionCloseTab_triggered();
void on_actionCloseWindow_triggered();
void on_actionFileProperties_triggered();
void on_actionFolderProperties_triggered();
void on_actionCut_triggered();
void on_actionCopy_triggered();
void on_actionPaste_triggered();
void on_actionDelete_triggered();
void on_actionRename_triggered();
void on_actionSelectAll_triggered();
void on_actionInvertSelection_triggered();
void on_actionPreferences_triggered();
void on_actionGoBack_triggered();
void on_actionGoForward_triggered();
void on_actionGoUp_triggered();
void on_actionHome_triggered();
void on_actionReload_triggered();
void on_actionIconView_triggered();
void on_actionCompactView_triggered();
void on_actionDetailedList_triggered();
void on_actionThumbnailView_triggered();
void on_actionGo_triggered();
void on_actionShowHidden_triggered(bool check);
void on_actionByFileName_triggered(bool checked);
void on_actionByMTime_triggered(bool checked);
void on_actionByOwner_triggered(bool checked);
void on_actionByFileType_triggered(bool checked);
void on_actionByFileSize_triggered(bool checked);
void on_actionAscending_triggered(bool checked);
void on_actionDescending_triggered(bool checked);
void on_actionFolderFirst_triggered(bool checked);
void on_actionCaseSensitive_triggered(bool checked);
void on_actionFilter_triggered(bool checked);
void on_actionApplications_triggered();
void on_actionComputer_triggered();
void on_actionTrash_triggered();
void on_actionNetwork_triggered();
void on_actionDesktop_triggered();
void on_actionAddToBookmarks_triggered();
void on_actionEditBookmarks_triggered();
void on_actionOpenTerminal_triggered();
void on_actionOpenAsRoot_triggered();
void on_actionFindFiles_triggered();
void on_actionAbout_triggered();
void onBookmarkActionTriggered();
void onTabBarCloseRequested(int index);
void onTabBarCurrentChanged(int index);
void onTabBarTabMoved(int from, int to);
void focusFilterBar();
void onFilterStringChanged(QString str);
void onShortcutPrevTab();
void onShortcutNextTab();
void onShortcutJumpToTab();
void onStackedWidgetWidgetRemoved(int index);
void onTabPageTitleChanged(QString title);
void onTabPageStatusChanged(int type, QString statusText);
void onTabPageOpenDirRequested(FmPath* path, int target);
void onTabPageSortFilterChanged();
void onSidePaneChdirRequested(int type, FmPath* path);
void onSidePaneOpenFolderInNewWindowRequested(FmPath* path);
void onSidePaneOpenFolderInNewTabRequested(FmPath* path);
void onSidePaneOpenFolderInTerminalRequested(FmPath* path);
void onSidePaneCreateNewFolderRequested(FmPath* path);
void onSidePaneModeChanged(Fm::SidePane::Mode mode);
void onSplitterMoved(int pos, int index);
void onResetFocus();
void onBackForwardContextMenu(QPoint pos);
void tabContextMenu(const QPoint& pos);
void closeLeftTabs();
void closeRightTabs();
void closeOtherTabs() {
closeLeftTabs();
closeRightTabs();
}
void focusPathEntry();
void toggleMenuBar(bool checked);
protected:
// void changeEvent( QEvent * event);
void closeTab(int index);
virtual void resizeEvent(QResizeEvent *event);
virtual void closeEvent(QCloseEvent *event);
private:
static void onBookmarksChanged(FmBookmarks* bookmarks, MainWindow* pThis);
void loadBookmarksMenu();
void updateUIForCurrentPage();
void updateViewMenuForCurrentPage();
void updateStatusBarForCurrentPage();
private:
Ui::MainWindow ui;
QLineEdit* pathEntry;
QLabel* fsInfoLabel;
FmBookmarks* bookmarks;
Launcher fileLauncher_;
int rightClickIndex;
};
}
#endif // FM_MAIN_WINDOW_H

View File

@ -1,29 +0,0 @@
<!DOCTYPE node PUBLIC "-//freedesktop//DTD D-BUS Object Introspection 1.0//EN" "http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd">
<node>
<interface name="org.pcmanfm.Application">
<method name="preferences">
<arg type="s" direction="in"/>
</method>
<method name="desktopPrefrences">
<arg type="s" direction="in"/>
</method>
<method name="desktopManager">
<arg type="b" direction="in"/>
</method>
<method name="launchFiles">
<arg type="s" direction="in"/>
<arg type="as" direction="in"/>
<arg type="b" direction="in"/>
</method>
<method name="quit">
</method>
<method name="setWallpaper">
<arg type="s" direction="in"/>
<arg type="s" direction="in"/>
</method>
<method name="findFiles">
<arg type="as" direction="in"/>
</method>
<property name="desktopManagerEnabled" type="b" access="read"/>
</interface>
</node>

View File

@ -1,9 +0,0 @@
[Desktop Entry]
Type=Application
Name=Desktop
GenericName=Desktop Settings
Comment=Change wallpapers and behavior of desktop manager
Exec=pcmanfm-qt --desktop-pref=general
Icon=user-desktop
Categories=Settings;Qt;DesktopSettings;
StartupNotify=true

View File

@ -1,10 +0,0 @@
[Desktop Entry]
Type=Application
Name=PCManFM File Manager
GenericName=File Manager
Comment=Browse the file system and manage the files
Exec=pcmanfm-qt %U
MimeType=inode/directory;
Icon=system-file-manager
Categories=FileManager;Utility;Core;Qt;
StartupNotify=true

View File

@ -1,13 +0,0 @@
#include <libfm/fm.h>
#include "application.h"
#include <libfm-qt/libfmqt.h>
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
qunsetenv("QT_NO_GLIB");
PCManFM::Application app(argc, argv);
app.init();
return app.exec();
}

File diff suppressed because it is too large Load Diff

View File

@ -1,386 +0,0 @@
/*
Copyright (C) 2013 Hong Jen Yee (PCMan) <pcman.tw@gmail.com>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#include "preferencesdialog.h"
#include "application.h"
#include "settings.h"
#include <QDir>
#include <QHash>
#include <QStringBuilder>
#include <QSettings>
#include <libfm-qt/folderview.h>
namespace PCManFM {
static int bigIconSizes[] = {96, 72, 64, 48, 36, 32, 24, 20};
static int smallIconSizes[] = {48, 36, 32, 24, 20, 16, 12};
static int thumbnailIconSizes[] = {256, 224, 192, 160, 128, 96, 64};
PreferencesDialog::PreferencesDialog (QString activePage, QWidget* parent):
QDialog (parent) {
ui.setupUi(this);
setAttribute(Qt::WA_DeleteOnClose);
// resize the list widget according to the width of its content.
ui.listWidget->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Expanding);
ui.listWidget->setMaximumWidth(ui.listWidget->sizeHintForColumn(0) + ui.listWidget->frameWidth() * 2 + 4);
initFromSettings();
selectPage(activePage);
adjustSize();
}
PreferencesDialog::~PreferencesDialog() {
}
static void findIconThemesInDir(QHash<QString, QString>& iconThemes, QString dirName) {
QDir dir(dirName);
QStringList subDirs = dir.entryList(QDir::AllDirs);
GKeyFile* kf = g_key_file_new();
Q_FOREACH(QString subDir, subDirs) {
QString indexFile = dirName % '/' % subDir % "/index.theme";
if(g_key_file_load_from_file(kf, indexFile.toLocal8Bit().constData(), GKeyFileFlags(0), NULL)) {
// FIXME: skip hidden ones
// icon theme must have this key, so it has icons if it has this key
// otherwise, it might be a cursor theme or any other kind of theme.
if(g_key_file_has_key(kf, "Icon Theme", "Directories", NULL)) {
char* dispName = g_key_file_get_locale_string(kf, "Icon Theme", "Name", NULL, NULL);
// char* comment = g_key_file_get_locale_string(kf, "Icon Theme", "Comment", NULL, NULL);
iconThemes[subDir] = dispName;
g_free(dispName);
}
}
}
g_key_file_free(kf);
}
void PreferencesDialog::initIconThemes(Settings& settings) {
// check if auto-detection is done (for example, from xsettings)
if(settings.useFallbackIconTheme()) { // auto-detection failed
// load xdg icon themes and select the current one
QHash<QString, QString> iconThemes;
// user customed icon themes
findIconThemesInDir(iconThemes, QString(g_get_home_dir()) % "/.icons");
// search for icons in system data dir
const char* const* dataDirs = g_get_system_data_dirs();
for(const char* const* dataDir = dataDirs; *dataDir; ++dataDir) {
findIconThemesInDir(iconThemes, QString(*dataDir) % "/icons");
}
iconThemes.remove("hicolor"); // remove hicolor, which is only a fallback
QHash<QString, QString>::const_iterator it;
for(it = iconThemes.begin(); it != iconThemes.end(); ++it) {
ui.iconTheme->addItem(it.value(), it.key());
}
ui.iconTheme->model()->sort(0); // sort the list of icon theme names
// select current theme name
int n = ui.iconTheme->count();
int i;
for(i = 0; i < n; ++i) {
QVariant itemData = ui.iconTheme->itemData(i);
if(itemData == settings.fallbackIconThemeName()) {
break;
}
}
if(i >= n)
i = 0;
ui.iconTheme->setCurrentIndex(i);
}
else { // auto-detection of icon theme works, hide the fallback icon theme combo box.
ui.iconThemeLabel->hide();
ui.iconTheme->hide();
}
ui.hMargin->setValue(settings.folderViewCellMargins().width());
ui.vMargin->setValue(settings.folderViewCellMargins().height());
connect(ui.lockMargins, &QAbstractButton::clicked, this, &PreferencesDialog::lockMargins);
}
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())
ui.archiver->setCurrentIndex(i);
}
}
void PreferencesDialog::initDisplayPage(Settings& settings) {
initIconThemes(settings);
// icon sizes
int i;
for(i = 0; i < G_N_ELEMENTS(bigIconSizes); ++i) {
int size = bigIconSizes[i];
ui.bigIconSize->addItem(QString("%1 x %1").arg(size), size);
if(settings.bigIconSize() == size)
ui.bigIconSize->setCurrentIndex(i);
}
for(i = 0; i < G_N_ELEMENTS(smallIconSizes); ++i) {
int size = smallIconSizes[i];
QString text = QString("%1 x %1").arg(size);
ui.smallIconSize->addItem(text, size);
if(settings.smallIconSize() == size)
ui.smallIconSize->setCurrentIndex(i);
ui.sidePaneIconSize->addItem(text, size);
if(settings.sidePaneIconSize() == size)
ui.sidePaneIconSize->setCurrentIndex(i);
}
for(i = 0; i < G_N_ELEMENTS(thumbnailIconSizes); ++i) {
int size = thumbnailIconSizes[i];
ui.thumbnailIconSize->addItem(QString("%1 x %1").arg(size), size);
if(settings.thumbnailIconSize() == size)
ui.thumbnailIconSize->setCurrentIndex(i);
}
ui.siUnit->setChecked(settings.siUnit());
ui.backupAsHidden->setChecked(settings.backupAsHidden());
ui.showFullNames->setChecked(settings.showFullNames());
ui.shadowHidden->setChecked(settings.shadowHidden());
// FIXME: Hide options that we don't support yet.
ui.showFullNames->hide();
ui.shadowHidden->hide();
}
void PreferencesDialog::initUiPage(Settings& settings) {
ui.alwaysShowTabs->setChecked(settings.alwaysShowTabs());
ui.fullWidthTabbar->setChecked(settings.fullWidthTabBar());
ui.showTabClose->setChecked(settings.showTabClose());
ui.rememberWindowSize->setChecked(settings.rememberWindowSize());
ui.fixedWindowWidth->setValue(settings.fixedWindowWidth());
ui.fixedWindowHeight->setValue(settings.fixedWindowHeight());
// FIXME: Hide options that we don't support yet.
ui.showInPlaces->parentWidget()->hide();
}
void PreferencesDialog::initBehaviorPage(Settings& settings) {
ui.singleClick->setChecked(settings.singleClick());
ui.autoSelectionDelay->setValue(double(settings.autoSelectionDelay()) / 1000);
ui.bookmarkOpenMethod->setCurrentIndex(settings.bookmarkOpenMethod());
ui.viewMode->addItem(tr("Icon View"), (int)Fm::FolderView::IconMode);
ui.viewMode->addItem(tr("Compact Icon View"), (int)Fm::FolderView::CompactMode);
ui.viewMode->addItem(tr("Thumbnail View"), (int)Fm::FolderView::ThumbnailMode);
ui.viewMode->addItem(tr("Detailed List View"), (int)Fm::FolderView::DetailedListMode);
const Fm::FolderView::ViewMode modes[] = {
Fm::FolderView::IconMode,
Fm::FolderView::CompactMode,
Fm::FolderView::ThumbnailMode,
Fm::FolderView::DetailedListMode
};
for(int i = 0; i < G_N_ELEMENTS(modes); ++i) {
if(modes[i] == settings.viewMode()) {
ui.viewMode->setCurrentIndex(i);
break;
}
}
ui.configmDelete->setChecked(settings.confirmDelete());
if(settings.supportTrash())
ui.useTrash->setChecked(settings.useTrash());
else {
ui.useTrash->hide();
}
ui.noUsbTrash->setChecked(settings.noUsbTrash());
ui.confirmTrash->setChecked(settings.confirmTrash());
ui.quickExec->setChecked(settings.quickExec());
}
void PreferencesDialog::initThumbnailPage(Settings& settings) {
ui.showThumbnails->setChecked(settings.showThumbnails());
ui.thumbnailLocal->setChecked(settings.thumbnailLocalFilesOnly());
ui.maxThumbnailFileSize->setValue(settings.maxThumbnailFileSize());
}
void PreferencesDialog::initVolumePage(Settings& settings) {
ui.mountOnStartup->setChecked(settings.mountOnStartup());
ui.mountRemovable->setChecked(settings.mountRemovable());
ui.autoRun->setChecked(settings.autoRun());
if(settings.closeOnUnmount())
ui.closeOnUnmount->setChecked(true);
else
ui.goHomeOnUnmount->setChecked(true);
}
void PreferencesDialog::initTerminals(Settings& settings) {
// load the known terminal list from the terminal.list file of libfm
QSettings termlist(LIBFM_DATA_DIR "/terminals.list", QSettings::IniFormat);
ui.terminal->addItems(termlist.childGroups());
ui.terminal->setEditText(settings.terminal());
}
void PreferencesDialog::initAdvancedPage(Settings& settings) {
initArchivers(settings);
initTerminals(settings);
ui.suCommand->setText(settings.suCommand());
ui.onlyUserTemplates->setChecked(settings.onlyUserTemplates());
ui.templateTypeOnce->setChecked(settings.templateTypeOnce());
ui.templateRunApp->setChecked(settings.templateRunApp());
// FIXME: Hide options that we don't support yet.
ui.templateRunApp->hide();
}
void PreferencesDialog::initFromSettings() {
Settings& settings = static_cast<Application*>(qApp)->settings();
initDisplayPage(settings);
initUiPage(settings);
initBehaviorPage(settings);
initThumbnailPage(settings);
initVolumePage(settings);
initAdvancedPage(settings);
}
void PreferencesDialog::applyDisplayPage(Settings& settings) {
if(settings.useFallbackIconTheme()) {
// only apply the value if icon theme combo box is in use
// the combo box is hidden when auto-detection of icon theme from xsettings works.
QString newIconTheme = ui.iconTheme->itemData(ui.iconTheme->currentIndex()).toString();
if(newIconTheme != settings.fallbackIconThemeName()) {
settings.setFallbackIconThemeName(newIconTheme);
QIcon::setThemeName(settings.fallbackIconThemeName());
// update the UI by emitting a style change event
Q_FOREACH(QWidget *widget, QApplication::allWidgets()) {
QEvent event(QEvent::StyleChange);
QApplication::sendEvent(widget, &event);
}
}
}
settings.setBigIconSize(ui.bigIconSize->itemData(ui.bigIconSize->currentIndex()).toInt());
settings.setSmallIconSize(ui.smallIconSize->itemData(ui.smallIconSize->currentIndex()).toInt());
settings.setThumbnailIconSize(ui.thumbnailIconSize->itemData(ui.thumbnailIconSize->currentIndex()).toInt());
settings.setSidePaneIconSize(ui.sidePaneIconSize->itemData(ui.sidePaneIconSize->currentIndex()).toInt());
settings.setSiUnit(ui.siUnit->isChecked());
settings.setBackupAsHidden(ui.backupAsHidden->isChecked());
settings.setShowFullNames(ui.showFullNames->isChecked());
settings.setShadowHidden(ui.shadowHidden->isChecked());
settings.setFolderViewCellMargins(QSize(ui.hMargin->value(), ui.vMargin->value()));
}
void PreferencesDialog::applyUiPage(Settings& settings) {
settings.setAlwaysShowTabs(ui.alwaysShowTabs->isChecked());
settings.setFullWidthTabBar(ui.fullWidthTabbar->isChecked());
settings.setShowTabClose(ui.showTabClose->isChecked());
settings.setRememberWindowSize(ui.rememberWindowSize->isChecked());
settings.setFixedWindowWidth(ui.fixedWindowWidth->value());
settings.setFixedWindowHeight(ui.fixedWindowHeight->value());
}
void PreferencesDialog::applyBehaviorPage(Settings& settings) {
settings.setSingleClick(ui.singleClick->isChecked());
settings.setAutoSelectionDelay(int(ui.autoSelectionDelay->value() * 1000));
settings.setBookmarkOpenMethod(OpenDirTargetType(ui.bookmarkOpenMethod->currentIndex()));
// FIXME: bug here?
Fm::FolderView::ViewMode mode = Fm::FolderView::ViewMode(ui.viewMode->itemData(ui.viewMode->currentIndex()).toInt());
settings.setViewMode(mode);
settings.setConfirmDelete(ui.configmDelete->isChecked());
if(settings.supportTrash())
settings.setUseTrash(ui.useTrash->isChecked());
settings.setNoUsbTrash(ui.noUsbTrash->isChecked());
settings.setConfirmTrash(ui.confirmTrash->isChecked());
settings.setQuickExec(ui.quickExec->isChecked());
}
void PreferencesDialog::applyThumbnailPage(Settings& settings) {
settings.setShowThumbnails(ui.showThumbnails->isChecked());
settings.setThumbnailLocalFilesOnly(ui.thumbnailLocal->isChecked());
settings.setMaxThumbnailFileSize(ui.maxThumbnailFileSize->value());
}
void PreferencesDialog::applyVolumePage(Settings& settings) {
settings.setAutoRun(ui.autoRun->isChecked());
settings.setMountOnStartup(ui.mountOnStartup->isChecked());
settings.setMountRemovable(ui.mountRemovable->isChecked());
settings.setCloseOnUnmount(ui.closeOnUnmount->isChecked());
}
void PreferencesDialog::applyAdvancedPage(Settings& settings) {
settings.setTerminal(ui.terminal->currentText());
settings.setSuCommand(ui.suCommand->text());
settings.setArchiver(ui.archiver->itemData(ui.archiver->currentIndex()).toString());
settings.setOnlyUserTemplates(ui.onlyUserTemplates->isChecked());
settings.setTemplateTypeOnce(ui.templateTypeOnce->isChecked());
settings.setTemplateRunApp(ui.templateRunApp->isChecked());
}
void PreferencesDialog::applySettings() {
Settings& settings = static_cast<Application*>(qApp)->settings();
applyDisplayPage(settings);
applyUiPage(settings);
applyBehaviorPage(settings);
applyThumbnailPage(settings);
applyVolumePage(settings);
applyAdvancedPage(settings);
settings.save();
Application* app = static_cast<Application*>(qApp);
app->updateFromSettings();
}
void PreferencesDialog::accept() {
applySettings();
QDialog::accept();
}
void PreferencesDialog::selectPage(QString name) {
if(!name.isEmpty()) {
QWidget* page = findChild<QWidget*>(name + "Page");
if(page) {
int index = ui.stackedWidget->indexOf(page);
ui.listWidget->setCurrentRow(index);
}
}
}
void PreferencesDialog::lockMargins(bool lock) {
ui.vMargin->setDisabled(lock);
if(lock) {
ui.vMargin->setValue(ui.hMargin->value());
connect(ui.hMargin, static_cast<void (QSpinBox::*)(int)>(&QSpinBox::valueChanged), ui.vMargin, &QSpinBox::setValue);
}
else
disconnect(ui.hMargin, static_cast<void (QSpinBox::*)(int)>(&QSpinBox::valueChanged), ui.vMargin, &QSpinBox::setValue);
}
} // namespace PCManFM

View File

@ -1,75 +0,0 @@
/*
Copyright (C) 2013 Hong Jen Yee (PCMan) <pcman.tw@gmail.com>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#ifndef PCMANFM_PREFERENCESDIALOG_H
#define PCMANFM_PREFERENCESDIALOG_H
#include <QDialog>
#include "ui_preferences.h"
#include <QString>
namespace PCManFM
{
class Settings;
class PreferencesDialog : public QDialog {
Q_OBJECT
public:
// activePage is the name of page to select (general, display, advanced...)
explicit PreferencesDialog(QString activePage = QString(), QWidget* parent = 0);
virtual ~PreferencesDialog();
virtual void accept();
void selectPage(QString name);
protected Q_SLOTS:
void lockMargins(bool lock);
private:
void initIconThemes(Settings& settings);
void initArchivers(Settings& settings);
void initDisplayPage(Settings& settings);
void initUiPage(Settings& settings);
void initBehaviorPage(Settings& settings);
void initThumbnailPage(Settings& settings);
void initVolumePage(Settings& settings);
void initAdvancedPage(Settings& settings);
void initTerminals(Settings& settings);
void applyUiPage(Settings& settings);
void applyDisplayPage(Settings& settings);
void applyBehaviorPage(Settings& settings);
void applyThumbnailPage(Settings& settings);
void applyVolumePage(Settings& settings);
void applyAdvancedPage(Settings& settings);
void initFromSettings();
void applySettings();
private:
Ui::PreferencesDialog ui;
};
}
#endif // PCMANFM_PREFERENCESDIALOG_H

View File

@ -1,565 +0,0 @@
/*
Copyright (C) 2013 Hong Jen Yee (PCMan) <pcman.tw@gmail.com>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#include "settings.h"
#include <QDir>
#include <QFile>
#include <QStringBuilder>
#include <QSettings>
#include <QApplication>
#include "desktopwindow.h"
#include <libfm-qt/utilities.h>
// #include <QDesktopServices>
namespace PCManFM {
inline static const char* bookmarkOpenMethodToString(OpenDirTargetType value);
inline static OpenDirTargetType bookmarkOpenMethodFromString(const QString str);
inline static const char* wallpaperModeToString(int value);
inline static int wallpaperModeFromString(const QString str);
inline static const char* viewModeToString(Fm::FolderView::ViewMode value);
inline static Fm::FolderView::ViewMode viewModeFromString(const QString str);
inline static const char* sidePaneModeToString(Fm::SidePane::Mode value);
inline static Fm::SidePane::Mode sidePaneModeFromString(const QString& str);
inline static const char* sortOrderToString(Qt::SortOrder order);
inline static Qt::SortOrder sortOrderFromString(const QString str);
inline static const char* sortColumnToString(Fm::FolderModel::ColumnId value);
inline static Fm::FolderModel::ColumnId sortColumnFromString(const QString str);
Settings::Settings():
QObject(),
supportTrash_(Fm::uriExists("trash:///")), // check if trash:/// is supported
fallbackIconThemeName_(),
useFallbackIconTheme_(QIcon::themeName().isEmpty() || QIcon::themeName() == "hicolor"),
bookmarkOpenMethod_(OpenInCurrentTab),
suCommand_(),
terminal_(),
mountOnStartup_(true),
mountRemovable_(true),
autoRun_(true),
closeOnUnmount_(false),
wallpaperMode_(0),
wallpaper_(),
desktopBgColor_(),
desktopFgColor_(),
desktopShadowColor_(),
showWmMenu_(false),
desktopShowHidden_(false),
desktopSortOrder_(Qt::AscendingOrder),
desktopSortColumn_(Fm::FolderModel::ColumnFileName),
alwaysShowTabs_(true),
showTabClose_(true),
rememberWindowSize_(true),
fixedWindowWidth_(640),
fixedWindowHeight_(480),
lastWindowWidth_(640),
lastWindowHeight_(480),
lastWindowMaximized_(false),
splitterPos_(120),
sidePaneMode_(Fm::SidePane::ModePlaces),
showMenuBar_(true),
fullWidthTabBar_(true),
viewMode_(Fm::FolderView::IconMode),
showHidden_(false),
sortOrder_(Qt::AscendingOrder),
sortColumn_(Fm::FolderModel::ColumnFileName),
sortFolderFirst_(true),
showFilter_(false),
// settings for use with libfm
singleClick_(false),
autoSelectionDelay_(600),
useTrash_(true),
confirmDelete_(true),
noUsbTrash_(false),
confirmTrash_(false),
quickExec_(false),
showThumbnails_(true),
archiver_(),
siUnit_(false),
placesHome_(true),
placesDesktop_(true),
placesApplications_(true),
placesTrash_(true),
placesRoot_(true),
placesComputer_(true),
placesNetwork_(true),
bigIconSize_(48),
smallIconSize_(24),
sidePaneIconSize_(24),
thumbnailIconSize_(128),
folderViewCellMargins_(QSize(3, 3)),
desktopCellMargins_(QSize(3, 1)) {
}
Settings::~Settings() {
}
QString Settings::profileDir(QString profile, bool useFallback) {
// NOTE: it's a shame that QDesktopServices does not handle XDG_CONFIG_HOME
// try user-specific config file first
QString dirName;
// WARNING: Don't use XDG_CONFIG_HOME with root because it might
// give the user config directory if gksu-properties is set to su.
if(geteuid())
dirName = QLatin1String(qgetenv("XDG_CONFIG_HOME"));
if (dirName.isEmpty())
dirName = QDir::homePath() % QLatin1String("/.config");
dirName = dirName % "/pcmanfm-qt/" % profile;
QDir dir(dirName);
// if user config dir does not exist, try system-wide config dirs instead
if(!dir.exists() && useFallback) {
QString fallbackDir;
for(const char* const* configDir = g_get_system_config_dirs(); *configDir; ++configDir) {
fallbackDir = QString(*configDir) % "/pcmanfm-qt/" % profile;
dir.setPath(fallbackDir);
if(dir.exists()) {
dirName = fallbackDir;
break;
}
}
}
return dirName;
}
bool Settings::load(QString profile) {
profileName_ = profile;
QString fileName = profileDir(profile, true) % "/settings.conf";
return loadFile(fileName);
}
bool Settings::save(QString profile) {
QString fileName = profileDir(profile.isEmpty() ? profileName_ : profile) % "/settings.conf";
return saveFile(fileName);
}
bool Settings::loadFile(QString filePath) {
QSettings settings(filePath, QSettings::IniFormat);
settings.beginGroup("System");
fallbackIconThemeName_ = settings.value("FallbackIconThemeName").toString();
if(fallbackIconThemeName_.isEmpty()) {
// FIXME: we should choose one from installed icon themes or get
// the value from XSETTINGS instead of hard code a fallback value.
fallbackIconThemeName_ = "elementary"; // fallback icon theme name
}
suCommand_ = settings.value("SuCommand", "lxqt-sudo %s").toString();
setTerminal(settings.value("Terminal", "xterm").toString());
setArchiver(settings.value("Archiver", "file-roller").toString());
setSiUnit(settings.value("SIUnit", false).toBool());
setOnlyUserTemplates(settings.value("OnlyUserTemplates", false).toBool());
setTemplateTypeOnce(settings.value("TemplateTypeOnce", false).toBool());
setTemplateRunApp(settings.value("TemplateRunApp", false).toBool());
settings.endGroup();
settings.beginGroup("Behavior");
bookmarkOpenMethod_ = bookmarkOpenMethodFromString(settings.value("BookmarkOpenMethod").toString());
// settings for use with libfm
useTrash_ = settings.value("UseTrash", true).toBool();
singleClick_ = settings.value("SingleClick", false).toBool();
autoSelectionDelay_ = settings.value("AutoSelectionDelay", 600).toInt();
confirmDelete_ = settings.value("ConfirmDelete", true).toBool();
setNoUsbTrash(settings.value("NoUsbTrash", false).toBool());
confirmTrash_ = settings.value("ConfirmTrash", false).toBool();
setQuickExec(settings.value("QuickExec", false).toBool());
// bool thumbnailLocal_;
// bool thumbnailMax;
settings.endGroup();
settings.beginGroup("Desktop");
wallpaperMode_ = wallpaperModeFromString(settings.value("WallpaperMode").toString());
wallpaper_ = settings.value("Wallpaper").toString();
desktopBgColor_.setNamedColor(settings.value("BgColor", "#000000").toString());
desktopFgColor_.setNamedColor(settings.value("FgColor", "#ffffff").toString());
desktopShadowColor_.setNamedColor(settings.value("ShadowColor", "#000000").toString());
if(settings.contains("Font"))
desktopFont_.fromString(settings.value("Font").toString());
else
desktopFont_ = QApplication::font();
showWmMenu_ = settings.value("ShowWmMenu", false).toBool();
desktopShowHidden_ = settings.value("ShowHidden", false).toBool();
desktopSortOrder_ = sortOrderFromString(settings.value("SortOrder").toString());
desktopSortColumn_ = sortColumnFromString(settings.value("SortColumn").toString());
desktopCellMargins_ = (settings.value("DesktopCellMargins", QSize(3, 1)).toSize()
.expandedTo(QSize(0, 0))).boundedTo(QSize(48, 48));
settings.endGroup();
settings.beginGroup("Volume");
mountOnStartup_ = settings.value("MountOnStartup", true).toBool();
mountRemovable_ = settings.value("MountRemovable", true).toBool();
autoRun_ = settings.value("AutoRun", true).toBool();
closeOnUnmount_ = settings.value("CloseOnUnmount", true).toBool();
settings.endGroup();
settings.beginGroup("Thumbnail");
showThumbnails_ = settings.value("ShowThumbnails", true).toBool();
setMaxThumbnailFileSize(settings.value("MaxThumbnailFileSize", 4096).toInt());
setThumbnailLocalFilesOnly(settings.value("ThumbnailLocalFilesOnly", true).toBool());
settings.endGroup();
settings.beginGroup("FolderView");
viewMode_ = viewModeFromString(settings.value("Mode", Fm::FolderView::IconMode).toString());
showHidden_ = settings.value("ShowHidden", false).toBool();
sortOrder_ = sortOrderFromString(settings.value("SortOrder").toString());
sortColumn_ = sortColumnFromString(settings.value("SortColumn").toString());
sortFolderFirst_ = settings.value("SortFolderFirst", true).toBool();
showFilter_ = settings.value("ShowFilter", false).toBool();
setBackupAsHidden(settings.value("BackupAsHidden", false).toBool());
showFullNames_ = settings.value("ShowFullNames", false).toBool();
shadowHidden_ = settings.value("ShadowHidden", false).toBool();
// override config in libfm's FmConfig
bigIconSize_ = settings.value("BigIconSize", 48).toInt();
smallIconSize_ = settings.value("SmallIconSize", 24).toInt();
sidePaneIconSize_ = settings.value("SidePaneIconSize", 24).toInt();
thumbnailIconSize_ = settings.value("ThumbnailIconSize", 128).toInt();
folderViewCellMargins_ = (settings.value("FolderViewCellMargins", QSize(3, 3)).toSize()
.expandedTo(QSize(0, 0))).boundedTo(QSize(48, 48));
settings.endGroup();
settings.beginGroup("Places");
placesHome_ = settings.value("PlacesHome", true).toBool();
placesDesktop_ = settings.value("PlacesDesktop", true).toBool();
placesApplications_ = settings.value("PlacesApplications", true).toBool();
placesTrash_ = settings.value("PlacesTrash", true).toBool();
placesRoot_ = settings.value("PlacesRoot", true).toBool();
placesComputer_ = settings.value("PlacesComputer", true).toBool();
placesNetwork_ = settings.value("PlacesNetwork", true).toBool();
settings.endGroup();
settings.beginGroup("Window");
fixedWindowWidth_ = settings.value("FixedWidth", 640).toInt();
fixedWindowHeight_ = settings.value("FixedHeight", 480).toInt();
lastWindowWidth_ = settings.value("LastWindowWidth", 640).toInt();
lastWindowHeight_ = settings.value("LastWindowHeight", 480).toInt();
lastWindowMaximized_ = settings.value("LastWindowMaximized", false).toBool();
rememberWindowSize_ = settings.value("RememberWindowSize", true).toBool();
alwaysShowTabs_ = settings.value("AlwaysShowTabs", true).toBool();
showTabClose_ = settings.value("ShowTabClose", true).toBool();
splitterPos_ = settings.value("SplitterPos", 150).toInt();
sidePaneMode_ = sidePaneModeFromString(settings.value("SidePaneMode").toString());
showMenuBar_ = settings.value("ShowMenuBar", true).toBool();
fullWidthTabBar_ = settings.value("FullWidthTabBar", true).toBool();
settings.endGroup();
return true;
}
bool Settings::saveFile(QString filePath) {
QSettings settings(filePath, QSettings::IniFormat);
settings.beginGroup("System");
settings.setValue("FallbackIconThemeName", fallbackIconThemeName_);
settings.setValue("SuCommand", suCommand_);
settings.setValue("Terminal", terminal_);
settings.setValue("Archiver", archiver_);
settings.setValue("SIUnit", siUnit_);
settings.setValue("OnlyUserTemplates", onlyUserTemplates_);
settings.setValue("TemplateTypeOnce", templateTypeOnce_);
settings.setValue("TemplateRunApp", templateRunApp_);
settings.endGroup();
settings.beginGroup("Behavior");
settings.setValue("BookmarkOpenMethod", bookmarkOpenMethodToString(bookmarkOpenMethod_));
// settings for use with libfm
settings.setValue("UseTrash", useTrash_);
settings.setValue("SingleClick", singleClick_);
settings.setValue("AutoSelectionDelay", autoSelectionDelay_);
settings.setValue("ConfirmDelete", confirmDelete_);
settings.setValue("NoUsbTrash", noUsbTrash_);
settings.setValue("ConfirmTrash", confirmTrash_);
settings.setValue("QuickExec", quickExec_);
// bool thumbnailLocal_;
// bool thumbnailMax;
settings.endGroup();
settings.beginGroup("Desktop");
settings.setValue("WallpaperMode", wallpaperModeToString(wallpaperMode_));
settings.setValue("Wallpaper", wallpaper_);
settings.setValue("BgColor", desktopBgColor_.name());
settings.setValue("FgColor", desktopFgColor_.name());
settings.setValue("ShadowColor", desktopShadowColor_.name());
settings.setValue("Font", desktopFont_.toString());
settings.setValue("ShowWmMenu", showWmMenu_);
settings.setValue("ShowHidden", desktopShowHidden_);
settings.setValue("SortOrder", sortOrderToString(desktopSortOrder_));
settings.setValue("SortColumn", sortColumnToString(desktopSortColumn_));
settings.setValue("DesktopCellMargins", desktopCellMargins_);
settings.endGroup();
settings.beginGroup("Volume");
settings.setValue("MountOnStartup", mountOnStartup_);
settings.setValue("MountRemovable", mountRemovable_);
settings.setValue("AutoRun", autoRun_);
settings.setValue("CloseOnUnmount", closeOnUnmount_);
settings.endGroup();
settings.beginGroup("Thumbnail");
settings.setValue("ShowThumbnails", showThumbnails_);
settings.setValue("MaxThumbnailFileSize", maxThumbnailFileSize());
settings.setValue("ThumbnailLocalFilesOnly", thumbnailLocalFilesOnly());
settings.endGroup();
settings.beginGroup("FolderView");
settings.setValue("Mode", viewModeToString(viewMode_));
settings.setValue("ShowHidden", showHidden_);
settings.setValue("SortOrder", sortOrderToString(sortOrder_));
settings.setValue("SortColumn", sortColumnToString(sortColumn_));
settings.setValue("SortFolderFirst", sortFolderFirst_);
settings.setValue("ShowFilter", showFilter_);
settings.setValue("BackupAsHidden", backupAsHidden_);
settings.setValue("ShowFullNames", showFullNames_);
settings.setValue("ShadowHidden", shadowHidden_);
// override config in libfm's FmConfig
settings.setValue("BigIconSize", bigIconSize_);
settings.setValue("SmallIconSize", smallIconSize_);
settings.setValue("SidePaneIconSize", sidePaneIconSize_);
settings.setValue("ThumbnailIconSize", thumbnailIconSize_);
settings.setValue("FolderViewCellMargins", folderViewCellMargins_);
settings.endGroup();
settings.beginGroup("Places");
settings.setValue("PlacesHome", placesHome_);
settings.setValue("PlacesDesktop", placesDesktop_);
settings.setValue("PlacesApplications", placesApplications_);
settings.setValue("PlacesTrash", placesTrash_);
settings.setValue("PlacesRoot", placesRoot_);
settings.setValue("PlacesComputer", placesComputer_);
settings.setValue("PlacesNetwork", placesNetwork_);
settings.endGroup();
settings.beginGroup("Window");
settings.setValue("FixedWidth", fixedWindowWidth_);
settings.setValue("FixedHeight", fixedWindowHeight_);
settings.setValue("LastWindowWidth", lastWindowWidth_);
settings.setValue("LastWindowHeight", lastWindowHeight_);
settings.setValue("LastWindowMaximized", lastWindowMaximized_);
settings.setValue("RememberWindowSize", rememberWindowSize_);
settings.setValue("AlwaysShowTabs", alwaysShowTabs_);
settings.setValue("ShowTabClose", showTabClose_);
settings.setValue("SplitterPos", splitterPos_);
settings.setValue("SidePaneMode", sidePaneModeToString(sidePaneMode_));
settings.setValue("ShowMenuBar", showMenuBar_);
settings.setValue("FullWidthTabBar", fullWidthTabBar_);
settings.endGroup();
return true;
}
static const char* bookmarkOpenMethodToString(OpenDirTargetType value) {
switch(value) {
case OpenInCurrentTab:
default:
return "current_tab";
case OpenInNewTab:
return "new_tab";
case OpenInNewWindow:
return "new_window";
case OpenInLastActiveWindow:
return "last_window";
}
return "";
}
static OpenDirTargetType bookmarkOpenMethodFromString(const QString str) {
if(str == QStringLiteral("new_tab"))
return OpenInNewTab;
else if(str == QStringLiteral("new_window"))
return OpenInNewWindow;
else if(str == QStringLiteral("last_window"))
return OpenInLastActiveWindow;
return OpenInCurrentTab;
}
static const char* viewModeToString(Fm::FolderView::ViewMode value) {
const char* ret;
switch(value) {
case Fm::FolderView::IconMode:
default:
ret = "icon";
break;
case Fm::FolderView::CompactMode:
ret = "compact";
break;
case Fm::FolderView::DetailedListMode:
ret = "detailed";
break;
case Fm::FolderView::ThumbnailMode:
ret = "thumbnail";
break;
}
return ret;
}
Fm::FolderView::ViewMode viewModeFromString(const QString str) {
Fm::FolderView::ViewMode ret;
if(str == "icon")
ret = Fm::FolderView::IconMode;
else if(str == "compact")
ret = Fm::FolderView::CompactMode;
else if(str == "detailed")
ret = Fm::FolderView::DetailedListMode;
else if(str == "thumbnail")
ret = Fm::FolderView::ThumbnailMode;
else
ret = Fm::FolderView::IconMode;
return ret;
}
static const char* sortOrderToString(Qt::SortOrder order) {
return (order == Qt::DescendingOrder ? "descending" : "ascending");
}
static Qt::SortOrder sortOrderFromString(const QString str) {
return (str == "descending" ? Qt::DescendingOrder : Qt::AscendingOrder);
}
static const char* sortColumnToString(Fm::FolderModel::ColumnId value) {
const char* ret;
switch(value) {
case Fm::FolderModel::ColumnFileName:
default:
ret = "name";
break;
case Fm::FolderModel::ColumnFileType:
ret = "type";
break;
case Fm::FolderModel::ColumnFileSize:
ret = "size";
break;
case Fm::FolderModel::ColumnFileMTime:
ret = "mtime";
break;
case Fm::FolderModel::ColumnFileOwner:
ret = "owner";
break;
}
return ret;
}
static Fm::FolderModel::ColumnId sortColumnFromString(const QString str) {
Fm::FolderModel::ColumnId ret;
if(str == "name")
ret = Fm::FolderModel::ColumnFileName;
else if(str == "type")
ret = Fm::FolderModel::ColumnFileType;
else if(str == "size")
ret = Fm::FolderModel::ColumnFileSize;
else if(str == "mtime")
ret = Fm::FolderModel::ColumnFileMTime;
else if(str == "owner")
ret = Fm::FolderModel::ColumnFileOwner;
else
ret = Fm::FolderModel::ColumnFileName;
return ret;
}
static const char* wallpaperModeToString(int value) {
const char* ret;
switch(value) {
case DesktopWindow::WallpaperNone:
default:
ret = "none";
break;
case DesktopWindow::WallpaperStretch:
ret = "stretch";
break;
case DesktopWindow::WallpaperFit:
ret = "fit";
break;
case DesktopWindow::WallpaperCenter:
ret = "center";
break;
case DesktopWindow::WallpaperTile:
ret = "tile";
break;
}
return ret;
}
static int wallpaperModeFromString(const QString str) {
int ret;
if(str == "stretch")
ret = DesktopWindow::WallpaperStretch;
else if(str == "fit")
ret = DesktopWindow::WallpaperFit;
else if(str == "center")
ret = DesktopWindow::WallpaperCenter;
else if(str == "tile")
ret = DesktopWindow::WallpaperTile;
else
ret = DesktopWindow::WallpaperNone;
return ret;
}
static const char* sidePaneModeToString(Fm::SidePane::Mode value) {
const char* ret;
switch(value) {
case Fm::SidePane::ModePlaces:
default:
ret = "places";
break;
case Fm::SidePane::ModeDirTree:
ret = "dirtree";
break;
case Fm::SidePane::ModeNone:
ret = "none";
break;
}
return ret;
}
static Fm::SidePane::Mode sidePaneModeFromString(const QString& str) {
Fm::SidePane::Mode ret;
if(str == "none")
ret = Fm::SidePane::ModeNone;
else if(str == "dirtree")
ret = Fm::SidePane::ModeDirTree;
else
ret = Fm::SidePane::ModePlaces;
return ret;
}
void Settings::setTerminal(QString terminalCommand) {
terminal_ = terminalCommand;
// override the settings in libfm FmConfig.
g_free(fm_config->terminal);
fm_config->terminal = g_strdup(terminal_.toLocal8Bit().constData());
g_signal_emit_by_name(fm_config, "changed::terminal");
}
} // namespace PCManFM

View File

@ -1,718 +0,0 @@
/*
Copyright (C) 2013 Hong Jen Yee (PCMan) <pcman.tw@gmail.com>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#ifndef PCMANFM_SETTINGS_H
#define PCMANFM_SETTINGS_H
#include <QObject>
#include <libfm/fm.h>
#include <libfm-qt/folderview.h>
#include <libfm-qt/foldermodel.h>
#include "desktopwindow.h"
#include <libfm-qt/sidepane.h>
#include <libfm-qt/thumbnailloader.h>
namespace PCManFM {
enum OpenDirTargetType {
OpenInCurrentTab,
OpenInNewTab,
OpenInNewWindow,
OpenInLastActiveWindow
};
class Settings : public QObject {
Q_OBJECT
public:
Settings();
virtual ~Settings();
bool load(QString profile = "default");
bool save(QString profile = QString());
bool loadFile(QString filePath);
bool saveFile(QString filePath);
QString profileDir(QString profile, bool useFallback = false);
// setter/getter functions
QString profileName() const {
return profileName_;
}
bool supportTrash() const {
return supportTrash_;
}
QString fallbackIconThemeName() const {
return fallbackIconThemeName_;
}
bool useFallbackIconTheme() const {
return useFallbackIconTheme_;
}
void setFallbackIconThemeName(QString iconThemeName) {
fallbackIconThemeName_ = iconThemeName;
}
OpenDirTargetType bookmarkOpenMethod() {
return bookmarkOpenMethod_;
}
void setBookmarkOpenMethod(OpenDirTargetType bookmarkOpenMethod) {
bookmarkOpenMethod_ = bookmarkOpenMethod;
}
QString suCommand() const {
return suCommand_;
}
void setSuCommand(QString suCommand) {
suCommand_ = suCommand;
}
QString terminal() {
return terminal_;
}
void setTerminal(QString terminalCommand);
QString archiver() const {
return archiver_;
}
void setArchiver(QString archiver) {
archiver_ = archiver;
// override libfm FmConfig
g_free(fm_config->archiver);
fm_config->archiver = g_strdup(archiver_.toLocal8Bit().constData());
}
bool mountOnStartup() const {
return mountOnStartup_;
}
void setMountOnStartup(bool mountOnStartup) {
mountOnStartup_ = mountOnStartup;
}
bool mountRemovable() {
return mountRemovable_;
}
void setMountRemovable(bool mountRemovable) {
mountRemovable_ = mountRemovable;
}
bool autoRun() const {
return autoRun_;
}
void setAutoRun(bool autoRun) {
autoRun_ = autoRun;
}
bool closeOnUnmount() const {
return closeOnUnmount_;
}
void setCloseOnUnmount(bool value) {
closeOnUnmount_ = value;
}
DesktopWindow::WallpaperMode wallpaperMode() const {
return DesktopWindow::WallpaperMode(wallpaperMode_);
}
void setWallpaperMode(int wallpaperMode) {
wallpaperMode_ = wallpaperMode;
}
QString wallpaper() const {
return wallpaper_;
}
void setWallpaper(QString wallpaper) {
wallpaper_ = wallpaper;
}
const QColor& desktopBgColor() const {
return desktopBgColor_;
}
void setDesktopBgColor(QColor desktopBgColor) {
desktopBgColor_ = desktopBgColor;
}
const QColor& desktopFgColor() const {
return desktopFgColor_;
}
void setDesktopFgColor(QColor desktopFgColor) {
desktopFgColor_ = desktopFgColor;
}
const QColor& desktopShadowColor() const {
return desktopShadowColor_;
}
void setDesktopShadowColor(QColor desktopShadowColor) {
desktopShadowColor_ = desktopShadowColor;
}
QFont desktopFont() const {
return desktopFont_;
}
void setDesktopFont(QFont font) {
desktopFont_ = font;
}
bool showWmMenu() const {
return showWmMenu_;
}
void setShowWmMenu(bool value) {
showWmMenu_ = value;
}
bool desktopShowHidden() const {
return desktopShowHidden_;
}
void setDesktopShowHidden(bool desktopShowHidden) {
desktopShowHidden_ = desktopShowHidden;
}
Qt::SortOrder desktopSortOrder() const {
return desktopSortOrder_;
}
void setDesktopSortOrder(Qt::SortOrder desktopSortOrder) {
desktopSortOrder_ = desktopSortOrder;
}
Fm::FolderModel::ColumnId desktopSortColumn() const {
return desktopSortColumn_;
}
void setDesktopSortColumn(Fm::FolderModel::ColumnId desktopSortColumn) {
desktopSortColumn_ = desktopSortColumn;
}
bool alwaysShowTabs() const {
return alwaysShowTabs_;
}
void setAlwaysShowTabs(bool alwaysShowTabs) {
alwaysShowTabs_ = alwaysShowTabs;
}
bool showTabClose() const {
return showTabClose_;
}
void setShowTabClose(bool showTabClose) {
showTabClose_ = showTabClose;
}
bool rememberWindowSize() const {
return rememberWindowSize_;
}
void setRememberWindowSize(bool rememberWindowSize) {
rememberWindowSize_ = rememberWindowSize;
}
int windowWidth() const {
if(rememberWindowSize_)
return lastWindowWidth_;
else
return fixedWindowWidth_;
}
int windowHeight() const {
if(rememberWindowSize_)
return lastWindowHeight_;
else
return fixedWindowHeight_;
}
bool windowMaximized() const {
if(rememberWindowSize_)
return lastWindowMaximized_;
else
return false;
}
int fixedWindowWidth() const {
return fixedWindowWidth_;
}
void setFixedWindowWidth(int fixedWindowWidth) {
fixedWindowWidth_ = fixedWindowWidth;
}
int fixedWindowHeight() const {
return fixedWindowHeight_;
}
void setFixedWindowHeight(int fixedWindowHeight) {
fixedWindowHeight_ = fixedWindowHeight;
}
void setLastWindowWidth(int lastWindowWidth) {
lastWindowWidth_ = lastWindowWidth;
}
void setLastWindowHeight(int lastWindowHeight) {
lastWindowHeight_ = lastWindowHeight;
}
void setLastWindowMaximized(bool lastWindowMaximized) {
lastWindowMaximized_ = lastWindowMaximized;
}
int splitterPos() const {
return splitterPos_;
}
void setSplitterPos(int splitterPos) {
splitterPos_ = splitterPos;
}
Fm::SidePane::Mode sidePaneMode() const {
return sidePaneMode_;
}
void setSidePaneMode(Fm::SidePane::Mode sidePaneMode) {
sidePaneMode_ = sidePaneMode;
}
bool showMenuBar() const {
return showMenuBar_;
}
void setShowMenuBar(bool showMenuBar) {
showMenuBar_ = showMenuBar;
}
bool fullWidthTabBar() const {
return fullWidthTabBar_;
}
void setFullWidthTabBar(bool fullWith) {
fullWidthTabBar_ = fullWith;
}
Fm::FolderView::ViewMode viewMode() const {
return viewMode_;
}
void setViewMode(Fm::FolderView::ViewMode viewMode) {
viewMode_ = viewMode;
}
bool showHidden() const {
return showHidden_;
}
void setShowHidden(bool showHidden) {
showHidden_ = showHidden;
}
bool placesHome() const {
return placesHome_;
}
void setPlacesHome(bool placesHome) {
placesHome_ = placesHome;
}
bool placesDesktop() const {
return placesDesktop_;
}
void setPlacesDesktop(bool placesDesktop) {
placesDesktop_ = placesDesktop;
}
bool placesApplications() const {
return placesApplications_;
}
void setPlacesApplications(bool placesApplications) {
placesApplications_ = placesApplications;
}
bool placesTrash() const {
return placesTrash_;
}
void setPlacesTrash(bool placesTrash) {
placesTrash_ = placesTrash;
}
bool placesRoot() const {
return placesRoot_;
}
void setPlacesRoot(bool placesRoot) {
placesRoot_ = placesRoot;
}
bool placesComputer() const {
return placesComputer_;
}
void setPlacesComputer(bool placesComputer) {
placesComputer_ = placesComputer;
}
bool placesNetwork() const {
return placesNetwork_;
}
void setPlacesNetwork(bool placesNetwork) {
placesNetwork_ = placesNetwork;
}
Qt::SortOrder sortOrder() const {
return sortOrder_;
}
void setSortOrder(Qt::SortOrder sortOrder) {
sortOrder_ = sortOrder;
}
Fm::FolderModel::ColumnId sortColumn() const {
return sortColumn_;
}
void setSortColumn(Fm::FolderModel::ColumnId sortColumn) {
sortColumn_ = sortColumn;
}
bool sortFolderFirst() const {
return sortFolderFirst_;
}
void setSortFolderFirst(bool folderFirst) {
sortFolderFirst_ = folderFirst;
}
bool showFilter() const {
return showFilter_;
}
void setShowFilter(bool value) {
showFilter_ = value;
}
// settings for use with libfm
bool singleClick() const {
return singleClick_;
}
void setSingleClick(bool singleClick) {
singleClick_ = singleClick;
}
int autoSelectionDelay() const {
return autoSelectionDelay_;
}
void setAutoSelectionDelay(int value) {
autoSelectionDelay_ = value;
}
bool useTrash() const {
if(!supportTrash_)
return false;
return useTrash_;
}
void setUseTrash(bool useTrash) {
useTrash_ = useTrash;
}
bool confirmDelete() const {
return confirmDelete_;
}
void setConfirmDelete(bool confirmDelete) {
confirmDelete_ = confirmDelete;
}
bool noUsbTrash() const {
return noUsbTrash_;
}
void setNoUsbTrash(bool noUsbTrash) {
noUsbTrash_ = noUsbTrash;
fm_config->no_usb_trash = noUsbTrash_; // also set this to libfm since FmFileOpsJob reads this config value before trashing files.
}
bool confirmTrash() const {
return confirmTrash_;
}
void setConfirmTrash(bool value) {
confirmTrash_ = value;
}
bool quickExec() const {
return quickExec_;
}
void setQuickExec(bool value) {
quickExec_ = value;
fm_config->quick_exec = quickExec_;
}
// bool thumbnailLocal_;
// bool thumbnailMax;
int bigIconSize() const {
return bigIconSize_;
}
void setBigIconSize(int bigIconSize) {
bigIconSize_ = bigIconSize;
}
int smallIconSize() const {
return smallIconSize_;
}
void setSmallIconSize(int smallIconSize) {
smallIconSize_ = smallIconSize;
}
int sidePaneIconSize() const {
return sidePaneIconSize_;
}
void setSidePaneIconSize(int sidePaneIconSize) {
sidePaneIconSize_ = sidePaneIconSize;
}
int thumbnailIconSize() const {
return thumbnailIconSize_;
}
QSize folderViewCellMargins() const {
return folderViewCellMargins_;
}
void setFolderViewCellMargins(QSize size) {
folderViewCellMargins_ = size;
}
QSize desktopCellMargins() const {
return desktopCellMargins_;
}
void setDesktopCellMargins(QSize size) {
desktopCellMargins_ = size;
}
bool showThumbnails() {
return showThumbnails_;
}
void setShowThumbnails(bool show) {
showThumbnails_ = show;
}
void setThumbnailLocalFilesOnly(bool value) {
Fm::ThumbnailLoader::setLocalFilesOnly(value);
}
bool thumbnailLocalFilesOnly() {
return Fm::ThumbnailLoader::localFilesOnly();
}
int maxThumbnailFileSize() {
return Fm::ThumbnailLoader::maxThumbnailFileSize();
}
void setMaxThumbnailFileSize(int size) {
Fm::ThumbnailLoader::setMaxThumbnailFileSize(size);
}
void setThumbnailIconSize(int thumbnailIconSize) {
thumbnailIconSize_ = thumbnailIconSize;
}
bool siUnit() {
return siUnit_;
}
void setSiUnit(bool siUnit) {
siUnit_ = siUnit;
// override libfm FmConfig settings. FIXME: should we do this?
fm_config->si_unit = (gboolean)siUnit_;
}
bool backupAsHidden() const {
return backupAsHidden_;
}
void setBackupAsHidden(bool value) {
backupAsHidden_ = value;
fm_config->backup_as_hidden = backupAsHidden_; // also set this to libfm since fm_file_info_is_hidden() reads this value internally.
}
bool showFullNames() const {
return showFullNames_;
}
void setShowFullNames(bool value) {
showFullNames_ = value;
}
bool shadowHidden() const {
return shadowHidden_;
}
void setShadowHidden(bool value) {
shadowHidden_ = value;
}
bool onlyUserTemplates() const {
return onlyUserTemplates_;
}
void setOnlyUserTemplates(bool value) {
onlyUserTemplates_ = value;
fm_config->only_user_templates = onlyUserTemplates_;
}
bool templateTypeOnce() const {
return templateTypeOnce_;
}
void setTemplateTypeOnce(bool value) {
templateTypeOnce_ = value;
fm_config->template_type_once = templateTypeOnce_;
}
bool templateRunApp() const {
return templateRunApp_;
}
void setTemplateRunApp(bool value) {
templateRunApp_ = value;
fm_config->template_run_app = templateRunApp_;
}
private:
QString profileName_;
bool supportTrash_;
// PCManFM specific
QString fallbackIconThemeName_;
bool useFallbackIconTheme_;
OpenDirTargetType bookmarkOpenMethod_;
QString suCommand_;
QString terminal_;
bool mountOnStartup_;
bool mountRemovable_;
bool autoRun_;
bool closeOnUnmount_;
int wallpaperMode_;
QString wallpaper_;
QColor desktopBgColor_;
QColor desktopFgColor_;
QColor desktopShadowColor_;
QFont desktopFont_;
bool showWmMenu_;
bool desktopShowHidden_;
Qt::SortOrder desktopSortOrder_;
Fm::FolderModel::ColumnId desktopSortColumn_;
bool alwaysShowTabs_;
bool showTabClose_;
bool rememberWindowSize_;
int fixedWindowWidth_;
int fixedWindowHeight_;
int lastWindowWidth_;
int lastWindowHeight_;
bool lastWindowMaximized_;
int splitterPos_;
Fm::SidePane::Mode sidePaneMode_;
bool showMenuBar_;
bool fullWidthTabBar_;
Fm::FolderView::ViewMode viewMode_;
bool showHidden_;
Qt::SortOrder sortOrder_;
Fm::FolderModel::ColumnId sortColumn_;
bool sortFolderFirst_;
bool showFilter_;
// settings for use with libfm
bool singleClick_;
int autoSelectionDelay_;
bool useTrash_;
bool confirmDelete_;
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 showThumbnails_;
QString archiver_;
bool siUnit_;
bool backupAsHidden_;
bool showFullNames_;
bool shadowHidden_;
bool placesHome_;
bool placesDesktop_;
bool placesApplications_;
bool placesTrash_;
bool placesRoot_;
bool placesComputer_;
bool placesNetwork_;
int bigIconSize_;
int smallIconSize_;
int sidePaneIconSize_;
int thumbnailIconSize_;
bool onlyUserTemplates_;
bool templateTypeOnce_;
bool templateRunApp_;
QSize folderViewCellMargins_;
QSize desktopCellMargins_;
};
}
#endif // PCMANFM_SETTINGS_H

View File

@ -1,41 +0,0 @@
/*
Copyright (C) 2014 Kuzma Shapran <kuzma.shapran@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 "tabbar.h"
#include <QMouseEvent>
namespace PCManFM {
TabBar::TabBar(QWidget *parent):
QTabBar(parent)
{
}
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);
}
}

View File

@ -1,42 +0,0 @@
/*
Copyright (C) 2014 Kuzma Shapran <kuzma.shapran@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 FM_TABBAR_H
#define FM_TABBAR_H
#include <QTabBar>
class QMouseEvent;
namespace PCManFM {
class TabBar : public QTabBar {
Q_OBJECT
public:
explicit TabBar(QWidget *parent = 0);
protected:
void mouseReleaseEvent(QMouseEvent *event);
};
}
#endif // FM_TABBAR_H

View File

@ -1,539 +0,0 @@
/*
Copyright (C) 2013 Hong Jen Yee (PCMan) <pcman.tw@gmail.com>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#include "tabpage.h"
#include "launcher.h"
#include <libfm-qt/filemenu.h>
#include <libfm-qt/mountoperation.h>
#include <QApplication>
#include <QCursor>
#include <QMessageBox>
#include <QScrollBar>
#include <libfm-qt/proxyfoldermodel.h>
#include "settings.h"
#include "application.h"
#include <libfm-qt/cachedfoldermodel.h>
#include <QTimer>
#include <QTextStream>
using namespace Fm;
namespace PCManFM {
bool ProxyFilter::filterAcceptsRow(const Fm::ProxyFolderModel* model, FmFileInfo* info) const {
if(!model || !info)
return true;
QString baseName(fm_file_info_get_name(info));
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(FmFolder* folder) {
virtHiddenList_ = QStringList(); // reset the list
if(!folder) return;
if(FmPath* path = fm_folder_get_path(folder)) {
char* pathStr = fm_path_to_str(path);
if(pathStr) {
QString dotHidden = QString(pathStr) + QString("/.hidden");
g_free(pathStr);
QFile file(dotHidden);
if(file.open(QIODevice::ReadOnly | QIODevice::Text)) {
QTextStream in(&file);
while(!in.atEnd())
virtHiddenList_.append(in.readLine());
file.close();
}
}
}
}
TabPage::TabPage(FmPath* path, QWidget* parent):
QWidget(parent),
folder_(NULL),
folderModel_(NULL),
overrideCursor_(false) {
Settings& settings = static_cast<Application*>(qApp)->settings();
// create proxy folder model to do item filtering
proxyModel_ = new ProxyFolderModel();
proxyModel_->setShowHidden(settings.showHidden());
proxyModel_->setShowThumbnails(settings.showThumbnails());
connect(proxyModel_, &ProxyFolderModel::sortFilterChanged, this, &TabPage::onModelSortFilterChanged);
verticalLayout = new QVBoxLayout(this);
verticalLayout->setContentsMargins(0, 0, 0, 0);
folderView_ = new View(settings.viewMode(), this);
folderView_->setMargins(settings.folderViewCellMargins());
// newView->setColumnWidth(Fm::FolderModel::ColumnName, 200);
connect(folderView_, &View::openDirRequested, this, &TabPage::onOpenDirRequested);
connect(folderView_, &View::selChanged, this, &TabPage::onSelChanged);
connect(folderView_, &View::clickedBack, this, &TabPage::backwardRequested);
connect(folderView_, &View::clickedForward, this, &TabPage::forwardRequested);
proxyFilter_ = new ProxyFilter();
proxyModel_->addFilter(proxyFilter_);
// FIXME: this is very dirty
folderView_->setModel(proxyModel_);
verticalLayout->addWidget(folderView_);
chdir(path, true);
}
TabPage::~TabPage() {
freeFolder();
if(proxyFilter_)
delete proxyFilter_;
if(proxyModel_)
delete proxyModel_;
if(folderModel_)
folderModel_->unref();
if(overrideCursor_) {
QApplication::restoreOverrideCursor(); // remove busy cursor
}
}
void TabPage::freeFolder() {
if(folder_) {
g_signal_handlers_disconnect_by_func(folder_, (gpointer)onFolderStartLoading, this);
g_signal_handlers_disconnect_by_func(folder_, (gpointer)onFolderFinishLoading, this);
g_signal_handlers_disconnect_by_func(folder_, (gpointer)onFolderError, this);
g_signal_handlers_disconnect_by_func(folder_, (gpointer)onFolderFsInfo, this);
g_signal_handlers_disconnect_by_func(folder_, (gpointer)onFolderRemoved, this);
g_signal_handlers_disconnect_by_func(folder_, (gpointer)onFolderUnmount, this);
g_signal_handlers_disconnect_by_func(folder_, (gpointer)onFolderContentChanged, this);
g_object_unref(folder_);
folder_ = NULL;
}
}
/*static*/ void TabPage::onFolderStartLoading(FmFolder* _folder, TabPage* pThis) {
if(!pThis->overrideCursor_) {
// FIXME: sometimes FmFolder of libfm generates unpaired "start-loading" and
// "finish-loading" signals of uncertain reasons. This should be a bug in libfm.
// Until it's fixed in libfm, we need to workaround the problem here, not to
// override the cursor twice.
QApplication::setOverrideCursor(QCursor(Qt::WaitCursor));
pThis->overrideCursor_ = true;
}
#if 0
#if FM_CHECK_VERSION(1, 0, 2) && 0 // disabled
if(fm_folder_is_incremental(_folder)) {
/* create a model for the folder and set it to the view
it is delayed for non-incremental folders since adding rows into
model is much faster without handlers connected to its signals */
FmFolderModel* model = fm_folder_model_new(folder, FALSE);
fm_folder_view_set_model(fv, model);
fm_folder_model_set_sort(model, app_config->sort_by,
(app_config->sort_type == GTK_SORT_ASCENDING) ?
FM_SORT_ASCENDING : FM_SORT_DESCENDING);
g_object_unref(model);
}
else
#endif
fm_folder_view_set_model(fv, NULL);
#endif
}
// slot
void TabPage::restoreScrollPos() {
// scroll to recorded position
folderView_->childView()->verticalScrollBar()->setValue(browseHistory().currentScrollPos());
// if the current folder is the parent folder of the last browsed folder,
// select the folder item in current view.
if(lastFolderPath_.parent() == path()) {
QModelIndex index = folderView_->indexFromFolderPath(lastFolderPath_.data());
if(index.isValid()) {
folderView_->childView()->scrollTo(index, QAbstractItemView::EnsureVisible);
folderView_->childView()->setCurrentIndex(index);
}
}
}
/*static*/ void TabPage::onFolderFinishLoading(FmFolder* _folder, TabPage* pThis) {
// FIXME: is this needed?
FmFileInfo* fi = fm_folder_get_info(_folder);
if(fi) { // if loading of the folder fails, it's possible that we don't have FmFileInfo.
pThis->title_ = QString::fromUtf8(fm_file_info_get_disp_name(fi));
Q_EMIT pThis->titleChanged(pThis->title_);
}
fm_folder_query_filesystem_info(_folder); // FIXME: is this needed?
#if 0
FmFolderView* fv = folder_view;
const FmNavHistoryItem* item;
GtkScrolledWindow* scroll = GTK_SCROLLED_WINDOW(fv);
/* Note: most of the time, we delay the creation of the
* folder model and do it after the whole folder is loaded.
* That is because adding rows into model is much faster when no handlers
* are connected to its signals. So we detach the model from folder view
* and create the model again when it's fully loaded.
* This optimization, however, is not used for FmFolder objects
* with incremental loading (search://) */
if(fm_folder_view_get_model(fv) == NULL) {
/* create a model for the folder and set it to the view */
FmFolderModel* model = fm_folder_model_new(folder, app_config->show_hidden);
fm_folder_view_set_model(fv, model);
#if FM_CHECK_VERSION(1, 0, 2)
/* since 1.0.2 sorting should be applied on model instead of view */
fm_folder_model_set_sort(model, app_config->sort_by,
(app_config->sort_type == GTK_SORT_ASCENDING) ?
FM_SORT_ASCENDING : FM_SORT_DESCENDING);
#endif
g_object_unref(model);
}
#endif
// update status text
QString& text = pThis->statusText_[StatusTextNormal];
text = pThis->formatStatusText();
Q_EMIT pThis->statusChanged(StatusTextNormal, text);
if(pThis->overrideCursor_) {
QApplication::restoreOverrideCursor(); // remove busy cursor
pThis->overrideCursor_ = false;
}
// After finishing loading the folder, the model is updated, but Qt delays the UI update
// for performance reasons. Therefore at this point the UI is not up to date.
// Of course, the scrollbar ranges are not updated yet. We solve this by installing an Qt timeout handler.
QTimer::singleShot(10, pThis, SLOT(restoreScrollPos()));
}
/*static*/ FmJobErrorAction TabPage::onFolderError(FmFolder* _folder, GError* err, FmJobErrorSeverity severity, TabPage* pThis) {
if(err->domain == G_IO_ERROR) {
if(err->code == G_IO_ERROR_NOT_MOUNTED && severity < FM_JOB_ERROR_CRITICAL) {
FmPath* path = fm_folder_get_path(_folder);
MountOperation* op = new MountOperation(pThis);
op->mount(path);
if(op->wait()) { // blocking event loop, wait for mount operation to finish.
// This will reload the folder, which generates a new "start-loading"
// signal, so we get more "start-loading" signals than "finish-loading"
// signals. FIXME: This is a bug of libfm.
// Because the two signals are not correctly paired, we need to
// remove busy cursor here since "finish-loading" is not emitted.
QApplication::restoreOverrideCursor(); // remove busy cursor
pThis->overrideCursor_ = false;
return FM_JOB_RETRY;
}
}
}
if(severity >= FM_JOB_ERROR_MODERATE) {
/* Only show more severe errors to the users and
* ignore milder errors. Otherwise too many error
* message boxes can be annoying.
* This fixes bug #3411298- Show "Permission denied" when switching to super user mode.
* https://sourceforge.net/tracker/?func=detail&aid=3411298&group_id=156956&atid=801864
* */
// FIXME: consider replacing this modal dialog with an info bar to improve usability
QMessageBox::critical(pThis, tr("Error"), QString::fromUtf8(err->message));
}
return FM_JOB_CONTINUE;
}
/*static*/ void TabPage::onFolderFsInfo(FmFolder* _folder, TabPage* pThis) {
guint64 free, total;
QString& msg = pThis->statusText_[StatusTextFSInfo];
if(fm_folder_get_filesystem_info(_folder, &total, &free)) {
char total_str[64];
char free_str[64];
fm_file_size_to_str(free_str, sizeof(free_str), free, fm_config->si_unit);
fm_file_size_to_str(total_str, sizeof(total_str), total, fm_config->si_unit);
msg = tr("Free space: %1 (Total: %2)")
.arg(QString::fromUtf8(free_str))
.arg(QString::fromUtf8(total_str));
}
else
msg.clear();
Q_EMIT pThis->statusChanged(StatusTextFSInfo, msg);
}
QString TabPage::formatStatusText() {
if(proxyModel_ && folder_) {
FmFileInfoList* files = fm_folder_get_files(folder_);
int total_files = fm_file_info_list_get_length(files);
int shown_files = proxyModel_->rowCount();
int hidden_files = total_files - shown_files;
QString text = tr("%n item(s)", "", shown_files);
if(hidden_files > 0)
text += tr(" (%n hidden)", "", hidden_files);
return text;
}
return QString();
}
/*static*/ void TabPage::onFolderRemoved(FmFolder* _folder, TabPage* pThis) {
// the folder we're showing is removed, destroy the widget
qDebug("folder removed");
Settings& settings = static_cast<Application*>(qApp)->settings();
// NOTE: call pThis->deleteLater() directly from this GObject signal handler
// does not work but I don't know why.
// Maybe it's the problem of glib mainloop integration?
// Call it when idle works, though.
if(settings.closeOnUnmount())
QTimer::singleShot(0, pThis, SLOT(deleteLater()));
else
pThis->chdir(fm_path_get_home());
}
/*static*/ void TabPage::onFolderUnmount(FmFolder* _folder, TabPage* pThis) {
// the folder we're showing is unmounted, destroy the widget
qDebug("folder unmount");
// NOTE: call pThis->deleteLater() directly from this GObject signal handler
// does not work but I don't know why.
// Maybe it's the problem of glib mainloop integration?
// Call it when idle works, though.
Settings& settings = static_cast<Application*>(qApp)->settings();
// NOTE: call pThis->deleteLater() directly from this GObject signal handler
// does not work but I don't know why.
// Maybe it's the problem of glib mainloop integration?
// Call it when idle works, though.
if(settings.closeOnUnmount())
QTimer::singleShot(0, pThis, SLOT(deleteLater()));
else
pThis->chdir(fm_path_get_home());
}
/*static */ void TabPage::onFolderContentChanged(FmFolder* _folder, TabPage* pThis) {
/* update status text */
pThis->statusText_[StatusTextNormal] = pThis->formatStatusText();
Q_EMIT pThis->statusChanged(StatusTextNormal, pThis->statusText_[StatusTextNormal]);
}
QString TabPage::pathName() {
char* disp_path = fm_path_display_name(path(), TRUE);
QString ret = QString::fromUtf8(disp_path);
g_free(disp_path);
return ret;
}
void TabPage::chdir(FmPath* newPath, bool addHistory) {
if(folder_) {
// we're already in the specified dir
if(fm_path_equal(newPath, fm_folder_get_path(folder_)))
return;
// remember the previous folder path that we have browsed.
lastFolderPath_ = fm_folder_get_path(folder_);
if(addHistory) {
// store current scroll pos in the browse history
BrowseHistoryItem& item = history_.currentItem();
QAbstractItemView* childView = folderView_->childView();
item.setScrollPos(childView->verticalScrollBar()->value());
}
// free the previous model
if(folderModel_) {
proxyModel_->setSourceModel(NULL);
folderModel_->unref(); // unref the cached model
folderModel_ = NULL;
}
freeFolder();
}
char* disp_name = fm_path_display_basename(newPath);
title_ = QString::fromUtf8(disp_name);
Q_EMIT titleChanged(title_);
g_free(disp_name);
folder_ = fm_folder_from_path(newPath);
proxyFilter_->setVirtHidden(folder_);
if(addHistory) {
// add current path to browse history
history_.add(path());
}
g_signal_connect(folder_, "start-loading", G_CALLBACK(onFolderStartLoading), this);
g_signal_connect(folder_, "finish-loading", G_CALLBACK(onFolderFinishLoading), this);
g_signal_connect(folder_, "error", G_CALLBACK(onFolderError), this);
g_signal_connect(folder_, "fs-info", G_CALLBACK(onFolderFsInfo), this);
/* destroy the page when the folder is unmounted or deleted. */
g_signal_connect(folder_, "removed", G_CALLBACK(onFolderRemoved), this);
g_signal_connect(folder_, "unmount", G_CALLBACK(onFolderUnmount), this);
g_signal_connect(folder_, "content-changed", G_CALLBACK(onFolderContentChanged), this);
folderModel_ = CachedFolderModel::modelFromFolder(folder_);
proxyModel_->setSourceModel(folderModel_);
proxyModel_->sort(proxyModel_->sortColumn(), proxyModel_->sortOrder());
Settings& settings = static_cast<Application*>(qApp)->settings();
proxyModel_->setFolderFirst(settings.sortFolderFirst());
proxyModel_->sort(settings.sortColumn(), settings.sortOrder());
if(fm_folder_is_loaded(folder_)) {
onFolderStartLoading(folder_, this);
onFolderFinishLoading(folder_, this);
onFolderFsInfo(folder_, this);
}
else
onFolderStartLoading(folder_, this);
}
void TabPage::selectAll() {
folderView_->selectAll();
}
void TabPage::invertSelection() {
folderView_->invertSelection();
}
void TabPage::onOpenDirRequested(FmPath* path, int target) {
Q_EMIT openDirRequested(path, target);
}
// when the current selection in the folder view is changed
void TabPage::onSelChanged(int numSel) {
QString msg;
if(numSel > 0) {
/* FIXME: display total size of all selected files. */
if(numSel == 1) { /* only one file is selected */
FmFileInfoList* files = folderView_->selectedFiles();
FmFileInfo* fi = fm_file_info_list_peek_head(files);
const char* size_str = fm_file_info_get_disp_size(fi);
if(size_str) {
msg = QString("\"%1\" (%2) %3")
.arg(QString::fromUtf8(fm_file_info_get_disp_name(fi)))
.arg(QString::fromUtf8(size_str ? size_str : ""))
.arg(QString::fromUtf8(fm_file_info_get_desc(fi)));
}
else {
msg = QString("\"%1\" %2")
.arg(QString::fromUtf8(fm_file_info_get_disp_name(fi)))
.arg(QString::fromUtf8(fm_file_info_get_desc(fi)));
}
/* FIXME: should we support statusbar plugins as in the gtk+ version? */
fm_file_info_list_unref(files);
}
else {
goffset sum;
GList* l;
msg = tr("%1 item(s) selected", NULL, numSel).arg(numSel);
/* don't count if too many files are selected, that isn't lightweight */
if(numSel < 1000) {
sum = 0;
FmFileInfoList* files = folderView_->selectedFiles();
for(l = fm_file_info_list_peek_head_link(files); l; l = l->next) {
if(fm_file_info_is_dir(FM_FILE_INFO(l->data))) {
/* if we got a directory then we cannot tell it's size
unless we do deep count but we cannot afford it */
sum = -1;
break;
}
sum += fm_file_info_get_size(FM_FILE_INFO(l->data));
}
if(sum >= 0) {
char size_str[128];
fm_file_size_to_str(size_str, sizeof(size_str), sum,
fm_config->si_unit);
msg += QString(" (%1)").arg(QString::fromUtf8(size_str));
}
/* FIXME: should we support statusbar plugins as in the gtk+ version? */
fm_file_info_list_unref(files);
}
/* FIXME: can we show some more info on selection?
that isn't lightweight if a lot of files are selected */
}
}
statusText_[StatusTextSelectedFiles] = msg;
Q_EMIT statusChanged(StatusTextSelectedFiles, msg);
}
void TabPage::backward() {
// remember current scroll position
BrowseHistoryItem& item = history_.currentItem();
QAbstractItemView* childView = folderView_->childView();
item.setScrollPos(childView->verticalScrollBar()->value());
history_.backward();
chdir(history_.currentPath(), false);
}
void TabPage::forward() {
// remember current scroll position
BrowseHistoryItem& item = history_.currentItem();
QAbstractItemView* childView = folderView_->childView();
item.setScrollPos(childView->verticalScrollBar()->value());
history_.forward();
chdir(history_.currentPath(), false);
}
void TabPage::jumpToHistory(int index)
{
if(index >=0 && index < history_.size()) {
// remember current scroll position
BrowseHistoryItem& item = history_.currentItem();
QAbstractItemView* childView = folderView_->childView();
item.setScrollPos(childView->verticalScrollBar()->value());
history_.setCurrentIndex(index);
chdir(history_.currentPath(), false);
}
}
bool TabPage::canUp() {
return (path() != NULL && fm_path_get_parent(path()) != NULL);
}
void TabPage::up() {
FmPath* _path = path();
if(_path) {
FmPath* parent = fm_path_get_parent(_path);
if(parent) {
chdir(parent, true);
}
}
}
void TabPage::onModelSortFilterChanged() {
Q_EMIT sortFilterChanged();
}
void TabPage::updateFromSettings(Settings& settings) {
folderView_->updateFromSettings(settings);
}
void TabPage::setShowHidden(bool showHidden) {
if(!proxyModel_ || showHidden == proxyModel_->showHidden())
return;
proxyModel_->setShowHidden(showHidden);
statusText_[StatusTextNormal] = formatStatusText();
Q_EMIT statusChanged(StatusTextNormal, statusText_[StatusTextNormal]);
}
void TabPage:: applyFilter() {
if(!proxyModel_) return;
proxyModel_->updateFilters();
statusText_[StatusTextNormal] = formatStatusText();
Q_EMIT statusChanged(StatusTextNormal, statusText_[StatusTextNormal]);
}
} // namespace PCManFM

View File

@ -1,252 +0,0 @@
/*
Copyright (C) 2013 Hong Jen Yee (PCMan) <pcman.tw@gmail.com>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#ifndef FM_TABPAGE_H
#define FM_TABPAGE_H
#include <QWidget>
#include <QVBoxLayout>
#include <libfm/fm.h>
#include <libfm-qt/browsehistory.h>
#include "view.h"
#include <libfm-qt/path.h>
namespace Fm {
class FileLauncher;
class FolderModel;
class ProxyFolderModel;
class CachedFolderModel;
};
namespace PCManFM {
class Settings;
class Launcher;
class ProxyFilter : public Fm::ProxyFolderModelFilter {
public:
bool filterAcceptsRow(const Fm::ProxyFolderModel* model, FmFileInfo* info) const;
virtual ~ProxyFilter() {}
void setVirtHidden(FmFolder* folder);
QString getFilterStr() {
return filterStr_;
}
void setFilterStr(QString str) {
filterStr_ = str;
}
private:
QString filterStr_;
QStringList virtHiddenList_;
};
class TabPage : public QWidget {
Q_OBJECT
public:
enum StatusTextType {
StatusTextNormal,
StatusTextSelectedFiles,
StatusTextFSInfo,
StatusTextNum
};
public:
explicit TabPage(FmPath* path, QWidget* parent = nullptr);
virtual ~TabPage();
void chdir(FmPath* newPath, bool addHistory = true);
Fm::FolderView::ViewMode viewMode() {
return folderView_->viewMode();
}
void setViewMode(Fm::FolderView::ViewMode mode) {
folderView_->setViewMode(mode);
}
void sort(int col, Qt::SortOrder order = Qt::AscendingOrder) {
// if(folderModel_)
// folderModel_->sort(col, order);
if(proxyModel_)
proxyModel_->sort(col, order);
}
int sortColumn() {
return proxyModel_->sortColumn();
}
Qt::SortOrder sortOrder() {
return proxyModel_->sortOrder();
}
bool sortFolderFirst() {
return proxyModel_->folderFirst();
}
void setSortFolderFirst(bool value) {
proxyModel_->setFolderFirst(value);
}
bool sortCaseSensitive() {
return proxyModel_->sortCaseSensitivity();
}
void setSortCaseSensitive(bool value) {
proxyModel_->setSortCaseSensitivity(value ? Qt::CaseSensitive : Qt::CaseInsensitive);
}
bool showHidden() {
return proxyModel_->showHidden();
}
void setShowHidden(bool showHidden);
FmPath* path() {
return folder_ ? fm_folder_get_path(folder_) : nullptr;
}
QString pathName();
FmFolder* folder() {
return folder_;
}
Fm::FolderModel* folderModel() {
return reinterpret_cast<Fm::FolderModel*>(folderModel_);
}
View* folderView() {
return folderView_;
}
Fm::BrowseHistory& browseHistory() {
return history_;
}
FmFileInfoList* selectedFiles() {
return folderView_->selectedFiles();
}
FmPathList* selectedFilePaths() {
return folderView_->selectedFilePaths();
}
void selectAll();
void invertSelection();
void reload() {
if(folder_) {
proxyFilter_->setVirtHidden(folder_); // reread ".hidden"
fm_folder_reload(folder_);
}
}
QString title() const {
return title_;
}
QString statusText(StatusTextType type = StatusTextNormal) const {
return statusText_[type];
}
bool canBackward() {
return history_.canBackward();
}
void backward();
bool canForward() {
return history_.canForward();
}
void forward();
void jumpToHistory(int index);
bool canUp();
void up();
void updateFromSettings(Settings& settings);
void setFileLauncher(Fm::FileLauncher* launcher) {
folderView_->setFileLauncher(launcher);
}
Fm::FileLauncher* fileLauncher() {
return folderView_->fileLauncher();
}
QString getFilterStr() {
if(proxyFilter_)
return proxyFilter_->getFilterStr();
return QString();
}
void setFilterStr(QString str) {
if(proxyFilter_)
proxyFilter_->setFilterStr(str);
}
void applyFilter();
Q_SIGNALS:
void statusChanged(int type, QString statusText);
void titleChanged(QString title);
void openDirRequested(FmPath* path, int target);
void sortFilterChanged();
void forwardRequested();
void backwardRequested();
protected Q_SLOTS:
void onOpenDirRequested(FmPath* path, int target);
void onModelSortFilterChanged();
void onSelChanged(int numSel);
void restoreScrollPos();
private:
void freeFolder();
QString formatStatusText();
static void onFolderStartLoading(FmFolder* _folder, TabPage* pThis);
static void onFolderFinishLoading(FmFolder* _folder, TabPage* pThis);
static FmJobErrorAction onFolderError(FmFolder* _folder, GError* err, FmJobErrorSeverity severity, TabPage* pThis);
static void onFolderFsInfo(FmFolder* _folder, TabPage* pThis);
static void onFolderRemoved(FmFolder* _folder, TabPage* pThis);
static void onFolderUnmount(FmFolder* _folder, TabPage* pThis);
static void onFolderContentChanged(FmFolder* _folder, TabPage* pThis);
private:
View* folderView_;
Fm::CachedFolderModel* folderModel_;
Fm::ProxyFolderModel* proxyModel_;
ProxyFilter* proxyFilter_;
QVBoxLayout* verticalLayout;
FmFolder* folder_;
QString title_;
QString statusText_[StatusTextNum];
Fm::BrowseHistory history_; // browsing history
Fm::Path lastFolderPath_; // last browsed folder
bool overrideCursor_;
};
}
#endif // FM_TABPAGE_H

View File

@ -1,4 +0,0 @@
#Translations
Name[de]=Schreibtisch
GenericName[de]=Schreibtischeinstellungen
Comment[de]=Einstellungen wie Hintergrundbild oder verwendete Menüs

View File

@ -1,3 +0,0 @@
Name[el]=Επιφάνεια εργασίας
GenericName[el]=Ρυθμίσεις της επιφάνειας εργασίας
Comment[el]=Αλλαγή της ταπετσαρίας και της συμπεριφοράς του διαχειριστή της επιφάνειας εργασίας

View File

@ -1,4 +0,0 @@
#Translations
Name[hu]=Asztal
GenericName[hu]=Asztalbeállítás
Comment[hu]=Asztal kinézet és viselkedés beállítása

View File

@ -1,4 +0,0 @@
#Translations
Name[it]=Scrivania
GenericName[it]=Preferenze della scrivania
Comment[it]=Configura percorso e aspetto della scrivania

View File

@ -1,4 +0,0 @@
#Translations
Name[pl]=Pulpit
GenericName[pl]=Ustawienia pulpitu
Comment[pl]=Zmiana tapety oraz zachowania pulpitu

View File

@ -1,4 +0,0 @@
#Translations
Name[pt]=Área de trabalho
GenericName[pt]=Definições da área de trabalho
Comment[pt]=Mudar o papel de parede e o comportamento da área de trabalho

View File

@ -1,4 +0,0 @@
#Translations
Name[ru]=Рабочий стол
GenericName[ru]=Настройки рабочего стола
Comment[ru]=Изменить обои и поведение менеджера рабочего стола

View File

@ -1,4 +0,0 @@
#Translations / translated by tulliana <tulliana@yandex.com>
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..)

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -1,4 +0,0 @@
#Translations
Name[de]=PCManFM-Qt
GenericName[de]=Dateimanager
Comment[de]=Dateimanager der Desktop-Umgebung LXQt

File diff suppressed because it is too large Load Diff

View File

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

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -1,4 +0,0 @@
#Translations
Name[hu]=PCManFM-Qt fájlkezelő
GenericName[hu]=Fájlkezelő
Comment[hu]=Fájlok böngészése és karbantartása

File diff suppressed because it is too large Load Diff

View File

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

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

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

File diff suppressed because it is too large Load Diff

View File

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

File diff suppressed because it is too large Load Diff

View File

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

File diff suppressed because it is too large Load Diff

View File

@ -1,4 +0,0 @@
#Translations / translated by tulliana <tulliana@yandex.com>
Name[tr]=PCManFM-Qt
GenericName[tr]=Dosya Yönetici
Comment[tr]=Lxqt dosya ve masaüstü yöneticisi

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -1,148 +0,0 @@
/*
Copyright (C) 2013 Hong Jen Yee (PCMan) <pcman.tw@gmail.com>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#include "view.h"
#include <libfm-qt/filemenu.h>
#include <libfm-qt/foldermenu.h>
#include "application.h"
#include "settings.h"
#include "application.h"
#include "mainwindow.h"
#include "launcher.h"
#include <QAction>
namespace PCManFM {
View::View(Fm::FolderView::ViewMode _mode, QWidget* parent):
Fm::FolderView(_mode, parent) {
Settings& settings = static_cast<Application*>(qApp)->settings();
updateFromSettings(settings);
}
View::~View() {
}
void View::onFileClicked(int type, FmFileInfo* fileInfo) {
if(type == MiddleClick) {
if(fm_file_info_is_dir(fileInfo)) {
Q_EMIT openDirRequested(fm_file_info_get_path(fileInfo), OpenInNewTab);
}
}
else {
Fm::FolderView::onFileClicked(type, fileInfo);
}
}
void View::onNewWindow() {
Fm::FileMenu* menu = static_cast<Fm::FileMenu*>(sender()->parent());
// FIXME: open the files in a new window
Application* app = static_cast<Application*>(qApp);
app->openFolders(menu->files());
}
void View::onNewTab() {
Fm::FileMenu* menu = static_cast<Fm::FileMenu*>(sender()->parent());
for(GList* l = fm_file_info_list_peek_head_link(menu->files()); l; l = l->next) {
FmFileInfo* file = FM_FILE_INFO(l->data);
Q_EMIT openDirRequested(fm_file_info_get_path(file), OpenInNewTab);
}
}
void View::onOpenInTerminal() {
Application* app = static_cast<Application*>(qApp);
Fm::FileMenu* menu = static_cast<Fm::FileMenu*>(sender()->parent());
for(GList* l = fm_file_info_list_peek_head_link(menu->files()); l; l = l->next) {
FmFileInfo* file = FM_FILE_INFO(l->data);
app->openFolderInTerminal(fm_file_info_get_path(file));
}
}
void View::onSearch() {
}
void View::prepareFileMenu(Fm::FileMenu* menu) {
Application* app = static_cast<Application*>(qApp);
menu->setConfirmDelete(app->settings().confirmDelete());
menu->setConfirmTrash(app->settings().confirmTrash());
menu->setUseTrash(app->settings().useTrash());
// add some more menu items for dirs
bool all_native = true;
bool all_directory = true;
FmFileInfoList* files = menu->files();
for(GList* l = fm_file_info_list_peek_head_link(files); l; l = l->next) {
FmFileInfo* fi = FM_FILE_INFO(l->data);
if(!fm_file_info_is_dir(fi))
all_directory = false;
else if(fm_file_info_is_dir(fi) && !fm_file_info_is_native(fi))
all_native = false;
}
if (all_directory)
{
QAction* action = new QAction(QIcon::fromTheme("window-new"), tr("Open in New T&ab"), menu);
connect(action, &QAction::triggered, this, &View::onNewTab);
menu->insertAction(menu->separator1(), action);
action = new QAction(QIcon::fromTheme("window-new"), tr("Open in New Win&dow"), menu);
connect(action, &QAction::triggered, this, &View::onNewWindow);
menu->insertAction(menu->separator1(), action);
// TODO: add search
// action = menu->addAction(_("Search"));
if(all_native)
{
action = new QAction(QIcon::fromTheme("utilities-terminal"), tr("Open in Termina&l"), menu);
connect(action, &QAction::triggered, this, &View::onOpenInTerminal);
menu->insertAction(menu->separator1(), action);
}
}
else {
if(menu->pasteAction()) // NULL for trash
menu->pasteAction()->setVisible(false);
if(menu->createAction())
menu->createAction()->setVisible(false);
}
}
void View::prepareFolderMenu(Fm::FolderMenu* menu) {
}
void View::updateFromSettings(Settings& settings) {
setIconSize(Fm::FolderView::IconMode, QSize(settings.bigIconSize(), settings.bigIconSize()));
setIconSize(Fm::FolderView::CompactMode, QSize(settings.smallIconSize(), settings.smallIconSize()));
setIconSize(Fm::FolderView::ThumbnailMode, QSize(settings.thumbnailIconSize(), settings.thumbnailIconSize()));
setIconSize(Fm::FolderView::DetailedListMode, QSize(settings.smallIconSize(), settings.smallIconSize()));
setMargins(settings.folderViewCellMargins());
setAutoSelectionDelay(settings.autoSelectionDelay());
Fm::ProxyFolderModel* proxyModel = model();
if(proxyModel) {
proxyModel->setShowThumbnails(settings.showThumbnails());
}
}
} // namespace PCManFM

View File

@ -1,70 +0,0 @@
/*
Copyright (C) 2013 Hong Jen Yee (PCMan) <pcman.tw@gmail.com>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#ifndef PCMANFM_FOLDERVIEW_H
#define PCMANFM_FOLDERVIEW_H
#include <libfm-qt/folderview.h>
namespace Fm {
class FileMenu;
class FolderMenu;
}
namespace PCManFM {
class Settings;
class View : public Fm::FolderView {
Q_OBJECT
public:
explicit View(Fm::FolderView::ViewMode _mode = IconMode, QWidget* parent = 0);
virtual ~View();
void updateFromSettings(Settings& settings);
QSize getMargins() const {
return Fm::FolderView::getMargins();
}
void setMargins(QSize size) {
Fm::FolderView::setMargins(size);
}
Q_SIGNALS:
void openDirRequested(FmPath* path, int target);
protected Q_SLOTS:
void onNewWindow();
void onNewTab();
void onOpenInTerminal();
void onSearch();
protected:
virtual void onFileClicked(int type, FmFileInfo* fileInfo);
virtual void prepareFileMenu(Fm::FileMenu* menu);
virtual void prepareFolderMenu(Fm::FolderMenu* menu);
private:
};
};
#endif // PCMANFM_FOLDERVIEW_H

View File

@ -1,72 +0,0 @@
/*
* Copyright (C) 2013 Hong Jen Yee (PCMan) <pcman.tw@gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#include "xdgdir.h"
#include <QStandardPaths>
#include <QFile>
#include <QDir>
#include <QSaveFile>
QString XdgDir::readUserDirsFile() {
QFile file(QStandardPaths::writableLocation(QStandardPaths::ConfigLocation) + QStringLiteral("/user-dirs.dirs"));
if(file.open(QIODevice::ReadOnly | QIODevice::Text)) {
QByteArray data = file.readAll();
file.close();
return QString::fromLocal8Bit(data);
}
return QString();
}
QString XdgDir::readDesktopDir() {
QString str = readUserDirsFile();
if(str.isEmpty())
return QStandardPaths::writableLocation(QStandardPaths::HomeLocation) + QStringLiteral("/Desktop");
QRegExp reg(QStringLiteral("XDG_DESKTOP_DIR=\"([^\n]*)\""));
if(reg.lastIndexIn(str) != -1) {
str = reg.cap(1);
if(str.startsWith(QStringLiteral("$HOME")))
str = QStandardPaths::writableLocation(QStandardPaths::HomeLocation) + str.mid(5);
return str;
}
return QString();
}
void XdgDir::setDesktopDir(QString path) {
QString home = QStandardPaths::writableLocation(QStandardPaths::HomeLocation);
if(path.startsWith(home))
path = QStringLiteral("$HOME") + path.mid(home.length());
QString str = readUserDirsFile();
QRegExp reg(QStringLiteral("XDG_DESKTOP_DIR=\"([^\n]*)\""));
QString line = QStringLiteral("XDG_DESKTOP_DIR=\"") + path + '\"';
if(reg.indexIn(str) != -1)
str.replace(reg, line);
else {
if(!str.endsWith('\n'))
str += '\n';
str += line + '\n';
}
QString dir = QStandardPaths::writableLocation(QStandardPaths::ConfigLocation);
if(QDir().mkpath(dir)) { // write the file
QSaveFile file(dir + QStringLiteral("/user-dirs.dirs"));
if(file.open(QIODevice::WriteOnly | QIODevice::Text)) {
file.write(str.toLocal8Bit());
file.commit();
}
}
}

View File

@ -1,33 +0,0 @@
/*
* Copyright (C) 2013 Hong Jen Yee (PCMan) <pcman.tw@gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#include <QObject>
#include <QString>
class XdgDir : public QObject
{
Q_OBJECT
public:
static QString readDesktopDir();
static void setDesktopDir(QString path);
private:
static QString readUserDirsFile();
};