Compare commits
245 Commits
upstream/0
...
ubuntu/res
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
94e298c24c | ||
|
|
ed46e61a09 | ||
|
|
9727f7564b | ||
|
|
bb985fed7f | ||
|
|
1af1980266 | ||
|
|
610add6501 | ||
|
|
e4a78d19ce | ||
|
|
ff4187fca2 | ||
|
|
55244fb70b | ||
|
|
f39b1afb68 | ||
|
|
6e8d336cf1 | ||
|
|
b0b04ce74f | ||
|
|
805559fe59 | ||
|
|
d2b1a49c26 | ||
|
|
dacc4fa73a | ||
|
|
ba7bf3807f | ||
|
|
f758b2179b | ||
|
|
c422de58f5 | ||
|
|
bda3cd1f38 | ||
| 069c9da5aa | |||
| ad03d8a076 | |||
| 4fbafd6c70 | |||
| 42b7416e2e | |||
| ed9760f617 | |||
| e1aa429d8b | |||
| c3075b3182 | |||
| a90ab52cb3 | |||
| a7c55cca9d | |||
| 49541811db | |||
|
|
017f7c8a4d | ||
|
|
b26925ea07 | ||
|
|
802f5579bb | ||
|
|
0f9f5df868 | ||
|
|
1db48c93b7 | ||
|
|
644c99327e | ||
|
|
ea95d92cfa | ||
|
|
2c7d5a99f5 | ||
|
|
b2307df376 | ||
| d327b18479 | |||
| c5f0c347e1 | |||
| fa8e6fa423 | |||
| d5ecfb6681 | |||
| 6dab1b3af8 | |||
| b2487aad6c | |||
| a575de56f8 | |||
| c3f4fc8b10 | |||
| 40e11089cc | |||
| 98f5f397dc | |||
|
|
d0c06c5d6b | ||
|
|
052a556bc0 | ||
|
|
83c034bd6f | ||
|
|
900d477f1d | ||
|
|
e251a6aa32 | ||
|
|
a273e1567d | ||
|
|
eb615c3512 | ||
|
|
0672e46c73 | ||
| cbe58deaea | |||
| f0df77303e | |||
| d6371bc277 | |||
| 5fd9107a93 | |||
| f10ba18860 | |||
| 1e0ecbdf79 | |||
| c98bcd1948 | |||
| 1fa81fcbb4 | |||
| 2602979b29 | |||
| 0f65b41150 | |||
| be07f15a59 | |||
| 0a196e7e16 | |||
| 944ca043e5 | |||
| b6b785512d | |||
| 0db4d62f51 | |||
| 6a7fd542a9 | |||
| 1cb774dd2e | |||
| 9f419a4e10 | |||
| 84bf4caa68 | |||
| c5631d7a2d | |||
| 8654c7904b | |||
| ce2f4feab5 | |||
| 755cf858f6 | |||
| 32558ac832 | |||
| 817faa5457 | |||
| f4f7453d4f | |||
| dbe70dd76e | |||
| 1bb5e074ae | |||
| 1c098568f3 | |||
| 0888e2bed8 | |||
| fa135f8e2a | |||
| 5eca821f28 | |||
|
|
748c733729 | ||
|
|
f1cccbe4e1 | ||
|
|
8e2977cd88 | ||
|
|
24b035552e | ||
|
|
1215d360d8 | ||
| c448ea0a2f | |||
|
|
19d5b222af | ||
| a56d40dc0a | |||
| 70bbac5c92 | |||
| 54b50f5152 | |||
| f742be6a17 | |||
| ac41f3a96b | |||
| a084e5bb86 | |||
| c1ffd9db39 | |||
| 251d898efc | |||
|
|
b671b41618 | ||
|
|
6df0173c9b | ||
| 370ce0986a | |||
| ff3efabd56 | |||
| 897e1d1d5f | |||
| b3e9f2e54d | |||
| c4a6bb316b | |||
| ea2f48482a | |||
| d1c409451e | |||
|
|
b75411bb14 | ||
|
|
bc3e4bc2b2 | ||
|
|
4d37efb21b | ||
|
|
e8e7d9bd5a | ||
| 4cfa12445f | |||
|
|
3663fb0ed1 | ||
|
|
ba535b4af8 | ||
|
|
53e5a55691 | ||
|
|
faec7ee9c2 | ||
|
|
89d37d65c4 | ||
|
|
5e3b197f0d | ||
|
|
bdd05e9657 | ||
|
|
cd3ad840e2 | ||
|
|
ac1face24d | ||
|
|
9e81f0eb04 | ||
|
|
973fb83019 | ||
|
|
5d2a1fd479 | ||
|
|
e727e901ee | ||
|
|
73e2e10e1c | ||
|
|
d71da0cea2 | ||
|
|
f653c90d68 | ||
|
|
1635b116c7 | ||
|
|
18db7b2935 | ||
|
|
cb42c7b187 | ||
| 3fa1ce108c | |||
|
|
532bd6d192 | ||
|
|
6efc7478dc | ||
|
|
e0447781be | ||
|
|
a95affe263 | ||
|
|
6ff37a972c | ||
|
|
d02d893e30 | ||
|
|
ff19c6a4b1 | ||
|
|
6a38fac102 | ||
|
|
27c0a43d79 | ||
|
|
88d19f7ee1 | ||
|
|
03320d44ae | ||
|
|
50446e08c8 | ||
|
|
714eb972db | ||
| b6d30257ca | |||
|
|
cd29302e86 | ||
|
|
9abec1c8dd | ||
|
|
8c2c6c557d | ||
|
|
d209d89d25 | ||
|
|
b37b537033 | ||
| c1952b6dda | |||
|
|
b1b8e0fe3b | ||
|
|
095c25bf98 | ||
|
|
f628332f45 | ||
|
|
19fd5f3c8b | ||
|
|
02f480e84c | ||
|
|
44cc4cabd2 | ||
|
|
52954c35b8 | ||
|
|
30fcfd50cc | ||
|
|
bed2009381 | ||
|
|
07036c23c2 | ||
|
|
b0dea37e48 | ||
|
|
48279cbc14 | ||
|
|
9460e026ac | ||
|
|
b562e2049e | ||
|
|
de628236f1 | ||
|
|
0e2cc2d4d9 | ||
|
|
2292f9bb92 | ||
|
|
b10231239f | ||
|
|
0f438f3c4e | ||
|
|
42bbfcfa06 | ||
|
|
e3d6831346 | ||
|
|
0829311d25 | ||
|
|
f95b471116 | ||
|
|
25b4cd12db | ||
|
|
42298bb676 | ||
|
|
1d98459023 | ||
|
|
da5049a849 | ||
|
|
636c0537ae | ||
|
|
08cccd439f | ||
|
|
cd0c8b6b34 | ||
|
|
62586d93d9 | ||
|
|
7f75fc0761 | ||
|
|
266bf72447 | ||
|
|
5182ca1192 | ||
|
|
410c3a1dd3 | ||
|
|
ed1fdfc113 | ||
|
|
d97c2d94db | ||
|
|
68ce865507 | ||
|
|
96d0b2e0c5 | ||
|
|
851d7d6d5a | ||
|
|
8e36c0e4c8 | ||
|
|
2589ff82cd | ||
|
|
735419abd6 | ||
|
|
ee4ebf1387 | ||
|
|
8a46637444 | ||
|
|
20c37d50e0 | ||
|
|
06afe727c0 | ||
|
|
d2185fdd02 | ||
|
|
f9dbc3d3f5 | ||
|
|
b86fc9a309 | ||
|
|
ab577ebf4a | ||
|
|
048dacc3dc | ||
|
|
d080b7eccb | ||
|
|
e689726de0 | ||
|
|
309e36f613 | ||
|
|
2d3153362f | ||
|
|
4fb772898e | ||
|
|
6a7e956597 | ||
|
|
4866b6ee5b | ||
|
|
f0c1da7f29 | ||
|
|
a5e6e5a14d | ||
|
|
9b3ea9ee35 | ||
|
|
f8b1be1590 | ||
|
|
e5ab509f5a | ||
|
|
1f75eb1597 | ||
|
|
700bc74ef3 | ||
|
|
ea757e4af0 | ||
|
|
2e496b302c | ||
|
|
da03a71631 | ||
|
|
057bb75ee9 | ||
|
|
5b9cc02532 | ||
|
|
f2b1f23fdf | ||
|
|
108dbfc235 | ||
|
|
629380765b | ||
|
|
9cc75963be | ||
|
|
e2aefc1a39 | ||
|
|
25794f3459 | ||
|
|
d71a447819 | ||
|
|
26b0945d5e | ||
|
|
ec716b799a | ||
|
|
39a4a06335 | ||
|
|
79a13cfd58 | ||
|
|
23d8969e34 | ||
|
|
47a19025a7 | ||
|
|
97a0434757 | ||
|
|
1441044b2e | ||
|
|
1dd85c3090 | ||
|
|
2e77afc48c |
6
AUTHORS
6
AUTHORS
@ -1,6 +0,0 @@
|
|||||||
Upstream Authors:
|
|
||||||
LXQt team: http://lxqt.org
|
|
||||||
Hong Jen Yee (PCMan) <pcman.tw@gmail.com>
|
|
||||||
|
|
||||||
Copyright:
|
|
||||||
Copyright (c) 2013-2015 LXQt team
|
|
||||||
132
CMakeLists.txt
132
CMakeLists.txt
@ -1,132 +0,0 @@
|
|||||||
cmake_minimum_required(VERSION 3.0.2)
|
|
||||||
project(libfm-qt)
|
|
||||||
|
|
||||||
set(LIBFM_QT_LIBRARY_NAME "fm-qt" CACHE STRING "fm-qt")
|
|
||||||
|
|
||||||
set(LIBFM_QT_VERSION_MAJOR 0)
|
|
||||||
set(LIBFM_QT_VERSION_MINOR 10)
|
|
||||||
set(LIBFM_QT_VERSION_PATCH 0)
|
|
||||||
set(LIBFM_QT_VERSION ${LIBFM_QT_VERSION_MAJOR}.${LIBFM_QT_VERSION_MINOR}.${LIBFM_QT_VERSION_PATCH})
|
|
||||||
|
|
||||||
list(APPEND CMAKE_MODULE_PATH "${PROJECT_SOURCE_DIR}/cmake")
|
|
||||||
|
|
||||||
# We use the libtool versioning scheme for the internal so name, "current:revision:age"
|
|
||||||
# http://www.gnu.org/software/libtool/manual/html_node/Updating-version-info.html#Updating-version-info
|
|
||||||
# https://www.sourceware.org/autobook/autobook/autobook_91.html
|
|
||||||
# http://pusling.com/blog/?p=352
|
|
||||||
# Actually, libtool uses different ways on different operating systems. So there is no
|
|
||||||
# universal way to translate a libtool version-info to a cmake version.
|
|
||||||
# We use "(current-age).age.revision" as the cmake version.
|
|
||||||
# current: 2, revision: 0, age: 0 => version: 2.0.0
|
|
||||||
set(LIBFM_QT_LIB_VERSION "2.0.0")
|
|
||||||
set(LIBFM_QT_LIB_SOVERSION "2")
|
|
||||||
|
|
||||||
set(REQUIRED_QT_VERSION "5.2")
|
|
||||||
set(REQUIRED_LIBFM_VERSION "1.2.0")
|
|
||||||
set(REQUIRED_LIBMENUCACHE_VERSION "0.4.0")
|
|
||||||
|
|
||||||
if (NOT CMAKE_BUILD_TYPE)
|
|
||||||
set(CMAKE_BUILD_TYPE Release)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
find_package(Qt5Widgets "${REQUIRED_QT_VERSION}" REQUIRED)
|
|
||||||
find_package(Qt5LinguistTools "${REQUIRED_QT_VERSION}" REQUIRED)
|
|
||||||
find_package(Qt5X11Extras "${REQUIRED_QT_VERSION}" REQUIRED)
|
|
||||||
|
|
||||||
find_package(PkgConfig)
|
|
||||||
pkg_check_modules(SYSTEM_LIBS REQUIRED
|
|
||||||
glib-2.0
|
|
||||||
gio-2.0
|
|
||||||
gio-unix-2.0
|
|
||||||
xcb
|
|
||||||
)
|
|
||||||
|
|
||||||
pkg_check_modules(LIBFM REQUIRED libfm>="${REQUIRED_LIBFM_VERSION}")
|
|
||||||
pkg_check_modules(LIBMENUCACHE REQUIRED libmenu-cache>="${REQUIRED_LIBMENUCACHE_VERSION}")
|
|
||||||
|
|
||||||
option(UPDATE_TRANSLATIONS "Update source translation translations/*.ts files" OFF)
|
|
||||||
include(GNUInstallDirs)
|
|
||||||
include(GenerateExportHeader)
|
|
||||||
include(CMakePackageConfigHelpers)
|
|
||||||
include(LXQtTranslateTs)
|
|
||||||
include(LXQtTranslateDesktop)
|
|
||||||
|
|
||||||
add_definitions(-DQT_NO_KEYWORDS)
|
|
||||||
|
|
||||||
# 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(CMAKE_CXX_FLAGS "-fno-exceptions ${CMAKE_CXX_FLAGS}")
|
|
||||||
endif()
|
|
||||||
|
|
||||||
set(CMAKE_AUTOMOC TRUE)
|
|
||||||
set(CMAKE_INCLUDE_CURRENT_DIR ON)
|
|
||||||
|
|
||||||
write_basic_package_version_file(
|
|
||||||
"${CMAKE_BINARY_DIR}/${LIBFM_QT_LIBRARY_NAME}-config-version.cmake"
|
|
||||||
VERSION ${LIBFM_QT_LIB_VERSION}
|
|
||||||
COMPATIBILITY AnyNewerVersion
|
|
||||||
)
|
|
||||||
|
|
||||||
install(FILES
|
|
||||||
"${CMAKE_BINARY_DIR}/${LIBFM_QT_LIBRARY_NAME}-config-version.cmake"
|
|
||||||
DESTINATION "${CMAKE_INSTALL_DATADIR}/cmake/${LIBFM_QT_LIBRARY_NAME}"
|
|
||||||
COMPONENT Devel
|
|
||||||
)
|
|
||||||
|
|
||||||
add_subdirectory(src)
|
|
||||||
|
|
||||||
# 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}"
|
|
||||||
COMPONENT Devel
|
|
||||||
)
|
|
||||||
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 ${LIBFM_QT_VERSION_MAJOR})
|
|
||||||
set(CPACK_PACKAGE_VERSION_MINOR ${LIBFM_QT_VERSION_MINOR})
|
|
||||||
set(CPACK_PACKAGE_VERSION_PATCH ${LIBFM_QT_VERSION_PATCH})
|
|
||||||
set(CPACK_GENERATOR TBZ2)
|
|
||||||
set(CPACK_SOURCE_GENERATOR TBZ2)
|
|
||||||
set(CPACK_SOURCE_IGNORE_FILES /build/;.gitignore;.*~;.git;.kdev4;temp)
|
|
||||||
include(CPack)
|
|
||||||
1890
Doxyfile.in
1890
Doxyfile.in
File diff suppressed because it is too large
Load Diff
458
LICENSE
458
LICENSE
@ -1,458 +0,0 @@
|
|||||||
GNU LESSER GENERAL PUBLIC LICENSE
|
|
||||||
Version 2.1, February 1999
|
|
||||||
|
|
||||||
Copyright (C) 1991, 1999 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.
|
|
||||||
|
|
||||||
[This is the first released version of the Lesser GPL. It also counts
|
|
||||||
as the successor of the GNU Library Public License, version 2, hence
|
|
||||||
the version number 2.1.]
|
|
||||||
|
|
||||||
Preamble
|
|
||||||
|
|
||||||
The licenses for most software are designed to take away your
|
|
||||||
freedom to share and change it. By contrast, the GNU General Public
|
|
||||||
Licenses are intended to guarantee your freedom to share and change
|
|
||||||
free software--to make sure the software is free for all its users.
|
|
||||||
|
|
||||||
This license, the Lesser General Public License, applies to some
|
|
||||||
specially designated software packages--typically libraries--of the
|
|
||||||
Free Software Foundation and other authors who decide to use it. You
|
|
||||||
can use it too, but we suggest you first think carefully about whether
|
|
||||||
this license or the ordinary General Public License is the better
|
|
||||||
strategy to use in any particular case, based on the explanations below.
|
|
||||||
|
|
||||||
When we speak of free software, we are referring to freedom of use,
|
|
||||||
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 and use pieces of
|
|
||||||
it in new free programs; and that you are informed that you can do
|
|
||||||
these things.
|
|
||||||
|
|
||||||
To protect your rights, we need to make restrictions that forbid
|
|
||||||
distributors to deny you these rights or to ask you to surrender these
|
|
||||||
rights. These restrictions translate to certain responsibilities for
|
|
||||||
you if you distribute copies of the library or if you modify it.
|
|
||||||
|
|
||||||
For example, if you distribute copies of the library, whether gratis
|
|
||||||
or for a fee, you must give the recipients all the rights that we gave
|
|
||||||
you. You must make sure that they, too, receive or can get the source
|
|
||||||
code. If you link other code with the library, you must provide
|
|
||||||
complete object files to the recipients, so that they can relink them
|
|
||||||
with the library after making changes to the library and recompiling
|
|
||||||
it. And you must show them these terms so they know their rights.
|
|
||||||
|
|
||||||
We protect your rights with a two-step method: (1) we copyright the
|
|
||||||
library, and (2) we offer you this license, which gives you legal
|
|
||||||
permission to copy, distribute and/or modify the library.
|
|
||||||
|
|
||||||
To protect each distributor, we want to make it very clear that
|
|
||||||
there is no warranty for the free library. Also, if the library is
|
|
||||||
modified by someone else and passed on, the recipients should know
|
|
||||||
that what they have is not the original version, so that the original
|
|
||||||
author's reputation will not be affected by problems that might be
|
|
||||||
introduced by others.
|
|
||||||
|
|
||||||
Finally, software patents pose a constant threat to the existence of
|
|
||||||
any free program. We wish to make sure that a company cannot
|
|
||||||
effectively restrict the users of a free program by obtaining a
|
|
||||||
restrictive license from a patent holder. Therefore, we insist that
|
|
||||||
any patent license obtained for a version of the library must be
|
|
||||||
consistent with the full freedom of use specified in this license.
|
|
||||||
|
|
||||||
Most GNU software, including some libraries, is covered by the
|
|
||||||
ordinary GNU General Public License. This license, the GNU Lesser
|
|
||||||
General Public License, applies to certain designated libraries, and
|
|
||||||
is quite different from the ordinary General Public License. We use
|
|
||||||
this license for certain libraries in order to permit linking those
|
|
||||||
libraries into non-free programs.
|
|
||||||
|
|
||||||
When a program is linked with a library, whether statically or using
|
|
||||||
a shared library, the combination of the two is legally speaking a
|
|
||||||
combined work, a derivative of the original library. The ordinary
|
|
||||||
General Public License therefore permits such linking only if the
|
|
||||||
entire combination fits its criteria of freedom. The Lesser General
|
|
||||||
Public License permits more lax criteria for linking other code with
|
|
||||||
the library.
|
|
||||||
|
|
||||||
We call this license the "Lesser" General Public License because it
|
|
||||||
does Less to protect the user's freedom than the ordinary General
|
|
||||||
Public License. It also provides other free software developers Less
|
|
||||||
of an advantage over competing non-free programs. These disadvantages
|
|
||||||
are the reason we use the ordinary General Public License for many
|
|
||||||
libraries. However, the Lesser license provides advantages in certain
|
|
||||||
special circumstances.
|
|
||||||
|
|
||||||
For example, on rare occasions, there may be a special need to
|
|
||||||
encourage the widest possible use of a certain library, so that it becomes
|
|
||||||
a de-facto standard. To achieve this, non-free programs must be
|
|
||||||
allowed to use the library. A more frequent case is that a free
|
|
||||||
library does the same job as widely used non-free libraries. In this
|
|
||||||
case, there is little to gain by limiting the free library to free
|
|
||||||
software only, so we use the Lesser General Public License.
|
|
||||||
|
|
||||||
In other cases, permission to use a particular library in non-free
|
|
||||||
programs enables a greater number of people to use a large body of
|
|
||||||
free software. For example, permission to use the GNU C Library in
|
|
||||||
non-free programs enables many more people to use the whole GNU
|
|
||||||
operating system, as well as its variant, the GNU/Linux operating
|
|
||||||
system.
|
|
||||||
|
|
||||||
Although the Lesser General Public License is Less protective of the
|
|
||||||
users' freedom, it does ensure that the user of a program that is
|
|
||||||
linked with the Library has the freedom and the wherewithal to run
|
|
||||||
that program using a modified version of the Library.
|
|
||||||
|
|
||||||
The precise terms and conditions for copying, distribution and
|
|
||||||
modification follow. Pay close attention to the difference between a
|
|
||||||
"work based on the library" and a "work that uses the library". The
|
|
||||||
former contains code derived from the library, whereas the latter must
|
|
||||||
be combined with the library in order to run.
|
|
||||||
|
|
||||||
GNU LESSER GENERAL PUBLIC LICENSE
|
|
||||||
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
|
||||||
|
|
||||||
0. This License Agreement applies to any software library or other
|
|
||||||
program which contains a notice placed by the copyright holder or
|
|
||||||
other authorized party saying it may be distributed under the terms of
|
|
||||||
this Lesser General Public License (also called "this License").
|
|
||||||
Each licensee is addressed as "you".
|
|
||||||
|
|
||||||
A "library" means a collection of software functions and/or data
|
|
||||||
prepared so as to be conveniently linked with application programs
|
|
||||||
(which use some of those functions and data) to form executables.
|
|
||||||
|
|
||||||
The "Library", below, refers to any such software library or work
|
|
||||||
which has been distributed under these terms. A "work based on the
|
|
||||||
Library" means either the Library or any derivative work under
|
|
||||||
copyright law: that is to say, a work containing the Library or a
|
|
||||||
portion of it, either verbatim or with modifications and/or translated
|
|
||||||
straightforwardly into another language. (Hereinafter, translation is
|
|
||||||
included without limitation in the term "modification".)
|
|
||||||
|
|
||||||
"Source code" for a work means the preferred form of the work for
|
|
||||||
making modifications to it. For a library, 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 library.
|
|
||||||
|
|
||||||
Activities other than copying, distribution and modification are not
|
|
||||||
covered by this License; they are outside its scope. The act of
|
|
||||||
running a program using the Library is not restricted, and output from
|
|
||||||
such a program is covered only if its contents constitute a work based
|
|
||||||
on the Library (independent of the use of the Library in a tool for
|
|
||||||
writing it). Whether that is true depends on what the Library does
|
|
||||||
and what the program that uses the Library does.
|
|
||||||
|
|
||||||
1. You may copy and distribute verbatim copies of the Library's
|
|
||||||
complete 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 distribute a copy of this License along with the
|
|
||||||
Library.
|
|
||||||
|
|
||||||
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 Library or any portion
|
|
||||||
of it, thus forming a work based on the Library, 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) The modified work must itself be a software library.
|
|
||||||
|
|
||||||
b) You must cause the files modified to carry prominent notices
|
|
||||||
stating that you changed the files and the date of any change.
|
|
||||||
|
|
||||||
c) You must cause the whole of the work to be licensed at no
|
|
||||||
charge to all third parties under the terms of this License.
|
|
||||||
|
|
||||||
d) If a facility in the modified Library refers to a function or a
|
|
||||||
table of data to be supplied by an application program that uses
|
|
||||||
the facility, other than as an argument passed when the facility
|
|
||||||
is invoked, then you must make a good faith effort to ensure that,
|
|
||||||
in the event an application does not supply such function or
|
|
||||||
table, the facility still operates, and performs whatever part of
|
|
||||||
its purpose remains meaningful.
|
|
||||||
|
|
||||||
(For example, a function in a library to compute square roots has
|
|
||||||
a purpose that is entirely well-defined independent of the
|
|
||||||
application. Therefore, Subsection 2d requires that any
|
|
||||||
application-supplied function or table used by this function must
|
|
||||||
be optional: if the application does not supply it, the square
|
|
||||||
root function must still compute square roots.)
|
|
||||||
|
|
||||||
These requirements apply to the modified work as a whole. If
|
|
||||||
identifiable sections of that work are not derived from the Library,
|
|
||||||
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 Library, 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 Library.
|
|
||||||
|
|
||||||
In addition, mere aggregation of another work not based on the Library
|
|
||||||
with the Library (or with a work based on the Library) on a volume of
|
|
||||||
a storage or distribution medium does not bring the other work under
|
|
||||||
the scope of this License.
|
|
||||||
|
|
||||||
3. You may opt to apply the terms of the ordinary GNU General Public
|
|
||||||
License instead of this License to a given copy of the Library. To do
|
|
||||||
this, you must alter all the notices that refer to this License, so
|
|
||||||
that they refer to the ordinary GNU General Public License, version 2,
|
|
||||||
instead of to this License. (If a newer version than version 2 of the
|
|
||||||
ordinary GNU General Public License has appeared, then you can specify
|
|
||||||
that version instead if you wish.) Do not make any other change in
|
|
||||||
these notices.
|
|
||||||
|
|
||||||
Once this change is made in a given copy, it is irreversible for
|
|
||||||
that copy, so the ordinary GNU General Public License applies to all
|
|
||||||
subsequent copies and derivative works made from that copy.
|
|
||||||
|
|
||||||
This option is useful when you wish to copy part of the code of
|
|
||||||
the Library into a program that is not a library.
|
|
||||||
|
|
||||||
4. You may copy and distribute the Library (or a portion or
|
|
||||||
derivative of it, under Section 2) in object code or executable form
|
|
||||||
under the terms of Sections 1 and 2 above provided that you 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.
|
|
||||||
|
|
||||||
If distribution of 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 satisfies the requirement to
|
|
||||||
distribute the source code, even though third parties are not
|
|
||||||
compelled to copy the source along with the object code.
|
|
||||||
|
|
||||||
5. A program that contains no derivative of any portion of the
|
|
||||||
Library, but is designed to work with the Library by being compiled or
|
|
||||||
linked with it, is called a "work that uses the Library". Such a
|
|
||||||
work, in isolation, is not a derivative work of the Library, and
|
|
||||||
therefore falls outside the scope of this License.
|
|
||||||
|
|
||||||
However, linking a "work that uses the Library" with the Library
|
|
||||||
creates an executable that is a derivative of the Library (because it
|
|
||||||
contains portions of the Library), rather than a "work that uses the
|
|
||||||
library". The executable is therefore covered by this License.
|
|
||||||
Section 6 states terms for distribution of such executables.
|
|
||||||
|
|
||||||
When a "work that uses the Library" uses material from a header file
|
|
||||||
that is part of the Library, the object code for the work may be a
|
|
||||||
derivative work of the Library even though the source code is not.
|
|
||||||
Whether this is true is especially significant if the work can be
|
|
||||||
linked without the Library, or if the work is itself a library. The
|
|
||||||
threshold for this to be true is not precisely defined by law.
|
|
||||||
|
|
||||||
If such an object file uses only numerical parameters, data
|
|
||||||
structure layouts and accessors, and small macros and small inline
|
|
||||||
functions (ten lines or less in length), then the use of the object
|
|
||||||
file is unrestricted, regardless of whether it is legally a derivative
|
|
||||||
work. (Executables containing this object code plus portions of the
|
|
||||||
Library will still fall under Section 6.)
|
|
||||||
|
|
||||||
Otherwise, if the work is a derivative of the Library, you may
|
|
||||||
distribute the object code for the work under the terms of Section 6.
|
|
||||||
Any executables containing that work also fall under Section 6,
|
|
||||||
whether or not they are linked directly with the Library itself.
|
|
||||||
|
|
||||||
6. As an exception to the Sections above, you may also combine or
|
|
||||||
link a "work that uses the Library" with the Library to produce a
|
|
||||||
work containing portions of the Library, and distribute that work
|
|
||||||
under terms of your choice, provided that the terms permit
|
|
||||||
modification of the work for the customer's own use and reverse
|
|
||||||
engineering for debugging such modifications.
|
|
||||||
|
|
||||||
You must give prominent notice with each copy of the work that the
|
|
||||||
Library is used in it and that the Library and its use are covered by
|
|
||||||
this License. You must supply a copy of this License. If the work
|
|
||||||
during execution displays copyright notices, you must include the
|
|
||||||
copyright notice for the Library among them, as well as a reference
|
|
||||||
directing the user to the copy of this License. Also, you must do one
|
|
||||||
of these things:
|
|
||||||
|
|
||||||
a) Accompany the work with the complete corresponding
|
|
||||||
machine-readable source code for the Library including whatever
|
|
||||||
changes were used in the work (which must be distributed under
|
|
||||||
Sections 1 and 2 above); and, if the work is an executable linked
|
|
||||||
with the Library, with the complete machine-readable "work that
|
|
||||||
uses the Library", as object code and/or source code, so that the
|
|
||||||
user can modify the Library and then relink to produce a modified
|
|
||||||
executable containing the modified Library. (It is understood
|
|
||||||
that the user who changes the contents of definitions files in the
|
|
||||||
Library will not necessarily be able to recompile the application
|
|
||||||
to use the modified definitions.)
|
|
||||||
|
|
||||||
b) Use a suitable shared library mechanism for linking with the
|
|
||||||
Library. A suitable mechanism is one that (1) uses at run time a
|
|
||||||
copy of the library already present on the user's computer system,
|
|
||||||
rather than copying library functions into the executable, and (2)
|
|
||||||
will operate properly with a modified version of the library, if
|
|
||||||
the user installs one, as long as the modified version is
|
|
||||||
interface-compatible with the version that the work was made with.
|
|
||||||
|
|
||||||
c) Accompany the work with a written offer, valid for at
|
|
||||||
least three years, to give the same user the materials
|
|
||||||
specified in Subsection 6a, above, for a charge no more
|
|
||||||
than the cost of performing this distribution.
|
|
||||||
|
|
||||||
d) If distribution of the work is made by offering access to copy
|
|
||||||
from a designated place, offer equivalent access to copy the above
|
|
||||||
specified materials from the same place.
|
|
||||||
|
|
||||||
e) Verify that the user has already received a copy of these
|
|
||||||
materials or that you have already sent this user a copy.
|
|
||||||
|
|
||||||
For an executable, the required form of the "work that uses the
|
|
||||||
Library" must include any data and utility programs needed for
|
|
||||||
reproducing the executable from it. However, as a special exception,
|
|
||||||
the materials to be 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.
|
|
||||||
|
|
||||||
It may happen that this requirement contradicts the license
|
|
||||||
restrictions of other proprietary libraries that do not normally
|
|
||||||
accompany the operating system. Such a contradiction means you cannot
|
|
||||||
use both them and the Library together in an executable that you
|
|
||||||
distribute.
|
|
||||||
|
|
||||||
7. You may place library facilities that are a work based on the
|
|
||||||
Library side-by-side in a single library together with other library
|
|
||||||
facilities not covered by this License, and distribute such a combined
|
|
||||||
library, provided that the separate distribution of the work based on
|
|
||||||
the Library and of the other library facilities is otherwise
|
|
||||||
permitted, and provided that you do these two things:
|
|
||||||
|
|
||||||
a) Accompany the combined library with a copy of the same work
|
|
||||||
based on the Library, uncombined with any other library
|
|
||||||
facilities. This must be distributed under the terms of the
|
|
||||||
Sections above.
|
|
||||||
|
|
||||||
b) Give prominent notice with the combined library of the fact
|
|
||||||
that part of it is a work based on the Library, and explaining
|
|
||||||
where to find the accompanying uncombined form of the same work.
|
|
||||||
|
|
||||||
8. You may not copy, modify, sublicense, link with, or distribute
|
|
||||||
the Library except as expressly provided under this License. Any
|
|
||||||
attempt otherwise to copy, modify, sublicense, link with, or
|
|
||||||
distribute the Library 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.
|
|
||||||
|
|
||||||
9. 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 Library or its derivative works. These actions are
|
|
||||||
prohibited by law if you do not accept this License. Therefore, by
|
|
||||||
modifying or distributing the Library (or any work based on the
|
|
||||||
Library), you indicate your acceptance of this License to do so, and
|
|
||||||
all its terms and conditions for copying, distributing or modifying
|
|
||||||
the Library or works based on it.
|
|
||||||
|
|
||||||
10. Each time you redistribute the Library (or any work based on the
|
|
||||||
Library), the recipient automatically receives a license from the
|
|
||||||
original licensor to copy, distribute, link with or modify the Library
|
|
||||||
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 with
|
|
||||||
this License.
|
|
||||||
|
|
||||||
11. 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 Library at all. For example, if a patent
|
|
||||||
license would not permit royalty-free redistribution of the Library 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 Library.
|
|
||||||
|
|
||||||
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.
|
|
||||||
|
|
||||||
12. If the distribution and/or use of the Library is restricted in
|
|
||||||
certain countries either by patents or by copyrighted interfaces, the
|
|
||||||
original copyright holder who places the Library 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.
|
|
||||||
|
|
||||||
13. The Free Software Foundation may publish revised and/or new
|
|
||||||
versions of the Lesser 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 Library
|
|
||||||
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 Library does not specify a
|
|
||||||
license version number, you may choose any version ever published by
|
|
||||||
the Free Software Foundation.
|
|
||||||
|
|
||||||
14. If you wish to incorporate parts of the Library into other free
|
|
||||||
programs whose distribution conditions are incompatible with these,
|
|
||||||
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
|
|
||||||
|
|
||||||
15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
|
|
||||||
WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
|
|
||||||
EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
|
|
||||||
OTHER PARTIES PROVIDE THE LIBRARY "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
|
|
||||||
LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
|
|
||||||
THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
|
|
||||||
|
|
||||||
16. 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 LIBRARY 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
|
|
||||||
LIBRARY (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 LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
|
|
||||||
SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
|
|
||||||
DAMAGES.
|
|
||||||
|
|
||||||
END OF TERMS AND CONDITIONS
|
|
||||||
21
README.md
21
README.md
@ -1,21 +0,0 @@
|
|||||||
# libfm-qt
|
|
||||||
|
|
||||||
Includes libfm-qt, the Qt port of the libfm - a library providing components to
|
|
||||||
build desktop file managers.
|
|
||||||
|
|
||||||
Issue tracker:
|
|
||||||
https://github.com/lxde/pcmanfm-qt/issues
|
|
||||||
|
|
||||||
LXQt website:
|
|
||||||
http://lxqt.org
|
|
||||||
|
|
||||||
LXDE website:
|
|
||||||
http://lxde.org
|
|
||||||
|
|
||||||
|
|
||||||
# License
|
|
||||||
|
|
||||||
libfm-qt is licensed under the terms of the
|
|
||||||
[LGPLv2.1](https://www.gnu.org/licenses/old-licenses/lgpl-2.1.html) or any later version.
|
|
||||||
|
|
||||||
See the LICENSE file for the full text of the license.
|
|
||||||
@ -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 -v "'#TRANSLATIONS_DIR='" ${_inFile} > ${_outFile}
|
|
||||||
COMMAND grep -h ${_pattern} ${_translations} >> ${_outFile}
|
|
||||||
COMMENT "Generating ${_fileName}${_fileExt}"
|
|
||||||
)
|
|
||||||
else()
|
|
||||||
add_custom_command(OUTPUT ${_outFile}
|
|
||||||
COMMAND grep -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)
|
|
||||||
@ -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()
|
|
||||||
@ -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()
|
|
||||||
@ -1,63 +0,0 @@
|
|||||||
#=============================================================================
|
|
||||||
# Copyright 2015 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.
|
|
||||||
#=============================================================================
|
|
||||||
|
|
||||||
@PACKAGE_INIT@
|
|
||||||
|
|
||||||
if (CMAKE_VERSION VERSION_LESS 3.0.2)
|
|
||||||
message(FATAL_ERROR \"fm-qt requires at least CMake version 3.0.2\")
|
|
||||||
endif()
|
|
||||||
|
|
||||||
include(CMakeFindDependencyMacro)
|
|
||||||
|
|
||||||
find_dependency(Qt5Widgets "@REQUIRED_QT_VERSION@")
|
|
||||||
find_dependency(Qt5X11Extras "@REQUIRED_QT_VERSION@")
|
|
||||||
|
|
||||||
find_package(PkgConfig REQUIRED)
|
|
||||||
pkg_check_modules(PKG_GLIB glib-2.0)
|
|
||||||
pkg_check_modules(PKG_GIO
|
|
||||||
gio-2.0
|
|
||||||
gio-unix-2.0
|
|
||||||
)
|
|
||||||
|
|
||||||
pkg_check_modules(PKG_FM REQUIRED libfm>=@REQUIRED_LIBFM_VERSION@)
|
|
||||||
pkg_check_modules(PKG_MENUCACHE REQUIRED libmenu-cache>=@REQUIRED_LIBMENUCACHE_VERSION@)
|
|
||||||
|
|
||||||
if (NOT TARGET @LIBFM_QT_LIBRARY_NAME@)
|
|
||||||
include("${CMAKE_CURRENT_LIST_DIR}/@LIBFM_QT_LIBRARY_NAME@-targets.cmake")
|
|
||||||
set_property(TARGET "@LIBFM_QT_LIBRARY_NAME@" APPEND PROPERTY
|
|
||||||
INTERFACE_INCLUDE_DIRECTORIES
|
|
||||||
"${PKG_GLIB_INCLUDE_DIRS}"
|
|
||||||
"${PKG_GIO_INCLUDE_DIRS}"
|
|
||||||
"${PKG_FM_INCLUDE_DIRS}"
|
|
||||||
"${PKG_MENUCACHE_INCLUDE_DIRS}"
|
|
||||||
)
|
|
||||||
set_property(TARGET "@LIBFM_QT_LIBRARY_NAME@" APPEND PROPERTY
|
|
||||||
INTERFACE_COMPILE_DEFINITIONS
|
|
||||||
"QT_NO_KEYWORDS"
|
|
||||||
"LIBFM_DATA_DIR=\"${PKG_FM_PREFIX}/share/libfm\""
|
|
||||||
)
|
|
||||||
endif()
|
|
||||||
10
debian/.gitignore
vendored
Normal file
10
debian/.gitignore
vendored
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
/*.debhelper
|
||||||
|
/*.log
|
||||||
|
/*.substvars
|
||||||
|
/files
|
||||||
|
/mangled
|
||||||
|
/debhelper-build-stamp
|
||||||
|
|
||||||
|
/libfm-qt3/
|
||||||
|
/libfm-qt-dev/
|
||||||
|
/tmp
|
||||||
665
debian/changelog
vendored
Normal file
665
debian/changelog
vendored
Normal file
@ -0,0 +1,665 @@
|
|||||||
|
libfm-qt (2.3.1-0ubuntu1) resolute; urgency=medium
|
||||||
|
|
||||||
|
* New upstream release.
|
||||||
|
- Update build dependencies.
|
||||||
|
- Bump soname.
|
||||||
|
- Update symbols.
|
||||||
|
* Update copyright file.
|
||||||
|
* Update Standards-Version to 4.7.3, no changes needed.
|
||||||
|
* Remove redundant 'Rules-Requires-Root: no' control line.
|
||||||
|
|
||||||
|
-- Aaron Rainbolt <arraybolt3@ubuntu.com> Thu, 19 Feb 2026 14:44:44 -0500
|
||||||
|
|
||||||
|
libfm-qt (2.2.0-0ubuntu3) questing; urgency=medium
|
||||||
|
|
||||||
|
* debian/control: Drop for now unnecessary libfm-qt6-16
|
||||||
|
Breaks/Replaces on libfm-qt6-15. There are no shared files, and this
|
||||||
|
is currently making proposed migration of other lxqt packages more
|
||||||
|
difficult.
|
||||||
|
|
||||||
|
-- Rik Mills <rikmills@kde.org> Sun, 17 Aug 2025 07:36:50 +0100
|
||||||
|
|
||||||
|
libfm-qt (2.2.0-0ubuntu2) questing; urgency=medium
|
||||||
|
|
||||||
|
* Update symbols from Questing build logs."
|
||||||
|
|
||||||
|
-- Rik Mills <rikmills@kde.org> Fri, 15 Aug 2025 22:02:00 +0100
|
||||||
|
|
||||||
|
libfm-qt (2.2.0-0ubuntu1) questing; urgency=medium
|
||||||
|
|
||||||
|
* New upstream release.
|
||||||
|
- Update build dependencies.
|
||||||
|
- Bump soname.
|
||||||
|
- Update symbols.
|
||||||
|
* Update copyright file.
|
||||||
|
* Update Standards-Version to 4.7.2, no changes needed.
|
||||||
|
|
||||||
|
-- Aaron Rainbolt <arraybolt3@ubuntu.com> Thu, 03 Jul 2025 15:45:39 -0500
|
||||||
|
|
||||||
|
libfm-qt (2.1.0-0ubuntu7) plucky; urgency=medium
|
||||||
|
|
||||||
|
* Update Standards-Version to 4.7.1, no changes needed.
|
||||||
|
|
||||||
|
-- Simon Quigley <tsimonq2@ubuntu.com> Fri, 21 Feb 2025 16:22:38 -0600
|
||||||
|
|
||||||
|
libfm-qt (2.1.0-0ubuntu6) plucky; urgency=medium
|
||||||
|
|
||||||
|
* Add a Provides: libfm-qt6 line, to make it easier to track and use in
|
||||||
|
reverse dependencies.
|
||||||
|
|
||||||
|
-- Simon Quigley <tsimonq2@ubuntu.com> Sun, 16 Feb 2025 18:59:48 -0600
|
||||||
|
|
||||||
|
libfm-qt (2.1.0-0ubuntu5) plucky; urgency=medium
|
||||||
|
|
||||||
|
* No-change rebuild for Qt 6.8.2.
|
||||||
|
|
||||||
|
-- Simon Quigley <tsimonq2@ubuntu.com> Mon, 03 Feb 2025 11:33:27 -0600
|
||||||
|
|
||||||
|
libfm-qt (2.1.0-0ubuntu4) plucky; urgency=medium
|
||||||
|
|
||||||
|
* No-change rebuild for lxqt-build-tools C++17 -> C++20.
|
||||||
|
* Update symbols from build logs.
|
||||||
|
|
||||||
|
-- Simon Quigley <tsimonq2@ubuntu.com> Fri, 03 Jan 2025 03:53:09 -0600
|
||||||
|
|
||||||
|
libfm-qt (2.1.0-0ubuntu3) plucky; urgency=medium
|
||||||
|
|
||||||
|
* No-change rebuild for Qt 6.8.1.
|
||||||
|
|
||||||
|
-- Simon Quigley <tsimonq2@ubuntu.com> Wed, 04 Dec 2024 14:32:17 -0600
|
||||||
|
|
||||||
|
libfm-qt (2.1.0-0ubuntu2) plucky; urgency=medium
|
||||||
|
|
||||||
|
* No-change rebuild for Qt 6.8.0.
|
||||||
|
|
||||||
|
-- Simon Quigley <tsimonq2@ubuntu.com> Wed, 04 Dec 2024 14:32:17 -0600
|
||||||
|
|
||||||
|
libfm-qt (2.1.0-0ubuntu1) plucky; urgency=medium
|
||||||
|
|
||||||
|
* New upstream release.
|
||||||
|
- Bump build dependencies.
|
||||||
|
- Update symbols from amd64 build logs.
|
||||||
|
* Add new build dependencies from the CMake output.
|
||||||
|
* Make the package Lintian-clean.
|
||||||
|
|
||||||
|
-- Simon Quigley <tsimonq2@ubuntu.com> Fri, 15 Nov 2024 15:31:59 -0600
|
||||||
|
|
||||||
|
libfm-qt (2.0.2-0ubuntu3) plucky; urgency=medium
|
||||||
|
|
||||||
|
* No-change rebuild against Qt 6.7.2 private-abi.
|
||||||
|
|
||||||
|
-- Rik Mills <rikmills@kde.org> Thu, 17 Oct 2024 17:52:48 +0100
|
||||||
|
|
||||||
|
libfm-qt (2.0.2-0ubuntu2) oracular; urgency=medium
|
||||||
|
|
||||||
|
* Fix symbols file.
|
||||||
|
|
||||||
|
-- Aaron Rainbolt <arraybolt3@ubuntu.com> Sun, 25 Aug 2024 22:22:47 -0500
|
||||||
|
|
||||||
|
libfm-qt (2.0.2-0ubuntu1) oracular; urgency=medium
|
||||||
|
|
||||||
|
* New upstream release.
|
||||||
|
* Bump Standards-Version to 4.7.0, no changes necessary.
|
||||||
|
* Update copyright file.
|
||||||
|
* Bump build deps.
|
||||||
|
* Change binary package name to libfm-qt6.
|
||||||
|
* Update symbols file.
|
||||||
|
|
||||||
|
-- Aaron Rainbolt <arraybolt3@ubuntu.com> Thu, 15 Aug 2024 16:06:46 -0500
|
||||||
|
|
||||||
|
libfm-qt (1.4.0-0ubuntu1) noble; urgency=medium
|
||||||
|
|
||||||
|
* New upstream release.
|
||||||
|
* Reorganized and fixed copyright file.
|
||||||
|
* Added lxqt-menu-data as a build dependency.
|
||||||
|
* Bumped soname to libfm-qt14.
|
||||||
|
* Updated symbols file.
|
||||||
|
|
||||||
|
-- Aaron Rainbolt <arraybolt3@gmail.com> Sun, 05 Nov 2023 17:15:40 -0600
|
||||||
|
|
||||||
|
libfm-qt (1.3.0-0ubuntu2) mantic; urgency=medium
|
||||||
|
|
||||||
|
* Update symbols from build logs.
|
||||||
|
|
||||||
|
-- Simon Quigley <tsimonq2@ubuntu.com> Fri, 11 Aug 2023 10:16:27 -0500
|
||||||
|
|
||||||
|
libfm-qt (1.3.0-0ubuntu1) mantic; urgency=medium
|
||||||
|
|
||||||
|
* New upstream release.
|
||||||
|
- Bump build dependency accordingly.
|
||||||
|
* Rename binary package for SONAME change, update symbols accordingly.
|
||||||
|
|
||||||
|
-- Simon Quigley <tsimonq2@ubuntu.com> Wed, 26 Jul 2023 16:25:53 -0500
|
||||||
|
|
||||||
|
libfm-qt (1.2.1-0ubuntu1) lunar; urgency=medium
|
||||||
|
|
||||||
|
* New upstream release.
|
||||||
|
* Updated copyright file.
|
||||||
|
* Bumped Standards-Version to 4.6.2, no changes necessary.
|
||||||
|
* Updated symbols file.
|
||||||
|
* Ran wrap-and-sort.
|
||||||
|
|
||||||
|
-- Aaron Rainbolt <arraybolt3@ubuntu.com> Thu, 26 Jan 2023 20:18:59 -0600
|
||||||
|
|
||||||
|
libfm-qt (1.2.0-0ubuntu3) lunar; urgency=medium
|
||||||
|
|
||||||
|
* No-change rebuild against Qt 5.15.8.
|
||||||
|
|
||||||
|
-- Dmitry Shachnev <mitya57@ubuntu.com> Sat, 14 Jan 2023 10:19:25 +0300
|
||||||
|
|
||||||
|
libfm-qt (1.2.0-0ubuntu2) lunar; urgency=medium
|
||||||
|
|
||||||
|
* No-change rebuild against Qt 5.15.7.
|
||||||
|
|
||||||
|
-- Dmitry Shachnev <mitya57@ubuntu.com> Sat, 10 Dec 2022 12:50:58 +0300
|
||||||
|
|
||||||
|
libfm-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.
|
||||||
|
* Remove reverse-applicable upstream patches.
|
||||||
|
* Bump build dependencies to the latest upstream LXQt versions.
|
||||||
|
* Rename libfm-qt11 -> libfm-qt12 and add necessary Breaks/Replaces.
|
||||||
|
* Update symbols from amd64 build logs.
|
||||||
|
|
||||||
|
-- Simon Quigley <tsimonq2@ubuntu.com> Wed, 16 Nov 2022 19:21:46 -0600
|
||||||
|
|
||||||
|
libfm-qt (1.1.0-3ubuntu1) kinetic; urgency=medium
|
||||||
|
|
||||||
|
* Revert the previous upload.
|
||||||
|
* Make Breaks/Replaces stricter for libfm-qt11 on libfm-qt-common due to the
|
||||||
|
nature of the reverted upload.
|
||||||
|
|
||||||
|
-- Simon Quigley <tsimonq2@ubuntu.com> Mon, 10 Oct 2022 11:06:03 -0500
|
||||||
|
|
||||||
|
libfm-qt (1.1.0-2ubuntu1) kinetic; urgency=medium
|
||||||
|
|
||||||
|
* Update debian/libfm-qt11.symbols for GCC 12.
|
||||||
|
|
||||||
|
-- Dmitry Shachnev <mitya57@ubuntu.com> Sat, 13 Aug 2022 21:37:11 +0300
|
||||||
|
|
||||||
|
libfm-qt (1.1.0-2) experimental; urgency=medium
|
||||||
|
|
||||||
|
* Upstreamed compatible changes from Ubuntu, modifying the following files:
|
||||||
|
- control
|
||||||
|
- copyright
|
||||||
|
- libfm-qt11.symbols
|
||||||
|
- libfm-qt-common.install
|
||||||
|
- libfm-qt-dev.install
|
||||||
|
- rules
|
||||||
|
- upstream/*
|
||||||
|
- patches directory
|
||||||
|
|
||||||
|
-- Aaron Rainbolt <arraybolt3@gmail.com> Thu, 14 Jul 2022 15:45:41 -0500
|
||||||
|
|
||||||
|
libfm-qt (1.1.0-1) experimental; urgency=medium
|
||||||
|
|
||||||
|
* debian/changelog: fix a typo.
|
||||||
|
* New upstream version 1.0.0
|
||||||
|
* Add debian/salsa-ci.yml file.
|
||||||
|
* Update debian/upstream/signing-key.asc.
|
||||||
|
* New upstream version 1.1.0
|
||||||
|
* debian/control: build-deps on lxqt-build-tools (>=0.11.0~).
|
||||||
|
* Bump to libfm-qt11 to match soname changes.
|
||||||
|
* debian/libfm-qt11.shlibs: Added, restrict to latest upstream version.
|
||||||
|
* Drop C++ symbols according to
|
||||||
|
https://wiki.debian.org/UsingSymbolsFiles.
|
||||||
|
|
||||||
|
-- Andrew Lee (李健秋) <ajqlee@debian.org> Tue, 12 Jul 2022 22:33:35 +0800
|
||||||
|
|
||||||
|
libfm-qt (0.16.0-3) unstable; urgency=high
|
||||||
|
|
||||||
|
* Update symbols for armel, armhf, i386, mipsel and s390x to fix FTBFS.
|
||||||
|
|
||||||
|
-- Andrew Lee (李健秋) <ajqlee@debian.org> Sat, 09 Jan 2021 03:15:46 +0800
|
||||||
|
|
||||||
|
libfm-qt (0.16.0-2) unstable; urgency=medium
|
||||||
|
|
||||||
|
* Source only upload.
|
||||||
|
|
||||||
|
-- Andrew Lee (李健秋) <ajqlee@debian.org> Wed, 06 Jan 2021 21:31:49 +0800
|
||||||
|
|
||||||
|
libfm-qt (0.16.0-1) unstable; urgency=medium
|
||||||
|
|
||||||
|
* New upstream release. (Closes: #978219)
|
||||||
|
* Drop fixed upstream patches.
|
||||||
|
* Bump to libfm-qt8 to match soname changes.
|
||||||
|
* Refresh debian/libfm-qt8.symbols file.
|
||||||
|
|
||||||
|
-- Andrew Lee (李健秋) <ajqlee@debian.org> Wed, 06 Jan 2021 04:30:38 +0800
|
||||||
|
|
||||||
|
libfm-qt (0.14.1-12.2) unstable; urgency=medium
|
||||||
|
|
||||||
|
* Non-maintainer upload.
|
||||||
|
* Update symbols files from buildds’ logs to fix FTBFS on armel.
|
||||||
|
|
||||||
|
-- Dmitry Shachnev <mitya57@debian.org> Fri, 23 Oct 2020 20:28:57 +0300
|
||||||
|
|
||||||
|
libfm-qt (0.14.1-12.1) unstable; urgency=medium
|
||||||
|
|
||||||
|
* Non-maintainer upload.
|
||||||
|
* Update symbols files for GCC 10 (closes: #957436).
|
||||||
|
|
||||||
|
-- Dmitry Shachnev <mitya57@debian.org> Sat, 17 Oct 2020 20:11:39 +0300
|
||||||
|
|
||||||
|
libfm-qt (0.14.1-12) unstable; urgency=medium
|
||||||
|
|
||||||
|
* Fixed symbol QRegEx -> QRegularExpression
|
||||||
|
|
||||||
|
-- Alf Gaida <agaida@siduction.org> Tue, 22 Oct 2019 23:52:39 +0200
|
||||||
|
|
||||||
|
libfm-qt (0.14.1-11) unstable; urgency=medium
|
||||||
|
|
||||||
|
* Bumped Standards to 4.4.1, no changes needed
|
||||||
|
* Switched to gbp, gbp.conf added
|
||||||
|
|
||||||
|
-- Alf Gaida <agaida@siduction.org> Sat, 05 Oct 2019 12:56:09 +0200
|
||||||
|
|
||||||
|
libfm-qt (0.14.1-10) unstable; urgency=medium
|
||||||
|
|
||||||
|
* Fixed symbols for gcc 9.2.1 (Closes: #925742)
|
||||||
|
* Bumped Standards to 4.4.0, no changes needed
|
||||||
|
|
||||||
|
-- Alf Gaida <agaida@siduction.org> Sat, 17 Aug 2019 13:00:08 +0200
|
||||||
|
|
||||||
|
libfm-qt (0.14.1-9) unstable; urgency=medium
|
||||||
|
|
||||||
|
* Added upstream patch workaround-missed-file-monitoring.patch
|
||||||
|
(Closes: #926803)
|
||||||
|
* Added two new symbols - internal use only
|
||||||
|
|
||||||
|
-- Alf Gaida <agaida@siduction.org> Sat, 08 Jun 2019 16:39:11 +0200
|
||||||
|
|
||||||
|
libfm-qt (0.14.1-8) unstable; urgency=medium
|
||||||
|
|
||||||
|
* Removed the wrongly introduced build dependency on lxqt-qtplugin
|
||||||
|
|
||||||
|
-- Alf Gaida <agaida@siduction.org> Sat, 27 Apr 2019 18:40:25 +0200
|
||||||
|
|
||||||
|
libfm-qt (0.14.1-7) unstable; urgency=medium
|
||||||
|
|
||||||
|
* Workaround for GLib's recursive moving error (Closes: #927708)
|
||||||
|
|
||||||
|
-- Alf Gaida <agaida@siduction.org> Sat, 27 Apr 2019 10:50:16 +0200
|
||||||
|
|
||||||
|
libfm-qt (0.14.1-6) unstable; urgency=medium
|
||||||
|
|
||||||
|
* Fixed ignored creation-deletion sequences (Closes: #927707)
|
||||||
|
|
||||||
|
-- Alf Gaida <agaida@siduction.org> Sun, 21 Apr 2019 20:50:23 +0200
|
||||||
|
|
||||||
|
libfm-qt (0.14.1-5) unstable; urgency=medium
|
||||||
|
|
||||||
|
* Fixed license for vfs-search.c and vfs-menu.c - was forgotten upstream.
|
||||||
|
* Fixed d/copyright that way.
|
||||||
|
|
||||||
|
-- Alf Gaida <agaida@siduction.org> Thu, 18 Apr 2019 20:52:30 +0200
|
||||||
|
|
||||||
|
libfm-qt (0.14.1-4) unstable; urgency=medium
|
||||||
|
|
||||||
|
* Fix recursive copy to smb shares (and possible other remote filesystems)
|
||||||
|
(Closes: #926626)
|
||||||
|
|
||||||
|
-- Alf Gaida <agaida@siduction.org> Mon, 08 Apr 2019 19:03:43 +0200
|
||||||
|
|
||||||
|
libfm-qt (0.14.1-3) unstable; urgency=medium
|
||||||
|
|
||||||
|
* Fixed the remaining symbols
|
||||||
|
|
||||||
|
-- Alf Gaida <agaida@siduction.org> Fri, 01 Mar 2019 01:34:43 +0100
|
||||||
|
|
||||||
|
libfm-qt (0.14.1-2) unstable; urgency=medium
|
||||||
|
|
||||||
|
* Fixed new and optional symbols
|
||||||
|
|
||||||
|
-- Alf Gaida <agaida@siduction.org> Tue, 26 Feb 2019 22:07:40 +0100
|
||||||
|
|
||||||
|
libfm-qt (0.14.1-1) unstable; urgency=medium
|
||||||
|
|
||||||
|
* Cherry-picking upstream release 0.14.1.
|
||||||
|
* Fixed some symbols
|
||||||
|
|
||||||
|
-- Alf Gaida <agaida@siduction.org> Sun, 24 Feb 2019 19:31:01 +0100
|
||||||
|
|
||||||
|
libfm-qt (0.14.0-3) unstable; urgency=medium
|
||||||
|
|
||||||
|
* Switched to unstable
|
||||||
|
* Fixed some more symbols
|
||||||
|
* Ported back some upstream patches
|
||||||
|
|
||||||
|
-- Alf Gaida <agaida@siduction.org> Tue, 05 Feb 2019 20:11:09 +0100
|
||||||
|
|
||||||
|
libfm-qt (0.14.0-2) experimental; urgency=medium
|
||||||
|
|
||||||
|
* Fixed a bunch of symbols for misc. architectures.
|
||||||
|
|
||||||
|
-- Alf Gaida <agaida@siduction.org> Sat, 02 Feb 2019 17:46:02 +0100
|
||||||
|
|
||||||
|
libfm-qt (0.14.0-1) experimental; urgency=medium
|
||||||
|
|
||||||
|
* Cherry-picking upstream release 0.14.0.
|
||||||
|
* Switched to experimental
|
||||||
|
* 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
|
||||||
|
* Removed obsolete build dependency libfm-dev
|
||||||
|
* Added Build-Depends-Package field to symbols
|
||||||
|
* Added l10n-package, moved from lxqt-l10n
|
||||||
|
* Fixed symbols file for 0.14.0
|
||||||
|
* Added d/upstream/metadata
|
||||||
|
* Added new files do debian/copyright
|
||||||
|
|
||||||
|
-- Alf Gaida <agaida@siduction.org> Wed, 30 Jan 2019 20:32:59 +0100
|
||||||
|
|
||||||
|
libfm-qt (0.13.1-10) unstable; urgency=medium
|
||||||
|
|
||||||
|
* Added Build-Depends-Package: libfm-qt-dev to libfm-qt-dev.symbols
|
||||||
|
* Bumped Standards to 4.2.1
|
||||||
|
* Fixed the first symbols (Closes: #916158)
|
||||||
|
|
||||||
|
-- Alf Gaida <agaida@siduction.org> Fri, 28 Dec 2018 16:41:09 +0100
|
||||||
|
|
||||||
|
libfm-qt (0.13.1-9) unstable; urgency=medium
|
||||||
|
|
||||||
|
* Fixed armel and riscv symbols
|
||||||
|
|
||||||
|
-- Alf Gaida <agaida@siduction.org> Fri, 31 Aug 2018 19:35:35 +0200
|
||||||
|
|
||||||
|
libfm-qt (0.13.1-8) unstable; urgency=medium
|
||||||
|
|
||||||
|
* Fixed missed blank in symbols
|
||||||
|
|
||||||
|
-- Alf Gaida <agaida@siduction.org> Fri, 31 Aug 2018 00:51:51 +0200
|
||||||
|
|
||||||
|
libfm-qt (0.13.1-7) unstable; urgency=medium
|
||||||
|
|
||||||
|
* Fixed another bunch of symbols
|
||||||
|
|
||||||
|
-- Alf Gaida <agaida@siduction.org> Thu, 30 Aug 2018 22:36:25 +0200
|
||||||
|
|
||||||
|
libfm-qt (0.13.1-6) unstable; urgency=medium
|
||||||
|
|
||||||
|
* Fixed a bunch of symbols
|
||||||
|
|
||||||
|
-- Alf Gaida <agaida@siduction.org> Tue, 31 Jul 2018 18:15:12 +0200
|
||||||
|
|
||||||
|
libfm-qt (0.13.1-5) unstable; urgency=medium
|
||||||
|
|
||||||
|
* Switch to unstable
|
||||||
|
* Another round of symbol fixes
|
||||||
|
* Bumped Standards to 4.1.5, no changes needed
|
||||||
|
|
||||||
|
-- Alf Gaida <agaida@siduction.org> Sat, 07 Jul 2018 13:05:18 +0200
|
||||||
|
|
||||||
|
libfm-qt (0.13.1-4) experimental; urgency=medium
|
||||||
|
|
||||||
|
* Fixed some more symbols in architectures
|
||||||
|
|
||||||
|
-- Alf Gaida <agaida@siduction.org> Fri, 29 Jun 2018 19:34:00 +0200
|
||||||
|
|
||||||
|
libfm-qt (0.13.1-3) experimental; urgency=medium
|
||||||
|
|
||||||
|
* Fixed some powerpcspe symbols
|
||||||
|
|
||||||
|
-- Alf Gaida <agaida@siduction.org> Thu, 28 Jun 2018 01:22:45 +0200
|
||||||
|
|
||||||
|
libfm-qt (0.13.1-2) experimental; urgency=medium
|
||||||
|
|
||||||
|
* Added dependency libglib2.0-bin (Closes: #902053)
|
||||||
|
|
||||||
|
-- Alf Gaida <agaida@siduction.org> Sat, 23 Jun 2018 14:45:18 +0200
|
||||||
|
|
||||||
|
libfm-qt (0.13.1-1) experimental; urgency=medium
|
||||||
|
|
||||||
|
* Cherry-picking upstream release 0.13.1.
|
||||||
|
* Fixed some symbols
|
||||||
|
|
||||||
|
-- Alf Gaida <agaida@siduction.org> Sun, 03 Jun 2018 01:30:24 +0200
|
||||||
|
|
||||||
|
libfm-qt (0.13.0-2) experimental; urgency=medium
|
||||||
|
|
||||||
|
* Fixed the first big bunch of symbols
|
||||||
|
|
||||||
|
-- Alf Gaida <agaida@siduction.org> Mon, 28 May 2018 19:36:36 +0200
|
||||||
|
|
||||||
|
libfm-qt (0.13.0-1) experimental; urgency=medium
|
||||||
|
|
||||||
|
* Cherry-picking upstream release 0.13.0.
|
||||||
|
* Removed build dependency libglib2.0-dev, thrown in via lxqt-build-tools
|
||||||
|
* Bumped build dependency lxqt-build-tools to >= 0.5.0~
|
||||||
|
* Renamed libfm-qt3 -> libfm-qt5. soname bumped
|
||||||
|
* Added Breaks and replaces for libfm-qt3
|
||||||
|
* Bumped years in copyright
|
||||||
|
* Messed around with symbols (gcc7/gcc8, removals, new symbols)
|
||||||
|
|
||||||
|
-- Alf Gaida <agaida@siduction.org> Wed, 23 May 2018 23:02:00 +0200
|
||||||
|
|
||||||
|
libfm-qt (0.12.0-17) unstable; urgency=medium
|
||||||
|
|
||||||
|
* Fixed symbols for ia64
|
||||||
|
* Fixed watch file to lxqt
|
||||||
|
|
||||||
|
-- Alf Gaida <agaida@siduction.org> Sun, 29 Apr 2018 02:31:23 +0200
|
||||||
|
|
||||||
|
libfm-qt (0.12.0-16) unstable; urgency=medium
|
||||||
|
|
||||||
|
* fix some typos in symbols
|
||||||
|
|
||||||
|
-- Alf Gaida <agaida@siduction.org> Mon, 23 Apr 2018 02:07:46 +0200
|
||||||
|
|
||||||
|
libfm-qt (0.12.0-15) unstable; urgency=medium
|
||||||
|
|
||||||
|
* Added missed symbols (Closes: #896514)
|
||||||
|
* Bumped debhelper build dependency to 11~
|
||||||
|
* Bumped compat to 11
|
||||||
|
* Bumped Standards to 4.1.4
|
||||||
|
* Fixed VCS fields for salsa
|
||||||
|
* Fixed upstream homepage
|
||||||
|
* Fixed years and source in copyright
|
||||||
|
|
||||||
|
-- Alf Gaida <agaida@siduction.org> Sun, 22 Apr 2018 22:39:57 +0200
|
||||||
|
|
||||||
|
libfm-qt (0.12.0-14) unstable; urgency=medium
|
||||||
|
|
||||||
|
* Bumped Standards to 4.1.2, no changes needed
|
||||||
|
* Removed branch from VCS fields
|
||||||
|
* Removed debian/gbp.conf
|
||||||
|
* Removed trailing whitespaces
|
||||||
|
|
||||||
|
-- Alf Gaida <agaida@siduction.org> Wed, 13 Dec 2017 20:08:02 +0100
|
||||||
|
|
||||||
|
libfm-qt (0.12.0-13) unstable; urgency=medium
|
||||||
|
|
||||||
|
* Transition to unstable
|
||||||
|
|
||||||
|
-- Alf Gaida <agaida@siduction.org> Mon, 04 Dec 2017 18:41:41 +0100
|
||||||
|
|
||||||
|
libfm-qt (0.12.0-12) experimental; urgency=medium
|
||||||
|
|
||||||
|
* finally fixed the symbols for the very most architectures
|
||||||
|
|
||||||
|
-- Alf Gaida <agaida@siduction.org> Fri, 01 Dec 2017 20:51:49 +0100
|
||||||
|
|
||||||
|
libfm-qt (0.12.0-11) experimental; urgency=medium
|
||||||
|
|
||||||
|
* added new symbol to mips64el
|
||||||
|
* added and fixed a bunch of armel symbols
|
||||||
|
|
||||||
|
-- Alf Gaida <agaida@siduction.org> Sun, 05 Nov 2017 00:27:13 +0100
|
||||||
|
|
||||||
|
libfm-qt (0.12.0-10) experimental; urgency=medium
|
||||||
|
|
||||||
|
* fixed symbols for mips64el
|
||||||
|
|
||||||
|
-- Alf Gaida <agaida@siduction.org> Sat, 04 Nov 2017 17:55:04 +0100
|
||||||
|
|
||||||
|
libfm-qt (0.12.0-9) experimental; urgency=medium
|
||||||
|
|
||||||
|
* next round of symbols
|
||||||
|
|
||||||
|
-- Alf Gaida <agaida@siduction.org> Sun, 29 Oct 2017 02:59:13 +0200
|
||||||
|
|
||||||
|
libfm-qt (0.12.0-8) experimental; urgency=medium
|
||||||
|
|
||||||
|
* introduced two optional symbols
|
||||||
|
* fixed sh4 symbols
|
||||||
|
|
||||||
|
-- Alf Gaida <agaida@siduction.org> Sat, 28 Oct 2017 17:45:54 +0200
|
||||||
|
|
||||||
|
libfm-qt (0.12.0-7) experimental; urgency=medium
|
||||||
|
|
||||||
|
* Some more symbol fixes for armel, armhf, mips, mipsel. hppa, m68k,
|
||||||
|
ppc64 and sh4
|
||||||
|
|
||||||
|
-- Alf Gaida <agaida@siduction.org> Thu, 26 Oct 2017 16:30:32 +0200
|
||||||
|
|
||||||
|
libfm-qt (0.12.0-6) experimental; urgency=medium
|
||||||
|
|
||||||
|
* Fixed symbols for arm64, ppc64el, s390x, hppa, powerpc, ppc64 and sparc64
|
||||||
|
|
||||||
|
-- Alf Gaida <agaida@siduction.org> Thu, 26 Oct 2017 02:56:20 +0200
|
||||||
|
|
||||||
|
libfm-qt (0.12.0-5) experimental; urgency=medium
|
||||||
|
|
||||||
|
* Symbol fixes for i386 - this will introduce regressions for other
|
||||||
|
architectures
|
||||||
|
|
||||||
|
-- Alf Gaida <agaida@siduction.org> Thu, 26 Oct 2017 00:57:28 +0200
|
||||||
|
|
||||||
|
libfm-qt (0.12.0-4) experimental; urgency=medium
|
||||||
|
|
||||||
|
* Symbol fixes for armel, mipsel, hurd-i386, x32
|
||||||
|
|
||||||
|
-- Alf Gaida <agaida@siduction.org> Tue, 24 Oct 2017 23:49:03 +0200
|
||||||
|
|
||||||
|
libfm-qt (0.12.0-3) experimental; urgency=medium
|
||||||
|
|
||||||
|
* Next round of fixed symbols
|
||||||
|
|
||||||
|
-- Alf Gaida <agaida@siduction.org> Mon, 23 Oct 2017 01:29:24 +0200
|
||||||
|
|
||||||
|
libfm-qt (0.12.0-2) experimental; urgency=medium
|
||||||
|
|
||||||
|
* Fixed symbols for arm64 armhf i386 mips ppc64el alpha powerpc ppc64 sparc64
|
||||||
|
|
||||||
|
-- Alf Gaida <agaida@siduction.org> Sun, 22 Oct 2017 20:42:08 +0200
|
||||||
|
|
||||||
|
libfm-qt (0.12.0-1) experimental; urgency=medium
|
||||||
|
|
||||||
|
* Cherry-picking upstream release 0.12.0.
|
||||||
|
* Switched to experimental
|
||||||
|
* Bumped Standards to 4.1.1
|
||||||
|
* Fixed Symbols
|
||||||
|
* Added build dependency libexif-dev
|
||||||
|
* Added dependencies libexif-dev and libmenu-cache-dev to libfm-qt-dev
|
||||||
|
* Added override for dh_missing
|
||||||
|
* Bumped years in copyright
|
||||||
|
|
||||||
|
-- Alf Gaida <agaida@siduction.org> Sun, 22 Oct 2017 16:34:45 +0200
|
||||||
|
|
||||||
|
libfm-qt (0.11.2-2) unstable; urgency=medium
|
||||||
|
|
||||||
|
* Bumped Standards to 4.0.0
|
||||||
|
* Added dependency shared-mime-info (Closes: #866901)
|
||||||
|
|
||||||
|
-- Alf Gaida <agaida@siduction.org> Sun, 02 Jul 2017 23:01:43 +0200
|
||||||
|
|
||||||
|
libfm-qt (0.11.2-1) unstable; urgency=medium
|
||||||
|
|
||||||
|
* Cherry-picking upstream release 0.11.2
|
||||||
|
* Added new symbols
|
||||||
|
* Removed build dependencies:
|
||||||
|
- cmake
|
||||||
|
- liblxqt0-dev
|
||||||
|
- libqt5xdg-dev
|
||||||
|
- pkg-config
|
||||||
|
- qttools5-dev
|
||||||
|
- qttools5-dev-tools
|
||||||
|
* Added build dependency lxqt-build-tools
|
||||||
|
* Added build dependency libfm-dev to libfm-qt-dev
|
||||||
|
* Removed models.patch, applied upstream
|
||||||
|
|
||||||
|
-- Alf Gaida <agaida@siduction.org> Thu, 22 Dec 2016 01:32:58 +0100
|
||||||
|
|
||||||
|
libfm-qt (0.11.1-3) unstable; urgency=medium
|
||||||
|
|
||||||
|
* Backported a upstream fix for Icon Emblem Support.
|
||||||
|
* Added needed Symbols
|
||||||
|
|
||||||
|
-- Alf Gaida <agaida@siduction.org> Thu, 20 Oct 2016 18:00:38 +0200
|
||||||
|
|
||||||
|
libfm-qt (0.11.1-2) unstable; urgency=medium
|
||||||
|
|
||||||
|
* Cherry-picking upstream release 0.11.1.
|
||||||
|
* Syncded debian foo with experimental
|
||||||
|
* Bump compat to 10
|
||||||
|
* Removed --parallel from rules, standard compat 10
|
||||||
|
* Bumped Standards to 3.9.8, no changes needed
|
||||||
|
* Bump minimum version debhelper (>= 10)
|
||||||
|
* Bump minimum version libqt5xdg-dev (>= 2.0.0)
|
||||||
|
* Re-introduce build dependency liblxqt0-dev (>= 0.11.0)
|
||||||
|
* Added build dependency libqt5svg5-dev
|
||||||
|
* Added Recommends libfm-qt-l10n
|
||||||
|
* Exported LC_ALL=C.UTF-8 - define language settings for reproducible
|
||||||
|
builds
|
||||||
|
* Hard override translation control
|
||||||
|
* Use DCMAKE_BUILD_TYPE=RelWithDebInfo
|
||||||
|
* Fixed copyright Format field, using https
|
||||||
|
* Fixed copyrights, removed obsolete files
|
||||||
|
* Fixed libfm-qt3.install, don't install translations
|
||||||
|
|
||||||
|
-- Alf Gaida <agaida@siduction.org> Tue, 18 Oct 2016 01:07:52 +0200
|
||||||
|
|
||||||
|
libfm-qt (0.11.0-2) unstable; urgency=medium
|
||||||
|
|
||||||
|
* Merged changes into unstable
|
||||||
|
* Added five new symbols, leave the rest untouched
|
||||||
|
* Removed not needed build dependency liblxqt0-dev
|
||||||
|
* Removed not needed patches (libfm-qt contains no desktop files,
|
||||||
|
so the desktop translation must not be patched)
|
||||||
|
* Fixed VCS-* fields
|
||||||
|
|
||||||
|
-- Alf Gaida <agaida@siduction.org> Thu, 31 Mar 2016 21:38:41 +0200
|
||||||
|
|
||||||
|
libfm-qt (0.11.0-1) experimental; urgency=medium
|
||||||
|
|
||||||
|
* New upstream release.
|
||||||
|
* Bump soversion to 3.
|
||||||
|
|
||||||
|
-- ChangZhuo Chen (陳昌倬) <czchen@debian.org> Sat, 19 Mar 2016 15:51:15 +0800
|
||||||
|
|
||||||
|
libfm-qt (0.10.0+20151214-3) unstable; urgency=medium
|
||||||
|
|
||||||
|
* Add hardening=+all
|
||||||
|
* Bump Standards to 3.9.7
|
||||||
|
* Fix LXQtTranlateDesktop - just in case
|
||||||
|
* Fix year in copyrights
|
||||||
|
* fix grep usage in cmake/LXQtTranslateDesktop.cmake - just in case
|
||||||
|
|
||||||
|
-- Alf Gaida <agaida@siduction.org> Thu, 25 Feb 2016 22:16:17 +0100
|
||||||
|
|
||||||
|
libfm-qt (0.10.0+20151214-2) unstable; urgency=medium
|
||||||
|
|
||||||
|
[ Alf Gaida ]
|
||||||
|
* Dropped debug package, using the new -dbgsym
|
||||||
|
* Added initial arch-bits 32/64 in symbols
|
||||||
|
|
||||||
|
[ ChangZhuo Chen (陳昌倬) ]
|
||||||
|
* Update Vcs-* fields.
|
||||||
|
|
||||||
|
-- ChangZhuo Chen (陳昌倬) <czchen@debian.org> Sun, 07 Feb 2016 15:37:40 +0800
|
||||||
|
|
||||||
|
libfm-qt (0.10.0+20151214-1) unstable; urgency=medium
|
||||||
|
|
||||||
|
[ Alf Gaida ]
|
||||||
|
* forked pcmanfm-qt debian/$foo
|
||||||
|
* Imported upstream version 0.10.0+20151214.
|
||||||
|
* Initial release (Closes: #808192)
|
||||||
|
|
||||||
|
[ ChangZhuo Chen (陳昌倬) ]
|
||||||
|
* Add Breaks for old library name libfm-qt5-2.
|
||||||
|
|
||||||
|
-- Alf Gaida <agaida@siduction.org> Thu, 05 Nov 2015 00:28:39 +0100
|
||||||
112
debian/control
vendored
Normal file
112
debian/control
vendored
Normal file
@ -0,0 +1,112 @@
|
|||||||
|
Source: libfm-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>,
|
||||||
|
Simon Quigley <tsimonq2@debian.org>,
|
||||||
|
Aaron Rainbolt <arraybolt3@gmail.com>
|
||||||
|
Section: x11
|
||||||
|
Priority: optional
|
||||||
|
Build-Depends: debhelper-compat (= 13),
|
||||||
|
libexif-dev,
|
||||||
|
libmenu-cache-dev,
|
||||||
|
libx11-dev,
|
||||||
|
libxcb-composite0-dev,
|
||||||
|
libxcb-cursor-dev,
|
||||||
|
libxcb-damage0-dev,
|
||||||
|
libxcb-dpms0-dev,
|
||||||
|
libxcb-dri2-0-dev,
|
||||||
|
libxcb-dri3-dev,
|
||||||
|
libxcb-ewmh-dev,
|
||||||
|
libxcb-glx0-dev,
|
||||||
|
libxcb-icccm4-dev,
|
||||||
|
libxcb-image0-dev,
|
||||||
|
libxcb-keysyms1-dev,
|
||||||
|
libxcb-present-dev,
|
||||||
|
libxcb-randr0-dev,
|
||||||
|
libxcb-record0-dev,
|
||||||
|
libxcb-render-util0-dev,
|
||||||
|
libxcb-render0-dev,
|
||||||
|
libxcb-res0-dev,
|
||||||
|
libxcb-screensaver0-dev,
|
||||||
|
libxcb-shape0-dev,
|
||||||
|
libxcb-shm0-dev,
|
||||||
|
libxcb-sync-dev,
|
||||||
|
libxcb-util-dev,
|
||||||
|
libxcb-xf86dri0-dev,
|
||||||
|
libxcb-xfixes0-dev,
|
||||||
|
libxcb-xinerama0-dev,
|
||||||
|
libxcb-xinput-dev,
|
||||||
|
libxcb-xkb-dev,
|
||||||
|
libxcb-xtest0-dev,
|
||||||
|
libxcb-xv0-dev,
|
||||||
|
libxcb-xvmc0-dev,
|
||||||
|
lxqt-build-tools (>= 2.3.0),
|
||||||
|
lxqt-menu-data (>= 2.3.0),
|
||||||
|
qt6-base-private-dev (>= 6.6.0),
|
||||||
|
qt6-svg-dev (>= 6.6.0)
|
||||||
|
Standards-Version: 4.7.3
|
||||||
|
Vcs-Browser: https://git.lubuntu.me/Lubuntu/libfm-qt-packaging
|
||||||
|
Vcs-Git: https://git.lubuntu.me/Lubuntu/libfm-qt-packaging.git
|
||||||
|
Debian-Vcs-Browser: https://salsa.debian.org/lxqt-team/libfm-qt
|
||||||
|
Debian-Vcs-Git: https://salsa.debian.org/lxqt-team/libfm-qt.git
|
||||||
|
Homepage: https://github.com/lxqt/libfm-qt
|
||||||
|
|
||||||
|
Package: libfm-qt6-17
|
||||||
|
Provides: libfm-qt6 (= 17)
|
||||||
|
Replaces: libfm-qt14, libfm-qt6-14, libfm-qt6-15, libfm-qt6-16
|
||||||
|
Breaks: libfm-qt14, libfm-qt6-14, libfm-qt6-15, libfm-qt6-16
|
||||||
|
Architecture: any
|
||||||
|
Multi-Arch: same
|
||||||
|
Section: libs
|
||||||
|
Depends: libfm-qt6-common,
|
||||||
|
libglib2.0-bin,
|
||||||
|
shared-mime-info,
|
||||||
|
${misc:Depends},
|
||||||
|
${shlibs:Depends}
|
||||||
|
Recommends: libfm-qt6-l10n
|
||||||
|
Pre-Depends: ${misc:Pre-Depends}
|
||||||
|
Description: file management support for pcmanfm-qt
|
||||||
|
Libfm-Qt is a companion library providing components to build desktop file
|
||||||
|
managers.
|
||||||
|
.
|
||||||
|
This package contains helper library libfm-qt for pcmanfm-qt.
|
||||||
|
|
||||||
|
Package: libfm-qt6-common
|
||||||
|
Architecture: all
|
||||||
|
Multi-Arch: foreign
|
||||||
|
Section: libs
|
||||||
|
Depends: ${misc:Depends}
|
||||||
|
Breaks: libfm-qt14
|
||||||
|
Replaces: libfm-qt14
|
||||||
|
Description: Common files for libfm-qt
|
||||||
|
Libfm-Qt is a companion library providing components to build desktop file
|
||||||
|
managers.
|
||||||
|
.
|
||||||
|
This package contains common files for libfm-qt.
|
||||||
|
|
||||||
|
Package: libfm-qt6-dev
|
||||||
|
Architecture: any
|
||||||
|
Section: libdevel
|
||||||
|
Depends: libexif-dev,
|
||||||
|
libfm-qt6-17 (= ${binary:Version}),
|
||||||
|
libmenu-cache-dev,
|
||||||
|
${misc:Depends}
|
||||||
|
Description: file management support library for pcmanfm-qt (development files)
|
||||||
|
Libfm-Qt is a companion library providing components to build desktop file
|
||||||
|
managers.
|
||||||
|
.
|
||||||
|
This package contains development files for helper library libfm-qt.
|
||||||
|
|
||||||
|
Package: libfm-qt6-l10n
|
||||||
|
Architecture: all
|
||||||
|
Multi-Arch: foreign
|
||||||
|
Section: localization
|
||||||
|
Depends: qt6-translations-l10n, ${misc:Depends}
|
||||||
|
Description: Language package for libfm-qt
|
||||||
|
Libfm-Qt is a companion library providing components to build desktop file
|
||||||
|
managers.
|
||||||
|
.
|
||||||
|
This package contains the l10n files needed by the libfm-qt.
|
||||||
72
debian/copyright
vendored
Normal file
72
debian/copyright
vendored
Normal file
@ -0,0 +1,72 @@
|
|||||||
|
Format: https://www.debian.org/doc/packaging-manuals/copyright-format/1.0/
|
||||||
|
Upstream-Name: libfm-qt
|
||||||
|
Source: https://github.com/lxqt/libfm-qt
|
||||||
|
|
||||||
|
Files: *
|
||||||
|
Copyright: 2013-2025 LXQt team
|
||||||
|
2009 Juergen Hoetzel <juergen@archlinux.org>
|
||||||
|
2010 Shae Smittle <starfall87@gmail.com>
|
||||||
|
2014 Kuzma Shapran <kuzma.shapran@gmail.com>
|
||||||
|
2016 Mamoru TASAKA <mtasaka@fedoraproject.org>
|
||||||
|
2012-2016 Andriy Grytsenko (LStranger) <andrej@rep.kiev.ua>
|
||||||
|
2009-2019 Hong Jen Yee (PCMan) <pcman.tw@gmail.com>
|
||||||
|
License: LGPL-2.1+
|
||||||
|
|
||||||
|
Files: cmake/fm-qt-config.cmake.in
|
||||||
|
Copyright: 2015 Luís Pereira <luis.artur.pereira@gmail.com>
|
||||||
|
License: BSD-3-Clause
|
||||||
|
|
||||||
|
Files: debian/*
|
||||||
|
Copyright: 2015 Andrew Lee (李健秋) <ajqlee@debian.org>
|
||||||
|
2014-2015 Wen Liao <wen.cf83@gmail.com>
|
||||||
|
2019 Rik Mills <rikmills@kubuntu.org>
|
||||||
|
2013-2019 Alf Gaida <agaida@siduction.org>
|
||||||
|
2018-2019 Walter Lapchynski <wxl@ubuntu.com>
|
||||||
|
2018-2019 Dan Simmons <monetaryabyss@protonmail.com>
|
||||||
|
2020 Gianfranco Costamagna <locutusofborg@debian.org>
|
||||||
|
2019-2021 Raman Sarda <ramansarda2000@gmail.com>
|
||||||
|
2019-2021 apt-ghetto <apt-ghetto@protonmail.com>
|
||||||
|
2018-2025 Simon Quigley <tsimonq2@ubuntu.com>
|
||||||
|
2014-2025 ChangZhuo Chen (陳昌倬) <czchen@debian.org>
|
||||||
|
2022-2026 Aaron Rainbolt <arraybolt3@gmail.com>
|
||||||
|
License: LGPL-2.1+
|
||||||
|
|
||||||
|
License: BSD-3-Clause
|
||||||
|
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 above copyright
|
||||||
|
notice, this list of conditions and the following disclaimer.
|
||||||
|
2. 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.
|
||||||
|
3. Neither the name of the University 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 HOLDERS 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.
|
||||||
|
|
||||||
|
License: LGPL-2.1+
|
||||||
|
This program or 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.
|
||||||
|
.
|
||||||
|
On Debian systems, the complete text of the GNU Lesser General
|
||||||
|
Public License version 2.1 can be found in
|
||||||
|
"/usr/share/common-licenses/LGPL-2.1".
|
||||||
2
debian/docs
vendored
Normal file
2
debian/docs
vendored
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
AUTHORS
|
||||||
|
README.md
|
||||||
6
debian/gbp.conf
vendored
Normal file
6
debian/gbp.conf
vendored
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
[DEFAULT]
|
||||||
|
debian-branch = debian/sid
|
||||||
|
upstream-branch = upstream/latest
|
||||||
|
pristine-tar = True
|
||||||
|
compression = xz
|
||||||
|
|
||||||
1
debian/libfm-qt6-17.install
vendored
Normal file
1
debian/libfm-qt6-17.install
vendored
Normal file
@ -0,0 +1 @@
|
|||||||
|
usr/lib/*/*.so.*
|
||||||
1678
debian/libfm-qt6-17.symbols
vendored
Normal file
1678
debian/libfm-qt6-17.symbols
vendored
Normal file
File diff suppressed because it is too large
Load Diff
3
debian/libfm-qt6-common.install
vendored
Normal file
3
debian/libfm-qt6-common.install
vendored
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
usr/share/libfm-qt6/archivers.list
|
||||||
|
usr/share/libfm-qt6/terminals.list
|
||||||
|
usr/share/mime/packages/libfm-qt6-mimetypes.xml
|
||||||
8
debian/libfm-qt6-dev.install
vendored
Normal file
8
debian/libfm-qt6-dev.install
vendored
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
usr/include/libfm-qt6/*.h
|
||||||
|
usr/include/libfm-qt6/core/*.h
|
||||||
|
usr/include/libfm-qt6/core/legacy/*.h
|
||||||
|
usr/include/libfm-qt6/core/vfs/*.h
|
||||||
|
usr/include/libfm-qt6/customactions/*.h
|
||||||
|
usr/lib/*/*.so
|
||||||
|
usr/lib/*/pkgconfig/*
|
||||||
|
usr/share/cmake/fm-qt6/*.cmake
|
||||||
1
debian/libfm-qt6-l10n.install
vendored
Normal file
1
debian/libfm-qt6-l10n.install
vendored
Normal file
@ -0,0 +1 @@
|
|||||||
|
usr/share/libfm-qt6/translations
|
||||||
16
debian/patches/fix-metadata-for-trusting-executables.patch
vendored
Normal file
16
debian/patches/fix-metadata-for-trusting-executables.patch
vendored
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
Description: Fix metadata for trusting executables
|
||||||
|
To conform with the Ubuntu standard use metadata::trusted instead of metadata::trust. This patch must be applied after any upstream version changes since they refuse to conform.
|
||||||
|
Author: Dan Simmons <monetaryabyss@protonmail.com>
|
||||||
|
Bug: https://bugs.launchpad.net/bugs/1813687
|
||||||
|
Last-Update: 2019-01-29
|
||||||
|
--- a/src/core/fileinfo.cpp
|
||||||
|
+++ b/src/core/fileinfo.cpp
|
||||||
|
@@ -2,7 +2,7 @@
|
||||||
|
#include "fileinfo_p.h"
|
||||||
|
#include <gio/gio.h>
|
||||||
|
|
||||||
|
-#define METADATA_TRUST "metadata::trust"
|
||||||
|
+#define METADATA_TRUST "metadata::trusted"
|
||||||
|
|
||||||
|
namespace Fm {
|
||||||
|
|
||||||
1
debian/patches/series
vendored
Normal file
1
debian/patches/series
vendored
Normal file
@ -0,0 +1 @@
|
|||||||
|
fix-metadata-for-trusting-executables.patch
|
||||||
16
debian/rules
vendored
Executable file
16
debian/rules
vendored
Executable file
@ -0,0 +1,16 @@
|
|||||||
|
#!/usr/bin/make -f
|
||||||
|
# export DH_VERBOSE = 1
|
||||||
|
|
||||||
|
export LC_ALL=C.UTF-8
|
||||||
|
export DEB_BUILD_MAINT_OPTIONS = hardening=+all
|
||||||
|
|
||||||
|
%:
|
||||||
|
dh ${@} --buildsystem cmake
|
||||||
|
|
||||||
|
override_dh_missing:
|
||||||
|
dh_missing --fail-missing
|
||||||
|
|
||||||
|
override_dh_auto_configure:
|
||||||
|
dh_auto_configure -- \
|
||||||
|
-DUPDATE_TRANSLATIONS=OFF \
|
||||||
|
-DCMAKE_BUILD_TYPE=RelWithDebInfo
|
||||||
12
debian/salsa-ci.yml
vendored
Normal file
12
debian/salsa-ci.yml
vendored
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
# For more information on what jobs are run see:
|
||||||
|
# https://salsa.debian.org/salsa-ci-team/pipeline
|
||||||
|
#
|
||||||
|
# To enable the jobs, go to your repository (at salsa.debian.org)
|
||||||
|
# and click over Settings > CI/CD > Expand (in General pipelines).
|
||||||
|
# In "Custom CI config path" write debian/salsa-ci.yml and click
|
||||||
|
# in "Save Changes". The CI tests will run after the next commit.
|
||||||
|
---
|
||||||
|
include:
|
||||||
|
- https://salsa.debian.org/salsa-ci-team/pipeline/raw/master/salsa-ci.yml
|
||||||
|
- https://salsa.debian.org/salsa-ci-team/pipeline/raw/master/pipeline-jobs.yml
|
||||||
|
|
||||||
1
debian/source/format
vendored
Normal file
1
debian/source/format
vendored
Normal file
@ -0,0 +1 @@
|
|||||||
|
3.0 (quilt)
|
||||||
5
debian/source/lintian-overrides
vendored
Normal file
5
debian/source/lintian-overrides
vendored
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
# This list will always be very long, it's okay
|
||||||
|
libfm-qt source: very-long-line-length-in-source-file * > 512 [data/archivers.list:*]
|
||||||
|
|
||||||
|
# Long lines in the upstream changelog are okay
|
||||||
|
libfm-qt source: very-long-line-length-in-source-file * > 512 [CHANGELOG:*]
|
||||||
2
debian/source/local-options
vendored
Normal file
2
debian/source/local-options
vendored
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
unapply-patches
|
||||||
|
abort-on-upstream-changes
|
||||||
1
debian/source/options
vendored
Normal file
1
debian/source/options
vendored
Normal file
@ -0,0 +1 @@
|
|||||||
|
tar-ignore = .gitignore
|
||||||
5
debian/upstream/metadata
vendored
Normal file
5
debian/upstream/metadata
vendored
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
Name: libfm-qt
|
||||||
|
Bug-Database: https://github.com/lxqt/libfm-qt/issues
|
||||||
|
Bug-Submit: https://github.com/lxqt/libfm-qt/issues/new
|
||||||
|
Changelog: https://github.com/lxqt/libfm-qt/blob/master/CHANGELOG
|
||||||
|
Repository: https://github.com/lxqt/libfm-qt
|
||||||
52
debian/upstream/signing-key.asc
vendored
Normal file
52
debian/upstream/signing-key.asc
vendored
Normal file
@ -0,0 +1,52 @@
|
|||||||
|
-----BEGIN PGP PUBLIC KEY BLOCK-----
|
||||||
|
|
||||||
|
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-----
|
||||||
6
debian/watch
vendored
Normal file
6
debian/watch
vendored
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
Version: 5
|
||||||
|
Template: GitHub
|
||||||
|
Owner: lxqt
|
||||||
|
Project: @PACKAGE@
|
||||||
|
Download-Url-Mangle: s%https://api.github.com/repos/([^/]+)/@PACKAGE@/git/refs/tags/@ANY_VERSION@%https://github.com/$1/@PACKAGE@/releases/download/$2/@PACKAGE@-$2.tar.xz%g
|
||||||
|
Pgp-Mode: auto
|
||||||
@ -1,198 +0,0 @@
|
|||||||
set(libfm_TRANSLATION_TEMPLATE ${PROJECT_NAME})
|
|
||||||
|
|
||||||
include_directories(
|
|
||||||
"${LIBFM_INCLUDE_DIRS}"
|
|
||||||
"${LIBFM_INCLUDEDIR}/libfm" # to workaround incorrect #include in fm-actions.
|
|
||||||
"${LIBMENUCACHE_INCLUDE_DIRS}"
|
|
||||||
"${SYSTEM_LIBS_INCLUDE_DIRS}"
|
|
||||||
)
|
|
||||||
|
|
||||||
link_directories(
|
|
||||||
"${LIBFM_LIBRARY_DIRS}"
|
|
||||||
"${LIBMENUCACHE_LIBRARY_DIRS}"
|
|
||||||
"${SYSTEM_LIBS_LIBRARY_DIRS}"
|
|
||||||
)
|
|
||||||
|
|
||||||
set(libfm_SRCS
|
|
||||||
libfmqt.cpp
|
|
||||||
bookmarkaction.cpp
|
|
||||||
sidepane.cpp
|
|
||||||
icontheme.cpp
|
|
||||||
filelauncher.cpp
|
|
||||||
foldermodel.cpp
|
|
||||||
foldermodelitem.cpp
|
|
||||||
cachedfoldermodel.cpp
|
|
||||||
proxyfoldermodel.cpp
|
|
||||||
folderview.cpp
|
|
||||||
folderitemdelegate.cpp
|
|
||||||
createnewmenu.cpp
|
|
||||||
filemenu.cpp
|
|
||||||
foldermenu.cpp
|
|
||||||
filepropsdialog.cpp
|
|
||||||
applaunchcontext.cpp
|
|
||||||
placesview.cpp
|
|
||||||
placesmodel.cpp
|
|
||||||
placesmodelitem.cpp
|
|
||||||
dirtreeview.cpp
|
|
||||||
dirtreemodel.cpp
|
|
||||||
dirtreemodelitem.cpp
|
|
||||||
dnddest.cpp
|
|
||||||
mountoperation.cpp
|
|
||||||
mountoperationpassworddialog.cpp
|
|
||||||
mountoperationquestiondialog.cpp
|
|
||||||
fileoperation.cpp
|
|
||||||
fileoperationdialog.cpp
|
|
||||||
renamedialog.cpp
|
|
||||||
pathedit.cpp
|
|
||||||
colorbutton.cpp
|
|
||||||
fontbutton.cpp
|
|
||||||
browsehistory.cpp
|
|
||||||
utilities.cpp
|
|
||||||
dndactionmenu.cpp
|
|
||||||
editbookmarksdialog.cpp
|
|
||||||
thumbnailloader.cpp
|
|
||||||
path.cpp
|
|
||||||
execfiledialog.cpp
|
|
||||||
appchoosercombobox.cpp
|
|
||||||
appmenuview.cpp
|
|
||||||
appchooserdialog.cpp
|
|
||||||
filesearchdialog.cpp
|
|
||||||
fm-search.c # might be moved to libfm later
|
|
||||||
xdndworkaround.cpp
|
|
||||||
)
|
|
||||||
|
|
||||||
set(libfm_UIS
|
|
||||||
file-props.ui
|
|
||||||
file-operation-dialog.ui
|
|
||||||
rename-dialog.ui
|
|
||||||
mount-operation-password.ui
|
|
||||||
edit-bookmarks.ui
|
|
||||||
exec-file.ui
|
|
||||||
app-chooser-dialog.ui
|
|
||||||
filesearch.ui
|
|
||||||
)
|
|
||||||
|
|
||||||
qt5_wrap_ui(libfm_UIS_H ${libfm_UIS})
|
|
||||||
|
|
||||||
# add translation for libfm-qt
|
|
||||||
lxqt_translate_ts(QM_FILES
|
|
||||||
UPDATE_TRANSLATIONS ${UPDATE_TRANSLATIONS}
|
|
||||||
SOURCES ${libfm_SRCS} ${libfm_UIS}
|
|
||||||
TEMPLATE ${libfm_TRANSLATION_TEMPLATE}
|
|
||||||
)
|
|
||||||
|
|
||||||
add_library(${LIBFM_QT_LIBRARY_NAME} SHARED
|
|
||||||
${libfm_SRCS}
|
|
||||||
${libfm_UIS_H}
|
|
||||||
${QM_FILES}
|
|
||||||
)
|
|
||||||
|
|
||||||
set_property(
|
|
||||||
TARGET ${LIBFM_QT_LIBRARY_NAME} APPEND
|
|
||||||
PROPERTY COMPILE_DEFINITIONS
|
|
||||||
LIBFM_DATA_DIR="${CMAKE_INSTALL_FULL_DATADIR}/libfm-qt"
|
|
||||||
)
|
|
||||||
|
|
||||||
# only turn on custom actions support if it is enabled in libfm.
|
|
||||||
if(EXISTS "${LIBFM_INCLUDEDIR}/libfm/fm-actions.h")
|
|
||||||
set_property(TARGET ${LIBFM_QT_LIBRARY_NAME} APPEND PROPERTY COMPILE_DEFINITIONS CUSTOM_ACTIONS)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
install(EXPORT
|
|
||||||
"${LIBFM_QT_LIBRARY_NAME}-targets"
|
|
||||||
DESTINATION "${CMAKE_INSTALL_DATADIR}/cmake/${LIBFM_QT_LIBRARY_NAME}"
|
|
||||||
COMPONENT Devel
|
|
||||||
)
|
|
||||||
|
|
||||||
target_link_libraries(${LIBFM_QT_LIBRARY_NAME}
|
|
||||||
Qt5::Widgets
|
|
||||||
Qt5::X11Extras
|
|
||||||
${LIBFM_LIBRARIES}
|
|
||||||
${LIBMENUCACHE_LIBRARIES}
|
|
||||||
${SYSTEM_LIBS_LIBRARIES}
|
|
||||||
)
|
|
||||||
|
|
||||||
# set libtool soname
|
|
||||||
set_target_properties(${LIBFM_QT_LIBRARY_NAME} PROPERTIES
|
|
||||||
VERSION ${LIBFM_QT_LIB_VERSION}
|
|
||||||
SOVERSION ${LIBFM_QT_LIB_SOVERSION}
|
|
||||||
)
|
|
||||||
|
|
||||||
target_include_directories(${LIBFM_QT_LIBRARY_NAME}
|
|
||||||
PRIVATE "${LIB_XCB_INDLUDE_DIRS}"
|
|
||||||
PRIVATE "${Qt5Gui_PRIVATE_INCLUDE_DIRS}"
|
|
||||||
INTERFACE "$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>"
|
|
||||||
)
|
|
||||||
|
|
||||||
install(FILES
|
|
||||||
"${CMAKE_CURRENT_BINARY_DIR}/${LIBFM_QT_LIBRARY_NAME}_export.h"
|
|
||||||
DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}/libfm-qt"
|
|
||||||
COMPONENT Devel
|
|
||||||
)
|
|
||||||
|
|
||||||
# install include header files (FIXME: can we make this cleaner? should dir name be versioned?)
|
|
||||||
install(DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/"
|
|
||||||
DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}/libfm-qt"
|
|
||||||
COMPONENT Devel
|
|
||||||
FILES_MATCHING PATTERN "*.h"
|
|
||||||
)
|
|
||||||
|
|
||||||
generate_export_header(${LIBFM_QT_LIBRARY_NAME}
|
|
||||||
EXPORT_MACRO_NAME LIBFM_QT_API
|
|
||||||
)
|
|
||||||
|
|
||||||
configure_package_config_file(
|
|
||||||
"${PROJECT_SOURCE_DIR}/cmake/fm-qt-config.cmake.in"
|
|
||||||
"${PROJECT_BINARY_DIR}/install/${LIBFM_QT_LIBRARY_NAME}-config.cmake"
|
|
||||||
INSTALL_DESTINATION "${CMAKE_INSTALL_DATADIR}/cmake/${LIBFM_QT_LIBRARY_NAME}"
|
|
||||||
)
|
|
||||||
|
|
||||||
install(FILES
|
|
||||||
"${PROJECT_BINARY_DIR}/install/${LIBFM_QT_LIBRARY_NAME}-config.cmake"
|
|
||||||
DESTINATION "${CMAKE_INSTALL_DATADIR}/cmake/${LIBFM_QT_LIBRARY_NAME}"
|
|
||||||
COMPONENT Devel
|
|
||||||
)
|
|
||||||
|
|
||||||
# FIXME: add libtool version to the lib (soname) later.
|
|
||||||
# FIXME: only export public symbols
|
|
||||||
|
|
||||||
install(TARGETS ${LIBFM_QT_LIBRARY_NAME}
|
|
||||||
DESTINATION "${CMAKE_INSTALL_LIBDIR}"
|
|
||||||
EXPORT "${LIBFM_QT_LIBRARY_NAME}-targets"
|
|
||||||
LIBRARY DESTINATION "${CMAKE_INSTALL_LIBDIR}"
|
|
||||||
PUBLIC_HEADER
|
|
||||||
COMPONENT Runtime
|
|
||||||
)
|
|
||||||
|
|
||||||
export(TARGETS ${LIBFM_QT_LIBRARY_NAME}
|
|
||||||
FILE "${CMAKE_BINARY_DIR}/${LIBFM_QT_LIBRARY_NAME}-targets.cmake"
|
|
||||||
EXPORT_LINK_INTERFACE_LIBRARIES
|
|
||||||
)
|
|
||||||
|
|
||||||
# install a pkgconfig file for libfm-qt
|
|
||||||
set(REQUIRED_QT "Qt5Widgets >= ${REQUIRED_QT_VERSION} Qt5X11Extras >= ${REQUIRED_QT_VERSION}")
|
|
||||||
configure_file(libfm-qt.pc.in lib${LIBFM_QT_LIBRARY_NAME}.pc @ONLY)
|
|
||||||
# FreeBSD loves to install files to different locations
|
|
||||||
# http://www.freebsd.org/doc/handbook/dirstructure.html
|
|
||||||
if(${CMAKE_SYSTEM_NAME} STREQUAL "FreeBSD")
|
|
||||||
install(FILES
|
|
||||||
"${CMAKE_CURRENT_BINARY_DIR}/lib${LIBFM_QT_LIBRARY_NAME}.pc"
|
|
||||||
DESTINATION libdata/pkgconfig
|
|
||||||
COMPONENT Devel
|
|
||||||
)
|
|
||||||
else()
|
|
||||||
install(FILES
|
|
||||||
"${CMAKE_CURRENT_BINARY_DIR}/lib${LIBFM_QT_LIBRARY_NAME}.pc"
|
|
||||||
DESTINATION "${CMAKE_INSTALL_LIBDIR}/pkgconfig"
|
|
||||||
COMPONENT Devel
|
|
||||||
)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
install(FILES
|
|
||||||
${QM_FILES}
|
|
||||||
DESTINATION "${CMAKE_INSTALL_DATADIR}/libfm-qt/translations"
|
|
||||||
COMPONENT Runtime
|
|
||||||
)
|
|
||||||
|
|
||||||
# prevent the generated files from being deleted during make cleaner
|
|
||||||
set_directory_properties(PROPERTIES CLEAN_NO_CUSTOM true)
|
|
||||||
@ -1,183 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<ui version="4.0">
|
|
||||||
<class>AppChooserDialog</class>
|
|
||||||
<widget class="QDialog" name="AppChooserDialog">
|
|
||||||
<property name="geometry">
|
|
||||||
<rect>
|
|
||||||
<x>0</x>
|
|
||||||
<y>0</y>
|
|
||||||
<width>432</width>
|
|
||||||
<height>387</height>
|
|
||||||
</rect>
|
|
||||||
</property>
|
|
||||||
<property name="windowTitle">
|
|
||||||
<string>Choose an Application</string>
|
|
||||||
</property>
|
|
||||||
<layout class="QFormLayout" name="formLayout">
|
|
||||||
<property name="fieldGrowthPolicy">
|
|
||||||
<enum>QFormLayout::AllNonFixedFieldsGrow</enum>
|
|
||||||
</property>
|
|
||||||
<item row="0" column="1">
|
|
||||||
<widget class="QLabel" name="fileTypeHeader"/>
|
|
||||||
</item>
|
|
||||||
<item row="1" column="0" colspan="2">
|
|
||||||
<widget class="QTabWidget" name="tabWidget">
|
|
||||||
<property name="sizePolicy">
|
|
||||||
<sizepolicy hsizetype="Expanding" vsizetype="Expanding">
|
|
||||||
<horstretch>0</horstretch>
|
|
||||||
<verstretch>1</verstretch>
|
|
||||||
</sizepolicy>
|
|
||||||
</property>
|
|
||||||
<property name="currentIndex">
|
|
||||||
<number>0</number>
|
|
||||||
</property>
|
|
||||||
<widget class="QWidget" name="tab">
|
|
||||||
<attribute name="title">
|
|
||||||
<string>Installed Applications</string>
|
|
||||||
</attribute>
|
|
||||||
<layout class="QVBoxLayout" name="verticalLayout">
|
|
||||||
<item>
|
|
||||||
<widget class="Fm::AppMenuView" name="appMenuView"/>
|
|
||||||
</item>
|
|
||||||
</layout>
|
|
||||||
</widget>
|
|
||||||
<widget class="QWidget" name="tab_2">
|
|
||||||
<attribute name="title">
|
|
||||||
<string>Custom Command</string>
|
|
||||||
</attribute>
|
|
||||||
<layout class="QFormLayout" name="formLayout_2">
|
|
||||||
<item row="0" column="0" colspan="2">
|
|
||||||
<widget class="QLabel" name="label_3">
|
|
||||||
<property name="text">
|
|
||||||
<string>Command line to execute:</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="1" column="0" colspan="2">
|
|
||||||
<widget class="QLineEdit" name="cmdLine"/>
|
|
||||||
</item>
|
|
||||||
<item row="3" column="0">
|
|
||||||
<widget class="QLabel" name="label_4">
|
|
||||||
<property name="text">
|
|
||||||
<string>Application name:</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="3" column="1">
|
|
||||||
<widget class="QLineEdit" name="appName"/>
|
|
||||||
</item>
|
|
||||||
<item row="2" column="0" colspan="2">
|
|
||||||
<widget class="QLabel" name="label_5">
|
|
||||||
<property name="text">
|
|
||||||
<string><b>These special codes can be used in the command line:</b>
|
|
||||||
<ul>
|
|
||||||
<li><b>%f</b>: Represents a single file name</li>
|
|
||||||
<li><b>%F</b>: Represents multiple file names</li>
|
|
||||||
<li><b>%u</b>: Represents a single URI of the file</li>
|
|
||||||
<li><b>%U</b>: Represents multiple URIs</li>
|
|
||||||
</ul></string>
|
|
||||||
</property>
|
|
||||||
<property name="textFormat">
|
|
||||||
<enum>Qt::RichText</enum>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="5" column="0" colspan="2">
|
|
||||||
<widget class="QCheckBox" name="keepTermOpen">
|
|
||||||
<property name="enabled">
|
|
||||||
<bool>false</bool>
|
|
||||||
</property>
|
|
||||||
<property name="text">
|
|
||||||
<string>Keep terminal window open after command execution</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="4" column="0" colspan="2">
|
|
||||||
<widget class="QCheckBox" name="useTerminal">
|
|
||||||
<property name="text">
|
|
||||||
<string>Execute in terminal emulator</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
</layout>
|
|
||||||
</widget>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="2" column="0" colspan="2">
|
|
||||||
<widget class="QCheckBox" name="setDefault">
|
|
||||||
<property name="text">
|
|
||||||
<string>Set selected application as default action of this file type</string>
|
|
||||||
</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>
|
|
||||||
<customwidgets>
|
|
||||||
<customwidget>
|
|
||||||
<class>Fm::AppMenuView</class>
|
|
||||||
<extends>QTreeView</extends>
|
|
||||||
<header>appmenuview.h</header>
|
|
||||||
</customwidget>
|
|
||||||
</customwidgets>
|
|
||||||
<resources/>
|
|
||||||
<connections>
|
|
||||||
<connection>
|
|
||||||
<sender>buttonBox</sender>
|
|
||||||
<signal>accepted()</signal>
|
|
||||||
<receiver>AppChooserDialog</receiver>
|
|
||||||
<slot>accept()</slot>
|
|
||||||
<hints>
|
|
||||||
<hint type="sourcelabel">
|
|
||||||
<x>227</x>
|
|
||||||
<y>359</y>
|
|
||||||
</hint>
|
|
||||||
<hint type="destinationlabel">
|
|
||||||
<x>157</x>
|
|
||||||
<y>274</y>
|
|
||||||
</hint>
|
|
||||||
</hints>
|
|
||||||
</connection>
|
|
||||||
<connection>
|
|
||||||
<sender>buttonBox</sender>
|
|
||||||
<signal>rejected()</signal>
|
|
||||||
<receiver>AppChooserDialog</receiver>
|
|
||||||
<slot>reject()</slot>
|
|
||||||
<hints>
|
|
||||||
<hint type="sourcelabel">
|
|
||||||
<x>295</x>
|
|
||||||
<y>365</y>
|
|
||||||
</hint>
|
|
||||||
<hint type="destinationlabel">
|
|
||||||
<x>286</x>
|
|
||||||
<y>274</y>
|
|
||||||
</hint>
|
|
||||||
</hints>
|
|
||||||
</connection>
|
|
||||||
<connection>
|
|
||||||
<sender>useTerminal</sender>
|
|
||||||
<signal>toggled(bool)</signal>
|
|
||||||
<receiver>keepTermOpen</receiver>
|
|
||||||
<slot>setEnabled(bool)</slot>
|
|
||||||
<hints>
|
|
||||||
<hint type="sourcelabel">
|
|
||||||
<x>72</x>
|
|
||||||
<y>260</y>
|
|
||||||
</hint>
|
|
||||||
<hint type="destinationlabel">
|
|
||||||
<x>79</x>
|
|
||||||
<y>282</y>
|
|
||||||
</hint>
|
|
||||||
</hints>
|
|
||||||
</connection>
|
|
||||||
</connections>
|
|
||||||
</ui>
|
|
||||||
@ -1,153 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (C) 2014 - 2015 Hong Jen Yee (PCMan) <pcman.tw@gmail.com>
|
|
||||||
*
|
|
||||||
* 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 "appchoosercombobox.h"
|
|
||||||
#include "icontheme.h"
|
|
||||||
#include "appchooserdialog.h"
|
|
||||||
#include "utilities.h"
|
|
||||||
|
|
||||||
namespace Fm {
|
|
||||||
|
|
||||||
AppChooserComboBox::AppChooserComboBox(QWidget* parent):
|
|
||||||
QComboBox(parent),
|
|
||||||
defaultApp_(NULL),
|
|
||||||
appInfos_(NULL),
|
|
||||||
defaultAppIndex_(-1),
|
|
||||||
prevIndex_(0),
|
|
||||||
mimeType_(NULL),
|
|
||||||
blockOnCurrentIndexChanged_(false) {
|
|
||||||
|
|
||||||
// the new Qt5 signal/slot syntax cannot handle overloaded methods by default
|
|
||||||
// hence a type-casting is needed here. really ugly!
|
|
||||||
// reference: http://qt-project.org/forums/viewthread/21513
|
|
||||||
connect((QComboBox*)this, static_cast<void (QComboBox::*)(int)>(&QComboBox::currentIndexChanged), this, &AppChooserComboBox::onCurrentIndexChanged);
|
|
||||||
}
|
|
||||||
|
|
||||||
AppChooserComboBox::~AppChooserComboBox() {
|
|
||||||
if(mimeType_)
|
|
||||||
fm_mime_type_unref(mimeType_);
|
|
||||||
if(defaultApp_)
|
|
||||||
g_object_unref(defaultApp_);
|
|
||||||
// delete GAppInfo objects stored for Combobox
|
|
||||||
if(appInfos_) {
|
|
||||||
g_list_foreach(appInfos_, (GFunc)g_object_unref, NULL);
|
|
||||||
g_list_free(appInfos_);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void AppChooserComboBox::setMimeType(FmMimeType* mimeType) {
|
|
||||||
clear();
|
|
||||||
if(mimeType_)
|
|
||||||
fm_mime_type_unref(mimeType_);
|
|
||||||
|
|
||||||
mimeType_ = fm_mime_type_ref(mimeType);
|
|
||||||
if(mimeType_) {
|
|
||||||
const char* typeName = fm_mime_type_get_type(mimeType_);
|
|
||||||
defaultApp_ = g_app_info_get_default_for_type(typeName, FALSE);
|
|
||||||
appInfos_ = g_app_info_get_all_for_type(typeName);
|
|
||||||
int i = 0;
|
|
||||||
for(GList* l = appInfos_; l; l = l->next, ++i) {
|
|
||||||
GAppInfo* app = G_APP_INFO(l->data);
|
|
||||||
GIcon* gicon = g_app_info_get_icon(app);
|
|
||||||
QString name = QString::fromUtf8(g_app_info_get_name(app));
|
|
||||||
// QVariant data = qVariantFromValue<void*>(app);
|
|
||||||
// addItem(IconTheme::icon(gicon), name, data);
|
|
||||||
addItem(IconTheme::icon(gicon), name);
|
|
||||||
if(g_app_info_equal(app, defaultApp_))
|
|
||||||
defaultAppIndex_ = i;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// add "Other applications" item
|
|
||||||
insertSeparator(count());
|
|
||||||
addItem(tr("Customize"));
|
|
||||||
if(defaultAppIndex_ != -1)
|
|
||||||
setCurrentIndex(defaultAppIndex_);
|
|
||||||
}
|
|
||||||
|
|
||||||
// returns the currently selected app.
|
|
||||||
GAppInfo* AppChooserComboBox::selectedApp() {
|
|
||||||
return G_APP_INFO(g_list_nth_data(appInfos_, currentIndex()));
|
|
||||||
}
|
|
||||||
|
|
||||||
bool AppChooserComboBox::isChanged() {
|
|
||||||
return (defaultAppIndex_ != currentIndex());
|
|
||||||
}
|
|
||||||
|
|
||||||
void AppChooserComboBox::onCurrentIndexChanged(int index) {
|
|
||||||
if(index == -1 || index == prevIndex_ || blockOnCurrentIndexChanged_)
|
|
||||||
return;
|
|
||||||
|
|
||||||
// the last item is "Customize"
|
|
||||||
if(index == (count() - 1)) {
|
|
||||||
/* TODO: let the user choose an app or add custom actions here. */
|
|
||||||
QWidget* toplevel = topLevelWidget();
|
|
||||||
AppChooserDialog dlg(mimeType_, toplevel);
|
|
||||||
dlg.setWindowModality(Qt::WindowModal);
|
|
||||||
dlg.setCanSetDefault(false);
|
|
||||||
if(dlg.exec() == QDialog::Accepted) {
|
|
||||||
GAppInfo* app = dlg.selectedApp();
|
|
||||||
if(app) {
|
|
||||||
/* see if it's already in the list to prevent duplication */
|
|
||||||
GList* found = NULL;
|
|
||||||
for(found = appInfos_; found; found = found->next) {
|
|
||||||
if(g_app_info_equal(app, G_APP_INFO(found->data)))
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
// inserting new items or change current index will recursively trigger onCurrentIndexChanged.
|
|
||||||
// we need to block our handler to prevent recursive calls.
|
|
||||||
blockOnCurrentIndexChanged_ = true;
|
|
||||||
/* if it's already in the list, select it */
|
|
||||||
if(found) {
|
|
||||||
setCurrentIndex(g_list_position(appInfos_, found));
|
|
||||||
g_object_unref(app);
|
|
||||||
}
|
|
||||||
else { /* if it's not found, add it to the list */
|
|
||||||
appInfos_ = g_list_prepend(appInfos_, app);
|
|
||||||
GIcon* gicon = g_app_info_get_icon(app);
|
|
||||||
QString name = QString::fromUtf8(g_app_info_get_name(app));
|
|
||||||
insertItem(0, IconTheme::icon(gicon), name);
|
|
||||||
setCurrentIndex(0);
|
|
||||||
}
|
|
||||||
blockOnCurrentIndexChanged_ = false;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// block our handler to prevent recursive calls.
|
|
||||||
blockOnCurrentIndexChanged_ = true;
|
|
||||||
// restore to previously selected item
|
|
||||||
setCurrentIndex(prevIndex_);
|
|
||||||
blockOnCurrentIndexChanged_ = false;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
prevIndex_ = index;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
#if 0
|
|
||||||
/* get a list of custom apps added with app-chooser.
|
|
||||||
* the returned GList is owned by the combo box and shouldn't be freed. */
|
|
||||||
const GList* AppChooserComboBox::customApps() {
|
|
||||||
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
} // namespace Fm
|
|
||||||
@ -1,60 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (C) 2014 - 2015 Hong Jen Yee (PCMan) <pcman.tw@gmail.com>
|
|
||||||
*
|
|
||||||
* 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 FM_APPCHOOSERCOMBOBOX_H
|
|
||||||
#define FM_APPCHOOSERCOMBOBOX_H
|
|
||||||
|
|
||||||
#include "libfmqtglobals.h"
|
|
||||||
#include <QComboBox>
|
|
||||||
#include <libfm/fm.h>
|
|
||||||
|
|
||||||
namespace Fm {
|
|
||||||
|
|
||||||
class LIBFM_QT_API AppChooserComboBox : public QComboBox {
|
|
||||||
Q_OBJECT
|
|
||||||
public:
|
|
||||||
~AppChooserComboBox();
|
|
||||||
AppChooserComboBox(QWidget* parent);
|
|
||||||
|
|
||||||
void setMimeType(FmMimeType* mimeType);
|
|
||||||
|
|
||||||
FmMimeType* mimeType() {
|
|
||||||
return mimeType_;
|
|
||||||
}
|
|
||||||
|
|
||||||
GAppInfo* selectedApp();
|
|
||||||
// const GList* customApps();
|
|
||||||
|
|
||||||
bool isChanged();
|
|
||||||
|
|
||||||
private Q_SLOTS:
|
|
||||||
void onCurrentIndexChanged(int index);
|
|
||||||
|
|
||||||
private:
|
|
||||||
FmMimeType* mimeType_;
|
|
||||||
GList* appInfos_; // applications used to open the file type
|
|
||||||
GAppInfo* defaultApp_; // default application used to open the file type
|
|
||||||
int defaultAppIndex_;
|
|
||||||
int prevIndex_;
|
|
||||||
bool blockOnCurrentIndexChanged_;
|
|
||||||
};
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif // FM_APPCHOOSERCOMBOBOX_H
|
|
||||||
@ -1,286 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2010-2014 Hong Jen Yee (PCMan) <pcman.tw@gmail.com>
|
|
||||||
* Copyright 2012-2013 Andriy Grytsenko (LStranger) <andrej@rep.kiev.ua>
|
|
||||||
*
|
|
||||||
* 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 "appchooserdialog.h"
|
|
||||||
#include "ui_app-chooser-dialog.h"
|
|
||||||
#include <QPushButton>
|
|
||||||
#include <gio/gdesktopappinfo.h>
|
|
||||||
|
|
||||||
namespace Fm {
|
|
||||||
|
|
||||||
AppChooserDialog::AppChooserDialog(FmMimeType* mimeType, QWidget* parent, Qt::WindowFlags f):
|
|
||||||
QDialog(parent, f),
|
|
||||||
mimeType_(NULL),
|
|
||||||
selectedApp_(NULL),
|
|
||||||
canSetDefault_(true),
|
|
||||||
ui(new Ui::AppChooserDialog()) {
|
|
||||||
ui->setupUi(this);
|
|
||||||
|
|
||||||
connect(ui->appMenuView, &AppMenuView::selectionChanged, this, &AppChooserDialog::onSelectionChanged);
|
|
||||||
connect(ui->tabWidget, &QTabWidget::currentChanged, this, &AppChooserDialog::onTabChanged);
|
|
||||||
|
|
||||||
if(!ui->appMenuView->isAppSelected())
|
|
||||||
ui->buttonBox->button(QDialogButtonBox::Ok)->setEnabled(false); // disable OK button
|
|
||||||
|
|
||||||
if(mimeType)
|
|
||||||
setMimeType(mimeType);
|
|
||||||
}
|
|
||||||
|
|
||||||
AppChooserDialog::~AppChooserDialog() {
|
|
||||||
delete ui;
|
|
||||||
if(mimeType_)
|
|
||||||
fm_mime_type_unref(mimeType_);
|
|
||||||
if(selectedApp_)
|
|
||||||
g_object_unref(selectedApp_);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool AppChooserDialog::isSetDefault() {
|
|
||||||
return ui->setDefault->isChecked();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static void on_temp_appinfo_destroy(gpointer data, GObject* objptr) {
|
|
||||||
char* filename = (char*)data;
|
|
||||||
if(g_unlink(filename) < 0)
|
|
||||||
g_critical("failed to remove %s", filename);
|
|
||||||
/* else
|
|
||||||
qDebug("temp file %s removed", filename); */
|
|
||||||
g_free(filename);
|
|
||||||
}
|
|
||||||
|
|
||||||
static GAppInfo* app_info_create_from_commandline(const char* commandline,
|
|
||||||
const char* application_name,
|
|
||||||
const char* bin_name,
|
|
||||||
const char* mime_type,
|
|
||||||
gboolean terminal, gboolean keep) {
|
|
||||||
GAppInfo* app = NULL;
|
|
||||||
char* dirname = g_build_filename(g_get_user_data_dir(), "applications", NULL);
|
|
||||||
const char* app_basename = strrchr(bin_name, '/');
|
|
||||||
|
|
||||||
if(app_basename)
|
|
||||||
app_basename++;
|
|
||||||
else
|
|
||||||
app_basename = bin_name;
|
|
||||||
if(g_mkdir_with_parents(dirname, 0700) == 0) {
|
|
||||||
char* filename = g_strdup_printf("%s/userapp-%s-XXXXXX.desktop", dirname, app_basename);
|
|
||||||
int fd = g_mkstemp(filename);
|
|
||||||
if(fd != -1) {
|
|
||||||
GString* content = g_string_sized_new(256);
|
|
||||||
g_string_printf(content,
|
|
||||||
"[" G_KEY_FILE_DESKTOP_GROUP "]\n"
|
|
||||||
G_KEY_FILE_DESKTOP_KEY_TYPE "=" G_KEY_FILE_DESKTOP_TYPE_APPLICATION "\n"
|
|
||||||
G_KEY_FILE_DESKTOP_KEY_NAME "=%s\n"
|
|
||||||
G_KEY_FILE_DESKTOP_KEY_EXEC "=%s\n"
|
|
||||||
G_KEY_FILE_DESKTOP_KEY_CATEGORIES "=Other;\n"
|
|
||||||
G_KEY_FILE_DESKTOP_KEY_NO_DISPLAY "=true\n",
|
|
||||||
application_name,
|
|
||||||
commandline
|
|
||||||
);
|
|
||||||
if(mime_type)
|
|
||||||
g_string_append_printf(content,
|
|
||||||
G_KEY_FILE_DESKTOP_KEY_MIME_TYPE "=%s\n",
|
|
||||||
mime_type);
|
|
||||||
g_string_append_printf(content,
|
|
||||||
G_KEY_FILE_DESKTOP_KEY_TERMINAL "=%s\n",
|
|
||||||
terminal ? "true" : "false");
|
|
||||||
if(terminal)
|
|
||||||
g_string_append_printf(content, "X-KeepTerminal=%s\n",
|
|
||||||
keep ? "true" : "false");
|
|
||||||
close(fd); /* g_file_set_contents() may fail creating duplicate */
|
|
||||||
if(g_file_set_contents(filename, content->str, content->len, NULL)) {
|
|
||||||
char* fbname = g_path_get_basename(filename);
|
|
||||||
app = G_APP_INFO(g_desktop_app_info_new(fbname));
|
|
||||||
g_free(fbname);
|
|
||||||
/* if there is mime_type set then created application will be
|
|
||||||
saved for the mime type (see fm_choose_app_for_mime_type()
|
|
||||||
below) but if not then we should remove this temp. file */
|
|
||||||
if(!mime_type || !application_name[0])
|
|
||||||
/* save the name so this file will be removed later */
|
|
||||||
g_object_weak_ref(G_OBJECT(app), on_temp_appinfo_destroy,
|
|
||||||
g_strdup(filename));
|
|
||||||
}
|
|
||||||
else
|
|
||||||
g_unlink(filename);
|
|
||||||
g_string_free(content, TRUE);
|
|
||||||
}
|
|
||||||
g_free(filename);
|
|
||||||
}
|
|
||||||
g_free(dirname);
|
|
||||||
return app;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline static char* get_binary(const char* cmdline, gboolean* arg_found) {
|
|
||||||
/* see if command line contains %f, %F, %u, or %U. */
|
|
||||||
const char* p = strstr(cmdline, " %");
|
|
||||||
if(p) {
|
|
||||||
if(!strchr("fFuU", *(p + 2)))
|
|
||||||
p = NULL;
|
|
||||||
}
|
|
||||||
if(arg_found)
|
|
||||||
*arg_found = (p != NULL);
|
|
||||||
if(p)
|
|
||||||
return g_strndup(cmdline, p - cmdline);
|
|
||||||
else
|
|
||||||
return g_strdup(cmdline);
|
|
||||||
}
|
|
||||||
|
|
||||||
GAppInfo* AppChooserDialog::customCommandToApp() {
|
|
||||||
GAppInfo* app = NULL;
|
|
||||||
QByteArray cmdline = ui->cmdLine->text().toLocal8Bit();
|
|
||||||
QByteArray app_name = ui->appName->text().toUtf8();
|
|
||||||
if(!cmdline.isEmpty()) {
|
|
||||||
gboolean arg_found = FALSE;
|
|
||||||
char* bin1 = get_binary(cmdline.constData(), &arg_found);
|
|
||||||
qDebug("bin1 = %s", bin1);
|
|
||||||
/* see if command line contains %f, %F, %u, or %U. */
|
|
||||||
if(!arg_found) { /* append %f if no %f, %F, %u, or %U was found. */
|
|
||||||
cmdline += " %f";
|
|
||||||
}
|
|
||||||
|
|
||||||
/* FIXME: is there any better way to do this? */
|
|
||||||
/* We need to ensure that no duplicated items are added */
|
|
||||||
if(mimeType_) {
|
|
||||||
MenuCache* menu_cache;
|
|
||||||
/* see if the command is already in the list of known apps for this mime-type */
|
|
||||||
GList* apps = g_app_info_get_all_for_type(fm_mime_type_get_type(mimeType_));
|
|
||||||
GList* l;
|
|
||||||
for(l = apps; l; l = l->next) {
|
|
||||||
GAppInfo* app2 = G_APP_INFO(l->data);
|
|
||||||
const char* cmd = g_app_info_get_commandline(app2);
|
|
||||||
char* bin2 = get_binary(cmd, NULL);
|
|
||||||
if(g_strcmp0(bin1, bin2) == 0) {
|
|
||||||
app = G_APP_INFO(g_object_ref(app2));
|
|
||||||
qDebug("found in app list");
|
|
||||||
g_free(bin2);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
g_free(bin2);
|
|
||||||
}
|
|
||||||
g_list_foreach(apps, (GFunc)g_object_unref, NULL);
|
|
||||||
g_list_free(apps);
|
|
||||||
if(app)
|
|
||||||
goto _out;
|
|
||||||
|
|
||||||
/* see if this command can be found in menu cache */
|
|
||||||
menu_cache = menu_cache_lookup("applications.menu");
|
|
||||||
if(menu_cache) {
|
|
||||||
MenuCacheDir* root_dir = menu_cache_dup_root_dir(menu_cache);
|
|
||||||
if(root_dir) {
|
|
||||||
GSList* all_apps = menu_cache_list_all_apps(menu_cache);
|
|
||||||
GSList* l;
|
|
||||||
for(l = all_apps; l; l = l->next) {
|
|
||||||
MenuCacheApp* ma = MENU_CACHE_APP(l->data);
|
|
||||||
const char* exec = menu_cache_app_get_exec(ma);
|
|
||||||
char* bin2;
|
|
||||||
if(exec == NULL) {
|
|
||||||
g_warning("application %s has no Exec statement", menu_cache_item_get_id(MENU_CACHE_ITEM(ma)));
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
bin2 = get_binary(exec, NULL);
|
|
||||||
if(g_strcmp0(bin1, bin2) == 0) {
|
|
||||||
app = G_APP_INFO(g_desktop_app_info_new(menu_cache_item_get_id(MENU_CACHE_ITEM(ma))));
|
|
||||||
qDebug("found in menu cache");
|
|
||||||
menu_cache_item_unref(MENU_CACHE_ITEM(ma));
|
|
||||||
g_free(bin2);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
menu_cache_item_unref(MENU_CACHE_ITEM(ma));
|
|
||||||
g_free(bin2);
|
|
||||||
}
|
|
||||||
g_slist_free(all_apps);
|
|
||||||
menu_cache_item_unref(MENU_CACHE_ITEM(root_dir));
|
|
||||||
}
|
|
||||||
menu_cache_unref(menu_cache);
|
|
||||||
}
|
|
||||||
if(app)
|
|
||||||
goto _out;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* FIXME: g_app_info_create_from_commandline force the use of %f or %u, so this is not we need */
|
|
||||||
app = app_info_create_from_commandline(cmdline.constData(), app_name.constData(), bin1,
|
|
||||||
mimeType_ ? fm_mime_type_get_type(mimeType_) : NULL,
|
|
||||||
ui->useTerminal->isChecked(), ui->keepTermOpen->isChecked());
|
|
||||||
_out:
|
|
||||||
g_free(bin1);
|
|
||||||
}
|
|
||||||
return app;
|
|
||||||
}
|
|
||||||
|
|
||||||
void AppChooserDialog::accept() {
|
|
||||||
QDialog::accept();
|
|
||||||
|
|
||||||
if(ui->tabWidget->currentIndex() == 0) {
|
|
||||||
selectedApp_ = ui->appMenuView->selectedApp();
|
|
||||||
}
|
|
||||||
else { // custom command line
|
|
||||||
selectedApp_ = customCommandToApp();
|
|
||||||
}
|
|
||||||
|
|
||||||
if(selectedApp_) {
|
|
||||||
if(mimeType_ && fm_mime_type_get_type(mimeType_) && g_app_info_get_name(selectedApp_)[0]) {
|
|
||||||
/* add this app to the mime-type */
|
|
||||||
#if GLIB_CHECK_VERSION(2, 27, 6)
|
|
||||||
g_app_info_set_as_last_used_for_type(selectedApp_, fm_mime_type_get_type(mimeType_), NULL);
|
|
||||||
#else
|
|
||||||
g_app_info_add_supports_type(selectedApp_, fm_mime_type_get_type(mimeType_), NULL);
|
|
||||||
#endif
|
|
||||||
/* if need to set default */
|
|
||||||
if(ui->setDefault->isChecked())
|
|
||||||
g_app_info_set_as_default_for_type(selectedApp_, fm_mime_type_get_type(mimeType_), NULL);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void AppChooserDialog::onSelectionChanged() {
|
|
||||||
bool isAppSelected = ui->appMenuView->isAppSelected();
|
|
||||||
ui->buttonBox->button(QDialogButtonBox::Ok)->setEnabled(isAppSelected);
|
|
||||||
}
|
|
||||||
|
|
||||||
void AppChooserDialog::setMimeType(FmMimeType* mimeType) {
|
|
||||||
if(mimeType_)
|
|
||||||
fm_mime_type_unref(mimeType_);
|
|
||||||
|
|
||||||
mimeType_ = mimeType ? fm_mime_type_ref(mimeType) : NULL;
|
|
||||||
if(mimeType_) {
|
|
||||||
QString text = tr("Select an application to open \"%1\" files")
|
|
||||||
.arg(QString::fromUtf8(fm_mime_type_get_desc(mimeType_)));
|
|
||||||
ui->fileTypeHeader->setText(text);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
ui->fileTypeHeader->hide();
|
|
||||||
ui->setDefault->hide();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void AppChooserDialog::setCanSetDefault(bool value) {
|
|
||||||
canSetDefault_ = value;
|
|
||||||
ui->setDefault->setVisible(value);
|
|
||||||
}
|
|
||||||
|
|
||||||
void AppChooserDialog::onTabChanged(int index) {
|
|
||||||
if(index == 0) { // app menu view
|
|
||||||
onSelectionChanged();
|
|
||||||
}
|
|
||||||
else if(index == 1) { // custom command
|
|
||||||
ui->buttonBox->button(QDialogButtonBox::Ok)->setEnabled(true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace Fm
|
|
||||||
@ -1,74 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2010-2014 Hong Jen Yee (PCMan) <pcman.tw@gmail.com>
|
|
||||||
* Copyright 2012-2013 Andriy Grytsenko (LStranger) <andrej@rep.kiev.ua>
|
|
||||||
*
|
|
||||||
* 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 FM_APPCHOOSERDIALOG_H
|
|
||||||
#define FM_APPCHOOSERDIALOG_H
|
|
||||||
|
|
||||||
#include <QDialog>
|
|
||||||
#include "libfmqtglobals.h"
|
|
||||||
#include <libfm/fm.h>
|
|
||||||
|
|
||||||
namespace Ui {
|
|
||||||
class AppChooserDialog;
|
|
||||||
}
|
|
||||||
|
|
||||||
namespace Fm {
|
|
||||||
|
|
||||||
class LIBFM_QT_API AppChooserDialog : public QDialog {
|
|
||||||
Q_OBJECT
|
|
||||||
public:
|
|
||||||
explicit AppChooserDialog(FmMimeType* mimeType, QWidget* parent = NULL, Qt::WindowFlags f = 0);
|
|
||||||
~AppChooserDialog();
|
|
||||||
|
|
||||||
virtual void accept();
|
|
||||||
|
|
||||||
void setMimeType(FmMimeType* mimeType);
|
|
||||||
FmMimeType* mimeType() {
|
|
||||||
return mimeType_;
|
|
||||||
}
|
|
||||||
|
|
||||||
void setCanSetDefault(bool value);
|
|
||||||
bool canSetDefault() {
|
|
||||||
return canSetDefault_;
|
|
||||||
}
|
|
||||||
|
|
||||||
GAppInfo* selectedApp() {
|
|
||||||
return G_APP_INFO(g_object_ref(selectedApp_));
|
|
||||||
}
|
|
||||||
|
|
||||||
bool isSetDefault();
|
|
||||||
|
|
||||||
private:
|
|
||||||
GAppInfo* customCommandToApp();
|
|
||||||
|
|
||||||
private Q_SLOTS:
|
|
||||||
void onSelectionChanged();
|
|
||||||
void onTabChanged(int index);
|
|
||||||
|
|
||||||
private:
|
|
||||||
Ui::AppChooserDialog* ui;
|
|
||||||
FmMimeType* mimeType_;
|
|
||||||
bool canSetDefault_;
|
|
||||||
GAppInfo* selectedApp_;
|
|
||||||
};
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif // FM_APPCHOOSERDIALOG_H
|
|
||||||
@ -1,61 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (C) 2012 - 2015 Hong Jen Yee (PCMan) <pcman.tw@gmail.com>
|
|
||||||
*
|
|
||||||
* 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 "applaunchcontext.h"
|
|
||||||
#include <QX11Info>
|
|
||||||
#include <X11/Xlib.h>
|
|
||||||
|
|
||||||
typedef struct _FmAppLaunchContext {
|
|
||||||
GAppLaunchContext parent;
|
|
||||||
}FmAppLaunchContext;
|
|
||||||
|
|
||||||
G_DEFINE_TYPE(FmAppLaunchContext, fm_app_launch_context, G_TYPE_APP_LAUNCH_CONTEXT)
|
|
||||||
|
|
||||||
static char* fm_app_launch_context_get_display(GAppLaunchContext *context, GAppInfo *info, GList *files) {
|
|
||||||
Display* dpy = QX11Info::display();
|
|
||||||
if(dpy) {
|
|
||||||
char* xstr = DisplayString(dpy);
|
|
||||||
return g_strdup(xstr);
|
|
||||||
}
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
static char* fm_app_launch_context_get_startup_notify_id(GAppLaunchContext *context, GAppInfo *info, GList *files) {
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void fm_app_launch_context_class_init(FmAppLaunchContextClass* klass) {
|
|
||||||
GAppLaunchContextClass* app_launch_class = G_APP_LAUNCH_CONTEXT_CLASS(klass);
|
|
||||||
app_launch_class->get_display = fm_app_launch_context_get_display;
|
|
||||||
app_launch_class->get_startup_notify_id = fm_app_launch_context_get_startup_notify_id;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void fm_app_launch_context_init(FmAppLaunchContext* context) {
|
|
||||||
}
|
|
||||||
|
|
||||||
FmAppLaunchContext* fm_app_launch_context_new_for_widget(QWidget* widget) {
|
|
||||||
FmAppLaunchContext* context = (FmAppLaunchContext*)g_object_new(FM_TYPE_APP_LAUNCH_CONTEXT, NULL);
|
|
||||||
return context;
|
|
||||||
}
|
|
||||||
|
|
||||||
FmAppLaunchContext* fm_app_launch_context_new() {
|
|
||||||
FmAppLaunchContext* context = (FmAppLaunchContext*)g_object_new(FM_TYPE_APP_LAUNCH_CONTEXT, NULL);
|
|
||||||
return context;
|
|
||||||
}
|
|
||||||
@ -1,50 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (C) 2012 - 2015 Hong Jen Yee (PCMan) <pcman.tw@gmail.com>
|
|
||||||
*
|
|
||||||
* 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 FM_APP_LAUNCHCONTEXT_H
|
|
||||||
#define FM_APP_LAUNCHCONTEXT_H
|
|
||||||
|
|
||||||
#include "libfmqtglobals.h"
|
|
||||||
#include <gio/gio.h>
|
|
||||||
#include <QWidget>
|
|
||||||
|
|
||||||
#define FM_TYPE_APP_LAUNCH_CONTEXT (fm_app_launch_context_get_type())
|
|
||||||
#define FM_APP_LAUNCH_CONTEXT(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj),\
|
|
||||||
FM_TYPE_APP_LAUNCH_CONTEXT, FmAppLaunchContext))
|
|
||||||
#define FM_APP_LAUNCH_CONTEXT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass),\
|
|
||||||
FM_TYPE_APP_LAUNCH_CONTEXT, FmAppLaunchContextClass))
|
|
||||||
#define FM_IS_APP_LAUNCH_CONTEXT(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj),\
|
|
||||||
FM_TYPE_APP_LAUNCH_CONTEXT))
|
|
||||||
#define FM_IS_APP_LAUNCH_CONTEXT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass),\
|
|
||||||
FM_TYPE_APP_LAUNCH_CONTEXT))
|
|
||||||
#define FM_APP_LAUNCH_CONTEXT_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj),\
|
|
||||||
FM_TYPE_APP_LAUNCH_CONTEXT, FmAppLaunchContextClass))
|
|
||||||
|
|
||||||
typedef struct _FmAppLaunchContext FmAppLaunchContext;
|
|
||||||
|
|
||||||
typedef struct _FmAppLaunchContextClass {
|
|
||||||
GAppLaunchContextClass parent;
|
|
||||||
}FmAppLaunchContextClass;
|
|
||||||
|
|
||||||
FmAppLaunchContext* fm_app_launch_context_new();
|
|
||||||
FmAppLaunchContext* fm_app_launch_context_new_for_widget(QWidget* widget);
|
|
||||||
GType fm_app_launch_context_get_type();
|
|
||||||
|
|
||||||
#endif // FM_APPLAUNCHCONTEXT_H
|
|
||||||
@ -1,158 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (C) 2014 - 2015 Hong Jen Yee (PCMan) <pcman.tw@gmail.com>
|
|
||||||
*
|
|
||||||
* 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 "appmenuview.h"
|
|
||||||
#include <QStandardItemModel>
|
|
||||||
#include "icontheme.h"
|
|
||||||
#include "appmenuview_p.h"
|
|
||||||
#include <gio/gdesktopappinfo.h>
|
|
||||||
|
|
||||||
namespace Fm {
|
|
||||||
|
|
||||||
AppMenuView::AppMenuView(QWidget* parent):
|
|
||||||
model_(new QStandardItemModel()),
|
|
||||||
menu_cache(NULL),
|
|
||||||
menu_cache_reload_notify(NULL),
|
|
||||||
QTreeView(parent) {
|
|
||||||
|
|
||||||
setHeaderHidden(true);
|
|
||||||
setSelectionMode(SingleSelection);
|
|
||||||
|
|
||||||
// initialize model
|
|
||||||
// TODO: share one model among all app menu view widgets
|
|
||||||
// ensure that we're using lxmenu-data (FIXME: should we do this?)
|
|
||||||
QByteArray oldenv = qgetenv("XDG_MENU_PREFIX");
|
|
||||||
qputenv("XDG_MENU_PREFIX", "lxde-");
|
|
||||||
menu_cache = menu_cache_lookup("applications.menu");
|
|
||||||
// if(!oldenv.isEmpty())
|
|
||||||
qputenv("XDG_MENU_PREFIX", oldenv); // restore the original value if needed
|
|
||||||
|
|
||||||
if(menu_cache) {
|
|
||||||
MenuCacheDir* dir = menu_cache_dup_root_dir(menu_cache);
|
|
||||||
menu_cache_reload_notify = menu_cache_add_reload_notify(menu_cache, _onMenuCacheReload, this);
|
|
||||||
if(dir) { /* content of menu is already loaded */
|
|
||||||
addMenuItems(NULL, dir);
|
|
||||||
menu_cache_item_unref(MENU_CACHE_ITEM(dir));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
setModel(model_);
|
|
||||||
connect(selectionModel(), &QItemSelectionModel::selectionChanged, this, &AppMenuView::selectionChanged);
|
|
||||||
selectionModel()->select(model_->index(0, 0), QItemSelectionModel::SelectCurrent);
|
|
||||||
}
|
|
||||||
|
|
||||||
AppMenuView::~AppMenuView() {
|
|
||||||
delete model_;
|
|
||||||
if(menu_cache) {
|
|
||||||
if(menu_cache_reload_notify)
|
|
||||||
menu_cache_remove_reload_notify(menu_cache, menu_cache_reload_notify);
|
|
||||||
menu_cache_unref(menu_cache);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void AppMenuView::addMenuItems(QStandardItem* parentItem, MenuCacheDir* dir) {
|
|
||||||
GSList* l;
|
|
||||||
GSList* list;
|
|
||||||
/* Iterate over all menu items in this directory. */
|
|
||||||
for(l = list = menu_cache_dir_list_children(dir); l != NULL; l = l->next) {
|
|
||||||
/* Get the menu item. */
|
|
||||||
MenuCacheItem* menuItem = MENU_CACHE_ITEM(l->data);
|
|
||||||
switch(menu_cache_item_get_type(menuItem)) {
|
|
||||||
case MENU_CACHE_TYPE_NONE:
|
|
||||||
case MENU_CACHE_TYPE_SEP:
|
|
||||||
break;
|
|
||||||
case MENU_CACHE_TYPE_APP:
|
|
||||||
case MENU_CACHE_TYPE_DIR: {
|
|
||||||
AppMenuViewItem* newItem = new AppMenuViewItem(menuItem);
|
|
||||||
if(parentItem)
|
|
||||||
parentItem->insertRow(parentItem->rowCount(), newItem);
|
|
||||||
else
|
|
||||||
model_->insertRow(model_->rowCount(), newItem);
|
|
||||||
|
|
||||||
if(menu_cache_item_get_type(menuItem) == MENU_CACHE_TYPE_DIR)
|
|
||||||
addMenuItems(newItem, MENU_CACHE_DIR(menuItem));
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
g_slist_free_full(list, (GDestroyNotify)menu_cache_item_unref);
|
|
||||||
}
|
|
||||||
|
|
||||||
void AppMenuView::onMenuCacheReload(MenuCache* mc) {
|
|
||||||
MenuCacheDir* dir = menu_cache_dup_root_dir(mc);
|
|
||||||
model_->clear();
|
|
||||||
/* FIXME: preserve original selection */
|
|
||||||
if(dir) {
|
|
||||||
addMenuItems(NULL, dir);
|
|
||||||
menu_cache_item_unref(MENU_CACHE_ITEM(dir));
|
|
||||||
selectionModel()->select(model_->index(0, 0), QItemSelectionModel::SelectCurrent);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bool AppMenuView::isAppSelected() {
|
|
||||||
AppMenuViewItem* item = selectedItem();
|
|
||||||
return (item && item->isApp());
|
|
||||||
}
|
|
||||||
|
|
||||||
AppMenuViewItem* AppMenuView::selectedItem() {
|
|
||||||
QModelIndexList selected = selectedIndexes();
|
|
||||||
if(!selected.isEmpty()) {
|
|
||||||
AppMenuViewItem* item = static_cast<AppMenuViewItem*>(model_->itemFromIndex(selected.first()
|
|
||||||
));
|
|
||||||
return item;
|
|
||||||
}
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
GAppInfo* AppMenuView::selectedApp() {
|
|
||||||
const char* id = selectedAppDesktopId();
|
|
||||||
return id ? G_APP_INFO(g_desktop_app_info_new(id)) : NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
QByteArray AppMenuView::selectedAppDesktopFilePath() {
|
|
||||||
AppMenuViewItem* item = selectedItem();
|
|
||||||
if(item && item->isApp()) {
|
|
||||||
char* path = menu_cache_item_get_file_path(item->item());
|
|
||||||
QByteArray ret(path);
|
|
||||||
g_free(path);
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
return QByteArray();
|
|
||||||
}
|
|
||||||
|
|
||||||
const char* AppMenuView::selectedAppDesktopId() {
|
|
||||||
AppMenuViewItem* item = selectedItem();
|
|
||||||
if(item && item->isApp()) {
|
|
||||||
return menu_cache_item_get_id(item->item());
|
|
||||||
}
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
FmPath* AppMenuView::selectedAppDesktopPath() {
|
|
||||||
AppMenuViewItem* item = selectedItem();
|
|
||||||
if(item && item->isApp()) {
|
|
||||||
char* mpath = menu_cache_dir_make_path(MENU_CACHE_DIR(item));
|
|
||||||
FmPath* path = fm_path_new_relative(fm_path_get_apps_menu(),
|
|
||||||
mpath + 13 /* skip "/Applications" */);
|
|
||||||
g_free(mpath);
|
|
||||||
return path;
|
|
||||||
}
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace Fm
|
|
||||||
@ -1,72 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (C) 2014 - 2015 Hong Jen Yee (PCMan) <pcman.tw@gmail.com>
|
|
||||||
*
|
|
||||||
* 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 FM_APPMENUVIEW_H
|
|
||||||
#define FM_APPMENUVIEW_H
|
|
||||||
|
|
||||||
#include <QTreeView>
|
|
||||||
#include "libfmqtglobals.h"
|
|
||||||
#include <libfm/fm.h>
|
|
||||||
#include <menu-cache/menu-cache.h>
|
|
||||||
|
|
||||||
class QStandardItemModel;
|
|
||||||
class QStandardItem;
|
|
||||||
|
|
||||||
namespace Fm {
|
|
||||||
|
|
||||||
class AppMenuViewItem;
|
|
||||||
|
|
||||||
class LIBFM_QT_API AppMenuView : public QTreeView {
|
|
||||||
Q_OBJECT
|
|
||||||
public:
|
|
||||||
explicit AppMenuView(QWidget* parent = NULL);
|
|
||||||
~AppMenuView();
|
|
||||||
|
|
||||||
GAppInfo* selectedApp();
|
|
||||||
|
|
||||||
const char* selectedAppDesktopId();
|
|
||||||
|
|
||||||
QByteArray selectedAppDesktopFilePath();
|
|
||||||
|
|
||||||
FmPath * selectedAppDesktopPath();
|
|
||||||
|
|
||||||
bool isAppSelected();
|
|
||||||
|
|
||||||
Q_SIGNALS:
|
|
||||||
void selectionChanged();
|
|
||||||
|
|
||||||
private:
|
|
||||||
void addMenuItems(QStandardItem* parentItem, MenuCacheDir* dir);
|
|
||||||
void onMenuCacheReload(MenuCache* mc);
|
|
||||||
static void _onMenuCacheReload(MenuCache* mc, gpointer user_data) {
|
|
||||||
static_cast<AppMenuView*>(user_data)->onMenuCacheReload(mc);
|
|
||||||
}
|
|
||||||
|
|
||||||
AppMenuViewItem* selectedItem();
|
|
||||||
|
|
||||||
private:
|
|
||||||
// gboolean fm_app_menu_view_is_item_app(, GtkTreeIter* it);
|
|
||||||
QStandardItemModel* model_;
|
|
||||||
MenuCache* menu_cache;
|
|
||||||
MenuCacheNotifyId menu_cache_reload_notify;
|
|
||||||
};
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif // FM_APPMENUVIEW_H
|
|
||||||
@ -1,73 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (C) 2014 - 2015 Hong Jen Yee (PCMan) <pcman.tw@gmail.com>
|
|
||||||
*
|
|
||||||
* 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 FM_APPMENUVIEW_P_H
|
|
||||||
#define FM_APPMENUVIEW_P_H
|
|
||||||
|
|
||||||
#include <QStandardItem>
|
|
||||||
#include <menu-cache/menu-cache.h>
|
|
||||||
#include "icontheme.h"
|
|
||||||
|
|
||||||
namespace Fm {
|
|
||||||
|
|
||||||
class AppMenuViewItem : public QStandardItem {
|
|
||||||
public:
|
|
||||||
explicit AppMenuViewItem(MenuCacheItem* item):
|
|
||||||
item_(menu_cache_item_ref(item)) {
|
|
||||||
FmIcon* fmicon;
|
|
||||||
if(menu_cache_item_get_icon(item))
|
|
||||||
fmicon = fm_icon_from_name(menu_cache_item_get_icon(item));
|
|
||||||
else
|
|
||||||
fmicon = nullptr;
|
|
||||||
setText(QString::fromUtf8(menu_cache_item_get_name(item)));
|
|
||||||
setEditable(false);
|
|
||||||
setDragEnabled(false);
|
|
||||||
if(fmicon) {
|
|
||||||
setIcon(IconTheme::icon(fmicon));
|
|
||||||
fm_icon_unref(fmicon);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
~AppMenuViewItem() {
|
|
||||||
menu_cache_item_unref(item_);
|
|
||||||
}
|
|
||||||
|
|
||||||
MenuCacheItem* item() {
|
|
||||||
return item_;
|
|
||||||
}
|
|
||||||
|
|
||||||
MenuCacheType type() {
|
|
||||||
return menu_cache_item_get_type(item_);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool isApp() {
|
|
||||||
return type() == MENU_CACHE_TYPE_APP;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool isDir() {
|
|
||||||
return type() == MENU_CACHE_TYPE_DIR;
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
MenuCacheItem* item_;
|
|
||||||
};
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif // FM_APPMENUVIEW_P_H
|
|
||||||
@ -1,32 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (C) 2013 - 2015 Hong Jen Yee (PCMan) <pcman.tw@gmail.com>
|
|
||||||
*
|
|
||||||
* 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 "bookmarkaction.h"
|
|
||||||
|
|
||||||
namespace Fm {
|
|
||||||
|
|
||||||
BookmarkAction::BookmarkAction(FmBookmarkItem* item, QObject* parent):
|
|
||||||
QAction(parent),
|
|
||||||
item_(fm_bookmark_item_ref(item)) {
|
|
||||||
|
|
||||||
setText(QString::fromUtf8(item->name));
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace Fm
|
|
||||||
@ -1,54 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (C) 2013 - 2015 Hong Jen Yee (PCMan) <pcman.tw@gmail.com>
|
|
||||||
*
|
|
||||||
* 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 BOOKMARKACTION_H
|
|
||||||
#define BOOKMARKACTION_H
|
|
||||||
|
|
||||||
#include "libfmqtglobals.h"
|
|
||||||
#include <QAction>
|
|
||||||
#include <libfm/fm.h>
|
|
||||||
|
|
||||||
namespace Fm {
|
|
||||||
|
|
||||||
// action used to create bookmark menu items
|
|
||||||
class LIBFM_QT_API BookmarkAction : public QAction {
|
|
||||||
public:
|
|
||||||
explicit BookmarkAction(FmBookmarkItem* item, QObject* parent = 0);
|
|
||||||
|
|
||||||
virtual ~BookmarkAction() {
|
|
||||||
if(item_)
|
|
||||||
fm_bookmark_item_unref(item_);
|
|
||||||
}
|
|
||||||
|
|
||||||
FmBookmarkItem* bookmark() {
|
|
||||||
return item_;
|
|
||||||
}
|
|
||||||
|
|
||||||
FmPath* path() {
|
|
||||||
return item_->path;
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
FmBookmarkItem* item_;
|
|
||||||
};
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif // BOOKMARKACTION_H
|
|
||||||
@ -1,90 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (C) 2013 - 2015 Hong Jen Yee (PCMan) <pcman.tw@gmail.com>
|
|
||||||
*
|
|
||||||
* 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 "browsehistory.h"
|
|
||||||
|
|
||||||
namespace Fm {
|
|
||||||
|
|
||||||
BrowseHistory::BrowseHistory():
|
|
||||||
currentIndex_(0),
|
|
||||||
maxCount_(10) {
|
|
||||||
}
|
|
||||||
|
|
||||||
BrowseHistory::~BrowseHistory() {
|
|
||||||
}
|
|
||||||
|
|
||||||
void BrowseHistory::add(FmPath* path, int scrollPos) {
|
|
||||||
int lastIndex = size() - 1;
|
|
||||||
if(currentIndex_ < lastIndex) {
|
|
||||||
// if we're not at the last item, remove items after the current one.
|
|
||||||
erase(begin() + currentIndex_ + 1, end());
|
|
||||||
}
|
|
||||||
|
|
||||||
if(size() + 1 > maxCount_) {
|
|
||||||
// if there are too many items, remove the oldest one.
|
|
||||||
// FIXME: what if currentIndex_ == 0? remove the last item instead?
|
|
||||||
if(currentIndex_ == 0)
|
|
||||||
remove(lastIndex);
|
|
||||||
else {
|
|
||||||
remove(0);
|
|
||||||
--currentIndex_;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// add a path and current scroll position to browse history
|
|
||||||
append(BrowseHistoryItem(path, scrollPos));
|
|
||||||
currentIndex_ = size() - 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
void BrowseHistory::setCurrentIndex(int index) {
|
|
||||||
if(index >= 0 && index < size()) {
|
|
||||||
currentIndex_ = index;
|
|
||||||
// FIXME: should we emit a signal for the change?
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bool BrowseHistory::canBackward() const {
|
|
||||||
return (currentIndex_ > 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
int BrowseHistory::backward() {
|
|
||||||
if(canBackward())
|
|
||||||
--currentIndex_;
|
|
||||||
return currentIndex_;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool BrowseHistory::canForward() const {
|
|
||||||
return (currentIndex_ + 1 < size());
|
|
||||||
}
|
|
||||||
|
|
||||||
int BrowseHistory::forward() {
|
|
||||||
if(canForward())
|
|
||||||
++currentIndex_;
|
|
||||||
return currentIndex_;
|
|
||||||
}
|
|
||||||
|
|
||||||
void BrowseHistory::setMaxCount(int maxCount) {
|
|
||||||
maxCount_ = maxCount;
|
|
||||||
if(size() > maxCount) {
|
|
||||||
// TODO: remove some items
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
} // namespace Fm
|
|
||||||
@ -1,131 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (C) 2013 - 2015 Hong Jen Yee (PCMan) <pcman.tw@gmail.com>
|
|
||||||
*
|
|
||||||
* 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 FM_BROWSEHISTORY_H
|
|
||||||
#define FM_BROWSEHISTORY_H
|
|
||||||
|
|
||||||
#include "libfmqtglobals.h"
|
|
||||||
#include <QVector>
|
|
||||||
#include <libfm/fm.h>
|
|
||||||
|
|
||||||
namespace Fm {
|
|
||||||
|
|
||||||
// class used to story browsing history of folder views
|
|
||||||
// We use this class to replace FmNavHistory provided by libfm since
|
|
||||||
// the original Libfm API is hard to use and confusing.
|
|
||||||
|
|
||||||
class LIBFM_QT_API BrowseHistoryItem {
|
|
||||||
public:
|
|
||||||
|
|
||||||
BrowseHistoryItem():
|
|
||||||
path_(NULL),
|
|
||||||
scrollPos_(0) {
|
|
||||||
}
|
|
||||||
|
|
||||||
BrowseHistoryItem(FmPath* path, int scrollPos = 0):
|
|
||||||
path_(fm_path_ref(path)),
|
|
||||||
scrollPos_(scrollPos) {
|
|
||||||
}
|
|
||||||
|
|
||||||
BrowseHistoryItem(const BrowseHistoryItem& other):
|
|
||||||
path_(other.path_ ? fm_path_ref(other.path_) : NULL),
|
|
||||||
scrollPos_(other.scrollPos_) {
|
|
||||||
}
|
|
||||||
|
|
||||||
~BrowseHistoryItem() {
|
|
||||||
if(path_)
|
|
||||||
fm_path_unref(path_);
|
|
||||||
}
|
|
||||||
|
|
||||||
BrowseHistoryItem& operator=(const BrowseHistoryItem& other) {
|
|
||||||
if(path_)
|
|
||||||
fm_path_unref(path_);
|
|
||||||
path_ = other.path_ ? fm_path_ref(other.path_) : NULL;
|
|
||||||
scrollPos_ = other.scrollPos_;
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
FmPath* path() const {
|
|
||||||
return path_;
|
|
||||||
}
|
|
||||||
|
|
||||||
int scrollPos() const {
|
|
||||||
return scrollPos_;
|
|
||||||
}
|
|
||||||
|
|
||||||
void setScrollPos(int pos) {
|
|
||||||
scrollPos_ = pos;
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
FmPath* path_;
|
|
||||||
int scrollPos_;
|
|
||||||
// TODO: we may need to store current selection as well. reserve room for furutre expansion.
|
|
||||||
// void* reserved1;
|
|
||||||
// void* reserved2;
|
|
||||||
};
|
|
||||||
|
|
||||||
class LIBFM_QT_API BrowseHistory : public QVector<BrowseHistoryItem> {
|
|
||||||
|
|
||||||
public:
|
|
||||||
BrowseHistory();
|
|
||||||
virtual ~BrowseHistory();
|
|
||||||
|
|
||||||
int currentIndex() const {
|
|
||||||
return currentIndex_;
|
|
||||||
}
|
|
||||||
void setCurrentIndex(int index);
|
|
||||||
|
|
||||||
FmPath* currentPath() const {
|
|
||||||
return at(currentIndex_).path();
|
|
||||||
}
|
|
||||||
|
|
||||||
int currentScrollPos() const {
|
|
||||||
return at(currentIndex_).scrollPos();
|
|
||||||
}
|
|
||||||
|
|
||||||
BrowseHistoryItem& currentItem() {
|
|
||||||
return operator[](currentIndex_);
|
|
||||||
}
|
|
||||||
|
|
||||||
void add(FmPath* path, int scrollPos = 0);
|
|
||||||
|
|
||||||
bool canForward() const;
|
|
||||||
|
|
||||||
bool canBackward() const;
|
|
||||||
|
|
||||||
int backward();
|
|
||||||
|
|
||||||
int forward();
|
|
||||||
|
|
||||||
int maxCount() const {
|
|
||||||
return maxCount_;
|
|
||||||
}
|
|
||||||
|
|
||||||
void setMaxCount(int maxCount);
|
|
||||||
|
|
||||||
private:
|
|
||||||
int currentIndex_;
|
|
||||||
int maxCount_;
|
|
||||||
};
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif // FM_BROWSEHISTORY_H
|
|
||||||
@ -1,74 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (C) 2013 - 2015 Hong Jen Yee (PCMan) <pcman.tw@gmail.com>
|
|
||||||
*
|
|
||||||
* 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 "cachedfoldermodel.h"
|
|
||||||
|
|
||||||
namespace Fm {
|
|
||||||
|
|
||||||
static GQuark data_id = 0;
|
|
||||||
|
|
||||||
|
|
||||||
CachedFolderModel::CachedFolderModel(FmFolder* folder):
|
|
||||||
FolderModel(),
|
|
||||||
refCount(1) {
|
|
||||||
|
|
||||||
FolderModel::setFolder(folder);
|
|
||||||
}
|
|
||||||
|
|
||||||
CachedFolderModel::~CachedFolderModel() {
|
|
||||||
}
|
|
||||||
|
|
||||||
CachedFolderModel* CachedFolderModel::modelFromFolder(FmFolder* folder) {
|
|
||||||
CachedFolderModel* model = NULL;
|
|
||||||
if(!data_id)
|
|
||||||
data_id = g_quark_from_static_string("CachedFolderModel");
|
|
||||||
gpointer qdata = g_object_get_qdata(G_OBJECT(folder), data_id);
|
|
||||||
model = reinterpret_cast<CachedFolderModel*>(qdata);
|
|
||||||
if(model) {
|
|
||||||
// qDebug("cache found!!");
|
|
||||||
model->ref();
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
model = new CachedFolderModel(folder);
|
|
||||||
g_object_set_qdata(G_OBJECT(folder), data_id, model);
|
|
||||||
}
|
|
||||||
return model;
|
|
||||||
}
|
|
||||||
|
|
||||||
CachedFolderModel* CachedFolderModel::modelFromPath(FmPath* path) {
|
|
||||||
FmFolder* folder = fm_folder_from_path(path);
|
|
||||||
if(folder) {
|
|
||||||
CachedFolderModel* model = modelFromFolder(folder);
|
|
||||||
g_object_unref(folder);
|
|
||||||
return model;
|
|
||||||
}
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
void CachedFolderModel::unref() {
|
|
||||||
// qDebug("unref cache");
|
|
||||||
--refCount;
|
|
||||||
if(refCount <= 0) {
|
|
||||||
g_object_set_qdata(G_OBJECT(folder()), data_id, NULL);
|
|
||||||
deleteLater();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
} // namespace Fm
|
|
||||||
@ -1,51 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (C) 2013 - 2015 Hong Jen Yee (PCMan) <pcman.tw@gmail.com>
|
|
||||||
*
|
|
||||||
* 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 FM_CACHEDFOLDERMODEL_H
|
|
||||||
#define FM_CACHEDFOLDERMODEL_H
|
|
||||||
|
|
||||||
#include "libfmqtglobals.h"
|
|
||||||
#include "foldermodel.h"
|
|
||||||
|
|
||||||
namespace Fm {
|
|
||||||
|
|
||||||
class LIBFM_QT_API CachedFolderModel : public FolderModel {
|
|
||||||
Q_OBJECT
|
|
||||||
public:
|
|
||||||
CachedFolderModel(FmFolder* folder);
|
|
||||||
void ref() {
|
|
||||||
++refCount;
|
|
||||||
}
|
|
||||||
void unref();
|
|
||||||
|
|
||||||
static CachedFolderModel* modelFromFolder(FmFolder* folder);
|
|
||||||
static CachedFolderModel* modelFromPath(FmPath* path);
|
|
||||||
|
|
||||||
private:
|
|
||||||
virtual ~CachedFolderModel();
|
|
||||||
void setFolder(FmFolder* folder);
|
|
||||||
private:
|
|
||||||
int refCount;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif // FM_CACHEDFOLDERMODEL_H
|
|
||||||
@ -1,53 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (C) 2013 - 2015 Hong Jen Yee (PCMan) <pcman.tw@gmail.com>
|
|
||||||
*
|
|
||||||
* 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 "colorbutton.h"
|
|
||||||
#include <QColorDialog>
|
|
||||||
|
|
||||||
namespace Fm {
|
|
||||||
|
|
||||||
ColorButton::ColorButton(QWidget* parent): QPushButton(parent) {
|
|
||||||
connect(this, &QPushButton::clicked, this, &ColorButton::onClicked);
|
|
||||||
}
|
|
||||||
|
|
||||||
ColorButton::~ColorButton() {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
void ColorButton::onClicked() {
|
|
||||||
QColorDialog dlg(color_);
|
|
||||||
if(dlg.exec() == QDialog::Accepted) {
|
|
||||||
setColor(dlg.selectedColor());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void ColorButton::setColor(const QColor& color) {
|
|
||||||
if(color != color_) {
|
|
||||||
color_ = color;
|
|
||||||
// use qss instead of QPalette to set the background color
|
|
||||||
// otherwise, this won't work when using the gtk style.
|
|
||||||
QString style = QString("QPushButton{background-color:%1;}").arg(color.name());
|
|
||||||
setStyleSheet(style);
|
|
||||||
Q_EMIT changed();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
} // namespace Fm
|
|
||||||
@ -1,55 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (C) 2013 - 2015 Hong Jen Yee (PCMan) <pcman.tw@gmail.com>
|
|
||||||
*
|
|
||||||
* 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 FM_COLORBUTTON_H
|
|
||||||
#define FM_COLORBUTTON_H
|
|
||||||
|
|
||||||
#include "libfmqtglobals.h"
|
|
||||||
#include <QPushButton>
|
|
||||||
#include <QColor>
|
|
||||||
|
|
||||||
namespace Fm {
|
|
||||||
|
|
||||||
class LIBFM_QT_API ColorButton : public QPushButton {
|
|
||||||
Q_OBJECT
|
|
||||||
|
|
||||||
public:
|
|
||||||
explicit ColorButton(QWidget* parent = 0);
|
|
||||||
virtual ~ColorButton();
|
|
||||||
|
|
||||||
void setColor(const QColor&);
|
|
||||||
|
|
||||||
QColor color() const {
|
|
||||||
return color_;
|
|
||||||
}
|
|
||||||
|
|
||||||
Q_SIGNALS:
|
|
||||||
void changed();
|
|
||||||
|
|
||||||
private Q_SLOTS:
|
|
||||||
void onClicked();
|
|
||||||
|
|
||||||
private:
|
|
||||||
QColor color_;
|
|
||||||
};
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif // FM_COLORBUTTON_H
|
|
||||||
@ -1,90 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (C) 2012 - 2015 Hong Jen Yee (PCMan) <pcman.tw@gmail.com>
|
|
||||||
*
|
|
||||||
* 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 "createnewmenu.h"
|
|
||||||
#include "folderview.h"
|
|
||||||
#include "icontheme.h"
|
|
||||||
#include "utilities.h"
|
|
||||||
|
|
||||||
namespace Fm {
|
|
||||||
|
|
||||||
CreateNewMenu::CreateNewMenu(QWidget* dialogParent, FmPath* dirPath, QWidget* parent):
|
|
||||||
QMenu(parent), dialogParent_(dialogParent), dirPath_(dirPath) {
|
|
||||||
QAction* action = new QAction(QIcon::fromTheme("folder-new"), tr("Folder"), this);
|
|
||||||
connect(action, &QAction::triggered, this, &CreateNewMenu::onCreateNewFolder);
|
|
||||||
addAction(action);
|
|
||||||
|
|
||||||
action = new QAction(QIcon::fromTheme("document-new"), tr("Blank File"), this);
|
|
||||||
connect(action, &QAction::triggered, this, &CreateNewMenu::onCreateNewFile);
|
|
||||||
addAction(action);
|
|
||||||
|
|
||||||
// add more items to "Create New" menu from templates
|
|
||||||
GList* templates = fm_template_list_all(fm_config->only_user_templates);
|
|
||||||
if(templates) {
|
|
||||||
addSeparator();
|
|
||||||
for(GList* l = templates; l; l = l->next) {
|
|
||||||
FmTemplate* templ = (FmTemplate*)l->data;
|
|
||||||
/* we support directories differently */
|
|
||||||
if(fm_template_is_directory(templ))
|
|
||||||
continue;
|
|
||||||
FmMimeType* mime_type = fm_template_get_mime_type(templ);
|
|
||||||
const char* label = fm_template_get_label(templ);
|
|
||||||
QString text = QString("%1 (%2)").arg(QString::fromUtf8(label)).arg(QString::fromUtf8(fm_mime_type_get_desc(mime_type)));
|
|
||||||
FmIcon* icon = fm_template_get_icon(templ);
|
|
||||||
if(!icon)
|
|
||||||
icon = fm_mime_type_get_icon(mime_type);
|
|
||||||
QAction* action = addAction(IconTheme::icon(icon), text);
|
|
||||||
action->setObjectName(QString::fromUtf8(fm_template_get_name(templ, NULL)));
|
|
||||||
connect(action, &QAction::triggered, this, &CreateNewMenu::onCreateNew);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
CreateNewMenu::~CreateNewMenu() {
|
|
||||||
}
|
|
||||||
|
|
||||||
void CreateNewMenu::onCreateNewFile() {
|
|
||||||
if(dirPath_)
|
|
||||||
createFileOrFolder(CreateNewTextFile, dirPath_);
|
|
||||||
}
|
|
||||||
|
|
||||||
void CreateNewMenu::onCreateNewFolder() {
|
|
||||||
if(dirPath_)
|
|
||||||
createFileOrFolder(CreateNewFolder, dirPath_);
|
|
||||||
}
|
|
||||||
|
|
||||||
void CreateNewMenu::onCreateNew() {
|
|
||||||
QAction* action = static_cast<QAction*>(sender());
|
|
||||||
QByteArray name = action->objectName().toUtf8();
|
|
||||||
GList* templates = fm_template_list_all(fm_config->only_user_templates);
|
|
||||||
FmTemplate* templ = NULL;
|
|
||||||
for(GList* l = templates; l; l = l->next) {
|
|
||||||
FmTemplate* t = (FmTemplate*)l->data;
|
|
||||||
if(name == fm_template_get_name(t, NULL)) {
|
|
||||||
templ = t;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if(templ) { // template found
|
|
||||||
if(dirPath_)
|
|
||||||
createFileOrFolder(CreateWithTemplate, dirPath_, templ, dialogParent_);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace Fm
|
|
||||||
@ -1,51 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (C) 2012 - 2015 Hong Jen Yee (PCMan) <pcman.tw@gmail.com>
|
|
||||||
*
|
|
||||||
* 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 FM_CREATENEWMENU_H
|
|
||||||
#define FM_CREATENEWMENU_H
|
|
||||||
|
|
||||||
#include "libfmqtglobals.h"
|
|
||||||
#include <QMenu>
|
|
||||||
#include <libfm/fm.h>
|
|
||||||
|
|
||||||
namespace Fm {
|
|
||||||
|
|
||||||
class FolderView;
|
|
||||||
|
|
||||||
class LIBFM_QT_API CreateNewMenu : public QMenu {
|
|
||||||
Q_OBJECT
|
|
||||||
|
|
||||||
public:
|
|
||||||
explicit CreateNewMenu(QWidget* dialogParent, FmPath* dirPath,
|
|
||||||
QWidget* parent = 0);
|
|
||||||
virtual ~CreateNewMenu();
|
|
||||||
|
|
||||||
protected Q_SLOTS:
|
|
||||||
void onCreateNewFolder();
|
|
||||||
void onCreateNewFile();
|
|
||||||
void onCreateNew();
|
|
||||||
|
|
||||||
private:
|
|
||||||
QWidget* dialogParent_;
|
|
||||||
FmPath* dirPath_;
|
|
||||||
};
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif // FM_CREATENEWMENU_H
|
|
||||||
@ -1,205 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (C) 2014 - 2015 Hong Jen Yee (PCMan) <pcman.tw@gmail.com>
|
|
||||||
*
|
|
||||||
* 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 "dirtreemodel.h"
|
|
||||||
#include "dirtreemodelitem.h"
|
|
||||||
#include <QDebug>
|
|
||||||
|
|
||||||
namespace Fm {
|
|
||||||
|
|
||||||
DirTreeModel::DirTreeModel(QObject* parent):
|
|
||||||
showHidden_(false) {
|
|
||||||
}
|
|
||||||
|
|
||||||
DirTreeModel::~DirTreeModel() {
|
|
||||||
}
|
|
||||||
|
|
||||||
// QAbstractItemModel implementation
|
|
||||||
|
|
||||||
Qt::ItemFlags DirTreeModel::flags(const QModelIndex& index) const {
|
|
||||||
DirTreeModelItem* item = itemFromIndex(index);
|
|
||||||
if(item && item->isPlaceHolder())
|
|
||||||
return Qt::ItemIsEnabled;
|
|
||||||
return QAbstractItemModel::flags(index);
|
|
||||||
}
|
|
||||||
|
|
||||||
QVariant DirTreeModel::data(const QModelIndex& index, int role) const {
|
|
||||||
if(!index.isValid() || index.column() > 1) {
|
|
||||||
return QVariant();
|
|
||||||
}
|
|
||||||
DirTreeModelItem* item = itemFromIndex(index);
|
|
||||||
if(item) {
|
|
||||||
FmFileInfo* info = item->fileInfo_;
|
|
||||||
switch(role) {
|
|
||||||
case Qt::ToolTipRole:
|
|
||||||
return QVariant(item->displayName_);
|
|
||||||
case Qt::DisplayRole:
|
|
||||||
return QVariant(item->displayName_);
|
|
||||||
case Qt::DecorationRole:
|
|
||||||
return QVariant(item->icon_);
|
|
||||||
case FileInfoRole:
|
|
||||||
return qVariantFromValue((void*)info);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return QVariant();
|
|
||||||
}
|
|
||||||
|
|
||||||
int DirTreeModel::columnCount(const QModelIndex& parent) const {
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
int DirTreeModel::rowCount(const QModelIndex& parent) const {
|
|
||||||
if(!parent.isValid())
|
|
||||||
return rootItems_.count();
|
|
||||||
DirTreeModelItem* item = itemFromIndex(parent);
|
|
||||||
if(item)
|
|
||||||
return item->children_.count();
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
QModelIndex DirTreeModel::parent(const QModelIndex& child) const {
|
|
||||||
DirTreeModelItem* item = itemFromIndex(child);
|
|
||||||
if(item && item->parent_) {
|
|
||||||
item = item->parent_; // go to parent item
|
|
||||||
if(item) {
|
|
||||||
const QList<DirTreeModelItem*>& items = item->parent_ ? item->parent_->children_ : rootItems_;
|
|
||||||
int row = items.indexOf(item); // this is Q(n) and may be slow :-(
|
|
||||||
if(row >= 0)
|
|
||||||
return createIndex(row, 0, (void*)item);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return QModelIndex();
|
|
||||||
}
|
|
||||||
|
|
||||||
QModelIndex DirTreeModel::index(int row, int column, const QModelIndex& parent) const {
|
|
||||||
if(row >= 0 && column >= 0 && column == 0) {
|
|
||||||
if(!parent.isValid()) { // root items
|
|
||||||
if(row < rootItems_.count()) {
|
|
||||||
const DirTreeModelItem* item = rootItems_.at(row);
|
|
||||||
return createIndex(row, column, (void*)item);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else { // child items
|
|
||||||
DirTreeModelItem* parentItem = itemFromIndex(parent);
|
|
||||||
if(row < parentItem->children_.count()) {
|
|
||||||
const DirTreeModelItem* item = parentItem->children_.at(row);
|
|
||||||
return createIndex(row, column, (void*)item);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return QModelIndex(); // invalid index
|
|
||||||
}
|
|
||||||
|
|
||||||
bool DirTreeModel::hasChildren(const QModelIndex& parent) const {
|
|
||||||
DirTreeModelItem* item = itemFromIndex(parent);
|
|
||||||
return item ? !item->isPlaceHolder() : true;
|
|
||||||
}
|
|
||||||
|
|
||||||
QModelIndex DirTreeModel::indexFromItem(DirTreeModelItem* item) const {
|
|
||||||
Q_ASSERT(item);
|
|
||||||
const QList<DirTreeModelItem*>& items = item->parent_ ? item->parent_->children_ : rootItems_;
|
|
||||||
int row = items.indexOf(item);
|
|
||||||
if(row >= 0)
|
|
||||||
return createIndex(row, 0, (void*)item);
|
|
||||||
return QModelIndex();
|
|
||||||
}
|
|
||||||
|
|
||||||
// public APIs
|
|
||||||
QModelIndex DirTreeModel::addRoot(FmFileInfo* root) {
|
|
||||||
DirTreeModelItem* item = new DirTreeModelItem(root, this);
|
|
||||||
int row = rootItems_.count();
|
|
||||||
beginInsertRows(QModelIndex(), row, row);
|
|
||||||
item->fileInfo_ = fm_file_info_ref(root);
|
|
||||||
rootItems_.append(item);
|
|
||||||
// add_place_holder_child_item(model, item_l, NULL, FALSE);
|
|
||||||
endInsertRows();
|
|
||||||
return QModelIndex();
|
|
||||||
}
|
|
||||||
|
|
||||||
DirTreeModelItem* DirTreeModel::itemFromIndex(const QModelIndex& index) const {
|
|
||||||
return reinterpret_cast<DirTreeModelItem*>(index.internalPointer());
|
|
||||||
}
|
|
||||||
|
|
||||||
QModelIndex DirTreeModel::indexFromPath(FmPath* path) const {
|
|
||||||
DirTreeModelItem* item = itemFromPath(path);
|
|
||||||
return item ? item->index() : QModelIndex();
|
|
||||||
}
|
|
||||||
|
|
||||||
DirTreeModelItem* DirTreeModel::itemFromPath(FmPath* path) const {
|
|
||||||
Q_FOREACH(DirTreeModelItem* item, rootItems_) {
|
|
||||||
if(item->fileInfo_ && fm_path_equal(path, fm_file_info_get_path(item->fileInfo_))) {
|
|
||||||
return item;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
DirTreeModelItem* child = item->childFromPath(path, true);
|
|
||||||
if(child)
|
|
||||||
return child;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void DirTreeModel::loadRow(const QModelIndex& index) {
|
|
||||||
DirTreeModelItem* item = itemFromIndex(index);
|
|
||||||
Q_ASSERT(item);
|
|
||||||
if(item && !item->isPlaceHolder())
|
|
||||||
item->loadFolder();
|
|
||||||
}
|
|
||||||
|
|
||||||
void DirTreeModel::unloadRow(const QModelIndex& index) {
|
|
||||||
DirTreeModelItem* item = itemFromIndex(index);
|
|
||||||
if(item && !item->isPlaceHolder())
|
|
||||||
item->unloadFolder();
|
|
||||||
}
|
|
||||||
|
|
||||||
bool DirTreeModel::isLoaded(const QModelIndex& index) {
|
|
||||||
DirTreeModelItem* item = itemFromIndex(index);
|
|
||||||
return item ? item->loaded_ : false;
|
|
||||||
}
|
|
||||||
|
|
||||||
QIcon DirTreeModel::icon(const QModelIndex& index) {
|
|
||||||
DirTreeModelItem* item = itemFromIndex(index);
|
|
||||||
return item ? item->icon_ : QIcon();
|
|
||||||
}
|
|
||||||
|
|
||||||
FmFileInfo* DirTreeModel::fileInfo(const QModelIndex& index) {
|
|
||||||
DirTreeModelItem* item = itemFromIndex(index);
|
|
||||||
return item ? item->fileInfo_ : NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
FmPath* DirTreeModel::filePath(const QModelIndex& index) {
|
|
||||||
DirTreeModelItem* item = itemFromIndex(index);
|
|
||||||
return item && item->fileInfo_ ? fm_file_info_get_path(item->fileInfo_) : NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
QString DirTreeModel::dispName(const QModelIndex& index) {
|
|
||||||
DirTreeModelItem* item = itemFromIndex(index);
|
|
||||||
return item ? item->displayName_ : QString();
|
|
||||||
}
|
|
||||||
|
|
||||||
void DirTreeModel::setShowHidden(bool show_hidden) {
|
|
||||||
showHidden_ = show_hidden;
|
|
||||||
Q_FOREACH(DirTreeModelItem* item, rootItems_) {
|
|
||||||
item->setShowHidden(show_hidden);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
} // namespace Fm
|
|
||||||
@ -1,89 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (C) 2014 - 2015 Hong Jen Yee (PCMan) <pcman.tw@gmail.com>
|
|
||||||
*
|
|
||||||
* 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 FM_DIRTREEMODEL_H
|
|
||||||
#define FM_DIRTREEMODEL_H
|
|
||||||
|
|
||||||
#include "libfmqtglobals.h"
|
|
||||||
#include <QModelIndex>
|
|
||||||
#include <QAbstractItemModel>
|
|
||||||
#include <QIcon>
|
|
||||||
#include <QList>
|
|
||||||
#include <QSharedPointer>
|
|
||||||
#include <libfm/fm.h>
|
|
||||||
|
|
||||||
namespace Fm {
|
|
||||||
|
|
||||||
class DirTreeModelItem;
|
|
||||||
class DirTreeView;
|
|
||||||
|
|
||||||
class LIBFM_QT_API DirTreeModel : public QAbstractItemModel {
|
|
||||||
Q_OBJECT
|
|
||||||
|
|
||||||
public:
|
|
||||||
friend class DirTreeModelItem; // allow direct access of private members in DirTreeModelItem
|
|
||||||
friend class DirTreeView; // allow direct access of private members in DirTreeView
|
|
||||||
|
|
||||||
enum Role {
|
|
||||||
FileInfoRole = Qt::UserRole
|
|
||||||
};
|
|
||||||
|
|
||||||
explicit DirTreeModel(QObject* parent);
|
|
||||||
~DirTreeModel();
|
|
||||||
|
|
||||||
QModelIndex addRoot(FmFileInfo* root);
|
|
||||||
void loadRow(const QModelIndex& index);
|
|
||||||
void unloadRow(const QModelIndex& index);
|
|
||||||
|
|
||||||
bool isLoaded(const QModelIndex& index);
|
|
||||||
QIcon icon(const QModelIndex& index);
|
|
||||||
FmFileInfo* fileInfo(const QModelIndex& index);
|
|
||||||
FmPath* filePath(const QModelIndex& index);
|
|
||||||
QString dispName(const QModelIndex& index);
|
|
||||||
|
|
||||||
void setShowHidden(bool show_hidden);
|
|
||||||
bool showHidden() const {
|
|
||||||
return showHidden_;
|
|
||||||
}
|
|
||||||
|
|
||||||
QModelIndex indexFromPath(FmPath* path) const;
|
|
||||||
|
|
||||||
virtual Qt::ItemFlags flags(const QModelIndex& index) const;
|
|
||||||
virtual QVariant data(const QModelIndex& index, int role) const;
|
|
||||||
virtual int columnCount(const QModelIndex& parent) const;
|
|
||||||
virtual int rowCount(const QModelIndex& parent) const;
|
|
||||||
virtual QModelIndex parent(const QModelIndex& child) const;
|
|
||||||
virtual QModelIndex index(int row, int column, const QModelIndex& parent) const;
|
|
||||||
virtual bool hasChildren(const QModelIndex& parent = QModelIndex()) const;
|
|
||||||
|
|
||||||
private:
|
|
||||||
DirTreeModelItem* itemFromPath(FmPath* path) const;
|
|
||||||
DirTreeModelItem* itemFromIndex(const QModelIndex& index) const;
|
|
||||||
QModelIndex indexFromItem(DirTreeModelItem* item) const;
|
|
||||||
|
|
||||||
Q_SIGNALS:
|
|
||||||
void rowLoaded(const QModelIndex& index);
|
|
||||||
|
|
||||||
private:
|
|
||||||
bool showHidden_;
|
|
||||||
QList<DirTreeModelItem*> rootItems_;
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif // FM_DIRTREEMODEL_H
|
|
||||||
@ -1,337 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (C) 2014 - 2015 Hong Jen Yee (PCMan) <pcman.tw@gmail.com>
|
|
||||||
*
|
|
||||||
* 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 "dirtreemodelitem.h"
|
|
||||||
#include "dirtreemodel.h"
|
|
||||||
#include "icontheme.h"
|
|
||||||
#include <QDebug>
|
|
||||||
|
|
||||||
namespace Fm {
|
|
||||||
|
|
||||||
DirTreeModelItem::DirTreeModelItem():
|
|
||||||
model_(nullptr),
|
|
||||||
folder_(nullptr),
|
|
||||||
expanded_(false),
|
|
||||||
loaded_(false),
|
|
||||||
fileInfo_(nullptr),
|
|
||||||
placeHolderChild_(nullptr),
|
|
||||||
parent_(nullptr) {
|
|
||||||
}
|
|
||||||
|
|
||||||
DirTreeModelItem::DirTreeModelItem(FmFileInfo* info, DirTreeModel* model, DirTreeModelItem* parent):
|
|
||||||
model_(model),
|
|
||||||
folder_(nullptr),
|
|
||||||
expanded_(false),
|
|
||||||
loaded_(false),
|
|
||||||
fileInfo_(fm_file_info_ref(info)),
|
|
||||||
displayName_(QString::fromUtf8(fm_file_info_get_disp_name(info))),
|
|
||||||
icon_(IconTheme::icon(fm_file_info_get_icon(info))),
|
|
||||||
placeHolderChild_(nullptr),
|
|
||||||
parent_(parent) {
|
|
||||||
|
|
||||||
if(info)
|
|
||||||
addPlaceHolderChild();
|
|
||||||
}
|
|
||||||
|
|
||||||
DirTreeModelItem::~DirTreeModelItem() {
|
|
||||||
if(fileInfo_)
|
|
||||||
fm_file_info_unref(fileInfo_);
|
|
||||||
|
|
||||||
if(folder_)
|
|
||||||
freeFolder();
|
|
||||||
|
|
||||||
// delete child items if needed
|
|
||||||
if(!children_.isEmpty()) {
|
|
||||||
Q_FOREACH(DirTreeModelItem* item, children_) {
|
|
||||||
delete item;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if(!hiddenChildren_.isEmpty()) {
|
|
||||||
Q_FOREACH(DirTreeModelItem* item, hiddenChildren_) {
|
|
||||||
delete item;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void DirTreeModelItem::addPlaceHolderChild() {
|
|
||||||
placeHolderChild_ = new DirTreeModelItem();
|
|
||||||
placeHolderChild_->parent_ = this;
|
|
||||||
placeHolderChild_->model_ = model_;
|
|
||||||
placeHolderChild_->displayName_ = DirTreeModel::tr("Loading...");
|
|
||||||
children_.append(placeHolderChild_);
|
|
||||||
}
|
|
||||||
|
|
||||||
void DirTreeModelItem::freeFolder() {
|
|
||||||
if(folder_) {
|
|
||||||
g_signal_handlers_disconnect_by_func(folder_, gpointer(onFolderFinishLoading), this);
|
|
||||||
g_signal_handlers_disconnect_by_func(folder_, gpointer(onFolderFilesAdded), this);
|
|
||||||
g_signal_handlers_disconnect_by_func(folder_, gpointer(onFolderFilesRemoved), this);
|
|
||||||
g_signal_handlers_disconnect_by_func(folder_, gpointer(onFolderFilesChanged), this);
|
|
||||||
g_object_unref(folder_);
|
|
||||||
folder_ = nullptr;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void DirTreeModelItem::loadFolder() {
|
|
||||||
if(!expanded_) {
|
|
||||||
/* dynamically load content of the folder. */
|
|
||||||
folder_ = fm_folder_from_path(fm_file_info_get_path(fileInfo_));
|
|
||||||
/* g_debug("fm_dir_tree_model_load_row()"); */
|
|
||||||
/* associate the data with loaded handler */
|
|
||||||
g_signal_connect(folder_, "finish-loading", G_CALLBACK(onFolderFinishLoading), this);
|
|
||||||
g_signal_connect(folder_, "files-added", G_CALLBACK(onFolderFilesAdded), this);
|
|
||||||
g_signal_connect(folder_, "files-removed", G_CALLBACK(onFolderFilesRemoved), this);
|
|
||||||
g_signal_connect(folder_, "files-changed", G_CALLBACK(onFolderFilesChanged), this);
|
|
||||||
|
|
||||||
/* set 'expanded' flag beforehand as callback may check it */
|
|
||||||
expanded_ = true;
|
|
||||||
/* if the folder is already loaded, call "loaded" handler ourselves */
|
|
||||||
if(fm_folder_is_loaded(folder_)) { // already loaded
|
|
||||||
GList* file_l;
|
|
||||||
FmFileInfoList* files = fm_folder_get_files(folder_);
|
|
||||||
for(file_l = fm_file_info_list_peek_head_link(files); file_l; file_l = file_l->next) {
|
|
||||||
FmFileInfo* fi = FM_FILE_INFO(file_l->data);
|
|
||||||
if(fm_file_info_is_dir(fi)) {
|
|
||||||
insertFileInfo(fi);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
onFolderFinishLoading(folder_, this);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void DirTreeModelItem::unloadFolder() {
|
|
||||||
if(expanded_) { /* do some cleanup */
|
|
||||||
/* remove all children, and replace them with a dummy child
|
|
||||||
* item to keep expander in the tree view around. */
|
|
||||||
|
|
||||||
// delete all visible child items
|
|
||||||
model_->beginRemoveRows(index(), 0, children_.count() - 1);
|
|
||||||
if(!children_.isEmpty()) {
|
|
||||||
Q_FOREACH(DirTreeModelItem* item, children_) {
|
|
||||||
delete item;
|
|
||||||
}
|
|
||||||
children_.clear();
|
|
||||||
}
|
|
||||||
model_->endRemoveRows();
|
|
||||||
|
|
||||||
// remove hidden children
|
|
||||||
if(!hiddenChildren_.isEmpty()) {
|
|
||||||
Q_FOREACH(DirTreeModelItem* item, hiddenChildren_) {
|
|
||||||
delete item;
|
|
||||||
}
|
|
||||||
hiddenChildren_.clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
/* now, we have no child since all child items are removed.
|
|
||||||
* So we add a place holder child item to keep the expander around. */
|
|
||||||
addPlaceHolderChild();
|
|
||||||
/* deactivate folder since it will be reactivated on expand */
|
|
||||||
freeFolder();
|
|
||||||
expanded_ = false;
|
|
||||||
loaded_ = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
QModelIndex DirTreeModelItem::index() {
|
|
||||||
Q_ASSERT(model_);
|
|
||||||
return model_->indexFromItem(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Add file info to parent node to proper position.
|
|
||||||
* GtkTreePath tp is the tree path of parent node. */
|
|
||||||
DirTreeModelItem* DirTreeModelItem::insertFileInfo(FmFileInfo* fi) {
|
|
||||||
// qDebug() << "insertFileInfo: " << fm_file_info_get_disp_name(fi);
|
|
||||||
DirTreeModelItem* item = new DirTreeModelItem(fi, model_);
|
|
||||||
insertItem(item);
|
|
||||||
return item;
|
|
||||||
}
|
|
||||||
|
|
||||||
// find a good position to insert the new item
|
|
||||||
int DirTreeModelItem::insertItem(DirTreeModelItem* newItem) {
|
|
||||||
if(model_->showHidden() || !newItem->fileInfo_ || !fm_file_info_is_hidden(newItem->fileInfo_)) {
|
|
||||||
const char* new_key = fm_file_info_get_collate_key(newItem->fileInfo_);
|
|
||||||
int pos = 0;
|
|
||||||
QList<DirTreeModelItem*>::iterator it;
|
|
||||||
for(it = children_.begin(); it != children_.end(); ++it) {
|
|
||||||
DirTreeModelItem* child = *it;
|
|
||||||
if(G_UNLIKELY(!child->fileInfo_))
|
|
||||||
continue;
|
|
||||||
const char* key = fm_file_info_get_collate_key(child->fileInfo_);
|
|
||||||
if(strcmp(new_key, key) <= 0)
|
|
||||||
break;
|
|
||||||
++pos;
|
|
||||||
}
|
|
||||||
// inform the world that we're about to insert the item
|
|
||||||
model_->beginInsertRows(index(), pos, pos);
|
|
||||||
newItem->parent_ = this;
|
|
||||||
children_.insert(it, newItem);
|
|
||||||
model_->endInsertRows();
|
|
||||||
return pos;
|
|
||||||
}
|
|
||||||
else { // hidden folder
|
|
||||||
hiddenChildren_.append(newItem);
|
|
||||||
}
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// FmFolder signal handlers
|
|
||||||
|
|
||||||
// static
|
|
||||||
void DirTreeModelItem::onFolderFinishLoading(FmFolder* folder, gpointer user_data) {
|
|
||||||
DirTreeModelItem* _this = (DirTreeModelItem*)user_data;
|
|
||||||
DirTreeModel* model = _this->model_;
|
|
||||||
/* set 'loaded' flag beforehand as callback may check it */
|
|
||||||
_this->loaded_ = true;
|
|
||||||
QModelIndex index = _this->index();
|
|
||||||
qDebug() << "folder loaded";
|
|
||||||
// remove the placeholder child if needed
|
|
||||||
if(_this->children_.count() == 1) { // we have no other child other than the place holder item, leave it
|
|
||||||
_this->placeHolderChild_->displayName_ = DirTreeModel::tr("<No sub folders>");
|
|
||||||
QModelIndex placeHolderIndex = _this->placeHolderChild_->index();
|
|
||||||
// qDebug() << "placeHolderIndex: "<<placeHolderIndex;
|
|
||||||
Q_EMIT model->dataChanged(placeHolderIndex, placeHolderIndex);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
int pos = _this->children_.indexOf(_this->placeHolderChild_);
|
|
||||||
model->beginRemoveRows(index, pos, pos);
|
|
||||||
_this->children_.removeAt(pos);
|
|
||||||
delete _this->placeHolderChild_;
|
|
||||||
model->endRemoveRows();
|
|
||||||
_this->placeHolderChild_ = nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
Q_EMIT model->rowLoaded(index);
|
|
||||||
}
|
|
||||||
|
|
||||||
// static
|
|
||||||
void DirTreeModelItem::onFolderFilesAdded(FmFolder* folder, GSList* files, gpointer user_data) {
|
|
||||||
GSList* l;
|
|
||||||
DirTreeModelItem* _this = (DirTreeModelItem*)user_data;
|
|
||||||
for(l = files; l; l = l->next) {
|
|
||||||
FmFileInfo* fi = FM_FILE_INFO(l->data);
|
|
||||||
if(fm_file_info_is_dir(fi)) { /* FIXME: maybe adding files can be allowed later */
|
|
||||||
/* Ideally FmFolder should not emit files-added signals for files that
|
|
||||||
* already exists. So there is no need to check for duplication here. */
|
|
||||||
_this->insertFileInfo(fi);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// static
|
|
||||||
void DirTreeModelItem::onFolderFilesRemoved(FmFolder* folder, GSList* files, gpointer user_data) {
|
|
||||||
DirTreeModelItem* _this = (DirTreeModelItem*)user_data;
|
|
||||||
DirTreeModel* model = _this->model_;
|
|
||||||
|
|
||||||
for(GSList* l = files; l; l = l->next) {
|
|
||||||
FmFileInfo* fi = FM_FILE_INFO(l->data);
|
|
||||||
int pos;
|
|
||||||
DirTreeModelItem* child = _this->childFromName(fm_file_info_get_name(fi), &pos);
|
|
||||||
if(child) {
|
|
||||||
model->beginRemoveRows(_this->index(), pos, pos);
|
|
||||||
_this->children_.removeAt(pos);
|
|
||||||
delete child;
|
|
||||||
model->endRemoveRows();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// static
|
|
||||||
void DirTreeModelItem::onFolderFilesChanged(FmFolder* folder, GSList* files, gpointer user_data) {
|
|
||||||
DirTreeModelItem* _this = (DirTreeModelItem*)user_data;
|
|
||||||
DirTreeModel* model = _this->model_;
|
|
||||||
|
|
||||||
for(GSList* l = files; l; l = l->next) {
|
|
||||||
FmFileInfo* changedFile = FM_FILE_INFO(l->data);
|
|
||||||
int pos;
|
|
||||||
DirTreeModelItem* child = _this->childFromName(fm_file_info_get_name(changedFile), &pos);
|
|
||||||
if(child) {
|
|
||||||
QModelIndex childIndex = child->index();
|
|
||||||
Q_EMIT model->dataChanged(childIndex, childIndex);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
DirTreeModelItem* DirTreeModelItem::childFromName(const char* utf8_name, int* pos) {
|
|
||||||
int i = 0;
|
|
||||||
for (const auto item : children_) {
|
|
||||||
if(item->fileInfo_ && strcmp(fm_file_info_get_name(item->fileInfo_), utf8_name) == 0) {
|
|
||||||
if(pos)
|
|
||||||
*pos = i;
|
|
||||||
return item;
|
|
||||||
}
|
|
||||||
++i;
|
|
||||||
}
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
DirTreeModelItem* DirTreeModelItem::childFromPath(FmPath* path, bool recursive) const {
|
|
||||||
Q_ASSERT(path != nullptr);
|
|
||||||
|
|
||||||
Q_FOREACH(DirTreeModelItem* item, children_) {
|
|
||||||
// if(item->fileInfo_)
|
|
||||||
// qDebug() << "child: " << QString::fromUtf8(fm_file_info_get_disp_name(item->fileInfo_));
|
|
||||||
if(item->fileInfo_ && fm_path_equal(fm_file_info_get_path(item->fileInfo_), path)) {
|
|
||||||
return item;
|
|
||||||
} else if(recursive) {
|
|
||||||
DirTreeModelItem* child = item->childFromPath(path, true);
|
|
||||||
if(child)
|
|
||||||
return child;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
void DirTreeModelItem::setShowHidden(bool show) {
|
|
||||||
if(show) {
|
|
||||||
// move all hidden children to visible list
|
|
||||||
Q_FOREACH(DirTreeModelItem* item, hiddenChildren_) {
|
|
||||||
insertItem(item);
|
|
||||||
}
|
|
||||||
hiddenChildren_.clear();
|
|
||||||
}
|
|
||||||
else { // hide hidden folders
|
|
||||||
QModelIndex _index = index();
|
|
||||||
QList<DirTreeModelItem*>::iterator it, next;
|
|
||||||
int pos = 0;
|
|
||||||
for(it = children_.begin(); it != children_.end(); ++pos) {
|
|
||||||
DirTreeModelItem* item = *it;
|
|
||||||
next = it + 1;
|
|
||||||
if(item->fileInfo_) {
|
|
||||||
if(fm_file_info_is_hidden(item->fileInfo_)) { // hidden folder
|
|
||||||
// remove from the model and add to the hiddenChildren_ list
|
|
||||||
model_->beginRemoveRows(_index, pos, pos);
|
|
||||||
children_.erase(it);
|
|
||||||
hiddenChildren_.append(item);
|
|
||||||
model_->endRemoveRows();
|
|
||||||
}
|
|
||||||
else { // visible folder, recursively filter its children
|
|
||||||
item->setShowHidden(show);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
it = next;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
} // namespace Fm
|
|
||||||
|
|
||||||
@ -1,83 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (C) 2014 - 2015 Hong Jen Yee (PCMan) <pcman.tw@gmail.com>
|
|
||||||
*
|
|
||||||
* 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 FM_DIRTREEMODELITEM_H
|
|
||||||
#define FM_DIRTREEMODELITEM_H
|
|
||||||
|
|
||||||
#include "libfmqtglobals.h"
|
|
||||||
#include <libfm/fm.h>
|
|
||||||
#include <QIcon>
|
|
||||||
#include <QList>
|
|
||||||
#include <QModelIndex>
|
|
||||||
|
|
||||||
namespace Fm {
|
|
||||||
|
|
||||||
class DirTreeModel;
|
|
||||||
class DirTreeView;
|
|
||||||
|
|
||||||
class LIBFM_QT_API DirTreeModelItem {
|
|
||||||
public:
|
|
||||||
friend class DirTreeModel; // allow direct access of private members in DirTreeModel
|
|
||||||
friend class DirTreeView; // allow direct access of private members in DirTreeView
|
|
||||||
|
|
||||||
explicit DirTreeModelItem();
|
|
||||||
explicit DirTreeModelItem(FmFileInfo* info, DirTreeModel* model, DirTreeModelItem* parent = nullptr);
|
|
||||||
~DirTreeModelItem();
|
|
||||||
|
|
||||||
void loadFolder();
|
|
||||||
void unloadFolder();
|
|
||||||
|
|
||||||
inline bool isPlaceHolder() const {
|
|
||||||
return (fileInfo_ == nullptr);
|
|
||||||
}
|
|
||||||
|
|
||||||
void setShowHidden(bool show);
|
|
||||||
|
|
||||||
private:
|
|
||||||
void freeFolder();
|
|
||||||
void addPlaceHolderChild();
|
|
||||||
DirTreeModelItem* childFromName(const char* utf8_name, int* pos);
|
|
||||||
DirTreeModelItem* childFromPath(FmPath* path, bool recursive) const;
|
|
||||||
|
|
||||||
DirTreeModelItem* insertFileInfo(FmFileInfo* fi);
|
|
||||||
int insertItem(Fm::DirTreeModelItem* newItem);
|
|
||||||
QModelIndex index();
|
|
||||||
|
|
||||||
static void onFolderFinishLoading(FmFolder* folder, gpointer user_data);
|
|
||||||
static void onFolderFilesAdded(FmFolder* folder, GSList* files, gpointer user_data);
|
|
||||||
static void onFolderFilesRemoved(FmFolder* folder, GSList* files, gpointer user_data);
|
|
||||||
static void onFolderFilesChanged(FmFolder* folder, GSList* files, gpointer user_data);
|
|
||||||
|
|
||||||
private:
|
|
||||||
FmFileInfo* fileInfo_;
|
|
||||||
FmFolder* folder_;
|
|
||||||
QString displayName_ ;
|
|
||||||
QIcon icon_;
|
|
||||||
bool expanded_;
|
|
||||||
bool loaded_;
|
|
||||||
DirTreeModelItem* parent_;
|
|
||||||
DirTreeModelItem* placeHolderChild_;
|
|
||||||
QList<DirTreeModelItem*> children_;
|
|
||||||
QList<DirTreeModelItem*> hiddenChildren_;
|
|
||||||
DirTreeModel* model_;
|
|
||||||
};
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif // FM_DIRTREEMODELITEM_H
|
|
||||||
@ -1,298 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (C) 2014 - 2015 Hong Jen Yee (PCMan) <pcman.tw@gmail.com>
|
|
||||||
*
|
|
||||||
* 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 "dirtreeview.h"
|
|
||||||
#include <QHeaderView>
|
|
||||||
#include <QDebug>
|
|
||||||
#include <QItemSelection>
|
|
||||||
#include <QGuiApplication>
|
|
||||||
#include <QMouseEvent>
|
|
||||||
#include "dirtreemodel.h"
|
|
||||||
#include "dirtreemodelitem.h"
|
|
||||||
#include "filemenu.h"
|
|
||||||
|
|
||||||
namespace Fm {
|
|
||||||
|
|
||||||
DirTreeView::DirTreeView(QWidget* parent):
|
|
||||||
currentExpandingItem_(NULL),
|
|
||||||
currentPath_(NULL) {
|
|
||||||
|
|
||||||
setSelectionMode(QAbstractItemView::SingleSelection);
|
|
||||||
setHeaderHidden(true);
|
|
||||||
setHorizontalScrollBarPolicy(Qt::ScrollBarAsNeeded);
|
|
||||||
header()->setStretchLastSection(false);
|
|
||||||
|
|
||||||
connect(this, &DirTreeView::collapsed, this, &DirTreeView::onCollapsed);
|
|
||||||
connect(this, &DirTreeView::expanded, this, &DirTreeView::onExpanded);
|
|
||||||
|
|
||||||
setContextMenuPolicy(Qt::CustomContextMenu);
|
|
||||||
connect(this, &DirTreeView::customContextMenuRequested,
|
|
||||||
this, &DirTreeView::onCustomContextMenuRequested);
|
|
||||||
}
|
|
||||||
|
|
||||||
DirTreeView::~DirTreeView() {
|
|
||||||
if(currentPath_)
|
|
||||||
fm_path_unref(currentPath_);
|
|
||||||
}
|
|
||||||
|
|
||||||
void DirTreeView::cancelPendingChdir() {
|
|
||||||
if(!pathsToExpand_.isEmpty()) {
|
|
||||||
pathsToExpand_.clear();
|
|
||||||
if(!currentExpandingItem_)
|
|
||||||
return;
|
|
||||||
DirTreeModel* _model = static_cast<DirTreeModel*>(model());
|
|
||||||
disconnect(_model, &DirTreeModel::rowLoaded, this, &DirTreeView::onRowLoaded);
|
|
||||||
currentExpandingItem_ = NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void DirTreeView::expandPendingPath() {
|
|
||||||
if(pathsToExpand_.isEmpty())
|
|
||||||
return;
|
|
||||||
|
|
||||||
FmPath* path = pathsToExpand_.first().data();
|
|
||||||
// qDebug() << "expanding: " << Path(path).displayBasename();
|
|
||||||
DirTreeModel* _model = static_cast<DirTreeModel*>(model());
|
|
||||||
DirTreeModelItem* item = _model->itemFromPath(path);
|
|
||||||
// qDebug() << "findItem: " << item;
|
|
||||||
if(item) {
|
|
||||||
currentExpandingItem_ = item;
|
|
||||||
connect(_model, &DirTreeModel::rowLoaded, this, &DirTreeView::onRowLoaded);
|
|
||||||
if(item->loaded_) { // the node is already loaded
|
|
||||||
onRowLoaded(item->index());
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
// _model->loadRow(item->index());
|
|
||||||
item->loadFolder();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
selectionModel()->clear();
|
|
||||||
/* since we never get it loaded we need to update cwd here */
|
|
||||||
if(currentPath_)
|
|
||||||
fm_path_unref(currentPath_);
|
|
||||||
currentPath_ = fm_path_ref(path);
|
|
||||||
|
|
||||||
cancelPendingChdir(); // FIXME: is this correct? this is not done in the gtk+ version of libfm.
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void DirTreeView::onRowLoaded(const QModelIndex& index) {
|
|
||||||
DirTreeModel* _model = static_cast<DirTreeModel*>(model());
|
|
||||||
if(!currentExpandingItem_)
|
|
||||||
return;
|
|
||||||
if(currentExpandingItem_ != _model->itemFromIndex(index)) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
/* disconnect the handler since we only need it once */
|
|
||||||
disconnect(_model, &DirTreeModel::rowLoaded, this, &DirTreeView::onRowLoaded);
|
|
||||||
|
|
||||||
// DirTreeModelItem* item = _model->itemFromIndex(index);
|
|
||||||
// qDebug() << "row loaded: " << item->displayName_;
|
|
||||||
/* after the folder is loaded, the files should have been added to
|
|
||||||
* the tree model */
|
|
||||||
expand(index);
|
|
||||||
|
|
||||||
/* remove the expanded path from pending list */
|
|
||||||
pathsToExpand_.removeFirst();
|
|
||||||
if(pathsToExpand_.isEmpty()) { /* this is the last one and we're done, select the item */
|
|
||||||
// qDebug() << "Done!";
|
|
||||||
selectionModel()->select(index, QItemSelectionModel::SelectCurrent|QItemSelectionModel::Clear);
|
|
||||||
scrollTo(index, QAbstractItemView::EnsureVisible);
|
|
||||||
}
|
|
||||||
else { /* continue expanding next pending path */
|
|
||||||
expandPendingPath();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void DirTreeView::setCurrentPath(FmPath* path) {
|
|
||||||
DirTreeModel* _model = static_cast<DirTreeModel*>(model());
|
|
||||||
if(!_model)
|
|
||||||
return;
|
|
||||||
int rowCount = _model->rowCount(QModelIndex());
|
|
||||||
if(rowCount <= 0 || fm_path_equal(currentPath_, path))
|
|
||||||
return;
|
|
||||||
|
|
||||||
if(currentPath_)
|
|
||||||
fm_path_unref(currentPath_);
|
|
||||||
currentPath_ = fm_path_ref(path);
|
|
||||||
|
|
||||||
// NOTE: The content of each node is loaded on demand dynamically.
|
|
||||||
// So, when we ask for a chdir operation, some nodes do not exists yet.
|
|
||||||
// We have to wait for the loading of child nodes and continue the
|
|
||||||
// pending chdir operation after the child nodes become available.
|
|
||||||
|
|
||||||
// cancel previous pending tree expansion
|
|
||||||
cancelPendingChdir();
|
|
||||||
|
|
||||||
/* find a root item containing this path */
|
|
||||||
FmPath* root;
|
|
||||||
for(int row = 0; row < rowCount; ++row) {
|
|
||||||
QModelIndex index = _model->index(row, 0, QModelIndex());
|
|
||||||
root = _model->filePath(index);
|
|
||||||
if(fm_path_has_prefix(path, root))
|
|
||||||
break;
|
|
||||||
root = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(root) { /* root item is found */
|
|
||||||
do { /* add path elements one by one to a list */
|
|
||||||
pathsToExpand_.prepend(path);
|
|
||||||
// qDebug() << "prepend path: " << Path(path).displayBasename();
|
|
||||||
if(fm_path_equal(path, root))
|
|
||||||
break;
|
|
||||||
path = fm_path_get_parent(path);
|
|
||||||
}
|
|
||||||
while(path);
|
|
||||||
|
|
||||||
expandPendingPath();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void DirTreeView::setModel(QAbstractItemModel* model) {
|
|
||||||
Q_ASSERT(model->inherits("Fm::DirTreeModel"));
|
|
||||||
|
|
||||||
if(!pathsToExpand_.isEmpty()) // if a chdir request is in progress, cancel it
|
|
||||||
cancelPendingChdir();
|
|
||||||
|
|
||||||
QTreeView::setModel(model);
|
|
||||||
header()->setSectionResizeMode(0, QHeaderView::ResizeToContents);
|
|
||||||
connect(selectionModel(), &QItemSelectionModel::selectionChanged, this, &DirTreeView::onSelectionChanged);
|
|
||||||
}
|
|
||||||
|
|
||||||
void DirTreeView::mousePressEvent(QMouseEvent* event) {
|
|
||||||
if(event && event->button() == Qt::RightButton &&
|
|
||||||
event->type() == QEvent::MouseButtonPress) {
|
|
||||||
// Do not change the selection when the context menu is activated.
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
QTreeView::mousePressEvent(event);
|
|
||||||
}
|
|
||||||
|
|
||||||
void DirTreeView::onCustomContextMenuRequested(const QPoint& pos) {
|
|
||||||
QModelIndex index = indexAt(pos);
|
|
||||||
if(index.isValid()) {
|
|
||||||
QVariant data = index.data(DirTreeModel::FileInfoRole);
|
|
||||||
FmFileInfo* fileInfo = reinterpret_cast<FmFileInfo*>(data.value<void*>());
|
|
||||||
if(fileInfo) {
|
|
||||||
FmPath* path = fm_file_info_get_path(fileInfo);
|
|
||||||
FmFileInfoList* files = fm_file_info_list_new();
|
|
||||||
fm_file_info_list_push_tail(files, fileInfo);
|
|
||||||
Fm::FileMenu* menu = new Fm::FileMenu(files, fileInfo, path);
|
|
||||||
// FIXME: apply some settings to the menu and set a proper file launcher to it
|
|
||||||
Q_EMIT prepareFileMenu(menu);
|
|
||||||
fm_file_info_list_unref(files);
|
|
||||||
QVariant pathData = qVariantFromValue(reinterpret_cast<void*>(path));
|
|
||||||
QAction* action = menu->openAction();
|
|
||||||
action->disconnect();
|
|
||||||
action->setData(index);
|
|
||||||
connect(action, &QAction::triggered, this, &DirTreeView::onOpen);
|
|
||||||
action = new QAction(QIcon::fromTheme("window-new"), tr("Open in New T&ab"), menu);
|
|
||||||
action->setData(pathData);
|
|
||||||
connect(action, &QAction::triggered, this, &DirTreeView::onNewTab);
|
|
||||||
menu->insertAction(menu->separator1(), action);
|
|
||||||
action = new QAction(QIcon::fromTheme("window-new"), tr("Open in New Win&dow"), menu);
|
|
||||||
action->setData(pathData);
|
|
||||||
connect(action, &QAction::triggered, this, &DirTreeView::onNewWindow);
|
|
||||||
menu->insertAction(menu->separator1(), action);
|
|
||||||
if(fm_file_info_is_native(fileInfo)) {
|
|
||||||
action = new QAction(QIcon::fromTheme("utilities-terminal"), tr("Open in Termina&l"), menu);
|
|
||||||
action->setData(pathData);
|
|
||||||
connect(action, &QAction::triggered, this, &DirTreeView::onOpenInTerminal);
|
|
||||||
menu->insertAction(menu->separator1(), action);
|
|
||||||
}
|
|
||||||
menu->exec(mapToGlobal(pos));
|
|
||||||
delete menu;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void DirTreeView::onOpen() {
|
|
||||||
if(QAction* action = qobject_cast<QAction*>(sender())) {
|
|
||||||
setCurrentIndex(action->data().toModelIndex());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void DirTreeView::onNewWindow() {
|
|
||||||
if(QAction* action = qobject_cast<QAction*>(sender())) {
|
|
||||||
FmPath* path = reinterpret_cast<FmPath*>(action->data().value<void*>());
|
|
||||||
Q_EMIT openFolderInNewWindowRequested(path);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void DirTreeView::onNewTab() {
|
|
||||||
if(QAction* action = qobject_cast<QAction*>(sender())) {
|
|
||||||
FmPath* path = reinterpret_cast<FmPath*>(action->data().value<void*>());
|
|
||||||
Q_EMIT openFolderInNewTabRequested(path);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void DirTreeView::onOpenInTerminal() {
|
|
||||||
if(QAction* action = qobject_cast<QAction*>(sender())) {
|
|
||||||
FmPath* path = reinterpret_cast<FmPath*>(action->data().value<void*>());
|
|
||||||
Q_EMIT openFolderInTerminalRequested(path);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void DirTreeView::onNewFolder() {
|
|
||||||
if(QAction* action = qobject_cast<QAction*>(sender())) {
|
|
||||||
FmPath* path = reinterpret_cast<FmPath*>(action->data().value<void*>());
|
|
||||||
Q_EMIT createNewFolderRequested(path);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void DirTreeView::onCollapsed(const QModelIndex& index) {
|
|
||||||
DirTreeModel* treeModel = static_cast<DirTreeModel*>(model());
|
|
||||||
if(treeModel) {
|
|
||||||
treeModel->unloadRow(index);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void DirTreeView::onExpanded(const QModelIndex& index) {
|
|
||||||
DirTreeModel* treeModel = static_cast<DirTreeModel*>(model());
|
|
||||||
if(treeModel) {
|
|
||||||
treeModel->loadRow(index);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void DirTreeView::onSelectionChanged(const QItemSelection & selected, const QItemSelection & deselected) {
|
|
||||||
if(!selected.isEmpty()) {
|
|
||||||
QModelIndex index = selected.first().topLeft();
|
|
||||||
DirTreeModel* _model = static_cast<DirTreeModel*>(model());
|
|
||||||
FmPath* path = _model->filePath(index);
|
|
||||||
if(path && currentPath_ && fm_path_equal(path, currentPath_))
|
|
||||||
return;
|
|
||||||
cancelPendingChdir();
|
|
||||||
if(!path)
|
|
||||||
return;
|
|
||||||
if(currentPath_)
|
|
||||||
fm_path_unref(currentPath_);
|
|
||||||
currentPath_ = fm_path_ref(path);
|
|
||||||
|
|
||||||
// FIXME: use enums for type rather than hard-coded values 0 or 1
|
|
||||||
int type = 0;
|
|
||||||
if(QGuiApplication::mouseButtons() & Qt::MiddleButton)
|
|
||||||
type = 1;
|
|
||||||
Q_EMIT chdirRequested(type, path);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
} // namespace Fm
|
|
||||||
@ -1,94 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (C) 2014 - 2015 Hong Jen Yee (PCMan) <pcman.tw@gmail.com>
|
|
||||||
*
|
|
||||||
* 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 FM_DIRTREEVIEW_H
|
|
||||||
#define FM_DIRTREEVIEW_H
|
|
||||||
|
|
||||||
#include "libfmqtglobals.h"
|
|
||||||
#include <QTreeView>
|
|
||||||
#include <libfm/fm.h>
|
|
||||||
#include "path.h"
|
|
||||||
|
|
||||||
class QItemSelection;
|
|
||||||
|
|
||||||
namespace Fm {
|
|
||||||
|
|
||||||
class FileMenu;
|
|
||||||
class DirTreeModelItem;
|
|
||||||
|
|
||||||
class LIBFM_QT_API DirTreeView : public QTreeView {
|
|
||||||
Q_OBJECT
|
|
||||||
|
|
||||||
public:
|
|
||||||
DirTreeView(QWidget* parent);
|
|
||||||
~DirTreeView();
|
|
||||||
|
|
||||||
FmPath* currentPath() {
|
|
||||||
return currentPath_;
|
|
||||||
}
|
|
||||||
|
|
||||||
void setCurrentPath(FmPath* path);
|
|
||||||
|
|
||||||
// libfm-gtk compatible alias
|
|
||||||
FmPath* getCwd() {
|
|
||||||
return currentPath();
|
|
||||||
}
|
|
||||||
|
|
||||||
void chdir(FmPath* path) {
|
|
||||||
setCurrentPath(path);
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual void setModel(QAbstractItemModel* model);
|
|
||||||
|
|
||||||
protected:
|
|
||||||
virtual void mousePressEvent(QMouseEvent* event);
|
|
||||||
|
|
||||||
private:
|
|
||||||
void cancelPendingChdir();
|
|
||||||
void expandPendingPath();
|
|
||||||
|
|
||||||
Q_SIGNALS:
|
|
||||||
void chdirRequested(int type, FmPath* path);
|
|
||||||
void openFolderInNewWindowRequested(FmPath* path);
|
|
||||||
void openFolderInNewTabRequested(FmPath* path);
|
|
||||||
void openFolderInTerminalRequested(FmPath* path);
|
|
||||||
void createNewFolderRequested(FmPath* path);
|
|
||||||
void prepareFileMenu(Fm::FileMenu* menu); // emit before showing a Fm::FileMenu
|
|
||||||
|
|
||||||
protected Q_SLOTS:
|
|
||||||
void onCollapsed(const QModelIndex & index);
|
|
||||||
void onExpanded(const QModelIndex & index);
|
|
||||||
void onRowLoaded(const QModelIndex& index);
|
|
||||||
void onSelectionChanged(const QItemSelection & selected, const QItemSelection & deselected);
|
|
||||||
void onCustomContextMenuRequested(const QPoint& pos);
|
|
||||||
void onOpen();
|
|
||||||
void onNewWindow();
|
|
||||||
void onNewTab();
|
|
||||||
void onOpenInTerminal();
|
|
||||||
void onNewFolder();
|
|
||||||
|
|
||||||
private:
|
|
||||||
FmPath* currentPath_;
|
|
||||||
QList<Path> pathsToExpand_;
|
|
||||||
DirTreeModelItem* currentExpandingItem_;
|
|
||||||
};
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif // FM_DIRTREEVIEW_H
|
|
||||||
@ -1,63 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (C) 2013 - 2015 Hong Jen Yee (PCMan) <pcman.tw@gmail.com>
|
|
||||||
*
|
|
||||||
* 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 "dndactionmenu.h"
|
|
||||||
|
|
||||||
namespace Fm {
|
|
||||||
|
|
||||||
DndActionMenu::DndActionMenu(Qt::DropActions possibleActions, QWidget* parent)
|
|
||||||
: QMenu(parent)
|
|
||||||
, copyAction(nullptr)
|
|
||||||
, moveAction(nullptr)
|
|
||||||
, linkAction(nullptr)
|
|
||||||
, cancelAction(nullptr)
|
|
||||||
{
|
|
||||||
if (possibleActions.testFlag(Qt::CopyAction))
|
|
||||||
copyAction = addAction(QIcon::fromTheme("edit-copy"), tr("Copy here"));
|
|
||||||
if (possibleActions.testFlag(Qt::MoveAction))
|
|
||||||
moveAction = addAction(tr("Move here"));
|
|
||||||
if (possibleActions.testFlag(Qt::LinkAction))
|
|
||||||
linkAction = addAction(tr("Create symlink here"));
|
|
||||||
addSeparator();
|
|
||||||
cancelAction = addAction(tr("Cancel"));
|
|
||||||
}
|
|
||||||
|
|
||||||
DndActionMenu::~DndActionMenu() {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
Qt::DropAction DndActionMenu::askUser(Qt::DropActions possibleActions, QPoint pos) {
|
|
||||||
Qt::DropAction result = Qt::IgnoreAction;
|
|
||||||
DndActionMenu menu{possibleActions};
|
|
||||||
QAction* action = menu.exec(pos);
|
|
||||||
if (nullptr != action)
|
|
||||||
{
|
|
||||||
if(action == menu.copyAction)
|
|
||||||
result = Qt::CopyAction;
|
|
||||||
else if(action == menu.moveAction)
|
|
||||||
result = Qt::MoveAction;
|
|
||||||
else if(action == menu.linkAction)
|
|
||||||
result = Qt::LinkAction;
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
} // namespace Fm
|
|
||||||
@ -1,47 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (C) 2013 - 2015 Hong Jen Yee (PCMan) <pcman.tw@gmail.com>
|
|
||||||
*
|
|
||||||
* 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 FM_DNDACTIONMENU_H
|
|
||||||
#define FM_DNDACTIONMENU_H
|
|
||||||
|
|
||||||
#include "libfmqtglobals.h"
|
|
||||||
#include <QMenu>
|
|
||||||
#include <QAction>
|
|
||||||
|
|
||||||
namespace Fm {
|
|
||||||
|
|
||||||
class DndActionMenu : public QMenu {
|
|
||||||
Q_OBJECT
|
|
||||||
public:
|
|
||||||
explicit DndActionMenu(Qt::DropActions possibleActions, QWidget* parent = 0);
|
|
||||||
virtual ~DndActionMenu();
|
|
||||||
|
|
||||||
static Qt::DropAction askUser(Qt::DropActions possibleActions, QPoint pos);
|
|
||||||
|
|
||||||
private:
|
|
||||||
QAction* copyAction;
|
|
||||||
QAction* moveAction;
|
|
||||||
QAction* linkAction;
|
|
||||||
QAction* cancelAction;
|
|
||||||
};
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif // FM_DNDACTIONMENU_H
|
|
||||||
@ -1,73 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (C) 2012 - 2015 Hong Jen Yee (PCMan) <pcman.tw@gmail.com>
|
|
||||||
*
|
|
||||||
* 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 "dnddest.h"
|
|
||||||
#include "fileoperation.h"
|
|
||||||
#include "utilities.h"
|
|
||||||
|
|
||||||
namespace Fm {
|
|
||||||
|
|
||||||
const char* supportedMimeTypes[] = {
|
|
||||||
"text/uri-list"
|
|
||||||
"XdndDirectSave0"/* X direct save */
|
|
||||||
/* TODO: add more targets to support: text types, _NETSCAPE_URL, property/bgimage ... */
|
|
||||||
};
|
|
||||||
|
|
||||||
DndDest::DndDest() {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
DndDest::~DndDest() {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
bool DndDest::dropMimeData(const QMimeData* data, Qt::DropAction action) {
|
|
||||||
// FIXME: should we put this in dropEvent handler of FolderView instead?
|
|
||||||
if(data->hasUrls()) {
|
|
||||||
qDebug("drop action: %d", action);
|
|
||||||
FmPathList* srcPaths = pathListFromQUrls(data->urls());
|
|
||||||
switch(action) {
|
|
||||||
case Qt::CopyAction:
|
|
||||||
FileOperation::copyFiles(srcPaths, destPath_.data());
|
|
||||||
break;
|
|
||||||
case Qt::MoveAction:
|
|
||||||
FileOperation::moveFiles(srcPaths, destPath_.data());
|
|
||||||
break;
|
|
||||||
case Qt::LinkAction:
|
|
||||||
FileOperation::symlinkFiles(srcPaths, destPath_.data());
|
|
||||||
default:
|
|
||||||
fm_path_list_unref(srcPaths);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
fm_path_list_unref(srcPaths);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool DndDest::isSupported(const QMimeData* data) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool DndDest::isSupported(QString mimeType) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
} // namespace Fm
|
|
||||||
@ -1,52 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (C) 2012 - 2015 Hong Jen Yee (PCMan) <pcman.tw@gmail.com>
|
|
||||||
*
|
|
||||||
* 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 FM_DNDDEST_H
|
|
||||||
#define FM_DNDDEST_H
|
|
||||||
|
|
||||||
#include <QMimeData>
|
|
||||||
#include "path.h"
|
|
||||||
|
|
||||||
namespace Fm {
|
|
||||||
|
|
||||||
class DndDest {
|
|
||||||
public:
|
|
||||||
DndDest();
|
|
||||||
~DndDest();
|
|
||||||
|
|
||||||
void setDestPath(FmPath* dest) {
|
|
||||||
destPath_ = dest;
|
|
||||||
}
|
|
||||||
|
|
||||||
const Path& destPath() {
|
|
||||||
return destPath_;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool isSupported(const QMimeData* data);
|
|
||||||
bool isSupported(QString mimeType);
|
|
||||||
|
|
||||||
bool dropMimeData(const QMimeData* data, Qt::DropAction action);
|
|
||||||
|
|
||||||
private:
|
|
||||||
Path destPath_;
|
|
||||||
};
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif // FM_DNDDEST_H
|
|
||||||
@ -1,143 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<ui version="4.0">
|
|
||||||
<class>EditBookmarksDialog</class>
|
|
||||||
<widget class="QDialog" name="EditBookmarksDialog">
|
|
||||||
<property name="geometry">
|
|
||||||
<rect>
|
|
||||||
<x>0</x>
|
|
||||||
<y>0</y>
|
|
||||||
<width>480</width>
|
|
||||||
<height>320</height>
|
|
||||||
</rect>
|
|
||||||
</property>
|
|
||||||
<property name="windowTitle">
|
|
||||||
<string>Edit Bookmarks</string>
|
|
||||||
</property>
|
|
||||||
<layout class="QGridLayout" name="gridLayout">
|
|
||||||
<item row="1" column="0">
|
|
||||||
<widget class="QTreeWidget" name="treeWidget">
|
|
||||||
<property name="acceptDrops">
|
|
||||||
<bool>true</bool>
|
|
||||||
</property>
|
|
||||||
<property name="dragEnabled">
|
|
||||||
<bool>true</bool>
|
|
||||||
</property>
|
|
||||||
<property name="dragDropMode">
|
|
||||||
<enum>QAbstractItemView::InternalMove</enum>
|
|
||||||
</property>
|
|
||||||
<property name="defaultDropAction">
|
|
||||||
<enum>Qt::MoveAction</enum>
|
|
||||||
</property>
|
|
||||||
<property name="rootIsDecorated">
|
|
||||||
<bool>false</bool>
|
|
||||||
</property>
|
|
||||||
<property name="itemsExpandable">
|
|
||||||
<bool>false</bool>
|
|
||||||
</property>
|
|
||||||
<attribute name="headerDefaultSectionSize">
|
|
||||||
<number>100</number>
|
|
||||||
</attribute>
|
|
||||||
<column>
|
|
||||||
<property name="text">
|
|
||||||
<string>Name</string>
|
|
||||||
</property>
|
|
||||||
</column>
|
|
||||||
<column>
|
|
||||||
<property name="text">
|
|
||||||
<string>Location</string>
|
|
||||||
</property>
|
|
||||||
</column>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="2" 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>
|
|
||||||
<item row="1" column="1">
|
|
||||||
<layout class="QVBoxLayout" name="verticalLayout">
|
|
||||||
<item>
|
|
||||||
<widget class="QPushButton" name="addItem">
|
|
||||||
<property name="text">
|
|
||||||
<string>&Add Item</string>
|
|
||||||
</property>
|
|
||||||
<property name="icon">
|
|
||||||
<iconset theme="list-add"/>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<widget class="QPushButton" name="removeItem">
|
|
||||||
<property name="text">
|
|
||||||
<string>&Remove Item</string>
|
|
||||||
</property>
|
|
||||||
<property name="icon">
|
|
||||||
<iconset theme="list-remove"/>
|
|
||||||
</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>
|
|
||||||
<item row="0" column="0">
|
|
||||||
<widget class="QLabel" name="label">
|
|
||||||
<property name="text">
|
|
||||||
<string>Use drag and drop to reorder the items</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
</layout>
|
|
||||||
</widget>
|
|
||||||
<resources/>
|
|
||||||
<connections>
|
|
||||||
<connection>
|
|
||||||
<sender>buttonBox</sender>
|
|
||||||
<signal>accepted()</signal>
|
|
||||||
<receiver>EditBookmarksDialog</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>EditBookmarksDialog</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>
|
|
||||||
@ -1,110 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (C) 2013 - 2015 Hong Jen Yee (PCMan) <pcman.tw@gmail.com>
|
|
||||||
*
|
|
||||||
* 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 "editbookmarksdialog.h"
|
|
||||||
#include "ui_edit-bookmarks.h"
|
|
||||||
#include <QByteArray>
|
|
||||||
#include <QUrl>
|
|
||||||
#include <QSaveFile>
|
|
||||||
#include <QStandardPaths>
|
|
||||||
#include <QDir>
|
|
||||||
|
|
||||||
namespace Fm {
|
|
||||||
|
|
||||||
EditBookmarksDialog::EditBookmarksDialog(FmBookmarks* bookmarks, QWidget* parent, Qt::WindowFlags f):
|
|
||||||
QDialog(parent, f),
|
|
||||||
ui(new Ui::EditBookmarksDialog()),
|
|
||||||
bookmarks_(FM_BOOKMARKS(g_object_ref(bookmarks))) {
|
|
||||||
|
|
||||||
ui->setupUi(this);
|
|
||||||
setAttribute(Qt::WA_DeleteOnClose); // auto delete on close
|
|
||||||
|
|
||||||
// load bookmarks
|
|
||||||
GList* allBookmarks = fm_bookmarks_get_all(bookmarks_);
|
|
||||||
for(GList* l = allBookmarks; l; l = l->next) {
|
|
||||||
FmBookmarkItem* bookmark = reinterpret_cast<FmBookmarkItem*>(l->data);
|
|
||||||
QTreeWidgetItem* item = new QTreeWidgetItem();
|
|
||||||
char* path_str = fm_path_display_name(bookmark->path, false);
|
|
||||||
item->setData(0, Qt::DisplayRole, QString::fromUtf8(bookmark->name));
|
|
||||||
item->setData(1, Qt::DisplayRole, QString::fromUtf8(path_str));
|
|
||||||
item->setFlags(Qt::ItemIsSelectable|Qt::ItemIsEditable|Qt::ItemIsDragEnabled|Qt::ItemIsEnabled);
|
|
||||||
g_free(path_str);
|
|
||||||
ui->treeWidget->addTopLevelItem(item);
|
|
||||||
}
|
|
||||||
g_list_free_full(allBookmarks, (GDestroyNotify)fm_bookmark_item_unref);
|
|
||||||
|
|
||||||
connect(ui->addItem, &QPushButton::clicked, this, &EditBookmarksDialog::onAddItem);
|
|
||||||
connect(ui->removeItem, &QPushButton::clicked, this, &EditBookmarksDialog::onRemoveItem);
|
|
||||||
}
|
|
||||||
|
|
||||||
EditBookmarksDialog::~EditBookmarksDialog() {
|
|
||||||
g_object_unref(bookmarks_);
|
|
||||||
delete ui;
|
|
||||||
}
|
|
||||||
|
|
||||||
void EditBookmarksDialog::accept() {
|
|
||||||
// save bookmarks
|
|
||||||
// it's easier to recreate the whole bookmark file than
|
|
||||||
// to manipulate FmBookmarks object. So here we generate the file directly.
|
|
||||||
// FIXME: maybe in the future we should add a libfm API to easily replace all FmBookmarks.
|
|
||||||
// Here we use gtk+ 3.0 bookmarks rather than the gtk+ 2.0 one.
|
|
||||||
// Since gtk+ 2.24.12, gtk+2 reads gtk+3 bookmarks file if it exists.
|
|
||||||
// So it's safe to only save gtk+3 bookmarks file.
|
|
||||||
QString path = QStandardPaths::writableLocation(QStandardPaths::ConfigLocation);
|
|
||||||
path += QLatin1String("/gtk-3.0");
|
|
||||||
if(!QDir().mkpath(path))
|
|
||||||
return; // fail to create ~/.config/gtk-3.0 dir
|
|
||||||
path += QLatin1String("/bookmarks");
|
|
||||||
QSaveFile file(path); // use QSaveFile for atomic file operation
|
|
||||||
if(file.open(QIODevice::WriteOnly)){
|
|
||||||
for(int row = 0; ; ++row) {
|
|
||||||
QTreeWidgetItem* item = ui->treeWidget->topLevelItem(row);
|
|
||||||
if(!item)
|
|
||||||
break;
|
|
||||||
QString name = item->data(0, Qt::DisplayRole).toString();
|
|
||||||
QUrl url = QUrl::fromUserInput(item->data(1, Qt::DisplayRole).toString());
|
|
||||||
file.write(url.toEncoded());
|
|
||||||
file.write(" ");
|
|
||||||
file.write(name.toUtf8());
|
|
||||||
file.write("\n");
|
|
||||||
}
|
|
||||||
// FIXME: should we support Qt or KDE specific bookmarks in the future?
|
|
||||||
file.commit();
|
|
||||||
}
|
|
||||||
QDialog::accept();
|
|
||||||
}
|
|
||||||
|
|
||||||
void EditBookmarksDialog::onAddItem() {
|
|
||||||
QTreeWidgetItem* item = new QTreeWidgetItem();
|
|
||||||
item->setData(0, Qt::DisplayRole, tr("New bookmark"));
|
|
||||||
item->setFlags(Qt::ItemIsSelectable|Qt::ItemIsEditable|Qt::ItemIsDragEnabled|Qt::ItemIsEnabled);
|
|
||||||
ui->treeWidget->addTopLevelItem(item);
|
|
||||||
ui->treeWidget->editItem(item);
|
|
||||||
}
|
|
||||||
|
|
||||||
void EditBookmarksDialog::onRemoveItem() {
|
|
||||||
QList<QTreeWidgetItem*> sels = ui->treeWidget->selectedItems();
|
|
||||||
Q_FOREACH(QTreeWidgetItem* item, sels) {
|
|
||||||
delete item;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
} // namespace Fm
|
|
||||||
@ -1,53 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (C) 2013 - 2015 Hong Jen Yee (PCMan) <pcman.tw@gmail.com>
|
|
||||||
*
|
|
||||||
* 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 FM_EDITBOOKMARKSDIALOG_H
|
|
||||||
#define FM_EDITBOOKMARKSDIALOG_H
|
|
||||||
|
|
||||||
#include "libfmqtglobals.h"
|
|
||||||
#include <QDialog>
|
|
||||||
#include <libfm/fm.h>
|
|
||||||
|
|
||||||
namespace Ui {
|
|
||||||
class EditBookmarksDialog;
|
|
||||||
};
|
|
||||||
|
|
||||||
namespace Fm {
|
|
||||||
|
|
||||||
class LIBFM_QT_API EditBookmarksDialog : public QDialog {
|
|
||||||
Q_OBJECT
|
|
||||||
public:
|
|
||||||
explicit EditBookmarksDialog(FmBookmarks* bookmarks, QWidget* parent = 0, Qt::WindowFlags f = 0);
|
|
||||||
virtual ~EditBookmarksDialog();
|
|
||||||
|
|
||||||
virtual void accept();
|
|
||||||
|
|
||||||
private Q_SLOTS:
|
|
||||||
void onAddItem();
|
|
||||||
void onRemoveItem();
|
|
||||||
|
|
||||||
private:
|
|
||||||
Ui::EditBookmarksDialog* ui;
|
|
||||||
FmBookmarks* bookmarks_;
|
|
||||||
};
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif // FM_EDITBOOKMARKSDIALOG_H
|
|
||||||
163
src/exec-file.ui
163
src/exec-file.ui
@ -1,163 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<ui version="4.0">
|
|
||||||
<class>ExecFileDialog</class>
|
|
||||||
<widget class="QDialog" name="ExecFileDialog">
|
|
||||||
<property name="geometry">
|
|
||||||
<rect>
|
|
||||||
<x>0</x>
|
|
||||||
<y>0</y>
|
|
||||||
<width>487</width>
|
|
||||||
<height>58</height>
|
|
||||||
</rect>
|
|
||||||
</property>
|
|
||||||
<property name="windowTitle">
|
|
||||||
<string>Execute file</string>
|
|
||||||
</property>
|
|
||||||
<layout class="QVBoxLayout" name="verticalLayout">
|
|
||||||
<item>
|
|
||||||
<layout class="QHBoxLayout" name="horizontalLayout_2" stretch="0,1">
|
|
||||||
<item>
|
|
||||||
<widget class="QLabel" name="icon"/>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<widget class="QLabel" name="msg">
|
|
||||||
<property name="text">
|
|
||||||
<string/>
|
|
||||||
</property>
|
|
||||||
<property name="wordWrap">
|
|
||||||
<bool>true</bool>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
</layout>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<layout class="QHBoxLayout" name="horizontalLayout">
|
|
||||||
<item>
|
|
||||||
<widget class="QPushButton" name="open">
|
|
||||||
<property name="text">
|
|
||||||
<string>&Open</string>
|
|
||||||
</property>
|
|
||||||
<property name="icon">
|
|
||||||
<iconset theme="document-open"/>
|
|
||||||
</property>
|
|
||||||
<property name="default">
|
|
||||||
<bool>true</bool>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<widget class="QPushButton" name="exec">
|
|
||||||
<property name="text">
|
|
||||||
<string>E&xecute</string>
|
|
||||||
</property>
|
|
||||||
<property name="icon">
|
|
||||||
<iconset theme="system-run"/>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<widget class="QPushButton" name="execTerm">
|
|
||||||
<property name="text">
|
|
||||||
<string>Execute in &Terminal</string>
|
|
||||||
</property>
|
|
||||||
<property name="icon">
|
|
||||||
<iconset theme="utilities-terminal"/>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<spacer name="horizontalSpacer">
|
|
||||||
<property name="orientation">
|
|
||||||
<enum>Qt::Horizontal</enum>
|
|
||||||
</property>
|
|
||||||
<property name="sizeHint" stdset="0">
|
|
||||||
<size>
|
|
||||||
<width>40</width>
|
|
||||||
<height>20</height>
|
|
||||||
</size>
|
|
||||||
</property>
|
|
||||||
</spacer>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<widget class="QPushButton" name="cancel">
|
|
||||||
<property name="text">
|
|
||||||
<string>Cancel</string>
|
|
||||||
</property>
|
|
||||||
<property name="icon">
|
|
||||||
<iconset theme="dialog-cancel"/>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
</layout>
|
|
||||||
</item>
|
|
||||||
</layout>
|
|
||||||
</widget>
|
|
||||||
<resources/>
|
|
||||||
<connections>
|
|
||||||
<connection>
|
|
||||||
<sender>cancel</sender>
|
|
||||||
<signal>clicked()</signal>
|
|
||||||
<receiver>ExecFileDialog</receiver>
|
|
||||||
<slot>reject()</slot>
|
|
||||||
<hints>
|
|
||||||
<hint type="sourcelabel">
|
|
||||||
<x>341</x>
|
|
||||||
<y>39</y>
|
|
||||||
</hint>
|
|
||||||
<hint type="destinationlabel">
|
|
||||||
<x>196</x>
|
|
||||||
<y>28</y>
|
|
||||||
</hint>
|
|
||||||
</hints>
|
|
||||||
</connection>
|
|
||||||
<connection>
|
|
||||||
<sender>exec</sender>
|
|
||||||
<signal>clicked()</signal>
|
|
||||||
<receiver>ExecFileDialog</receiver>
|
|
||||||
<slot>accept()</slot>
|
|
||||||
<hints>
|
|
||||||
<hint type="sourcelabel">
|
|
||||||
<x>56</x>
|
|
||||||
<y>39</y>
|
|
||||||
</hint>
|
|
||||||
<hint type="destinationlabel">
|
|
||||||
<x>196</x>
|
|
||||||
<y>28</y>
|
|
||||||
</hint>
|
|
||||||
</hints>
|
|
||||||
</connection>
|
|
||||||
<connection>
|
|
||||||
<sender>execTerm</sender>
|
|
||||||
<signal>clicked()</signal>
|
|
||||||
<receiver>ExecFileDialog</receiver>
|
|
||||||
<slot>accept()</slot>
|
|
||||||
<hints>
|
|
||||||
<hint type="sourcelabel">
|
|
||||||
<x>201</x>
|
|
||||||
<y>39</y>
|
|
||||||
</hint>
|
|
||||||
<hint type="destinationlabel">
|
|
||||||
<x>196</x>
|
|
||||||
<y>28</y>
|
|
||||||
</hint>
|
|
||||||
</hints>
|
|
||||||
</connection>
|
|
||||||
<connection>
|
|
||||||
<sender>open</sender>
|
|
||||||
<signal>clicked()</signal>
|
|
||||||
<receiver>ExecFileDialog</receiver>
|
|
||||||
<slot>accept()</slot>
|
|
||||||
<hints>
|
|
||||||
<hint type="sourcelabel">
|
|
||||||
<x>346</x>
|
|
||||||
<y>39</y>
|
|
||||||
</hint>
|
|
||||||
<hint type="destinationlabel">
|
|
||||||
<x>250</x>
|
|
||||||
<y>28</y>
|
|
||||||
</hint>
|
|
||||||
</hints>
|
|
||||||
</connection>
|
|
||||||
</connections>
|
|
||||||
</ui>
|
|
||||||
@ -1,69 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (C) 2014 - 2015 Hong Jen Yee (PCMan) <pcman.tw@gmail.com>
|
|
||||||
*
|
|
||||||
* 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 "execfiledialog_p.h"
|
|
||||||
#include "ui_exec-file.h"
|
|
||||||
#include "icontheme.h"
|
|
||||||
|
|
||||||
namespace Fm {
|
|
||||||
|
|
||||||
ExecFileDialog::ExecFileDialog(FmFileInfo* file, QWidget* parent, Qt::WindowFlags f):
|
|
||||||
QDialog (parent, f),
|
|
||||||
fileInfo_(fm_file_info_ref(file)),
|
|
||||||
result_(FM_FILE_LAUNCHER_EXEC_CANCEL),
|
|
||||||
ui(new Ui::ExecFileDialog()) {
|
|
||||||
|
|
||||||
ui->setupUi(this);
|
|
||||||
// show file icon
|
|
||||||
FmIcon* icon = fm_file_info_get_icon(fileInfo_);
|
|
||||||
ui->icon->setPixmap(IconTheme::icon(icon).pixmap(QSize(48, 48)));
|
|
||||||
|
|
||||||
QString msg;
|
|
||||||
if(fm_file_info_is_text(file)) {
|
|
||||||
msg = tr("This text file '%1' seems to be an executable script.\nWhat do you want to do with it?")
|
|
||||||
.arg(QString::fromUtf8(fm_file_info_get_disp_name(file)));
|
|
||||||
ui->execTerm->setDefault(true);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
msg= tr("This file '%1' is executable. Do you want to execute it?")
|
|
||||||
.arg(QString::fromUtf8(fm_file_info_get_disp_name(file)));
|
|
||||||
ui->exec->setDefault(true);
|
|
||||||
ui->open->hide();
|
|
||||||
}
|
|
||||||
ui->msg->setText(msg);
|
|
||||||
}
|
|
||||||
|
|
||||||
ExecFileDialog::~ExecFileDialog() {
|
|
||||||
delete ui;
|
|
||||||
if(fileInfo_)
|
|
||||||
fm_file_info_unref(fileInfo_);
|
|
||||||
}
|
|
||||||
|
|
||||||
void ExecFileDialog::accept() {
|
|
||||||
QObject* _sender = sender();
|
|
||||||
if(_sender == ui->exec)
|
|
||||||
result_ = FM_FILE_LAUNCHER_EXEC;
|
|
||||||
else if(_sender == ui->execTerm)
|
|
||||||
result_ = FM_FILE_LAUNCHER_EXEC_IN_TERMINAL;
|
|
||||||
else if(_sender == ui->open)
|
|
||||||
result_ = FM_FILE_LAUNCHER_EXEC_OPEN;
|
|
||||||
QDialog::accept();
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace Fm
|
|
||||||
@ -1,53 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (C) 2014 - 2015 Hong Jen Yee (PCMan) <pcman.tw@gmail.com>
|
|
||||||
*
|
|
||||||
* 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 FM_EXECFILEDIALOG_H
|
|
||||||
#define FM_EXECFILEDIALOG_H
|
|
||||||
|
|
||||||
#include <QDialog>
|
|
||||||
#include <libfm/fm.h>
|
|
||||||
|
|
||||||
namespace Ui {
|
|
||||||
class ExecFileDialog;
|
|
||||||
}
|
|
||||||
|
|
||||||
namespace Fm {
|
|
||||||
|
|
||||||
class ExecFileDialog : public QDialog {
|
|
||||||
Q_OBJECT
|
|
||||||
public:
|
|
||||||
~ExecFileDialog();
|
|
||||||
ExecFileDialog(FmFileInfo* fileInfo, QWidget* parent = 0, Qt::WindowFlags f = 0);
|
|
||||||
|
|
||||||
FmFileLauncherExecAction result() {
|
|
||||||
return result_;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected:
|
|
||||||
virtual void accept();
|
|
||||||
|
|
||||||
private:
|
|
||||||
Ui::ExecFileDialog* ui;
|
|
||||||
FmFileInfo* fileInfo_;
|
|
||||||
FmFileLauncherExecAction result_;
|
|
||||||
};
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif // FM_EXECFILEDIALOG_H
|
|
||||||
@ -1,171 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<ui version="4.0">
|
|
||||||
<class>FileOperationDialog</class>
|
|
||||||
<widget class="QDialog" name="FileOperationDialog">
|
|
||||||
<property name="geometry">
|
|
||||||
<rect>
|
|
||||||
<x>0</x>
|
|
||||||
<y>0</y>
|
|
||||||
<width>450</width>
|
|
||||||
<height>246</height>
|
|
||||||
</rect>
|
|
||||||
</property>
|
|
||||||
<property name="windowTitle">
|
|
||||||
<string/>
|
|
||||||
</property>
|
|
||||||
<layout class="QFormLayout" name="formLayout_2">
|
|
||||||
<item row="0" column="0" colspan="2">
|
|
||||||
<widget class="QLabel" name="message">
|
|
||||||
<property name="text">
|
|
||||||
<string/>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="1" column="1">
|
|
||||||
<layout class="QFormLayout" name="formLayout">
|
|
||||||
<property name="fieldGrowthPolicy">
|
|
||||||
<enum>QFormLayout::AllNonFixedFieldsGrow</enum>
|
|
||||||
</property>
|
|
||||||
<item row="1" column="0">
|
|
||||||
<widget class="QLabel" name="destLabel">
|
|
||||||
<property name="text">
|
|
||||||
<string>Destination:</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="1" column="1">
|
|
||||||
<widget class="QLabel" name="dest">
|
|
||||||
<property name="sizePolicy">
|
|
||||||
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
|
|
||||||
<horstretch>0</horstretch>
|
|
||||||
<verstretch>0</verstretch>
|
|
||||||
</sizepolicy>
|
|
||||||
</property>
|
|
||||||
<property name="text">
|
|
||||||
<string/>
|
|
||||||
</property>
|
|
||||||
<property name="wordWrap">
|
|
||||||
<bool>true</bool>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="2" column="0">
|
|
||||||
<widget class="QLabel" name="label_3">
|
|
||||||
<property name="text">
|
|
||||||
<string>Processing:</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="2" column="1">
|
|
||||||
<widget class="QLabel" name="curFile">
|
|
||||||
<property name="sizePolicy">
|
|
||||||
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
|
|
||||||
<horstretch>0</horstretch>
|
|
||||||
<verstretch>0</verstretch>
|
|
||||||
</sizepolicy>
|
|
||||||
</property>
|
|
||||||
<property name="text">
|
|
||||||
<string>Preparing...</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="3" column="0">
|
|
||||||
<widget class="QLabel" name="label_4">
|
|
||||||
<property name="text">
|
|
||||||
<string>Progress</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="3" column="1">
|
|
||||||
<widget class="QProgressBar" name="progressBar">
|
|
||||||
<property name="alignment">
|
|
||||||
<set>Qt::AlignCenter</set>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="4" column="0">
|
|
||||||
<widget class="QLabel" name="label_5">
|
|
||||||
<property name="sizePolicy">
|
|
||||||
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
|
|
||||||
<horstretch>0</horstretch>
|
|
||||||
<verstretch>0</verstretch>
|
|
||||||
</sizepolicy>
|
|
||||||
</property>
|
|
||||||
<property name="text">
|
|
||||||
<string>Time remaining:</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="4" column="1">
|
|
||||||
<widget class="QLabel" name="timeRemaining">
|
|
||||||
<property name="sizePolicy">
|
|
||||||
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
|
|
||||||
<horstretch>0</horstretch>
|
|
||||||
<verstretch>0</verstretch>
|
|
||||||
</sizepolicy>
|
|
||||||
</property>
|
|
||||||
<property name="text">
|
|
||||||
<string/>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="0" column="0" colspan="2">
|
|
||||||
<widget class="QListWidget" name="sourceFiles">
|
|
||||||
<property name="sizePolicy">
|
|
||||||
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
|
|
||||||
<horstretch>0</horstretch>
|
|
||||||
<verstretch>0</verstretch>
|
|
||||||
</sizepolicy>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
</layout>
|
|
||||||
</item>
|
|
||||||
<item row="2" column="0" colspan="2">
|
|
||||||
<widget class="QDialogButtonBox" name="buttonBox">
|
|
||||||
<property name="orientation">
|
|
||||||
<enum>Qt::Horizontal</enum>
|
|
||||||
</property>
|
|
||||||
<property name="standardButtons">
|
|
||||||
<set>QDialogButtonBox::Cancel</set>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
</layout>
|
|
||||||
</widget>
|
|
||||||
<resources/>
|
|
||||||
<connections>
|
|
||||||
<connection>
|
|
||||||
<sender>buttonBox</sender>
|
|
||||||
<signal>accepted()</signal>
|
|
||||||
<receiver>FileOperationDialog</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>FileOperationDialog</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>
|
|
||||||
@ -1,736 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<ui version="4.0">
|
|
||||||
<class>FilePropsDialog</class>
|
|
||||||
<widget class="QDialog" name="FilePropsDialog">
|
|
||||||
<property name="geometry">
|
|
||||||
<rect>
|
|
||||||
<x>0</x>
|
|
||||||
<y>0</y>
|
|
||||||
<width>424</width>
|
|
||||||
<height>456</height>
|
|
||||||
</rect>
|
|
||||||
</property>
|
|
||||||
<property name="windowTitle">
|
|
||||||
<string>File Properties</string>
|
|
||||||
</property>
|
|
||||||
<property name="windowIcon">
|
|
||||||
<iconset theme="document-properties">
|
|
||||||
<normaloff/>
|
|
||||||
</iconset>
|
|
||||||
</property>
|
|
||||||
<layout class="QVBoxLayout" name="verticalLayout">
|
|
||||||
<property name="leftMargin">
|
|
||||||
<number>10</number>
|
|
||||||
</property>
|
|
||||||
<property name="topMargin">
|
|
||||||
<number>10</number>
|
|
||||||
</property>
|
|
||||||
<property name="rightMargin">
|
|
||||||
<number>10</number>
|
|
||||||
</property>
|
|
||||||
<property name="bottomMargin">
|
|
||||||
<number>10</number>
|
|
||||||
</property>
|
|
||||||
<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="QFormLayout" name="formLayout_2">
|
|
||||||
<property name="horizontalSpacing">
|
|
||||||
<number>12</number>
|
|
||||||
</property>
|
|
||||||
<property name="verticalSpacing">
|
|
||||||
<number>6</number>
|
|
||||||
</property>
|
|
||||||
<item row="0" column="0">
|
|
||||||
<widget class="QPushButton" name="iconButton">
|
|
||||||
<property name="sizePolicy">
|
|
||||||
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
|
|
||||||
<horstretch>0</horstretch>
|
|
||||||
<verstretch>0</verstretch>
|
|
||||||
</sizepolicy>
|
|
||||||
</property>
|
|
||||||
<property name="text">
|
|
||||||
<string/>
|
|
||||||
</property>
|
|
||||||
<property name="icon">
|
|
||||||
<iconset theme="unknown">
|
|
||||||
<normaloff/>
|
|
||||||
</iconset>
|
|
||||||
</property>
|
|
||||||
<property name="iconSize">
|
|
||||||
<size>
|
|
||||||
<width>32</width>
|
|
||||||
<height>32</height>
|
|
||||||
</size>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="0" column="1">
|
|
||||||
<widget class="QLineEdit" name="fileName"/>
|
|
||||||
</item>
|
|
||||||
<item row="1" column="0">
|
|
||||||
<widget class="QLabel" name="label_2">
|
|
||||||
<property name="text">
|
|
||||||
<string>Location:</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="1" column="1">
|
|
||||||
<widget class="QLabel" name="location">
|
|
||||||
<property name="sizePolicy">
|
|
||||||
<sizepolicy hsizetype="Expanding" vsizetype="Preferred">
|
|
||||||
<horstretch>0</horstretch>
|
|
||||||
<verstretch>0</verstretch>
|
|
||||||
</sizepolicy>
|
|
||||||
</property>
|
|
||||||
<property name="text">
|
|
||||||
<string/>
|
|
||||||
</property>
|
|
||||||
<property name="wordWrap">
|
|
||||||
<bool>true</bool>
|
|
||||||
</property>
|
|
||||||
<property name="textInteractionFlags">
|
|
||||||
<set>Qt::LinksAccessibleByKeyboard|Qt::LinksAccessibleByMouse|Qt::TextBrowserInteraction|Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse</set>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="3" column="0">
|
|
||||||
<widget class="QLabel" name="label_4">
|
|
||||||
<property name="text">
|
|
||||||
<string>File type:</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="3" column="1">
|
|
||||||
<widget class="QLabel" name="fileType">
|
|
||||||
<property name="sizePolicy">
|
|
||||||
<sizepolicy hsizetype="Expanding" vsizetype="Preferred">
|
|
||||||
<horstretch>0</horstretch>
|
|
||||||
<verstretch>0</verstretch>
|
|
||||||
</sizepolicy>
|
|
||||||
</property>
|
|
||||||
<property name="text">
|
|
||||||
<string/>
|
|
||||||
</property>
|
|
||||||
<property name="textInteractionFlags">
|
|
||||||
<set>Qt::LinksAccessibleByKeyboard|Qt::LinksAccessibleByMouse|Qt::TextBrowserInteraction|Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse</set>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="4" column="0">
|
|
||||||
<widget class="QLabel" name="label">
|
|
||||||
<property name="text">
|
|
||||||
<string>Mime type:</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="4" column="1">
|
|
||||||
<widget class="QLabel" name="mimeType">
|
|
||||||
<property name="sizePolicy">
|
|
||||||
<sizepolicy hsizetype="Expanding" vsizetype="Preferred">
|
|
||||||
<horstretch>0</horstretch>
|
|
||||||
<verstretch>0</verstretch>
|
|
||||||
</sizepolicy>
|
|
||||||
</property>
|
|
||||||
<property name="text">
|
|
||||||
<string/>
|
|
||||||
</property>
|
|
||||||
<property name="textInteractionFlags">
|
|
||||||
<set>Qt::LinksAccessibleByKeyboard|Qt::LinksAccessibleByMouse|Qt::TextBrowserInteraction|Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse</set>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="6" column="0">
|
|
||||||
<widget class="QLabel" name="label_7">
|
|
||||||
<property name="text">
|
|
||||||
<string>File size:</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="6" column="1">
|
|
||||||
<widget class="QLabel" name="fileSize">
|
|
||||||
<property name="sizePolicy">
|
|
||||||
<sizepolicy hsizetype="Expanding" vsizetype="Preferred">
|
|
||||||
<horstretch>0</horstretch>
|
|
||||||
<verstretch>0</verstretch>
|
|
||||||
</sizepolicy>
|
|
||||||
</property>
|
|
||||||
<property name="text">
|
|
||||||
<string/>
|
|
||||||
</property>
|
|
||||||
<property name="textInteractionFlags">
|
|
||||||
<set>Qt::LinksAccessibleByKeyboard|Qt::LinksAccessibleByMouse|Qt::TextBrowserInteraction|Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse</set>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="7" column="0">
|
|
||||||
<widget class="QLabel" name="label_6">
|
|
||||||
<property name="text">
|
|
||||||
<string>On-disk size:</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="7" column="1">
|
|
||||||
<widget class="QLabel" name="onDiskSize">
|
|
||||||
<property name="sizePolicy">
|
|
||||||
<sizepolicy hsizetype="Expanding" vsizetype="Preferred">
|
|
||||||
<horstretch>0</horstretch>
|
|
||||||
<verstretch>0</verstretch>
|
|
||||||
</sizepolicy>
|
|
||||||
</property>
|
|
||||||
<property name="text">
|
|
||||||
<string/>
|
|
||||||
</property>
|
|
||||||
<property name="textInteractionFlags">
|
|
||||||
<set>Qt::LinksAccessibleByKeyboard|Qt::LinksAccessibleByMouse|Qt::TextBrowserInteraction|Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse</set>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="8" column="0">
|
|
||||||
<widget class="QLabel" name="label_3">
|
|
||||||
<property name="text">
|
|
||||||
<string>Last modified:</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="8" column="1">
|
|
||||||
<widget class="QLabel" name="lastModified">
|
|
||||||
<property name="sizePolicy">
|
|
||||||
<sizepolicy hsizetype="Expanding" vsizetype="Preferred">
|
|
||||||
<horstretch>0</horstretch>
|
|
||||||
<verstretch>0</verstretch>
|
|
||||||
</sizepolicy>
|
|
||||||
</property>
|
|
||||||
<property name="text">
|
|
||||||
<string/>
|
|
||||||
</property>
|
|
||||||
<property name="textInteractionFlags">
|
|
||||||
<set>Qt::LinksAccessibleByKeyboard|Qt::LinksAccessibleByMouse|Qt::TextBrowserInteraction|Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse</set>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="2" column="0">
|
|
||||||
<widget class="QLabel" name="targetLabel">
|
|
||||||
<property name="text">
|
|
||||||
<string>Link target:</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="2" column="1">
|
|
||||||
<widget class="QLabel" name="target">
|
|
||||||
<property name="sizePolicy">
|
|
||||||
<sizepolicy hsizetype="Expanding" vsizetype="Preferred">
|
|
||||||
<horstretch>0</horstretch>
|
|
||||||
<verstretch>0</verstretch>
|
|
||||||
</sizepolicy>
|
|
||||||
</property>
|
|
||||||
<property name="text">
|
|
||||||
<string/>
|
|
||||||
</property>
|
|
||||||
<property name="wordWrap">
|
|
||||||
<bool>true</bool>
|
|
||||||
</property>
|
|
||||||
<property name="textInteractionFlags">
|
|
||||||
<set>Qt::LinksAccessibleByKeyboard|Qt::LinksAccessibleByMouse|Qt::TextBrowserInteraction|Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse</set>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="5" column="0">
|
|
||||||
<widget class="QLabel" name="openWithLabel">
|
|
||||||
<property name="text">
|
|
||||||
<string>Open With:</string>
|
|
||||||
</property>
|
|
||||||
<property name="textInteractionFlags">
|
|
||||||
<set>Qt::LinksAccessibleByKeyboard|Qt::LinksAccessibleByMouse|Qt::TextBrowserInteraction|Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse</set>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="5" column="1">
|
|
||||||
<widget class="Fm::AppChooserComboBox" name="openWith">
|
|
||||||
<property name="sizePolicy">
|
|
||||||
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Fixed">
|
|
||||||
<horstretch>0</horstretch>
|
|
||||||
<verstretch>0</verstretch>
|
|
||||||
</sizepolicy>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="9" column="0">
|
|
||||||
<widget class="QLabel" name="label_12">
|
|
||||||
<property name="text">
|
|
||||||
<string>Last accessed:</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="9" column="1">
|
|
||||||
<widget class="QLabel" name="lastAccessed">
|
|
||||||
<property name="text">
|
|
||||||
<string/>
|
|
||||||
</property>
|
|
||||||
<property name="textInteractionFlags">
|
|
||||||
<set>Qt::LinksAccessibleByKeyboard|Qt::LinksAccessibleByMouse|Qt::TextBrowserInteraction|Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse</set>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
</layout>
|
|
||||||
</widget>
|
|
||||||
<widget class="QWidget" name="permissionsPage">
|
|
||||||
<attribute name="title">
|
|
||||||
<string>Permissions</string>
|
|
||||||
</attribute>
|
|
||||||
<layout class="QVBoxLayout" name="verticalLayout_2">
|
|
||||||
<property name="spacing">
|
|
||||||
<number>6</number>
|
|
||||||
</property>
|
|
||||||
<item>
|
|
||||||
<widget class="QGroupBox" name="groupBox_2">
|
|
||||||
<property name="sizePolicy">
|
|
||||||
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
|
|
||||||
<horstretch>0</horstretch>
|
|
||||||
<verstretch>0</verstretch>
|
|
||||||
</sizepolicy>
|
|
||||||
</property>
|
|
||||||
<property name="title">
|
|
||||||
<string>Ownership</string>
|
|
||||||
</property>
|
|
||||||
<layout class="QFormLayout" name="formLayout">
|
|
||||||
<property name="horizontalSpacing">
|
|
||||||
<number>12</number>
|
|
||||||
</property>
|
|
||||||
<property name="verticalSpacing">
|
|
||||||
<number>6</number>
|
|
||||||
</property>
|
|
||||||
<item row="1" column="1">
|
|
||||||
<widget class="QLineEdit" name="owner"/>
|
|
||||||
</item>
|
|
||||||
<item row="2" column="1">
|
|
||||||
<widget class="QLineEdit" name="ownerGroup"/>
|
|
||||||
</item>
|
|
||||||
<item row="2" column="0">
|
|
||||||
<widget class="QLabel" name="label_9">
|
|
||||||
<property name="sizePolicy">
|
|
||||||
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
|
|
||||||
<horstretch>0</horstretch>
|
|
||||||
<verstretch>0</verstretch>
|
|
||||||
</sizepolicy>
|
|
||||||
</property>
|
|
||||||
<property name="text">
|
|
||||||
<string>Group:</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="1" column="0">
|
|
||||||
<widget class="QLabel" name="label_8">
|
|
||||||
<property name="sizePolicy">
|
|
||||||
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
|
|
||||||
<horstretch>0</horstretch>
|
|
||||||
<verstretch>0</verstretch>
|
|
||||||
</sizepolicy>
|
|
||||||
</property>
|
|
||||||
<property name="text">
|
|
||||||
<string>Owner:</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
</layout>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<widget class="QGroupBox" name="groupBox">
|
|
||||||
<property name="sizePolicy">
|
|
||||||
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
|
|
||||||
<horstretch>0</horstretch>
|
|
||||||
<verstretch>0</verstretch>
|
|
||||||
</sizepolicy>
|
|
||||||
</property>
|
|
||||||
<property name="title">
|
|
||||||
<string>Access Control</string>
|
|
||||||
</property>
|
|
||||||
<layout class="QVBoxLayout" name="verticalLayout_3">
|
|
||||||
<item>
|
|
||||||
<widget class="QStackedWidget" name="stackedWidget">
|
|
||||||
<property name="sizePolicy">
|
|
||||||
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
|
|
||||||
<horstretch>0</horstretch>
|
|
||||||
<verstretch>0</verstretch>
|
|
||||||
</sizepolicy>
|
|
||||||
</property>
|
|
||||||
<property name="currentIndex">
|
|
||||||
<number>0</number>
|
|
||||||
</property>
|
|
||||||
<widget class="QWidget" name="page">
|
|
||||||
<layout class="QFormLayout" name="formLayout_3">
|
|
||||||
<item row="0" column="0">
|
|
||||||
<widget class="QLabel" name="ownerLabel">
|
|
||||||
<property name="text">
|
|
||||||
<string>Owner:</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="0" column="1">
|
|
||||||
<widget class="QComboBox" name="ownerPerm">
|
|
||||||
<property name="sizePolicy">
|
|
||||||
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Fixed">
|
|
||||||
<horstretch>0</horstretch>
|
|
||||||
<verstretch>0</verstretch>
|
|
||||||
</sizepolicy>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="1" column="0">
|
|
||||||
<widget class="QLabel" name="groupLabel">
|
|
||||||
<property name="text">
|
|
||||||
<string>Group:</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="1" column="1">
|
|
||||||
<widget class="QComboBox" name="groupPerm">
|
|
||||||
<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="otherLabel">
|
|
||||||
<property name="text">
|
|
||||||
<string>Other:</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="2" column="1">
|
|
||||||
<widget class="QComboBox" name="otherPerm">
|
|
||||||
<property name="sizePolicy">
|
|
||||||
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Fixed">
|
|
||||||
<horstretch>0</horstretch>
|
|
||||||
<verstretch>0</verstretch>
|
|
||||||
</sizepolicy>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="3" column="0" colspan="2">
|
|
||||||
<widget class="QCheckBox" name="executable">
|
|
||||||
<property name="text">
|
|
||||||
<string>Make the file executable</string>
|
|
||||||
</property>
|
|
||||||
<property name="tristate">
|
|
||||||
<bool>true</bool>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
</layout>
|
|
||||||
</widget>
|
|
||||||
<widget class="QWidget" name="page_2">
|
|
||||||
<layout class="QGridLayout" name="gridLayout_2" columnstretch="1,0,0">
|
|
||||||
<item row="0" column="0" rowspan="3">
|
|
||||||
<layout class="QGridLayout" name="gridLayout">
|
|
||||||
<property name="rightMargin">
|
|
||||||
<number>0</number>
|
|
||||||
</property>
|
|
||||||
<property name="spacing">
|
|
||||||
<number>6</number>
|
|
||||||
</property>
|
|
||||||
<item row="0" column="0">
|
|
||||||
<widget class="QLabel" name="label_5">
|
|
||||||
<property name="sizePolicy">
|
|
||||||
<sizepolicy hsizetype="Fixed" vsizetype="Preferred">
|
|
||||||
<horstretch>0</horstretch>
|
|
||||||
<verstretch>0</verstretch>
|
|
||||||
</sizepolicy>
|
|
||||||
</property>
|
|
||||||
<property name="text">
|
|
||||||
<string>Owner:</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="0" column="1">
|
|
||||||
<widget class="QCheckBox" name="checkBox">
|
|
||||||
<property name="sizePolicy">
|
|
||||||
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
|
|
||||||
<horstretch>0</horstretch>
|
|
||||||
<verstretch>0</verstretch>
|
|
||||||
</sizepolicy>
|
|
||||||
</property>
|
|
||||||
<property name="text">
|
|
||||||
<string>Read</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="0" column="2">
|
|
||||||
<widget class="QCheckBox" name="checkBox_5">
|
|
||||||
<property name="sizePolicy">
|
|
||||||
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
|
|
||||||
<horstretch>0</horstretch>
|
|
||||||
<verstretch>0</verstretch>
|
|
||||||
</sizepolicy>
|
|
||||||
</property>
|
|
||||||
<property name="text">
|
|
||||||
<string>Write</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="0" column="3">
|
|
||||||
<widget class="QCheckBox" name="checkBox_8">
|
|
||||||
<property name="sizePolicy">
|
|
||||||
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
|
|
||||||
<horstretch>0</horstretch>
|
|
||||||
<verstretch>0</verstretch>
|
|
||||||
</sizepolicy>
|
|
||||||
</property>
|
|
||||||
<property name="text">
|
|
||||||
<string>Execute</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="1" column="0">
|
|
||||||
<widget class="QLabel" name="label_10">
|
|
||||||
<property name="sizePolicy">
|
|
||||||
<sizepolicy hsizetype="Fixed" vsizetype="Preferred">
|
|
||||||
<horstretch>0</horstretch>
|
|
||||||
<verstretch>0</verstretch>
|
|
||||||
</sizepolicy>
|
|
||||||
</property>
|
|
||||||
<property name="text">
|
|
||||||
<string>Group:</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="1" column="1">
|
|
||||||
<widget class="QCheckBox" name="checkBox_4">
|
|
||||||
<property name="sizePolicy">
|
|
||||||
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
|
|
||||||
<horstretch>0</horstretch>
|
|
||||||
<verstretch>0</verstretch>
|
|
||||||
</sizepolicy>
|
|
||||||
</property>
|
|
||||||
<property name="text">
|
|
||||||
<string>Read</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="1" column="2">
|
|
||||||
<widget class="QCheckBox" name="checkBox_9">
|
|
||||||
<property name="sizePolicy">
|
|
||||||
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
|
|
||||||
<horstretch>0</horstretch>
|
|
||||||
<verstretch>0</verstretch>
|
|
||||||
</sizepolicy>
|
|
||||||
</property>
|
|
||||||
<property name="text">
|
|
||||||
<string>Write</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="1" column="3">
|
|
||||||
<widget class="QCheckBox" name="checkBox_3">
|
|
||||||
<property name="sizePolicy">
|
|
||||||
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
|
|
||||||
<horstretch>0</horstretch>
|
|
||||||
<verstretch>0</verstretch>
|
|
||||||
</sizepolicy>
|
|
||||||
</property>
|
|
||||||
<property name="text">
|
|
||||||
<string>Execute</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="2" column="0">
|
|
||||||
<widget class="QLabel" name="label_11">
|
|
||||||
<property name="sizePolicy">
|
|
||||||
<sizepolicy hsizetype="Fixed" vsizetype="Preferred">
|
|
||||||
<horstretch>0</horstretch>
|
|
||||||
<verstretch>0</verstretch>
|
|
||||||
</sizepolicy>
|
|
||||||
</property>
|
|
||||||
<property name="text">
|
|
||||||
<string>Other:</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="2" column="1">
|
|
||||||
<widget class="QCheckBox" name="checkBox_7">
|
|
||||||
<property name="sizePolicy">
|
|
||||||
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
|
|
||||||
<horstretch>0</horstretch>
|
|
||||||
<verstretch>0</verstretch>
|
|
||||||
</sizepolicy>
|
|
||||||
</property>
|
|
||||||
<property name="text">
|
|
||||||
<string>Read</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="2" column="2">
|
|
||||||
<widget class="QCheckBox" name="checkBox_2">
|
|
||||||
<property name="sizePolicy">
|
|
||||||
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
|
|
||||||
<horstretch>0</horstretch>
|
|
||||||
<verstretch>0</verstretch>
|
|
||||||
</sizepolicy>
|
|
||||||
</property>
|
|
||||||
<property name="text">
|
|
||||||
<string>Write</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="2" column="3">
|
|
||||||
<widget class="QCheckBox" name="checkBox_6">
|
|
||||||
<property name="sizePolicy">
|
|
||||||
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
|
|
||||||
<horstretch>0</horstretch>
|
|
||||||
<verstretch>0</verstretch>
|
|
||||||
</sizepolicy>
|
|
||||||
</property>
|
|
||||||
<property name="text">
|
|
||||||
<string>Execute</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
</layout>
|
|
||||||
</item>
|
|
||||||
<item row="0" column="2">
|
|
||||||
<widget class="QCheckBox" name="checkBox_10">
|
|
||||||
<property name="text">
|
|
||||||
<string>Sticky</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="1" column="2">
|
|
||||||
<widget class="QCheckBox" name="checkBox_11">
|
|
||||||
<property name="text">
|
|
||||||
<string>SetUID</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="2" column="2">
|
|
||||||
<widget class="QCheckBox" name="checkBox_12">
|
|
||||||
<property name="text">
|
|
||||||
<string>SetGID</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="0" column="1" rowspan="3">
|
|
||||||
<widget class="Line" name="line">
|
|
||||||
<property name="orientation">
|
|
||||||
<enum>Qt::Vertical</enum>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
</layout>
|
|
||||||
</widget>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<layout class="QHBoxLayout" name="horizontalLayout">
|
|
||||||
<item>
|
|
||||||
<spacer name="horizontalSpacer">
|
|
||||||
<property name="orientation">
|
|
||||||
<enum>Qt::Horizontal</enum>
|
|
||||||
</property>
|
|
||||||
<property name="sizeHint" stdset="0">
|
|
||||||
<size>
|
|
||||||
<width>40</width>
|
|
||||||
<height>20</height>
|
|
||||||
</size>
|
|
||||||
</property>
|
|
||||||
</spacer>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<widget class="QPushButton" name="pushButton">
|
|
||||||
<property name="enabled">
|
|
||||||
<bool>false</bool>
|
|
||||||
</property>
|
|
||||||
<property name="text">
|
|
||||||
<string>Advanced Mode</string>
|
|
||||||
</property>
|
|
||||||
<property name="checkable">
|
|
||||||
<bool>true</bool>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
</layout>
|
|
||||||
</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::Cancel|QDialogButtonBox::Ok</set>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
</layout>
|
|
||||||
</widget>
|
|
||||||
<customwidgets>
|
|
||||||
<customwidget>
|
|
||||||
<class>Fm::AppChooserComboBox</class>
|
|
||||||
<extends>QComboBox</extends>
|
|
||||||
<header>appchoosercombobox.h</header>
|
|
||||||
</customwidget>
|
|
||||||
</customwidgets>
|
|
||||||
<resources/>
|
|
||||||
<connections>
|
|
||||||
<connection>
|
|
||||||
<sender>buttonBox</sender>
|
|
||||||
<signal>accepted()</signal>
|
|
||||||
<receiver>FilePropsDialog</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>FilePropsDialog</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>
|
|
||||||
@ -1,123 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (C) 2012 - 2015 Hong Jen Yee (PCMan) <pcman.tw@gmail.com>
|
|
||||||
*
|
|
||||||
* 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 "filelauncher.h"
|
|
||||||
#include "applaunchcontext.h"
|
|
||||||
#include <QMessageBox>
|
|
||||||
#include <QDebug>
|
|
||||||
#include "execfiledialog_p.h"
|
|
||||||
#include "appchooserdialog.h"
|
|
||||||
#include "utilities.h"
|
|
||||||
|
|
||||||
namespace Fm {
|
|
||||||
|
|
||||||
FmFileLauncher FileLauncher::funcs = {
|
|
||||||
FileLauncher::_getApp,
|
|
||||||
/* gboolean (*before_open)(GAppLaunchContext* ctx, GList* folder_infos, gpointer user_data); */
|
|
||||||
(FmLaunchFolderFunc)FileLauncher::_openFolder,
|
|
||||||
FileLauncher::_execFile,
|
|
||||||
FileLauncher::_error,
|
|
||||||
FileLauncher::_ask
|
|
||||||
};
|
|
||||||
|
|
||||||
FileLauncher::FileLauncher():
|
|
||||||
quickExec_(false) {
|
|
||||||
}
|
|
||||||
|
|
||||||
FileLauncher::~FileLauncher() {
|
|
||||||
}
|
|
||||||
|
|
||||||
//static
|
|
||||||
bool FileLauncher::launchFiles(QWidget* parent, GList* file_infos) {
|
|
||||||
FmAppLaunchContext* context = fm_app_launch_context_new_for_widget(parent);
|
|
||||||
bool ret = fm_launch_files(G_APP_LAUNCH_CONTEXT(context), file_infos, &funcs, this);
|
|
||||||
g_object_unref(context);
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool FileLauncher::launchPaths(QWidget* parent, GList* paths) {
|
|
||||||
FmAppLaunchContext* context = fm_app_launch_context_new_for_widget(parent);
|
|
||||||
bool ret = fm_launch_paths(G_APP_LAUNCH_CONTEXT(context), paths, &funcs, this);
|
|
||||||
g_object_unref(context);
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
GAppInfo* FileLauncher::getApp(GList* file_infos, FmMimeType* mime_type, GError** err) {
|
|
||||||
AppChooserDialog dlg(NULL);
|
|
||||||
if(mime_type)
|
|
||||||
dlg.setMimeType(mime_type);
|
|
||||||
else
|
|
||||||
dlg.setCanSetDefault(false);
|
|
||||||
// FIXME: show error properly?
|
|
||||||
if(execModelessDialog(&dlg) == QDialog::Accepted) {
|
|
||||||
return dlg.selectedApp();
|
|
||||||
}
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool FileLauncher::openFolder(GAppLaunchContext* ctx, GList* folder_infos, GError** err) {
|
|
||||||
for(GList* l = folder_infos; l; l = l->next) {
|
|
||||||
FmFileInfo* fi = FM_FILE_INFO(l->data);
|
|
||||||
qDebug() << " folder:" << QString::fromUtf8(fm_file_info_get_disp_name(fi));
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
FmFileLauncherExecAction FileLauncher::execFile(FmFileInfo* file) {
|
|
||||||
if (quickExec_) {
|
|
||||||
/* SF bug#838: open terminal for each script may be just a waste.
|
|
||||||
User should open a terminal and start the script there
|
|
||||||
in case if user wants to see the script output anyway.
|
|
||||||
if (fm_file_info_is_text(file))
|
|
||||||
return FM_FILE_LAUNCHER_EXEC_IN_TERMINAL; */
|
|
||||||
return FM_FILE_LAUNCHER_EXEC;
|
|
||||||
}
|
|
||||||
|
|
||||||
FmFileLauncherExecAction res = FM_FILE_LAUNCHER_EXEC_CANCEL;
|
|
||||||
ExecFileDialog dlg(file);
|
|
||||||
if(execModelessDialog(&dlg) == QDialog::Accepted) {
|
|
||||||
res = dlg.result();
|
|
||||||
}
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
|
|
||||||
int FileLauncher::ask(const char* msg, char* const* btn_labels, int default_btn) {
|
|
||||||
/* FIXME: set default button properly */
|
|
||||||
// return fm_askv(data->parent, NULL, msg, btn_labels);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool FileLauncher::error(GAppLaunchContext* ctx, GError* err, FmPath* path) {
|
|
||||||
/* ask for mount if trying to launch unmounted path */
|
|
||||||
if(err->domain == G_IO_ERROR) {
|
|
||||||
if(path && err->code == G_IO_ERROR_NOT_MOUNTED) {
|
|
||||||
//if(fm_mount_path(data->parent, path, TRUE))
|
|
||||||
// return FALSE; /* ask to retry */
|
|
||||||
}
|
|
||||||
else if(err->code == G_IO_ERROR_FAILED_HANDLED)
|
|
||||||
return true; /* don't show error message */
|
|
||||||
}
|
|
||||||
QMessageBox dlg(QMessageBox::Critical, QObject::tr("Error"), QString::fromUtf8(err->message), QMessageBox::Ok);
|
|
||||||
execModelessDialog(&dlg);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
} // namespace Fm
|
|
||||||
@ -1,87 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (C) 2012 - 2015 Hong Jen Yee (PCMan) <pcman.tw@gmail.com>
|
|
||||||
*
|
|
||||||
* 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 FM_FILELAUNCHER_H
|
|
||||||
#define FM_FILELAUNCHER_H
|
|
||||||
|
|
||||||
#include "libfmqtglobals.h"
|
|
||||||
#include <QWidget>
|
|
||||||
#include <libfm/fm.h>
|
|
||||||
|
|
||||||
namespace Fm {
|
|
||||||
|
|
||||||
class LIBFM_QT_API FileLauncher {
|
|
||||||
public:
|
|
||||||
FileLauncher();
|
|
||||||
virtual ~FileLauncher();
|
|
||||||
|
|
||||||
bool launchFiles(QWidget* parent, FmFileInfoList* file_infos) {
|
|
||||||
GList* fileList = fm_file_info_list_peek_head_link(file_infos);
|
|
||||||
return launchFiles(parent, fileList);
|
|
||||||
}
|
|
||||||
bool launchPaths(QWidget* parent, FmPathList* paths) {
|
|
||||||
GList* pathList = fm_path_list_peek_head_link(paths);
|
|
||||||
return launchPaths(parent, pathList);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool launchFiles(QWidget* parent, GList* file_infos);
|
|
||||||
bool launchPaths(QWidget* parent, GList* paths);
|
|
||||||
|
|
||||||
bool quickExec() const {
|
|
||||||
return quickExec_;
|
|
||||||
}
|
|
||||||
|
|
||||||
void setQuickExec(bool value) {
|
|
||||||
quickExec_ = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected:
|
|
||||||
|
|
||||||
virtual GAppInfo* getApp(GList* file_infos, FmMimeType* mime_type, GError** err);
|
|
||||||
virtual bool openFolder(GAppLaunchContext* ctx, GList* folder_infos, GError** err);
|
|
||||||
virtual FmFileLauncherExecAction execFile(FmFileInfo* file);
|
|
||||||
virtual bool error(GAppLaunchContext* ctx, GError* err, FmPath* path);
|
|
||||||
virtual int ask(const char* msg, char* const* btn_labels, int default_btn);
|
|
||||||
|
|
||||||
private:
|
|
||||||
static GAppInfo* _getApp(GList* file_infos, FmMimeType* mime_type, gpointer user_data, GError** err) {
|
|
||||||
return reinterpret_cast<FileLauncher*>(user_data)->getApp(file_infos, mime_type, err);
|
|
||||||
}
|
|
||||||
static gboolean _openFolder(GAppLaunchContext* ctx, GList* folder_infos, gpointer user_data, GError** err) {
|
|
||||||
return reinterpret_cast<FileLauncher*>(user_data)->openFolder(ctx, folder_infos, err);
|
|
||||||
}
|
|
||||||
static FmFileLauncherExecAction _execFile(FmFileInfo* file, gpointer user_data) {
|
|
||||||
return reinterpret_cast<FileLauncher*>(user_data)->execFile(file);
|
|
||||||
}
|
|
||||||
static gboolean _error(GAppLaunchContext* ctx, GError* err, FmPath* file, gpointer user_data) {
|
|
||||||
return reinterpret_cast<FileLauncher*>(user_data)->error(ctx, err, file);
|
|
||||||
}
|
|
||||||
static int _ask(const char* msg, char* const* btn_labels, int default_btn, gpointer user_data) {
|
|
||||||
return reinterpret_cast<FileLauncher*>(user_data)->ask(msg, btn_labels, default_btn);
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
static FmFileLauncher funcs;
|
|
||||||
bool quickExec_; // Don't ask options on launch executable file
|
|
||||||
};
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif // FM_FILELAUNCHER_H
|
|
||||||
397
src/filemenu.cpp
397
src/filemenu.cpp
@ -1,397 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (C) 2012 - 2015 Hong Jen Yee (PCMan) <pcman.tw@gmail.com>
|
|
||||||
*
|
|
||||||
* 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 "filemenu.h"
|
|
||||||
#include "createnewmenu.h"
|
|
||||||
#include "icontheme.h"
|
|
||||||
#include "filepropsdialog.h"
|
|
||||||
#include "utilities.h"
|
|
||||||
#include "fileoperation.h"
|
|
||||||
#include "filelauncher.h"
|
|
||||||
#include "appchooserdialog.h"
|
|
||||||
#ifdef CUSTOM_ACTIONS
|
|
||||||
#include <libfm/fm-actions.h>
|
|
||||||
#endif
|
|
||||||
#include <QMessageBox>
|
|
||||||
#include <QDebug>
|
|
||||||
#include "filemenu_p.h"
|
|
||||||
|
|
||||||
namespace Fm {
|
|
||||||
|
|
||||||
FileMenu::FileMenu(FmFileInfoList* files, FmFileInfo* info, FmPath* cwd, QWidget* parent):
|
|
||||||
QMenu(parent),
|
|
||||||
fileLauncher_(NULL) {
|
|
||||||
createMenu(files, info, cwd);
|
|
||||||
}
|
|
||||||
|
|
||||||
FileMenu::FileMenu(FmFileInfoList* files, FmFileInfo* info, FmPath* cwd, const QString& title, QWidget* parent):
|
|
||||||
QMenu(title, parent),
|
|
||||||
fileLauncher_(NULL),
|
|
||||||
unTrashAction_(NULL) {
|
|
||||||
createMenu(files, info, cwd);
|
|
||||||
}
|
|
||||||
|
|
||||||
FileMenu::~FileMenu() {
|
|
||||||
if(files_)
|
|
||||||
fm_file_info_list_unref(files_);
|
|
||||||
if(info_)
|
|
||||||
fm_file_info_unref(info_);
|
|
||||||
if(cwd_)
|
|
||||||
fm_path_unref(cwd_);
|
|
||||||
}
|
|
||||||
|
|
||||||
void FileMenu::createMenu(FmFileInfoList* files, FmFileInfo* info, FmPath* cwd) {
|
|
||||||
useTrash_ = true;
|
|
||||||
confirmDelete_ = true;
|
|
||||||
confirmTrash_ = false; // Confirm before moving files into "trash can"
|
|
||||||
|
|
||||||
openAction_ = NULL;
|
|
||||||
openWithMenuAction_ = NULL;
|
|
||||||
openWithAction_ = NULL;
|
|
||||||
separator1_ = NULL;
|
|
||||||
cutAction_ = NULL;
|
|
||||||
copyAction_ = NULL;
|
|
||||||
pasteAction_ = NULL;
|
|
||||||
deleteAction_ = NULL;
|
|
||||||
unTrashAction_ = NULL;
|
|
||||||
renameAction_ = NULL;
|
|
||||||
separator2_ = NULL;
|
|
||||||
propertiesAction_ = NULL;
|
|
||||||
|
|
||||||
files_ = fm_file_info_list_ref(files);
|
|
||||||
info_ = info ? fm_file_info_ref(info) : NULL;
|
|
||||||
cwd_ = cwd ? fm_path_ref(cwd) : NULL;
|
|
||||||
|
|
||||||
FmFileInfo* first = fm_file_info_list_peek_head(files);
|
|
||||||
FmMimeType* mime_type = fm_file_info_get_mime_type(first);
|
|
||||||
FmPath* path = fm_file_info_get_path(first);
|
|
||||||
// check if the files are of the same type
|
|
||||||
sameType_ = fm_file_info_list_is_same_type(files);
|
|
||||||
// check if the files are on the same filesystem
|
|
||||||
sameFilesystem_ = fm_file_info_list_is_same_fs(files);
|
|
||||||
// check if the files are all virtual
|
|
||||||
allVirtual_ = sameFilesystem_ && fm_path_is_virtual(path);
|
|
||||||
// check if the files are all in the trash can
|
|
||||||
allTrash_ = sameFilesystem_ && fm_path_is_trash(path);
|
|
||||||
|
|
||||||
openAction_ = new QAction(QIcon::fromTheme("document-open"), tr("Open"), this);
|
|
||||||
connect(openAction_ , &QAction::triggered, this, &FileMenu::onOpenTriggered);
|
|
||||||
addAction(openAction_);
|
|
||||||
|
|
||||||
openWithMenuAction_ = new QAction(tr("Open With..."), this);
|
|
||||||
addAction(openWithMenuAction_);
|
|
||||||
// create the "Open with..." sub menu
|
|
||||||
QMenu* menu = new QMenu();
|
|
||||||
openWithMenuAction_->setMenu(menu);
|
|
||||||
|
|
||||||
if(sameType_) { /* add specific menu items for this mime type */
|
|
||||||
if(mime_type && !allVirtual_) { /* the file has a valid mime-type and its not virtual */
|
|
||||||
GList* apps = g_app_info_get_all_for_type(fm_mime_type_get_type(mime_type));
|
|
||||||
GList* l;
|
|
||||||
for(l=apps;l;l=l->next) {
|
|
||||||
GAppInfo* app = G_APP_INFO(l->data);
|
|
||||||
|
|
||||||
// check if the command really exists
|
|
||||||
gchar * program_path = g_find_program_in_path(g_app_info_get_executable(app));
|
|
||||||
if (!program_path)
|
|
||||||
continue;
|
|
||||||
g_free(program_path);
|
|
||||||
|
|
||||||
// create a QAction for the application.
|
|
||||||
AppInfoAction* action = new AppInfoAction(app);
|
|
||||||
connect(action, &QAction::triggered, this, &FileMenu::onApplicationTriggered);
|
|
||||||
menu->addAction(action);
|
|
||||||
}
|
|
||||||
g_list_free(apps); /* don't unref GAppInfos now */
|
|
||||||
}
|
|
||||||
}
|
|
||||||
menu->addSeparator();
|
|
||||||
openWithAction_ = new QAction(tr("Other Applications"), this);
|
|
||||||
connect(openWithAction_ , &QAction::triggered, this, &FileMenu::onOpenWithTriggered);
|
|
||||||
menu->addAction(openWithAction_);
|
|
||||||
|
|
||||||
separator1_ = addSeparator();
|
|
||||||
|
|
||||||
createAction_ = new QAction(tr("Create &New"), this);
|
|
||||||
FmPath* dirPath = fm_file_info_list_get_length(files) == 1 && fm_file_info_is_dir(first)
|
|
||||||
? path : cwd_;
|
|
||||||
createAction_->setMenu(new CreateNewMenu(NULL, dirPath, this));
|
|
||||||
addAction(createAction_);
|
|
||||||
|
|
||||||
separator2_ = addSeparator();
|
|
||||||
|
|
||||||
if(allTrash_) { // all selected files are in trash:///
|
|
||||||
bool can_restore = true;
|
|
||||||
/* only immediate children of trash:/// can be restored. */
|
|
||||||
for(GList* l = fm_file_info_list_peek_head_link(files_); l; l=l->next) {
|
|
||||||
FmPath *trash_path = fm_file_info_get_path(FM_FILE_INFO(l->data));
|
|
||||||
if(!fm_path_get_parent(trash_path) ||
|
|
||||||
!fm_path_is_trash_root(fm_path_get_parent(trash_path))) {
|
|
||||||
can_restore = false;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if(can_restore) {
|
|
||||||
unTrashAction_ = new QAction(tr("&Restore"), this);
|
|
||||||
connect(unTrashAction_, &QAction::triggered, this, &FileMenu::onUnTrashTriggered);
|
|
||||||
addAction(unTrashAction_);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else { // ordinary files
|
|
||||||
cutAction_ = new QAction(QIcon::fromTheme("edit-cut"), tr("Cut"), this);
|
|
||||||
connect(cutAction_, &QAction::triggered, this, &FileMenu::onCutTriggered);
|
|
||||||
addAction(cutAction_);
|
|
||||||
|
|
||||||
copyAction_ = new QAction(QIcon::fromTheme("edit-copy"), tr("Copy"), this);
|
|
||||||
connect(copyAction_, &QAction::triggered, this, &FileMenu::onCopyTriggered);
|
|
||||||
addAction(copyAction_);
|
|
||||||
|
|
||||||
pasteAction_ = new QAction(QIcon::fromTheme("edit-paste"), tr("Paste"), this);
|
|
||||||
connect(pasteAction_, &QAction::triggered, this, &FileMenu::onPasteTriggered);
|
|
||||||
addAction(pasteAction_);
|
|
||||||
|
|
||||||
deleteAction_ = new QAction(QIcon::fromTheme("user-trash"), tr("&Move to Trash"), this);
|
|
||||||
connect(deleteAction_, &QAction::triggered, this, &FileMenu::onDeleteTriggered);
|
|
||||||
addAction(deleteAction_);
|
|
||||||
|
|
||||||
renameAction_ = new QAction(tr("Rename"), this);
|
|
||||||
connect(renameAction_, &QAction::triggered, this, &FileMenu::onRenameTriggered);
|
|
||||||
addAction(renameAction_);
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef CUSTOM_ACTIONS
|
|
||||||
// DES-EMA custom actions integration
|
|
||||||
GList* files_list = fm_file_info_list_peek_head_link(files);
|
|
||||||
GList* items = fm_get_actions_for_files(files_list);
|
|
||||||
if(items) {
|
|
||||||
GList* l;
|
|
||||||
for(l=items; l; l=l->next) {
|
|
||||||
FmFileActionItem* item = FM_FILE_ACTION_ITEM(l->data);
|
|
||||||
addCustomActionItem(this, item);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
g_list_foreach(items, (GFunc)fm_file_action_item_unref, NULL);
|
|
||||||
g_list_free(items);
|
|
||||||
#endif
|
|
||||||
// archiver integration
|
|
||||||
// FIXME: we need to modify upstream libfm to include some Qt-based archiver programs.
|
|
||||||
if(!allVirtual_) {
|
|
||||||
if(sameType_) {
|
|
||||||
FmArchiver* archiver = fm_archiver_get_default();
|
|
||||||
if(archiver) {
|
|
||||||
if(fm_archiver_is_mime_type_supported(archiver, fm_mime_type_get_type(mime_type))) {
|
|
||||||
if(cwd_ && archiver->extract_to_cmd) {
|
|
||||||
QAction* action = new QAction(tr("Extract to..."), this);
|
|
||||||
connect(action, &QAction::triggered, this, &FileMenu::onExtract);
|
|
||||||
addAction(action);
|
|
||||||
}
|
|
||||||
if(archiver->extract_cmd) {
|
|
||||||
QAction* action = new QAction(tr("Extract Here"), this);
|
|
||||||
connect(action, &QAction::triggered, this, &FileMenu::onExtractHere);
|
|
||||||
addAction(action);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
QAction* action = new QAction(tr("Compress"), this);
|
|
||||||
connect(action, &QAction::triggered, this, &FileMenu::onCompress);
|
|
||||||
addAction(action);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
separator3_ = addSeparator();
|
|
||||||
|
|
||||||
propertiesAction_ = new QAction(QIcon::fromTheme("document-properties"), tr("Properties"), this);
|
|
||||||
connect(propertiesAction_, &QAction::triggered, this, &FileMenu::onFilePropertiesTriggered);
|
|
||||||
addAction(propertiesAction_);
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef CUSTOM_ACTIONS
|
|
||||||
void FileMenu::addCustomActionItem(QMenu* menu, FmFileActionItem* item) {
|
|
||||||
if(!item) { // separator
|
|
||||||
addSeparator();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// this action is not for context menu
|
|
||||||
if(fm_file_action_item_is_action(item) && !(fm_file_action_item_get_target(item) & FM_FILE_ACTION_TARGET_CONTEXT))
|
|
||||||
return;
|
|
||||||
|
|
||||||
CustomAction* action = new CustomAction(item, menu);
|
|
||||||
menu->addAction(action);
|
|
||||||
if(fm_file_action_item_is_menu(item)) {
|
|
||||||
GList* subitems = fm_file_action_item_get_sub_items(item);
|
|
||||||
for(GList* l = subitems; l; l = l->next) {
|
|
||||||
FmFileActionItem* subitem = FM_FILE_ACTION_ITEM(l->data);
|
|
||||||
QMenu* submenu = new QMenu(menu);
|
|
||||||
addCustomActionItem(submenu, subitem);
|
|
||||||
action->setMenu(submenu);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if(fm_file_action_item_is_action(item)) {
|
|
||||||
connect(action, &QAction::triggered, this, &FileMenu::onCustomActionTrigerred);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
void FileMenu::onOpenTriggered() {
|
|
||||||
if(fileLauncher_) {
|
|
||||||
fileLauncher_->launchFiles(NULL, files_);
|
|
||||||
}
|
|
||||||
else { // use the default launcher
|
|
||||||
Fm::FileLauncher launcher;
|
|
||||||
launcher.launchFiles(NULL, files_);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void FileMenu::onOpenWithTriggered() {
|
|
||||||
AppChooserDialog dlg(NULL);
|
|
||||||
if(sameType_) {
|
|
||||||
dlg.setMimeType(fm_file_info_get_mime_type(info_));
|
|
||||||
}
|
|
||||||
else { // we can only set the selected app as default if all files are of the same type
|
|
||||||
dlg.setCanSetDefault(false);
|
|
||||||
}
|
|
||||||
|
|
||||||
if(execModelessDialog(&dlg) == QDialog::Accepted) {
|
|
||||||
GAppInfo* app = dlg.selectedApp();
|
|
||||||
if(app) {
|
|
||||||
openFilesWithApp(app);
|
|
||||||
g_object_unref(app);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void FileMenu::openFilesWithApp(GAppInfo* app) {
|
|
||||||
FmPathList* paths = fm_path_list_new_from_file_info_list(files_);
|
|
||||||
GList* uris = NULL;
|
|
||||||
for(GList* l = fm_path_list_peek_head_link(paths); l; l = l->next) {
|
|
||||||
FmPath* path = FM_PATH(l->data);
|
|
||||||
char* uri = fm_path_to_uri(path);
|
|
||||||
uris = g_list_prepend(uris, uri);
|
|
||||||
}
|
|
||||||
fm_path_list_unref(paths);
|
|
||||||
fm_app_info_launch_uris(app, uris, NULL, NULL);
|
|
||||||
g_list_foreach(uris, (GFunc)g_free, NULL);
|
|
||||||
g_list_free(uris);
|
|
||||||
}
|
|
||||||
|
|
||||||
void FileMenu::onApplicationTriggered() {
|
|
||||||
AppInfoAction* action = static_cast<AppInfoAction*>(sender());
|
|
||||||
openFilesWithApp(action->appInfo());
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef CUSTOM_ACTIONS
|
|
||||||
void FileMenu::onCustomActionTrigerred() {
|
|
||||||
CustomAction* action = static_cast<CustomAction*>(sender());
|
|
||||||
FmFileActionItem* item = action->item();
|
|
||||||
|
|
||||||
GList* files = fm_file_info_list_peek_head_link(files_);
|
|
||||||
char* output = NULL;
|
|
||||||
/* g_debug("item: %s is activated, id:%s", fm_file_action_item_get_name(item),
|
|
||||||
fm_file_action_item_get_id(item)); */
|
|
||||||
fm_file_action_item_launch(item, NULL, files, &output);
|
|
||||||
if(output) {
|
|
||||||
QMessageBox::information(this, tr("Output"), QString::fromUtf8(output));
|
|
||||||
g_free(output);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
void FileMenu::onFilePropertiesTriggered() {
|
|
||||||
FilePropsDialog::showForFiles(files_);
|
|
||||||
}
|
|
||||||
|
|
||||||
void FileMenu::onCopyTriggered() {
|
|
||||||
FmPathList* paths = fm_path_list_new_from_file_info_list(files_);
|
|
||||||
Fm::copyFilesToClipboard(paths);
|
|
||||||
fm_path_list_unref(paths);
|
|
||||||
}
|
|
||||||
|
|
||||||
void FileMenu::onCutTriggered() {
|
|
||||||
FmPathList* paths = fm_path_list_new_from_file_info_list(files_);
|
|
||||||
Fm::cutFilesToClipboard(paths);
|
|
||||||
fm_path_list_unref(paths);
|
|
||||||
}
|
|
||||||
|
|
||||||
void FileMenu::onDeleteTriggered() {
|
|
||||||
FmPathList* paths = fm_path_list_new_from_file_info_list(files_);
|
|
||||||
if(useTrash_)
|
|
||||||
FileOperation::trashFiles(paths, confirmTrash_);
|
|
||||||
else
|
|
||||||
FileOperation::deleteFiles(paths, confirmDelete_);
|
|
||||||
fm_path_list_unref(paths);
|
|
||||||
}
|
|
||||||
|
|
||||||
void FileMenu::onUnTrashTriggered() {
|
|
||||||
FmPathList* paths = fm_path_list_new_from_file_info_list(files_);
|
|
||||||
FileOperation::unTrashFiles(paths);
|
|
||||||
}
|
|
||||||
|
|
||||||
void FileMenu::onPasteTriggered() {
|
|
||||||
Fm::pasteFilesFromClipboard(cwd_);
|
|
||||||
}
|
|
||||||
|
|
||||||
void FileMenu::onRenameTriggered() {
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void FileMenu::setUseTrash(bool trash) {
|
|
||||||
if(useTrash_ != trash) {
|
|
||||||
useTrash_ = trash;
|
|
||||||
if(deleteAction_) {
|
|
||||||
deleteAction_->setText(useTrash_ ? tr("&Move to Trash") : tr("&Delete"));
|
|
||||||
deleteAction_->setIcon(useTrash_ ? QIcon::fromTheme("user-trash") : QIcon::fromTheme("edit-delete"));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void FileMenu::onCompress() {
|
|
||||||
FmArchiver* archiver = fm_archiver_get_default();
|
|
||||||
if(archiver) {
|
|
||||||
FmPathList* paths = fm_path_list_new_from_file_info_list(files_);
|
|
||||||
fm_archiver_create_archive(archiver, NULL, paths);
|
|
||||||
fm_path_list_unref(paths);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void FileMenu::onExtract() {
|
|
||||||
FmArchiver* archiver = fm_archiver_get_default();
|
|
||||||
if(archiver) {
|
|
||||||
FmPathList* paths = fm_path_list_new_from_file_info_list(files_);
|
|
||||||
fm_archiver_extract_archives(archiver, NULL, paths);
|
|
||||||
fm_path_list_unref(paths);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void FileMenu::onExtractHere() {
|
|
||||||
FmArchiver* archiver = fm_archiver_get_default();
|
|
||||||
if(archiver) {
|
|
||||||
FmPathList* paths = fm_path_list_new_from_file_info_list(files_);
|
|
||||||
fm_archiver_extract_archives_to(archiver, NULL, paths, cwd_);
|
|
||||||
fm_path_list_unref(paths);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace Fm
|
|
||||||
218
src/filemenu.h
218
src/filemenu.h
@ -1,218 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (C) 2012 - 2015 Hong Jen Yee (PCMan) <pcman.tw@gmail.com>
|
|
||||||
*
|
|
||||||
* 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 FM_FILEMENU_H
|
|
||||||
#define FM_FILEMENU_H
|
|
||||||
|
|
||||||
#include "libfmqtglobals.h"
|
|
||||||
#include <QMenu>
|
|
||||||
#include <qabstractitemmodel.h>
|
|
||||||
#include <libfm/fm.h>
|
|
||||||
|
|
||||||
class QAction;
|
|
||||||
|
|
||||||
struct _FmFileActionItem;
|
|
||||||
|
|
||||||
namespace Fm {
|
|
||||||
|
|
||||||
class FileLauncher;
|
|
||||||
|
|
||||||
class LIBFM_QT_API FileMenu : public QMenu {
|
|
||||||
Q_OBJECT
|
|
||||||
|
|
||||||
public:
|
|
||||||
explicit FileMenu(FmFileInfoList* files, FmFileInfo* info, FmPath* cwd, QWidget* parent = 0);
|
|
||||||
explicit FileMenu(FmFileInfoList* files, FmFileInfo* info, FmPath* cwd, const QString& title, QWidget* parent = 0);
|
|
||||||
~FileMenu();
|
|
||||||
|
|
||||||
bool useTrash() {
|
|
||||||
return useTrash_;
|
|
||||||
}
|
|
||||||
|
|
||||||
void setUseTrash(bool trash);
|
|
||||||
|
|
||||||
bool confirmDelete() {
|
|
||||||
return confirmDelete_;
|
|
||||||
}
|
|
||||||
|
|
||||||
void setConfirmDelete(bool confirm) {
|
|
||||||
confirmDelete_ = confirm;
|
|
||||||
}
|
|
||||||
|
|
||||||
QAction* openAction() {
|
|
||||||
return openAction_;
|
|
||||||
}
|
|
||||||
|
|
||||||
QAction* openWithMenuAction() {
|
|
||||||
return openWithMenuAction_;
|
|
||||||
}
|
|
||||||
|
|
||||||
QAction* openWithAction() {
|
|
||||||
return openWithAction_;
|
|
||||||
}
|
|
||||||
|
|
||||||
QAction* separator1() {
|
|
||||||
return separator1_;
|
|
||||||
}
|
|
||||||
|
|
||||||
QAction* createAction() {
|
|
||||||
return createAction_;
|
|
||||||
}
|
|
||||||
|
|
||||||
QAction* separator2() {
|
|
||||||
return separator2_;
|
|
||||||
}
|
|
||||||
|
|
||||||
QAction* cutAction() {
|
|
||||||
return cutAction_;
|
|
||||||
}
|
|
||||||
|
|
||||||
QAction* copyAction() {
|
|
||||||
return copyAction_;
|
|
||||||
}
|
|
||||||
|
|
||||||
QAction* pasteAction() {
|
|
||||||
return pasteAction_;
|
|
||||||
}
|
|
||||||
|
|
||||||
QAction* deleteAction() {
|
|
||||||
return deleteAction_;
|
|
||||||
}
|
|
||||||
|
|
||||||
QAction* unTrashAction() {
|
|
||||||
return unTrashAction_;
|
|
||||||
}
|
|
||||||
|
|
||||||
QAction* renameAction() {
|
|
||||||
return renameAction_;
|
|
||||||
}
|
|
||||||
|
|
||||||
QAction* separator3() {
|
|
||||||
return separator3_;
|
|
||||||
}
|
|
||||||
|
|
||||||
QAction* propertiesAction() {
|
|
||||||
return propertiesAction_;
|
|
||||||
}
|
|
||||||
|
|
||||||
FmFileInfoList* files() {
|
|
||||||
return files_;
|
|
||||||
}
|
|
||||||
|
|
||||||
FmFileInfo* firstFile() {
|
|
||||||
return info_;
|
|
||||||
}
|
|
||||||
|
|
||||||
FmPath* cwd() {
|
|
||||||
return cwd_;
|
|
||||||
}
|
|
||||||
|
|
||||||
void setFileLauncher(FileLauncher* launcher) {
|
|
||||||
fileLauncher_ = launcher;
|
|
||||||
}
|
|
||||||
|
|
||||||
FileLauncher* fileLauncher() {
|
|
||||||
return fileLauncher_;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool sameType() const {
|
|
||||||
return sameType_;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool sameFilesystem() const {
|
|
||||||
return sameFilesystem_;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool allVirtual() const {
|
|
||||||
return allVirtual_;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool allTrash() const {
|
|
||||||
return allTrash_;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool confirmTrash() const {
|
|
||||||
return confirmTrash_;
|
|
||||||
}
|
|
||||||
|
|
||||||
void setConfirmTrash(bool value) {
|
|
||||||
confirmTrash_ = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected:
|
|
||||||
void createMenu(FmFileInfoList* files, FmFileInfo* info, FmPath* cwd);
|
|
||||||
#ifdef CUSTOM_ACTIONS
|
|
||||||
void addCustomActionItem(QMenu* menu, struct _FmFileActionItem* item);
|
|
||||||
#endif
|
|
||||||
void openFilesWithApp(GAppInfo* app);
|
|
||||||
|
|
||||||
protected Q_SLOTS:
|
|
||||||
void onOpenTriggered();
|
|
||||||
void onOpenWithTriggered();
|
|
||||||
void onFilePropertiesTriggered();
|
|
||||||
void onApplicationTriggered();
|
|
||||||
#ifdef CUSTOM_ACTIONS
|
|
||||||
void onCustomActionTrigerred();
|
|
||||||
#endif
|
|
||||||
void onCompress();
|
|
||||||
void onExtract();
|
|
||||||
void onExtractHere();
|
|
||||||
|
|
||||||
void onCutTriggered();
|
|
||||||
void onCopyTriggered();
|
|
||||||
void onPasteTriggered();
|
|
||||||
void onRenameTriggered();
|
|
||||||
void onDeleteTriggered();
|
|
||||||
void onUnTrashTriggered();
|
|
||||||
|
|
||||||
private:
|
|
||||||
FmFileInfoList* files_;
|
|
||||||
FmFileInfo* info_;
|
|
||||||
FmPath* cwd_;
|
|
||||||
bool useTrash_;
|
|
||||||
bool confirmDelete_;
|
|
||||||
bool confirmTrash_; // Confirm before moving files into "trash can"
|
|
||||||
|
|
||||||
bool sameType_;
|
|
||||||
bool sameFilesystem_;
|
|
||||||
bool allVirtual_;
|
|
||||||
bool allTrash_;
|
|
||||||
|
|
||||||
QAction* openAction_;
|
|
||||||
QAction* openWithMenuAction_;
|
|
||||||
QAction* openWithAction_;
|
|
||||||
QAction* separator1_;
|
|
||||||
QAction* createAction_;
|
|
||||||
QAction* separator2_;
|
|
||||||
QAction* cutAction_;
|
|
||||||
QAction* copyAction_;
|
|
||||||
QAction* pasteAction_;
|
|
||||||
QAction* deleteAction_;
|
|
||||||
QAction* unTrashAction_;
|
|
||||||
QAction* renameAction_;
|
|
||||||
QAction* separator3_;
|
|
||||||
QAction* propertiesAction_;
|
|
||||||
|
|
||||||
FileLauncher* fileLauncher_;
|
|
||||||
};
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif // FM_FILEMENU_H
|
|
||||||
@ -1,84 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (C) 2012 - 2015 Hong Jen Yee (PCMan) <pcman.tw@gmail.com>
|
|
||||||
*
|
|
||||||
* 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 FM_FILEMENU_P_H
|
|
||||||
#define FM_FILEMENU_P_H
|
|
||||||
|
|
||||||
#include "icontheme.h"
|
|
||||||
#ifdef CUSTOM_ACTIONS
|
|
||||||
#include <libfm/fm-actions.h>
|
|
||||||
#endif
|
|
||||||
#include <QDebug>
|
|
||||||
|
|
||||||
namespace Fm {
|
|
||||||
|
|
||||||
class AppInfoAction : public QAction {
|
|
||||||
Q_OBJECT
|
|
||||||
public:
|
|
||||||
explicit AppInfoAction(GAppInfo* app, QObject* parent = 0):
|
|
||||||
QAction(QString::fromUtf8(g_app_info_get_name(app)), parent),
|
|
||||||
appInfo_(G_APP_INFO(g_object_ref(app))) {
|
|
||||||
setToolTip(QString::fromUtf8(g_app_info_get_description(app)));
|
|
||||||
GIcon* gicon = g_app_info_get_icon(app);
|
|
||||||
QIcon icon = IconTheme::icon(gicon);
|
|
||||||
setIcon(icon);
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual ~AppInfoAction() {
|
|
||||||
if(appInfo_)
|
|
||||||
g_object_unref(appInfo_);
|
|
||||||
}
|
|
||||||
|
|
||||||
GAppInfo* appInfo() const {
|
|
||||||
return appInfo_;
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
GAppInfo* appInfo_;
|
|
||||||
};
|
|
||||||
|
|
||||||
#ifdef CUSTOM_ACTIONS
|
|
||||||
class CustomAction : public QAction {
|
|
||||||
Q_OBJECT
|
|
||||||
public:
|
|
||||||
explicit CustomAction(FmFileActionItem* item, QObject* parent = NULL):
|
|
||||||
QAction(QString::fromUtf8(fm_file_action_item_get_name(item)), parent),
|
|
||||||
item_(reinterpret_cast<FmFileActionItem*>(fm_file_action_item_ref(item))) {
|
|
||||||
const char* icon_name = fm_file_action_item_get_icon(item);
|
|
||||||
if(icon_name)
|
|
||||||
setIcon(QIcon::fromTheme(icon_name));
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual ~CustomAction() {
|
|
||||||
fm_file_action_item_unref(item_);
|
|
||||||
}
|
|
||||||
|
|
||||||
FmFileActionItem* item() {
|
|
||||||
return item_;
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
FmFileActionItem* item_;
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
} // namespace Fm
|
|
||||||
|
|
||||||
#endif
|
|
||||||
@ -1,307 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (C) 2012 - 2015 Hong Jen Yee (PCMan) <pcman.tw@gmail.com>
|
|
||||||
*
|
|
||||||
* 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 "fileoperation.h"
|
|
||||||
#include "fileoperationdialog.h"
|
|
||||||
#include <QTimer>
|
|
||||||
#include <QElapsedTimer>
|
|
||||||
#include <QMessageBox>
|
|
||||||
#include <QDebug>
|
|
||||||
|
|
||||||
namespace Fm {
|
|
||||||
|
|
||||||
#define SHOW_DLG_DELAY 1000
|
|
||||||
|
|
||||||
FileOperation::FileOperation(Type type, FmPathList* srcFiles, QObject* parent):
|
|
||||||
QObject(parent),
|
|
||||||
dlg(NULL),
|
|
||||||
destPath(NULL),
|
|
||||||
srcPaths(fm_path_list_ref(srcFiles)),
|
|
||||||
uiTimer(NULL),
|
|
||||||
elapsedTimer_(NULL),
|
|
||||||
lastElapsed_(0),
|
|
||||||
updateRemainingTime_(true),
|
|
||||||
autoDestroy_(true),
|
|
||||||
job_(fm_file_ops_job_new((FmFileOpType)type, srcFiles)) {
|
|
||||||
|
|
||||||
g_signal_connect(job_, "ask", G_CALLBACK(onFileOpsJobAsk), this);
|
|
||||||
g_signal_connect(job_, "ask-rename", G_CALLBACK(onFileOpsJobAskRename), this);
|
|
||||||
g_signal_connect(job_, "error", G_CALLBACK(onFileOpsJobError), this);
|
|
||||||
g_signal_connect(job_, "prepared", G_CALLBACK(onFileOpsJobPrepared), this);
|
|
||||||
g_signal_connect(job_, "cur-file", G_CALLBACK(onFileOpsJobCurFile), this);
|
|
||||||
g_signal_connect(job_, "percent", G_CALLBACK(onFileOpsJobPercent), this);
|
|
||||||
g_signal_connect(job_, "finished", G_CALLBACK(onFileOpsJobFinished), this);
|
|
||||||
g_signal_connect(job_, "cancelled", G_CALLBACK(onFileOpsJobCancelled), this);
|
|
||||||
}
|
|
||||||
|
|
||||||
void FileOperation::disconnectJob() {
|
|
||||||
g_signal_handlers_disconnect_by_func(job_, (gpointer)G_CALLBACK(onFileOpsJobAsk), this);
|
|
||||||
g_signal_handlers_disconnect_by_func(job_, (gpointer)G_CALLBACK(onFileOpsJobAskRename), this);
|
|
||||||
g_signal_handlers_disconnect_by_func(job_, (gpointer)G_CALLBACK(onFileOpsJobError), this);
|
|
||||||
g_signal_handlers_disconnect_by_func(job_, (gpointer)G_CALLBACK(onFileOpsJobPrepared), this);
|
|
||||||
g_signal_handlers_disconnect_by_func(job_, (gpointer)G_CALLBACK(onFileOpsJobCurFile), this);
|
|
||||||
g_signal_handlers_disconnect_by_func(job_, (gpointer)G_CALLBACK(onFileOpsJobPercent), this);
|
|
||||||
g_signal_handlers_disconnect_by_func(job_, (gpointer)G_CALLBACK(onFileOpsJobFinished), this);
|
|
||||||
g_signal_handlers_disconnect_by_func(job_, (gpointer)G_CALLBACK(onFileOpsJobCancelled), this);
|
|
||||||
}
|
|
||||||
|
|
||||||
FileOperation::~FileOperation() {
|
|
||||||
if(uiTimer) {
|
|
||||||
uiTimer->stop();
|
|
||||||
delete uiTimer;
|
|
||||||
uiTimer = NULL;
|
|
||||||
}
|
|
||||||
if(elapsedTimer_) {
|
|
||||||
delete elapsedTimer_;
|
|
||||||
elapsedTimer_ = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(job_) {
|
|
||||||
disconnectJob();
|
|
||||||
g_object_unref(job_);
|
|
||||||
}
|
|
||||||
|
|
||||||
if(srcPaths)
|
|
||||||
fm_path_list_unref(srcPaths);
|
|
||||||
|
|
||||||
if(destPath)
|
|
||||||
fm_path_unref(destPath);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool FileOperation::run() {
|
|
||||||
delete uiTimer;
|
|
||||||
// run the job
|
|
||||||
uiTimer = new QTimer();
|
|
||||||
uiTimer->start(SHOW_DLG_DELAY);
|
|
||||||
connect(uiTimer, &QTimer::timeout, this, &FileOperation::onUiTimeout);
|
|
||||||
|
|
||||||
return fm_job_run_async(FM_JOB(job_));
|
|
||||||
}
|
|
||||||
|
|
||||||
void FileOperation::onUiTimeout() {
|
|
||||||
if(dlg) {
|
|
||||||
dlg->setCurFile(curFile);
|
|
||||||
// estimate remaining time based on past history
|
|
||||||
// FIXME: avoid directly access data member of FmFileOpsJob
|
|
||||||
if(Q_LIKELY(job_->percent > 0 && updateRemainingTime_)) {
|
|
||||||
gint64 remaining = elapsedTime() * ((double(100 - job_->percent) / job_->percent) / 1000);
|
|
||||||
dlg->setRemainingTime(remaining);
|
|
||||||
}
|
|
||||||
// this timeout slot is called every 0.5 second.
|
|
||||||
// by adding this flag, we can update remaining time every 1 second.
|
|
||||||
updateRemainingTime_ = !updateRemainingTime_;
|
|
||||||
}
|
|
||||||
else{
|
|
||||||
showDialog();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void FileOperation::showDialog() {
|
|
||||||
if(!dlg) {
|
|
||||||
dlg = new FileOperationDialog(this);
|
|
||||||
dlg->setSourceFiles(srcPaths);
|
|
||||||
|
|
||||||
if(destPath)
|
|
||||||
dlg->setDestPath(destPath);
|
|
||||||
|
|
||||||
if(curFile.isEmpty()) {
|
|
||||||
dlg->setPrepared();
|
|
||||||
dlg->setCurFile(curFile);
|
|
||||||
}
|
|
||||||
uiTimer->setInterval(500); // change the interval of the timer
|
|
||||||
// now the timer is used to update current file display
|
|
||||||
dlg->show();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
gint FileOperation::onFileOpsJobAsk(FmFileOpsJob* job, const char* question, char*const* options, FileOperation* pThis) {
|
|
||||||
pThis->pauseElapsedTimer();
|
|
||||||
pThis->showDialog();
|
|
||||||
int ret = pThis->dlg->ask(QString::fromUtf8(question), options);
|
|
||||||
pThis->resumeElapsedTimer();
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
gint FileOperation::onFileOpsJobAskRename(FmFileOpsJob* job, FmFileInfo* src, FmFileInfo* dest, char** new_name, FileOperation* pThis) {
|
|
||||||
pThis->pauseElapsedTimer();
|
|
||||||
pThis->showDialog();
|
|
||||||
QString newName;
|
|
||||||
int ret = pThis->dlg->askRename(src, dest, newName);
|
|
||||||
if(!newName.isEmpty()) {
|
|
||||||
*new_name = g_strdup(newName.toUtf8().constData());
|
|
||||||
}
|
|
||||||
pThis->resumeElapsedTimer();
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
void FileOperation::onFileOpsJobCancelled(FmFileOpsJob* job, FileOperation* pThis) {
|
|
||||||
qDebug("file operation is cancelled!");
|
|
||||||
}
|
|
||||||
|
|
||||||
void FileOperation::onFileOpsJobCurFile(FmFileOpsJob* job, const char* cur_file, FileOperation* pThis) {
|
|
||||||
pThis->curFile = QString::fromUtf8(cur_file);
|
|
||||||
|
|
||||||
// We update the current file name in a timeout slot because drawing a string
|
|
||||||
// in the UI is expansive. Updating the label text too often cause
|
|
||||||
// significant impact on performance.
|
|
||||||
// if(pThis->dlg)
|
|
||||||
// pThis->dlg->setCurFile(pThis->curFile);
|
|
||||||
}
|
|
||||||
|
|
||||||
FmJobErrorAction FileOperation::onFileOpsJobError(FmFileOpsJob* job, GError* err, FmJobErrorSeverity severity, FileOperation* pThis) {
|
|
||||||
pThis->pauseElapsedTimer();
|
|
||||||
pThis->showDialog();
|
|
||||||
FmJobErrorAction act = pThis->dlg->error(err, severity);
|
|
||||||
pThis->resumeElapsedTimer();
|
|
||||||
return act;
|
|
||||||
}
|
|
||||||
|
|
||||||
void FileOperation::onFileOpsJobFinished(FmFileOpsJob* job, FileOperation* pThis) {
|
|
||||||
pThis->handleFinish();
|
|
||||||
}
|
|
||||||
|
|
||||||
void FileOperation::onFileOpsJobPercent(FmFileOpsJob* job, guint percent, FileOperation* pThis) {
|
|
||||||
if(pThis->dlg) {
|
|
||||||
pThis->dlg->setPercent(percent);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void FileOperation::onFileOpsJobPrepared(FmFileOpsJob* job, FileOperation* pThis) {
|
|
||||||
if(!pThis->elapsedTimer_) {
|
|
||||||
pThis->elapsedTimer_ = new QElapsedTimer();
|
|
||||||
pThis->elapsedTimer_->start();
|
|
||||||
}
|
|
||||||
if(pThis->dlg) {
|
|
||||||
pThis->dlg->setPrepared();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void FileOperation::handleFinish() {
|
|
||||||
disconnectJob();
|
|
||||||
|
|
||||||
if(uiTimer) {
|
|
||||||
uiTimer->stop();
|
|
||||||
delete uiTimer;
|
|
||||||
uiTimer = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(dlg) {
|
|
||||||
dlg->done(QDialog::Accepted);
|
|
||||||
delete dlg;
|
|
||||||
dlg = NULL;
|
|
||||||
}
|
|
||||||
Q_EMIT finished();
|
|
||||||
|
|
||||||
/* sepcial handling for trash
|
|
||||||
* FIXME: need to refactor this to use a more elegant way later. */
|
|
||||||
if(job_->type == FM_FILE_OP_TRASH) { /* FIXME: direct access to job struct! */
|
|
||||||
FmPathList* unable_to_trash = static_cast<FmPathList*>(g_object_get_data(G_OBJECT(job_), "trash-unsupported"));
|
|
||||||
/* some files cannot be trashed because underlying filesystems don't support it. */
|
|
||||||
if(unable_to_trash) { /* delete them instead */
|
|
||||||
/* FIXME: parent window might be already destroyed! */
|
|
||||||
QWidget* parent = NULL; // FIXME: currently, parent window is not set
|
|
||||||
if(QMessageBox::question(parent, tr("Error"),
|
|
||||||
tr("Some files cannot be moved to trash can because "
|
|
||||||
"the underlying file systems don't support this operation.\n"
|
|
||||||
"Do you want to delete them instead?")) == QMessageBox::Yes) {
|
|
||||||
deleteFiles(unable_to_trash, false);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
g_object_unref(job_);
|
|
||||||
job_ = NULL;
|
|
||||||
|
|
||||||
if(autoDestroy_)
|
|
||||||
delete this;
|
|
||||||
}
|
|
||||||
|
|
||||||
// static
|
|
||||||
FileOperation* FileOperation::copyFiles(FmPathList* srcFiles, FmPath* dest, QWidget* parent) {
|
|
||||||
FileOperation* op = new FileOperation(FileOperation::Copy, srcFiles);
|
|
||||||
op->setDestination(dest);
|
|
||||||
op->run();
|
|
||||||
return op;
|
|
||||||
}
|
|
||||||
|
|
||||||
// static
|
|
||||||
FileOperation* FileOperation::moveFiles(FmPathList* srcFiles, FmPath* dest, QWidget* parent) {
|
|
||||||
FileOperation* op = new FileOperation(FileOperation::Move, srcFiles);
|
|
||||||
op->setDestination(dest);
|
|
||||||
op->run();
|
|
||||||
return op;
|
|
||||||
}
|
|
||||||
|
|
||||||
//static
|
|
||||||
FileOperation* FileOperation::symlinkFiles(FmPathList* srcFiles, FmPath* dest, QWidget* parent) {
|
|
||||||
FileOperation* op = new FileOperation(FileOperation::Link, srcFiles);
|
|
||||||
op->setDestination(dest);
|
|
||||||
op->run();
|
|
||||||
return op;
|
|
||||||
}
|
|
||||||
|
|
||||||
//static
|
|
||||||
FileOperation* FileOperation::deleteFiles(FmPathList* srcFiles, bool prompt, QWidget* parent) {
|
|
||||||
if(prompt) {
|
|
||||||
int result = QMessageBox::warning(parent, tr("Confirm"),
|
|
||||||
tr("Do you want to delete the selected files?"),
|
|
||||||
QMessageBox::Yes|QMessageBox::No,
|
|
||||||
QMessageBox::No);
|
|
||||||
if(result != QMessageBox::Yes)
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
FileOperation* op = new FileOperation(FileOperation::Delete, srcFiles);
|
|
||||||
op->run();
|
|
||||||
return op;
|
|
||||||
}
|
|
||||||
|
|
||||||
//static
|
|
||||||
FileOperation* FileOperation::trashFiles(FmPathList* srcFiles, bool prompt, QWidget* parent) {
|
|
||||||
if(prompt) {
|
|
||||||
int result = QMessageBox::warning(parent, tr("Confirm"),
|
|
||||||
tr("Do you want to move the selected files to trash can?"),
|
|
||||||
QMessageBox::Yes|QMessageBox::No,
|
|
||||||
QMessageBox::No);
|
|
||||||
if(result != QMessageBox::Yes)
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
FileOperation* op = new FileOperation(FileOperation::Trash, srcFiles);
|
|
||||||
op->run();
|
|
||||||
return op;
|
|
||||||
}
|
|
||||||
|
|
||||||
//static
|
|
||||||
FileOperation* FileOperation::unTrashFiles(FmPathList* srcFiles, QWidget* parent) {
|
|
||||||
FileOperation* op = new FileOperation(FileOperation::UnTrash, srcFiles);
|
|
||||||
op->run();
|
|
||||||
return op;
|
|
||||||
}
|
|
||||||
|
|
||||||
// static
|
|
||||||
FileOperation* FileOperation::changeAttrFiles(FmPathList* srcFiles, QWidget* parent) {
|
|
||||||
//TODO
|
|
||||||
FileOperation* op = new FileOperation(FileOperation::ChangeAttr, srcFiles);
|
|
||||||
op->run();
|
|
||||||
return op;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
} // namespace Fm
|
|
||||||
@ -1,164 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (C) 2012 - 2015 Hong Jen Yee (PCMan) <pcman.tw@gmail.com>
|
|
||||||
*
|
|
||||||
* 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 FM_FILEOPERATION_H
|
|
||||||
#define FM_FILEOPERATION_H
|
|
||||||
|
|
||||||
#include "libfmqtglobals.h"
|
|
||||||
#include <QObject>
|
|
||||||
#include <QElapsedTimer>
|
|
||||||
#include <libfm/fm.h>
|
|
||||||
|
|
||||||
class QTimer;
|
|
||||||
|
|
||||||
namespace Fm {
|
|
||||||
|
|
||||||
class FileOperationDialog;
|
|
||||||
|
|
||||||
class LIBFM_QT_API FileOperation : public QObject {
|
|
||||||
Q_OBJECT
|
|
||||||
public:
|
|
||||||
enum Type {
|
|
||||||
Copy = FM_FILE_OP_COPY,
|
|
||||||
Move = FM_FILE_OP_MOVE,
|
|
||||||
Link = FM_FILE_OP_LINK,
|
|
||||||
Delete = FM_FILE_OP_DELETE,
|
|
||||||
Trash = FM_FILE_OP_TRASH,
|
|
||||||
UnTrash = FM_FILE_OP_UNTRASH,
|
|
||||||
ChangeAttr = FM_FILE_OP_CHANGE_ATTR
|
|
||||||
};
|
|
||||||
|
|
||||||
public:
|
|
||||||
explicit FileOperation(Type type, FmPathList* srcFiles, QObject* parent = 0);
|
|
||||||
virtual ~FileOperation();
|
|
||||||
|
|
||||||
void setDestination(FmPath* dest) {
|
|
||||||
destPath = fm_path_ref(dest);
|
|
||||||
fm_file_ops_job_set_dest(job_, dest);
|
|
||||||
}
|
|
||||||
|
|
||||||
void setChmod(mode_t newMode, mode_t newModeMask) {
|
|
||||||
fm_file_ops_job_set_chmod(job_, newMode, newModeMask);
|
|
||||||
}
|
|
||||||
|
|
||||||
void setChown(gint uid, gint gid) {
|
|
||||||
fm_file_ops_job_set_chown(job_, uid, gid);
|
|
||||||
}
|
|
||||||
|
|
||||||
// This only work for change attr jobs.
|
|
||||||
void setRecursiveChattr(bool recursive) {
|
|
||||||
fm_file_ops_job_set_recursive(job_, (gboolean)recursive);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool run();
|
|
||||||
|
|
||||||
void cancel() {
|
|
||||||
if(job_)
|
|
||||||
fm_job_cancel(FM_JOB(job_));
|
|
||||||
}
|
|
||||||
|
|
||||||
bool isRunning() const {
|
|
||||||
return job_ ? fm_job_is_running(FM_JOB(job_)) : false;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool isCancelled() const {
|
|
||||||
return job_ ? fm_job_is_cancelled(FM_JOB(job_)) : false;
|
|
||||||
}
|
|
||||||
|
|
||||||
FmFileOpsJob* job() {
|
|
||||||
return job_;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool autoDestroy() {
|
|
||||||
return autoDestroy_;
|
|
||||||
}
|
|
||||||
void setAutoDestroy(bool destroy = true) {
|
|
||||||
autoDestroy_ = destroy;
|
|
||||||
}
|
|
||||||
|
|
||||||
Type type() {
|
|
||||||
return (Type)job_->type;
|
|
||||||
}
|
|
||||||
|
|
||||||
// convinient static functions
|
|
||||||
static FileOperation* copyFiles(FmPathList* srcFiles, FmPath* dest, QWidget* parent = 0);
|
|
||||||
static FileOperation* moveFiles(FmPathList* srcFiles, FmPath* dest, QWidget* parent = 0);
|
|
||||||
static FileOperation* symlinkFiles(FmPathList* srcFiles, FmPath* dest, QWidget* parent = 0);
|
|
||||||
static FileOperation* deleteFiles(FmPathList* srcFiles, bool promp = true, QWidget* parent = 0);
|
|
||||||
static FileOperation* trashFiles(FmPathList* srcFiles, bool promp = true, QWidget* parent = 0);
|
|
||||||
static FileOperation* unTrashFiles(FmPathList* srcFiles, QWidget* parent = 0);
|
|
||||||
static FileOperation* changeAttrFiles(FmPathList* srcFiles, QWidget* parent = 0);
|
|
||||||
|
|
||||||
Q_SIGNALS:
|
|
||||||
void finished();
|
|
||||||
|
|
||||||
private:
|
|
||||||
static gint onFileOpsJobAsk(FmFileOpsJob* job, const char* question, char* const* options, FileOperation* pThis);
|
|
||||||
static gint onFileOpsJobAskRename(FmFileOpsJob* job, FmFileInfo* src, FmFileInfo* dest, char** new_name, FileOperation* pThis);
|
|
||||||
static FmJobErrorAction onFileOpsJobError(FmFileOpsJob* job, GError* err, FmJobErrorSeverity severity, FileOperation* pThis);
|
|
||||||
static void onFileOpsJobPrepared(FmFileOpsJob* job, FileOperation* pThis);
|
|
||||||
static void onFileOpsJobCurFile(FmFileOpsJob* job, const char* cur_file, FileOperation* pThis);
|
|
||||||
static void onFileOpsJobPercent(FmFileOpsJob* job, guint percent, FileOperation* pThis);
|
|
||||||
static void onFileOpsJobFinished(FmFileOpsJob* job, FileOperation* pThis);
|
|
||||||
static void onFileOpsJobCancelled(FmFileOpsJob* job, FileOperation* pThis);
|
|
||||||
|
|
||||||
void handleFinish();
|
|
||||||
void disconnectJob();
|
|
||||||
void showDialog();
|
|
||||||
|
|
||||||
void pauseElapsedTimer() {
|
|
||||||
if(Q_LIKELY(elapsedTimer_ != NULL)) {
|
|
||||||
lastElapsed_ += elapsedTimer_->elapsed();
|
|
||||||
elapsedTimer_->invalidate();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void resumeElapsedTimer() {
|
|
||||||
if(Q_LIKELY(elapsedTimer_ != NULL)) {
|
|
||||||
elapsedTimer_->start();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
qint64 elapsedTime() {
|
|
||||||
if(Q_LIKELY(elapsedTimer_ != NULL)) {
|
|
||||||
return lastElapsed_ + elapsedTimer_->elapsed();
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
private Q_SLOTS:
|
|
||||||
void onUiTimeout();
|
|
||||||
|
|
||||||
private:
|
|
||||||
FmFileOpsJob* job_;
|
|
||||||
FileOperationDialog* dlg;
|
|
||||||
FmPath* destPath;
|
|
||||||
FmPathList* srcPaths;
|
|
||||||
QTimer* uiTimer;
|
|
||||||
QElapsedTimer* elapsedTimer_;
|
|
||||||
qint64 lastElapsed_;
|
|
||||||
bool updateRemainingTime_;
|
|
||||||
QString curFile;
|
|
||||||
bool autoDestroy_;
|
|
||||||
};
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif // FM_FILEOPERATION_H
|
|
||||||
@ -1,178 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (C) 2012 - 2015 Hong Jen Yee (PCMan) <pcman.tw@gmail.com>
|
|
||||||
*
|
|
||||||
* 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 "fileoperationdialog.h"
|
|
||||||
#include "fileoperation.h"
|
|
||||||
#include "renamedialog.h"
|
|
||||||
#include <QMessageBox>
|
|
||||||
#include "ui_file-operation-dialog.h"
|
|
||||||
|
|
||||||
namespace Fm {
|
|
||||||
|
|
||||||
FileOperationDialog::FileOperationDialog(FileOperation* _operation):
|
|
||||||
QDialog(NULL),
|
|
||||||
operation(_operation),
|
|
||||||
defaultOption(-1) {
|
|
||||||
|
|
||||||
ui = new Ui::FileOperationDialog();
|
|
||||||
ui->setupUi(this);
|
|
||||||
|
|
||||||
QString title;
|
|
||||||
QString message;
|
|
||||||
switch(_operation->type()) {
|
|
||||||
case FM_FILE_OP_MOVE:
|
|
||||||
title = tr("Move files");
|
|
||||||
message = tr("Moving the following files to destination folder:");
|
|
||||||
break;
|
|
||||||
case FM_FILE_OP_COPY:
|
|
||||||
title = tr("Copy Files");
|
|
||||||
message = tr("Copying the following files to destination folder:");
|
|
||||||
break;
|
|
||||||
case FM_FILE_OP_TRASH:
|
|
||||||
title = tr("Trash Files");
|
|
||||||
message = tr("Moving the following files to trash can:");
|
|
||||||
break;
|
|
||||||
case FM_FILE_OP_DELETE:
|
|
||||||
title = tr("Delete Files");
|
|
||||||
message = tr("Deleting the following files");
|
|
||||||
ui->dest->hide();
|
|
||||||
ui->destLabel->hide();
|
|
||||||
break;
|
|
||||||
case FM_FILE_OP_LINK:
|
|
||||||
title = tr("Create Symlinks");
|
|
||||||
message = tr("Creating symlinks for the following files:");
|
|
||||||
break;
|
|
||||||
case FM_FILE_OP_CHANGE_ATTR:
|
|
||||||
title = tr("Change Attributes");
|
|
||||||
message = tr("Changing attributes of the following files:");
|
|
||||||
ui->dest->hide();
|
|
||||||
ui->destLabel->hide();
|
|
||||||
break;
|
|
||||||
case FM_FILE_OP_UNTRASH:
|
|
||||||
title = tr("Restore Trashed Files");
|
|
||||||
message = tr("Restoring the following files from trash can:");
|
|
||||||
ui->dest->hide();
|
|
||||||
ui->destLabel->hide();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
ui->message->setText(message);
|
|
||||||
setWindowTitle(title);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
FileOperationDialog::~FileOperationDialog() {
|
|
||||||
delete ui;
|
|
||||||
}
|
|
||||||
|
|
||||||
void FileOperationDialog::setDestPath(FmPath* dest) {
|
|
||||||
char* pathStr = fm_path_display_name(dest, false);
|
|
||||||
ui->dest->setText(QString::fromUtf8(pathStr));
|
|
||||||
g_free(pathStr);
|
|
||||||
}
|
|
||||||
|
|
||||||
void FileOperationDialog::setSourceFiles(FmPathList* srcFiles) {
|
|
||||||
GList* l;
|
|
||||||
for(l = fm_path_list_peek_head_link(srcFiles); l; l = l->next) {
|
|
||||||
FmPath* path = FM_PATH(l->data);
|
|
||||||
char* pathStr = fm_path_display_name(path, false);
|
|
||||||
ui->sourceFiles->addItem(QString::fromUtf8(pathStr));
|
|
||||||
g_free(pathStr);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
int FileOperationDialog::ask(QString question, char*const* options) {
|
|
||||||
// TODO: implement FileOperationDialog::ask()
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int FileOperationDialog::askRename(FmFileInfo* src, FmFileInfo* dest, QString& new_name) {
|
|
||||||
int ret;
|
|
||||||
if(defaultOption == -1) { // default action is not set, ask the user
|
|
||||||
RenameDialog dlg(src, dest, this);
|
|
||||||
dlg.exec();
|
|
||||||
switch(dlg.action()) {
|
|
||||||
case RenameDialog::ActionOverwrite:
|
|
||||||
ret = FM_FILE_OP_OVERWRITE;
|
|
||||||
if(dlg.applyToAll())
|
|
||||||
defaultOption = ret;
|
|
||||||
break;
|
|
||||||
case RenameDialog::ActionRename:
|
|
||||||
ret = FM_FILE_OP_RENAME;
|
|
||||||
new_name = dlg.newName();
|
|
||||||
break;
|
|
||||||
case RenameDialog::ActionIgnore:
|
|
||||||
ret = FM_FILE_OP_SKIP;
|
|
||||||
if(dlg.applyToAll())
|
|
||||||
defaultOption = ret;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
ret = FM_FILE_OP_CANCEL;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
ret = defaultOption;
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
FmJobErrorAction FileOperationDialog::error(GError* err, FmJobErrorSeverity severity) {
|
|
||||||
if(severity >= FM_JOB_ERROR_MODERATE) {
|
|
||||||
QMessageBox::critical(this, tr("Error"), QString::fromUtf8(err->message));
|
|
||||||
if(severity == FM_JOB_ERROR_CRITICAL)
|
|
||||||
return FM_JOB_ABORT;
|
|
||||||
}
|
|
||||||
return FM_JOB_CONTINUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
void FileOperationDialog::setCurFile(QString cur_file) {
|
|
||||||
ui->curFile->setText(cur_file);
|
|
||||||
}
|
|
||||||
|
|
||||||
void FileOperationDialog::setPercent(unsigned int percent) {
|
|
||||||
ui->progressBar->setValue(percent);
|
|
||||||
}
|
|
||||||
|
|
||||||
void FileOperationDialog::setRemainingTime(unsigned int sec) {
|
|
||||||
unsigned int min = 0;
|
|
||||||
unsigned int hr = 0;
|
|
||||||
if(sec > 60) {
|
|
||||||
min = sec / 60;
|
|
||||||
sec %= 60;
|
|
||||||
if(min > 60) {
|
|
||||||
hr = min / 60;
|
|
||||||
min %= 60;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
ui->timeRemaining->setText(QString("%1:%2:%3")
|
|
||||||
.arg(hr, 2, 10, QChar('0'))
|
|
||||||
.arg(min, 2, 10, QChar('0'))
|
|
||||||
.arg(sec, 2, 10, QChar('0')));
|
|
||||||
}
|
|
||||||
|
|
||||||
void FileOperationDialog::setPrepared() {
|
|
||||||
}
|
|
||||||
|
|
||||||
void FileOperationDialog::reject() {
|
|
||||||
operation->cancel();
|
|
||||||
QDialog::reject();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
} // namespace Fm
|
|
||||||
@ -1,63 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (C) 2012 - 2015 Hong Jen Yee (PCMan) <pcman.tw@gmail.com>
|
|
||||||
*
|
|
||||||
* 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 FM_FILEOPERATIONDIALOG_H
|
|
||||||
#define FM_FILEOPERATIONDIALOG_H
|
|
||||||
|
|
||||||
#include "libfmqtglobals.h"
|
|
||||||
#include <QDialog>
|
|
||||||
#include <libfm/fm.h>
|
|
||||||
|
|
||||||
namespace Ui {
|
|
||||||
class FileOperationDialog;
|
|
||||||
};
|
|
||||||
|
|
||||||
namespace Fm {
|
|
||||||
|
|
||||||
class FileOperation;
|
|
||||||
|
|
||||||
class LIBFM_QT_API FileOperationDialog : public QDialog {
|
|
||||||
Q_OBJECT
|
|
||||||
public:
|
|
||||||
explicit FileOperationDialog(FileOperation* _operation);
|
|
||||||
virtual ~FileOperationDialog();
|
|
||||||
|
|
||||||
void setSourceFiles(FmPathList* srcFiles);
|
|
||||||
void setDestPath(FmPath* dest);
|
|
||||||
|
|
||||||
int ask(QString question, char* const* options);
|
|
||||||
int askRename(FmFileInfo* src, FmFileInfo* dest, QString& new_name);
|
|
||||||
FmJobErrorAction error(GError* err, FmJobErrorSeverity severity);
|
|
||||||
void setPrepared();
|
|
||||||
void setCurFile(QString cur_file);
|
|
||||||
void setPercent(unsigned int percent);
|
|
||||||
void setRemainingTime(unsigned int sec);
|
|
||||||
|
|
||||||
virtual void reject();
|
|
||||||
|
|
||||||
private:
|
|
||||||
Ui::FileOperationDialog* ui;
|
|
||||||
FileOperation* operation;
|
|
||||||
int defaultOption;
|
|
||||||
};
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif // FM_FILEOPERATIONDIALOG_H
|
|
||||||
@ -1,444 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (C) 2012 - 2015 Hong Jen Yee (PCMan) <pcman.tw@gmail.com>
|
|
||||||
*
|
|
||||||
* 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 "filepropsdialog.h"
|
|
||||||
#include "ui_file-props.h"
|
|
||||||
#include "icontheme.h"
|
|
||||||
#include "utilities.h"
|
|
||||||
#include "fileoperation.h"
|
|
||||||
#include <QStringBuilder>
|
|
||||||
#include <QStringListModel>
|
|
||||||
#include <QMessageBox>
|
|
||||||
#include <qdial.h>
|
|
||||||
#include <sys/types.h>
|
|
||||||
#include <time.h>
|
|
||||||
|
|
||||||
#define DIFFERENT_UIDS ((uid)-1)
|
|
||||||
#define DIFFERENT_GIDS ((gid)-1)
|
|
||||||
#define DIFFERENT_PERMS ((mode_t)-1)
|
|
||||||
|
|
||||||
namespace Fm {
|
|
||||||
|
|
||||||
enum {
|
|
||||||
ACCESS_NO_CHANGE = 0,
|
|
||||||
ACCESS_READ_ONLY,
|
|
||||||
ACCESS_READ_WRITE,
|
|
||||||
ACCESS_FORBID
|
|
||||||
};
|
|
||||||
|
|
||||||
FilePropsDialog::FilePropsDialog(FmFileInfoList* files, QWidget* parent, Qt::WindowFlags f):
|
|
||||||
QDialog(parent, f),
|
|
||||||
fileInfos_(fm_file_info_list_ref(files)),
|
|
||||||
singleType(fm_file_info_list_is_same_type(files)),
|
|
||||||
singleFile(fm_file_info_list_get_length(files) == 1 ? true:false),
|
|
||||||
fileInfo(fm_file_info_list_peek_head(files)),
|
|
||||||
mimeType(NULL) {
|
|
||||||
|
|
||||||
setAttribute(Qt::WA_DeleteOnClose);
|
|
||||||
|
|
||||||
ui = new Ui::FilePropsDialog();
|
|
||||||
ui->setupUi(this);
|
|
||||||
|
|
||||||
if(singleType) {
|
|
||||||
mimeType = fm_mime_type_ref(fm_file_info_get_mime_type(fileInfo));
|
|
||||||
}
|
|
||||||
|
|
||||||
FmPathList* paths = fm_path_list_new_from_file_info_list(files);
|
|
||||||
deepCountJob = fm_deep_count_job_new(paths, FM_DC_JOB_DEFAULT);
|
|
||||||
fm_path_list_unref(paths);
|
|
||||||
|
|
||||||
initGeneralPage();
|
|
||||||
initPermissionsPage();
|
|
||||||
}
|
|
||||||
|
|
||||||
FilePropsDialog::~FilePropsDialog() {
|
|
||||||
delete ui;
|
|
||||||
|
|
||||||
if(fileInfos_)
|
|
||||||
fm_file_info_list_unref(fileInfos_);
|
|
||||||
if(deepCountJob)
|
|
||||||
g_object_unref(deepCountJob);
|
|
||||||
if(fileSizeTimer) {
|
|
||||||
fileSizeTimer->stop();
|
|
||||||
delete fileSizeTimer;
|
|
||||||
fileSizeTimer = NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void FilePropsDialog::initApplications() {
|
|
||||||
if(singleType && mimeType && !fm_file_info_is_dir(fileInfo)) {
|
|
||||||
ui->openWith->setMimeType(mimeType);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
ui->openWith->hide();
|
|
||||||
ui->openWithLabel->hide();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void FilePropsDialog::initPermissionsPage() {
|
|
||||||
// ownership handling
|
|
||||||
// get owner/group and mode of the first file in the list
|
|
||||||
uid = fm_file_info_get_uid(fileInfo);
|
|
||||||
gid = fm_file_info_get_gid(fileInfo);
|
|
||||||
mode_t mode = fm_file_info_get_mode(fileInfo);
|
|
||||||
ownerPerm = (mode & (S_IRUSR|S_IWUSR|S_IXUSR));
|
|
||||||
groupPerm = (mode & (S_IRGRP|S_IWGRP|S_IXGRP));
|
|
||||||
otherPerm = (mode & (S_IROTH|S_IWOTH|S_IXOTH));
|
|
||||||
execPerm = (mode & (S_IXUSR|S_IXGRP|S_IXOTH));
|
|
||||||
allNative = fm_file_info_is_native(fileInfo);
|
|
||||||
hasDir = S_ISDIR(mode);
|
|
||||||
|
|
||||||
// check if all selected files belongs to the same owner/group or have the same mode
|
|
||||||
// at the same time, check if all files are on native unix filesystems
|
|
||||||
GList* l;
|
|
||||||
for(l = fm_file_info_list_peek_head_link(fileInfos_)->next; l; l = l->next) {
|
|
||||||
FmFileInfo* fi = FM_FILE_INFO(l->data);
|
|
||||||
if(allNative && !fm_file_info_is_native(fi))
|
|
||||||
allNative = false; // not all of the files are native
|
|
||||||
|
|
||||||
mode_t fi_mode = fm_file_info_get_mode(fi);
|
|
||||||
if(S_ISDIR(fi_mode))
|
|
||||||
hasDir = true; // the files list contains dir(s)
|
|
||||||
|
|
||||||
if(uid != DIFFERENT_UIDS && uid != fm_file_info_get_uid(fi))
|
|
||||||
uid = DIFFERENT_UIDS; // not all files have the same owner
|
|
||||||
if(gid != DIFFERENT_GIDS && gid != fm_file_info_get_gid(fi))
|
|
||||||
gid = DIFFERENT_GIDS; // not all files have the same owner group
|
|
||||||
|
|
||||||
if(ownerPerm != DIFFERENT_PERMS && ownerPerm != (fi_mode & (S_IRUSR|S_IWUSR|S_IXUSR)))
|
|
||||||
ownerPerm = DIFFERENT_PERMS; // not all files have the same permission for owner
|
|
||||||
if(groupPerm != DIFFERENT_PERMS && groupPerm != (fi_mode & (S_IRGRP|S_IWGRP|S_IXGRP)))
|
|
||||||
groupPerm = DIFFERENT_PERMS; // not all files have the same permission for grop
|
|
||||||
if(otherPerm != DIFFERENT_PERMS && otherPerm != (fi_mode & (S_IROTH|S_IWOTH|S_IXOTH)))
|
|
||||||
otherPerm = DIFFERENT_PERMS; // not all files have the same permission for other
|
|
||||||
if(execPerm != DIFFERENT_PERMS && execPerm != (fi_mode & (S_IXUSR|S_IXGRP|S_IXOTH)))
|
|
||||||
execPerm = DIFFERENT_PERMS; // not all files have the same executable permission
|
|
||||||
}
|
|
||||||
|
|
||||||
// init owner/group
|
|
||||||
initOwner();
|
|
||||||
|
|
||||||
// if all files are of the same type, and some of them are dirs => all of the items are dirs
|
|
||||||
// rwx values have different meanings for dirs
|
|
||||||
// Let's make it clear for the users
|
|
||||||
// init combo boxes for file permissions here
|
|
||||||
QStringList comboItems;
|
|
||||||
comboItems.append("---"); // no change
|
|
||||||
if(singleType && hasDir) { // all files are dirs
|
|
||||||
comboItems.append(tr("View folder content"));
|
|
||||||
comboItems.append(tr("View and modify folder content"));
|
|
||||||
ui->executable->hide();
|
|
||||||
}
|
|
||||||
else { //not all of the files are dirs
|
|
||||||
comboItems.append(tr("Read"));
|
|
||||||
comboItems.append(tr("Read and write"));
|
|
||||||
}
|
|
||||||
comboItems.append(tr("Forbidden"));
|
|
||||||
QStringListModel* comboModel = new QStringListModel(comboItems, this);
|
|
||||||
ui->ownerPerm->setModel(comboModel);
|
|
||||||
ui->groupPerm->setModel(comboModel);
|
|
||||||
ui->otherPerm->setModel(comboModel);
|
|
||||||
|
|
||||||
// owner
|
|
||||||
ownerPermSel = ACCESS_NO_CHANGE;
|
|
||||||
if(ownerPerm != DIFFERENT_PERMS) { // permissions for owner are the same among all files
|
|
||||||
if(ownerPerm & S_IRUSR) { // can read
|
|
||||||
if(ownerPerm & S_IWUSR) // can write
|
|
||||||
ownerPermSel = ACCESS_READ_WRITE;
|
|
||||||
else
|
|
||||||
ownerPermSel = ACCESS_READ_ONLY;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
if((ownerPerm & S_IWUSR) == 0) // cannot read or write
|
|
||||||
ownerPermSel = ACCESS_FORBID;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
ui->ownerPerm->setCurrentIndex(ownerPermSel);
|
|
||||||
|
|
||||||
// owner and group
|
|
||||||
groupPermSel = ACCESS_NO_CHANGE;
|
|
||||||
if(groupPerm != DIFFERENT_PERMS) { // permissions for owner are the same among all files
|
|
||||||
if(groupPerm & S_IRGRP) { // can read
|
|
||||||
if(groupPerm & S_IWGRP) // can write
|
|
||||||
groupPermSel = ACCESS_READ_WRITE;
|
|
||||||
else
|
|
||||||
groupPermSel = ACCESS_READ_ONLY;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
if((groupPerm & S_IWGRP) == 0) // cannot read or write
|
|
||||||
groupPermSel = ACCESS_FORBID;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
ui->groupPerm->setCurrentIndex(groupPermSel);
|
|
||||||
|
|
||||||
// other
|
|
||||||
otherPermSel = ACCESS_NO_CHANGE;
|
|
||||||
if(otherPerm != DIFFERENT_PERMS) { // permissions for owner are the same among all files
|
|
||||||
if(otherPerm & S_IROTH) { // can read
|
|
||||||
if(otherPerm & S_IWOTH) // can write
|
|
||||||
otherPermSel = ACCESS_READ_WRITE;
|
|
||||||
else
|
|
||||||
otherPermSel = ACCESS_READ_ONLY;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
if((otherPerm & S_IWOTH) == 0) // cannot read or write
|
|
||||||
otherPermSel = ACCESS_FORBID;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
ui->otherPerm->setCurrentIndex(otherPermSel);
|
|
||||||
|
|
||||||
// set the checkbox to partially checked state
|
|
||||||
// when owner, group, and other have different executable flags set.
|
|
||||||
// some of them have exec, and others do not have.
|
|
||||||
execCheckState = Qt::PartiallyChecked;
|
|
||||||
if(execPerm != DIFFERENT_PERMS) { // if all files have the same executable permission
|
|
||||||
// check if the files are all executable
|
|
||||||
if((mode & (S_IXUSR|S_IXGRP|S_IXOTH)) == (S_IXUSR|S_IXGRP|S_IXOTH)) {
|
|
||||||
// owner, group, and other all have exec permission.
|
|
||||||
ui->executable->setTristate(false);
|
|
||||||
execCheckState = Qt::Checked;
|
|
||||||
}
|
|
||||||
else if((mode & (S_IXUSR|S_IXGRP|S_IXOTH)) == 0) {
|
|
||||||
// owner, group, and other all have no exec permission
|
|
||||||
ui->executable->setTristate(false);
|
|
||||||
execCheckState = Qt::Unchecked;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
ui->executable->setCheckState(execCheckState);
|
|
||||||
}
|
|
||||||
|
|
||||||
void FilePropsDialog::initGeneralPage() {
|
|
||||||
// update UI
|
|
||||||
if(singleType) { // all files are of the same mime-type
|
|
||||||
FmIcon* icon = NULL;
|
|
||||||
// FIXME: handle custom icons for some files
|
|
||||||
// FIXME: display special property pages for special files or
|
|
||||||
// some specified mime-types.
|
|
||||||
if(singleFile) { // only one file is selected.
|
|
||||||
icon = fm_file_info_get_icon(fileInfo);
|
|
||||||
}
|
|
||||||
if(mimeType) {
|
|
||||||
if(!icon) // get an icon from mime type if needed
|
|
||||||
icon = fm_mime_type_get_icon(mimeType);
|
|
||||||
ui->fileType->setText(QString::fromUtf8(fm_mime_type_get_desc(mimeType)));
|
|
||||||
ui->mimeType->setText(QString::fromUtf8(fm_mime_type_get_type(mimeType)));
|
|
||||||
}
|
|
||||||
if(icon) {
|
|
||||||
ui->iconButton->setIcon(IconTheme::icon(icon));
|
|
||||||
}
|
|
||||||
|
|
||||||
if(singleFile && fm_file_info_is_symlink(fileInfo)) {
|
|
||||||
ui->target->setText(QString::fromUtf8(fm_file_info_get_target(fileInfo)));
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
ui->target->hide();
|
|
||||||
ui->targetLabel->hide();
|
|
||||||
}
|
|
||||||
} // end if(singleType)
|
|
||||||
else { // not singleType, multiple files are selected at the same time
|
|
||||||
ui->fileType->setText(tr("Files of different types"));
|
|
||||||
ui->target->hide();
|
|
||||||
ui->targetLabel->hide();
|
|
||||||
}
|
|
||||||
|
|
||||||
// FIXME: check if all files has the same parent dir, mtime, or atime
|
|
||||||
if(singleFile) { // only one file is selected
|
|
||||||
FmPath* parent_path = fm_path_get_parent(fm_file_info_get_path(fileInfo));
|
|
||||||
char* parent_str = parent_path ? fm_path_display_name(parent_path, true) : NULL;
|
|
||||||
|
|
||||||
ui->fileName->setText(QString::fromUtf8(fm_file_info_get_disp_name(fileInfo)));
|
|
||||||
if(parent_str) {
|
|
||||||
ui->location->setText(QString::fromUtf8(parent_str));
|
|
||||||
g_free(parent_str);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
ui->location->clear();
|
|
||||||
|
|
||||||
ui->lastModified->setText(QString::fromUtf8(fm_file_info_get_disp_mtime(fileInfo)));
|
|
||||||
|
|
||||||
// FIXME: need to encapsulate this in an libfm API.
|
|
||||||
time_t atime;
|
|
||||||
struct tm tm;
|
|
||||||
atime = fm_file_info_get_atime(fileInfo);
|
|
||||||
localtime_r(&atime, &tm);
|
|
||||||
char buf[128];
|
|
||||||
strftime(buf, sizeof(buf), "%x %R", &tm);
|
|
||||||
ui->lastAccessed->setText(QString::fromUtf8(buf));
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
ui->fileName->setText(tr("Multiple Files"));
|
|
||||||
ui->fileName->setEnabled(false);
|
|
||||||
}
|
|
||||||
|
|
||||||
initApplications(); // init applications combo box
|
|
||||||
|
|
||||||
// calculate total file sizes
|
|
||||||
fileSizeTimer = new QTimer(this);
|
|
||||||
connect(fileSizeTimer, &QTimer::timeout, this, &FilePropsDialog::onFileSizeTimerTimeout);
|
|
||||||
fileSizeTimer->start(600);
|
|
||||||
g_signal_connect(deepCountJob, "finished", G_CALLBACK(onDeepCountJobFinished), this);
|
|
||||||
gboolean ret = fm_job_run_async(FM_JOB(deepCountJob));
|
|
||||||
}
|
|
||||||
|
|
||||||
/*static */ void FilePropsDialog::onDeepCountJobFinished(FmDeepCountJob* job, FilePropsDialog* pThis) {
|
|
||||||
|
|
||||||
pThis->onFileSizeTimerTimeout(); // update file size display
|
|
||||||
|
|
||||||
// free the job
|
|
||||||
g_object_unref(pThis->deepCountJob);
|
|
||||||
pThis->deepCountJob = NULL;
|
|
||||||
|
|
||||||
// stop the timer
|
|
||||||
if(pThis->fileSizeTimer) {
|
|
||||||
pThis->fileSizeTimer->stop();
|
|
||||||
delete pThis->fileSizeTimer;
|
|
||||||
pThis->fileSizeTimer = NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void FilePropsDialog::onFileSizeTimerTimeout() {
|
|
||||||
if(deepCountJob && !fm_job_is_cancelled(FM_JOB(deepCountJob))) {
|
|
||||||
char size_str[128];
|
|
||||||
fm_file_size_to_str(size_str, sizeof(size_str), deepCountJob->total_size,
|
|
||||||
fm_config->si_unit);
|
|
||||||
// FIXME:
|
|
||||||
// OMG! It's really unbelievable that Qt developers only implement
|
|
||||||
// QObject::tr(... int n). GNU gettext developers are smarter and
|
|
||||||
// they use unsigned long instead of int.
|
|
||||||
// We cannot use Qt here to handle plural forms. So sad. :-(
|
|
||||||
QString str = QString::fromUtf8(size_str) %
|
|
||||||
QString(" (%1 B)").arg(deepCountJob->total_size);
|
|
||||||
// tr(" (%n) byte(s)", "", deepCountJob->total_size);
|
|
||||||
ui->fileSize->setText(str);
|
|
||||||
|
|
||||||
fm_file_size_to_str(size_str, sizeof(size_str), deepCountJob->total_ondisk_size,
|
|
||||||
fm_config->si_unit);
|
|
||||||
str = QString::fromUtf8(size_str) %
|
|
||||||
QString(" (%1 B)").arg(deepCountJob->total_ondisk_size);
|
|
||||||
// tr(" (%n) byte(s)", "", deepCountJob->total_ondisk_size);
|
|
||||||
ui->onDiskSize->setText(str);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void FilePropsDialog::accept() {
|
|
||||||
|
|
||||||
// applications
|
|
||||||
if(mimeType && ui->openWith->isChanged()) {
|
|
||||||
GAppInfo* currentApp = ui->openWith->selectedApp();
|
|
||||||
g_app_info_set_as_default_for_type(currentApp, fm_mime_type_get_type(mimeType), NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
// check if chown or chmod is needed
|
|
||||||
guint32 newUid = uidFromName(ui->owner->text());
|
|
||||||
guint32 newGid = gidFromName(ui->ownerGroup->text());
|
|
||||||
bool needChown = (newUid != -1 && newUid != uid) || (newGid != -1 && newGid != gid);
|
|
||||||
|
|
||||||
int newOwnerPermSel = ui->ownerPerm->currentIndex();
|
|
||||||
int newGroupPermSel = ui->groupPerm->currentIndex();
|
|
||||||
int newOtherPermSel = ui->otherPerm->currentIndex();
|
|
||||||
Qt::CheckState newExecCheckState = ui->executable->checkState();
|
|
||||||
bool needChmod = ((newOwnerPermSel != ownerPermSel) ||
|
|
||||||
(newGroupPermSel != groupPermSel) ||
|
|
||||||
(newOtherPermSel != otherPermSel) ||
|
|
||||||
(newExecCheckState != execCheckState));
|
|
||||||
|
|
||||||
if(needChmod || needChown) {
|
|
||||||
FmPathList* paths = fm_path_list_new_from_file_info_list(fileInfos_);
|
|
||||||
FileOperation* op = new FileOperation(FileOperation::ChangeAttr, paths);
|
|
||||||
fm_path_list_unref(paths);
|
|
||||||
if(needChown) {
|
|
||||||
// don't do chown if new uid/gid and the original ones are actually the same.
|
|
||||||
if(newUid == uid)
|
|
||||||
newUid = -1;
|
|
||||||
if(newGid == gid)
|
|
||||||
newGid = -1;
|
|
||||||
op->setChown(newUid, newGid);
|
|
||||||
}
|
|
||||||
if(needChmod) {
|
|
||||||
mode_t newMode = 0;
|
|
||||||
mode_t newModeMask = 0;
|
|
||||||
// FIXME: we need to make sure that folders with "r" permission also have "x"
|
|
||||||
// at the same time. Otherwise, it's not able to browse the folder later.
|
|
||||||
if(newOwnerPermSel != ownerPermSel && newOwnerPermSel != ACCESS_NO_CHANGE) {
|
|
||||||
// owner permission changed
|
|
||||||
newModeMask |= (S_IRUSR|S_IWUSR); // affect user bits
|
|
||||||
if(newOwnerPermSel == ACCESS_READ_ONLY)
|
|
||||||
newMode |= S_IRUSR;
|
|
||||||
else if(newOwnerPermSel == ACCESS_READ_WRITE)
|
|
||||||
newMode |= (S_IRUSR|S_IWUSR);
|
|
||||||
}
|
|
||||||
if(newGroupPermSel != groupPermSel && newGroupPermSel != ACCESS_NO_CHANGE) {
|
|
||||||
qDebug("newGroupPermSel: %d", newGroupPermSel);
|
|
||||||
// group permission changed
|
|
||||||
newModeMask |= (S_IRGRP|S_IWGRP); // affect group bits
|
|
||||||
if(newGroupPermSel == ACCESS_READ_ONLY)
|
|
||||||
newMode |= S_IRGRP;
|
|
||||||
else if(newGroupPermSel == ACCESS_READ_WRITE)
|
|
||||||
newMode |= (S_IRGRP|S_IWGRP);
|
|
||||||
}
|
|
||||||
if(newOtherPermSel != otherPermSel && newOtherPermSel != ACCESS_NO_CHANGE) {
|
|
||||||
// other permission changed
|
|
||||||
newModeMask |= (S_IROTH|S_IWOTH); // affect other bits
|
|
||||||
if(newOtherPermSel == ACCESS_READ_ONLY)
|
|
||||||
newMode |= S_IROTH;
|
|
||||||
else if(newOtherPermSel == ACCESS_READ_WRITE)
|
|
||||||
newMode |= (S_IROTH|S_IWOTH);
|
|
||||||
}
|
|
||||||
if(newExecCheckState != execCheckState && newExecCheckState != Qt::PartiallyChecked) {
|
|
||||||
// executable state changed
|
|
||||||
newModeMask |= (S_IXUSR|S_IXGRP|S_IXOTH);
|
|
||||||
if(newExecCheckState == Qt::Checked)
|
|
||||||
newMode |= (S_IXUSR|S_IXGRP|S_IXOTH);
|
|
||||||
}
|
|
||||||
op->setChmod(newMode, newModeMask);
|
|
||||||
|
|
||||||
if(hasDir) { // if there are some dirs in our selected files
|
|
||||||
QMessageBox::StandardButton r = QMessageBox::question(this,
|
|
||||||
tr("Apply changes"),
|
|
||||||
tr("Do you want to recursively apply these changes to all files and sub-folders?"),
|
|
||||||
QMessageBox::Yes|QMessageBox::No);
|
|
||||||
if(r == QMessageBox::Yes)
|
|
||||||
op->setRecursiveChattr(true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
op->setAutoDestroy(true);
|
|
||||||
op->run();
|
|
||||||
}
|
|
||||||
|
|
||||||
QDialog::accept();
|
|
||||||
}
|
|
||||||
|
|
||||||
void FilePropsDialog::initOwner() {
|
|
||||||
if(allNative) {
|
|
||||||
if(uid != DIFFERENT_UIDS)
|
|
||||||
ui->owner->setText(uidToName(uid));
|
|
||||||
if(gid != DIFFERENT_GIDS)
|
|
||||||
ui->ownerGroup->setText(gidToName(gid));
|
|
||||||
|
|
||||||
if(geteuid() != 0) { // on local filesystems, only root can do chown.
|
|
||||||
ui->owner->setEnabled(false);
|
|
||||||
ui->ownerGroup->setEnabled(false);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
} // namespace Fm
|
|
||||||
@ -1,97 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (C) 2012 - 2015 Hong Jen Yee (PCMan) <pcman.tw@gmail.com>
|
|
||||||
*
|
|
||||||
* 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 FM_FILEPROPSDIALOG_H
|
|
||||||
#define FM_FILEPROPSDIALOG_H
|
|
||||||
|
|
||||||
#include "libfmqtglobals.h"
|
|
||||||
#include <QDialog>
|
|
||||||
#include <QTimer>
|
|
||||||
#include <libfm/fm.h>
|
|
||||||
|
|
||||||
namespace Ui {
|
|
||||||
class FilePropsDialog;
|
|
||||||
};
|
|
||||||
|
|
||||||
namespace Fm {
|
|
||||||
|
|
||||||
class LIBFM_QT_API FilePropsDialog : public QDialog {
|
|
||||||
Q_OBJECT
|
|
||||||
|
|
||||||
public:
|
|
||||||
explicit FilePropsDialog(FmFileInfoList* files, QWidget* parent = 0, Qt::WindowFlags f = 0);
|
|
||||||
virtual ~FilePropsDialog();
|
|
||||||
|
|
||||||
virtual void accept();
|
|
||||||
|
|
||||||
static FilePropsDialog* showForFile(FmFileInfo* file, QWidget* parent = 0) {
|
|
||||||
FmFileInfoList* files = fm_file_info_list_new();
|
|
||||||
fm_file_info_list_push_tail(files, file);
|
|
||||||
FilePropsDialog* dlg = showForFiles(files, parent);
|
|
||||||
fm_file_info_list_unref(files);
|
|
||||||
return dlg;
|
|
||||||
}
|
|
||||||
|
|
||||||
static FilePropsDialog* showForFiles(FmFileInfoList* files, QWidget* parent = 0) {
|
|
||||||
FilePropsDialog* dlg = new FilePropsDialog(files, parent);
|
|
||||||
dlg->show();
|
|
||||||
return dlg;
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
void initGeneralPage();
|
|
||||||
void initApplications();
|
|
||||||
void initPermissionsPage();
|
|
||||||
void initOwner();
|
|
||||||
|
|
||||||
static void onDeepCountJobFinished(FmDeepCountJob* job, FilePropsDialog* pThis);
|
|
||||||
|
|
||||||
private Q_SLOTS:
|
|
||||||
void onFileSizeTimerTimeout();
|
|
||||||
|
|
||||||
private:
|
|
||||||
Ui::FilePropsDialog* ui;
|
|
||||||
FmFileInfoList* fileInfos_; // list of all file infos
|
|
||||||
FmFileInfo* fileInfo; // file info of the first file in the list
|
|
||||||
bool singleType; // all files are of the same type?
|
|
||||||
bool singleFile; // only one file is selected?
|
|
||||||
bool hasDir; // is there any dir in the files?
|
|
||||||
bool allNative; // all files are on native UNIX filesystems (not virtual or remote)
|
|
||||||
|
|
||||||
FmMimeType* mimeType; // mime type of the files
|
|
||||||
|
|
||||||
gint32 uid; // owner uid of the files, -1 means all files do not have the same uid
|
|
||||||
gint32 gid; // owner gid of the files, -1 means all files do not have the same uid
|
|
||||||
mode_t ownerPerm; // read permission of the files, -1 means not all files have the same value
|
|
||||||
int ownerPermSel;
|
|
||||||
mode_t groupPerm; // read permission of the files, -1 means not all files have the same value
|
|
||||||
int groupPermSel;
|
|
||||||
mode_t otherPerm; // read permission of the files, -1 means not all files have the same value
|
|
||||||
int otherPermSel;
|
|
||||||
mode_t execPerm; // exec permission of the files
|
|
||||||
Qt::CheckState execCheckState;
|
|
||||||
|
|
||||||
FmDeepCountJob* deepCountJob; // job used to count total size
|
|
||||||
QTimer* fileSizeTimer;
|
|
||||||
};
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif // FM_FILEPROPSDIALOG_H
|
|
||||||
@ -1,565 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<ui version="4.0">
|
|
||||||
<class>SearchDialog</class>
|
|
||||||
<widget class="QDialog" name="SearchDialog">
|
|
||||||
<property name="geometry">
|
|
||||||
<rect>
|
|
||||||
<x>0</x>
|
|
||||||
<y>0</y>
|
|
||||||
<width>512</width>
|
|
||||||
<height>420</height>
|
|
||||||
</rect>
|
|
||||||
</property>
|
|
||||||
<property name="windowTitle">
|
|
||||||
<string>Search Files</string>
|
|
||||||
</property>
|
|
||||||
<property name="windowIcon">
|
|
||||||
<iconset theme="system-search">
|
|
||||||
<normaloff/>
|
|
||||||
</iconset>
|
|
||||||
</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_2" stretch="0,1">
|
|
||||||
<item>
|
|
||||||
<widget class="QGroupBox" name="groupBox">
|
|
||||||
<property name="title">
|
|
||||||
<string>File Name Patterns:</string>
|
|
||||||
</property>
|
|
||||||
<layout class="QVBoxLayout" name="verticalLayout_3">
|
|
||||||
<item>
|
|
||||||
<widget class="QLineEdit" name="namePatterns">
|
|
||||||
<property name="text">
|
|
||||||
<string>*</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<widget class="QCheckBox" name="nameCaseInsensitive">
|
|
||||||
<property name="text">
|
|
||||||
<string>Case insensitive</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<widget class="QCheckBox" name="nameRegExp">
|
|
||||||
<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_5">
|
|
||||||
<item>
|
|
||||||
<layout class="QHBoxLayout" name="horizontalLayout">
|
|
||||||
<item>
|
|
||||||
<widget class="QListWidget" name="listView"/>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<layout class="QVBoxLayout" name="verticalLayout_4">
|
|
||||||
<item>
|
|
||||||
<widget class="QPushButton" name="addPath">
|
|
||||||
<property name="text">
|
|
||||||
<string>&Add</string>
|
|
||||||
</property>
|
|
||||||
<property name="icon">
|
|
||||||
<iconset theme="list-add">
|
|
||||||
<normaloff/>
|
|
||||||
</iconset>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<widget class="QPushButton" name="removePath">
|
|
||||||
<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="recursiveSearch">
|
|
||||||
<property name="text">
|
|
||||||
<string>Search in sub directories</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<widget class="QCheckBox" name="searchHidden">
|
|
||||||
<property name="text">
|
|
||||||
<string>Search for 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_7">
|
|
||||||
<item>
|
|
||||||
<widget class="QGroupBox" name="groupBox_3">
|
|
||||||
<property name="title">
|
|
||||||
<string>Only search for files of following types:</string>
|
|
||||||
</property>
|
|
||||||
<layout class="QVBoxLayout" name="verticalLayout_6">
|
|
||||||
<item>
|
|
||||||
<widget class="QCheckBox" name="searchTextFiles">
|
|
||||||
<property name="text">
|
|
||||||
<string>Text files</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<widget class="QCheckBox" name="searchImages">
|
|
||||||
<property name="text">
|
|
||||||
<string>Image files</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<widget class="QCheckBox" name="searchAudio">
|
|
||||||
<property name="text">
|
|
||||||
<string>Audio files</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<widget class="QCheckBox" name="searchVideo">
|
|
||||||
<property name="text">
|
|
||||||
<string>Video files</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<widget class="QCheckBox" name="searchDocuments">
|
|
||||||
<property name="text">
|
|
||||||
<string>Documents</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<widget class="QCheckBox" name="searchFolders">
|
|
||||||
<property name="text">
|
|
||||||
<string>Folders</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_3">
|
|
||||||
<attribute name="title">
|
|
||||||
<string>Content</string>
|
|
||||||
</attribute>
|
|
||||||
<layout class="QVBoxLayout" name="verticalLayout_9">
|
|
||||||
<item>
|
|
||||||
<widget class="QGroupBox" name="groupBox_4">
|
|
||||||
<property name="title">
|
|
||||||
<string>File contains:</string>
|
|
||||||
</property>
|
|
||||||
<layout class="QVBoxLayout" name="verticalLayout_8">
|
|
||||||
<item>
|
|
||||||
<widget class="QLineEdit" name="contentPattern"/>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<widget class="QCheckBox" name="contentCaseInsensitive">
|
|
||||||
<property name="text">
|
|
||||||
<string>Case insensiti&ve</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<widget class="QCheckBox" name="contentRegExp">
|
|
||||||
<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>186</height>
|
|
||||||
</size>
|
|
||||||
</property>
|
|
||||||
</spacer>
|
|
||||||
</item>
|
|
||||||
</layout>
|
|
||||||
</widget>
|
|
||||||
<widget class="QWidget" name="tab_4">
|
|
||||||
<attribute name="title">
|
|
||||||
<string>Properties</string>
|
|
||||||
</attribute>
|
|
||||||
<layout class="QVBoxLayout" name="verticalLayout_10">
|
|
||||||
<item>
|
|
||||||
<widget class="QGroupBox" name="groupBox_5">
|
|
||||||
<property name="title">
|
|
||||||
<string>File Size:</string>
|
|
||||||
</property>
|
|
||||||
<layout class="QFormLayout" name="formLayout">
|
|
||||||
<item row="0" column="0">
|
|
||||||
<widget class="QCheckBox" name="largerThan">
|
|
||||||
<property name="text">
|
|
||||||
<string>Larger than:</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="0" column="1">
|
|
||||||
<layout class="QHBoxLayout" name="horizontalLayout_2">
|
|
||||||
<item>
|
|
||||||
<widget class="QSpinBox" name="minSize">
|
|
||||||
<property name="enabled">
|
|
||||||
<bool>false</bool>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<widget class="QComboBox" name="minSizeUnit">
|
|
||||||
<property name="enabled">
|
|
||||||
<bool>false</bool>
|
|
||||||
</property>
|
|
||||||
<property name="currentIndex">
|
|
||||||
<number>2</number>
|
|
||||||
</property>
|
|
||||||
<item>
|
|
||||||
<property name="text">
|
|
||||||
<string>Bytes</string>
|
|
||||||
</property>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<property name="text">
|
|
||||||
<string>KiB</string>
|
|
||||||
</property>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<property name="text">
|
|
||||||
<string>MiB</string>
|
|
||||||
</property>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<property name="text">
|
|
||||||
<string>GiB</string>
|
|
||||||
</property>
|
|
||||||
</item>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
</layout>
|
|
||||||
</item>
|
|
||||||
<item row="1" column="0">
|
|
||||||
<widget class="QCheckBox" name="smallerThan">
|
|
||||||
<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="maxSize">
|
|
||||||
<property name="enabled">
|
|
||||||
<bool>false</bool>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<widget class="QComboBox" name="maxSizeUnit">
|
|
||||||
<property name="enabled">
|
|
||||||
<bool>false</bool>
|
|
||||||
</property>
|
|
||||||
<property name="currentIndex">
|
|
||||||
<number>2</number>
|
|
||||||
</property>
|
|
||||||
<item>
|
|
||||||
<property name="text">
|
|
||||||
<string>Bytes</string>
|
|
||||||
</property>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<property name="text">
|
|
||||||
<string>KiB</string>
|
|
||||||
</property>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<property name="text">
|
|
||||||
<string>MiB</string>
|
|
||||||
</property>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<property name="text">
|
|
||||||
<string>GiB</string>
|
|
||||||
</property>
|
|
||||||
</item>
|
|
||||||
</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="earlierThan">
|
|
||||||
<property name="text">
|
|
||||||
<string>Earlier than:</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="1" column="0">
|
|
||||||
<widget class="QCheckBox" name="laterThan">
|
|
||||||
<property name="text">
|
|
||||||
<string>Later than:</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="0" column="1">
|
|
||||||
<widget class="QDateEdit" name="maxTime">
|
|
||||||
<property name="enabled">
|
|
||||||
<bool>false</bool>
|
|
||||||
</property>
|
|
||||||
<property name="calendarPopup">
|
|
||||||
<bool>true</bool>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="1" column="1">
|
|
||||||
<widget class="QDateEdit" name="minTime">
|
|
||||||
<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>SearchDialog</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>SearchDialog</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>
|
|
||||||
<connection>
|
|
||||||
<sender>largerThan</sender>
|
|
||||||
<signal>toggled(bool)</signal>
|
|
||||||
<receiver>minSizeUnit</receiver>
|
|
||||||
<slot>setEnabled(bool)</slot>
|
|
||||||
<hints>
|
|
||||||
<hint type="sourcelabel">
|
|
||||||
<x>93</x>
|
|
||||||
<y>84</y>
|
|
||||||
</hint>
|
|
||||||
<hint type="destinationlabel">
|
|
||||||
<x>403</x>
|
|
||||||
<y>88</y>
|
|
||||||
</hint>
|
|
||||||
</hints>
|
|
||||||
</connection>
|
|
||||||
<connection>
|
|
||||||
<sender>smallerThan</sender>
|
|
||||||
<signal>toggled(bool)</signal>
|
|
||||||
<receiver>maxSize</receiver>
|
|
||||||
<slot>setEnabled(bool)</slot>
|
|
||||||
<hints>
|
|
||||||
<hint type="sourcelabel">
|
|
||||||
<x>96</x>
|
|
||||||
<y>119</y>
|
|
||||||
</hint>
|
|
||||||
<hint type="destinationlabel">
|
|
||||||
<x>241</x>
|
|
||||||
<y>123</y>
|
|
||||||
</hint>
|
|
||||||
</hints>
|
|
||||||
</connection>
|
|
||||||
<connection>
|
|
||||||
<sender>largerThan</sender>
|
|
||||||
<signal>toggled(bool)</signal>
|
|
||||||
<receiver>minSize</receiver>
|
|
||||||
<slot>setEnabled(bool)</slot>
|
|
||||||
<hints>
|
|
||||||
<hint type="sourcelabel">
|
|
||||||
<x>93</x>
|
|
||||||
<y>84</y>
|
|
||||||
</hint>
|
|
||||||
<hint type="destinationlabel">
|
|
||||||
<x>241</x>
|
|
||||||
<y>88</y>
|
|
||||||
</hint>
|
|
||||||
</hints>
|
|
||||||
</connection>
|
|
||||||
<connection>
|
|
||||||
<sender>smallerThan</sender>
|
|
||||||
<signal>toggled(bool)</signal>
|
|
||||||
<receiver>maxSizeUnit</receiver>
|
|
||||||
<slot>setEnabled(bool)</slot>
|
|
||||||
<hints>
|
|
||||||
<hint type="sourcelabel">
|
|
||||||
<x>96</x>
|
|
||||||
<y>119</y>
|
|
||||||
</hint>
|
|
||||||
<hint type="destinationlabel">
|
|
||||||
<x>403</x>
|
|
||||||
<y>123</y>
|
|
||||||
</hint>
|
|
||||||
</hints>
|
|
||||||
</connection>
|
|
||||||
<connection>
|
|
||||||
<sender>laterThan</sender>
|
|
||||||
<signal>toggled(bool)</signal>
|
|
||||||
<receiver>minTime</receiver>
|
|
||||||
<slot>setEnabled(bool)</slot>
|
|
||||||
<hints>
|
|
||||||
<hint type="sourcelabel">
|
|
||||||
<x>88</x>
|
|
||||||
<y>223</y>
|
|
||||||
</hint>
|
|
||||||
<hint type="destinationlabel">
|
|
||||||
<x>319</x>
|
|
||||||
<y>226</y>
|
|
||||||
</hint>
|
|
||||||
</hints>
|
|
||||||
</connection>
|
|
||||||
<connection>
|
|
||||||
<sender>earlierThan</sender>
|
|
||||||
<signal>toggled(bool)</signal>
|
|
||||||
<receiver>maxTime</receiver>
|
|
||||||
<slot>setEnabled(bool)</slot>
|
|
||||||
<hints>
|
|
||||||
<hint type="sourcelabel">
|
|
||||||
<x>93</x>
|
|
||||||
<y>190</y>
|
|
||||||
</hint>
|
|
||||||
<hint type="destinationlabel">
|
|
||||||
<x>319</x>
|
|
||||||
<y>193</y>
|
|
||||||
</hint>
|
|
||||||
</hints>
|
|
||||||
</connection>
|
|
||||||
</connections>
|
|
||||||
</ui>
|
|
||||||
@ -1,143 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (C) 2015 Hong Jen Yee (PCMan) <pcman.tw@gmail.com>
|
|
||||||
*
|
|
||||||
* 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 "filesearchdialog.h"
|
|
||||||
#include <QMessageBox>
|
|
||||||
#include "fm-search.h"
|
|
||||||
#include "ui_filesearch.h"
|
|
||||||
#include <limits>
|
|
||||||
#include <QFileDialog>
|
|
||||||
|
|
||||||
namespace Fm {
|
|
||||||
|
|
||||||
FileSearchDialog::FileSearchDialog(QStringList paths, QWidget* parent, Qt::WindowFlags f):
|
|
||||||
QDialog(parent, f),
|
|
||||||
ui(new Ui::SearchDialog()) {
|
|
||||||
ui->setupUi(this);
|
|
||||||
ui->minSize->setMaximum(std::numeric_limits<int>().max());
|
|
||||||
ui->maxSize->setMaximum(std::numeric_limits<int>().max());
|
|
||||||
Q_FOREACH(const QString& path, paths) {
|
|
||||||
ui->listView->addItem(path);
|
|
||||||
}
|
|
||||||
|
|
||||||
ui->maxTime->setDate(QDate::currentDate());
|
|
||||||
ui->minTime->setDate(QDate::currentDate());
|
|
||||||
|
|
||||||
connect(ui->addPath, &QPushButton::clicked, this, &FileSearchDialog::onAddPath);
|
|
||||||
connect(ui->removePath, &QPushButton::clicked, this, &FileSearchDialog::onRemovePath);
|
|
||||||
}
|
|
||||||
|
|
||||||
FileSearchDialog::~FileSearchDialog() {
|
|
||||||
delete ui;
|
|
||||||
}
|
|
||||||
|
|
||||||
void FileSearchDialog::accept() {
|
|
||||||
// build the search:/// uri
|
|
||||||
int n = ui->listView->count();
|
|
||||||
if(n > 0) {
|
|
||||||
FmSearch* search = fm_search_new();
|
|
||||||
int i;
|
|
||||||
for(i = 0; i < n; ++i) { // add directories
|
|
||||||
QListWidgetItem* item = ui->listView->item(i);
|
|
||||||
fm_search_add_dir(search, item->text().toLocal8Bit().constData());
|
|
||||||
}
|
|
||||||
|
|
||||||
fm_search_set_recursive(search, ui->recursiveSearch->isChecked());
|
|
||||||
fm_search_set_show_hidden(search, ui->searchHidden->isChecked());
|
|
||||||
fm_search_set_name_patterns(search, ui->namePatterns->text().toUtf8().constData());
|
|
||||||
fm_search_set_name_ci(search, ui->nameCaseInsensitive->isChecked());
|
|
||||||
fm_search_set_name_regex(search, ui->nameRegExp->isChecked());
|
|
||||||
|
|
||||||
fm_search_set_content_pattern(search, ui->contentPattern->text().toUtf8().constData());
|
|
||||||
fm_search_set_content_ci(search, ui->contentCaseInsensitive->isChecked());
|
|
||||||
fm_search_set_content_regex(search, ui->contentRegExp->isChecked());
|
|
||||||
|
|
||||||
// search for the files of specific mime-types
|
|
||||||
if(ui->searchTextFiles->isChecked())
|
|
||||||
fm_search_add_mime_type(search, "text/plain");
|
|
||||||
if(ui->searchImages->isChecked())
|
|
||||||
fm_search_add_mime_type(search, "image/*");
|
|
||||||
if(ui->searchAudio->isChecked())
|
|
||||||
fm_search_add_mime_type(search, "audio/*");
|
|
||||||
if(ui->searchVideo->isChecked())
|
|
||||||
fm_search_add_mime_type(search, "video/*");
|
|
||||||
if(ui->searchFolders->isChecked())
|
|
||||||
fm_search_add_mime_type(search, "inode/directory");
|
|
||||||
if(ui->searchDocuments->isChecked()) {
|
|
||||||
const char* doc_types[] = {
|
|
||||||
"application/pdf",
|
|
||||||
/* "text/html;" */
|
|
||||||
"application/vnd.oasis.opendocument.*",
|
|
||||||
"application/vnd.openxmlformats-officedocument.*",
|
|
||||||
"application/msword;application/vnd.ms-word",
|
|
||||||
"application/msexcel;application/vnd.ms-excel"
|
|
||||||
};
|
|
||||||
for(i = 0; i < sizeof(doc_types)/sizeof(char*); ++i)
|
|
||||||
fm_search_add_mime_type(search, doc_types[i]);
|
|
||||||
}
|
|
||||||
|
|
||||||
// search based on file size
|
|
||||||
const unsigned int unit_bytes[] = {1, (1024), (1024*1024), (1024*1024*1024)};
|
|
||||||
if(ui->largerThan->isChecked()) {
|
|
||||||
guint64 size = ui->minSize->value() * unit_bytes[ui->minSizeUnit->currentIndex()];
|
|
||||||
fm_search_set_min_size(search, size);
|
|
||||||
}
|
|
||||||
|
|
||||||
if(ui->smallerThan->isChecked()) {
|
|
||||||
guint64 size = ui->maxSize->value() * unit_bytes[ui->maxSizeUnit->currentIndex()];
|
|
||||||
fm_search_set_max_size(search, size);
|
|
||||||
}
|
|
||||||
|
|
||||||
// search based on file mtime (we only support date in YYYY-MM-DD format)
|
|
||||||
if(ui->earlierThan->isChecked()) {
|
|
||||||
fm_search_set_max_mtime(search, ui->maxTime->date().toString(QStringLiteral("yyyy-MM-dd")).toUtf8().constData());
|
|
||||||
}
|
|
||||||
if(ui->laterThan->isChecked()) {
|
|
||||||
fm_search_set_min_mtime(search, ui->minTime->date().toString(QStringLiteral("yyyy-MM-dd")).toUtf8().constData());
|
|
||||||
}
|
|
||||||
|
|
||||||
searchUri_.take(fm_search_dup_path(search));
|
|
||||||
|
|
||||||
fm_search_free(search);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
QMessageBox::critical(this, tr("Error"), tr("You should add at least add one directory to search."));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
QDialog::accept();
|
|
||||||
}
|
|
||||||
|
|
||||||
void FileSearchDialog::onAddPath() {
|
|
||||||
QString dir = QFileDialog::getExistingDirectory(this, tr("Select a folder"));
|
|
||||||
if(dir.isEmpty())
|
|
||||||
return;
|
|
||||||
// avoid adding duplicated items
|
|
||||||
if(ui->listView->findItems(dir, Qt::MatchFixedString|Qt::MatchCaseSensitive).isEmpty()) {
|
|
||||||
ui->listView->addItem(dir);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void FileSearchDialog::onRemovePath() {
|
|
||||||
// remove selected items
|
|
||||||
Q_FOREACH(QListWidgetItem* item, ui->listView->selectedItems()) {
|
|
||||||
delete item;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@ -1,56 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (C) 2015 Hong Jen Yee (PCMan) <pcman.tw@gmail.com>
|
|
||||||
*
|
|
||||||
* 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 FM_FILESEARCHDIALOG_H
|
|
||||||
#define FM_FILESEARCHDIALOG_H
|
|
||||||
|
|
||||||
#include "libfmqtglobals.h"
|
|
||||||
#include <QDialog>
|
|
||||||
#include "path.h"
|
|
||||||
|
|
||||||
namespace Ui {
|
|
||||||
class SearchDialog;
|
|
||||||
}
|
|
||||||
|
|
||||||
namespace Fm {
|
|
||||||
|
|
||||||
class LIBFM_QT_API FileSearchDialog : public QDialog
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
FileSearchDialog(QStringList paths = QStringList(), QWidget * parent = 0, Qt::WindowFlags f = 0);
|
|
||||||
~FileSearchDialog();
|
|
||||||
|
|
||||||
Path searchUri() const {
|
|
||||||
return searchUri_;
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual void accept();
|
|
||||||
|
|
||||||
private Q_SLOTS:
|
|
||||||
void onAddPath();
|
|
||||||
void onRemovePath();
|
|
||||||
|
|
||||||
private:
|
|
||||||
Ui::SearchDialog* ui;
|
|
||||||
Path searchUri_;
|
|
||||||
};
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif // FM_FILESEARCHDIALOG_H
|
|
||||||
317
src/fm-search.c
317
src/fm-search.c
@ -1,317 +0,0 @@
|
|||||||
/*
|
|
||||||
* fm-search-uri.c
|
|
||||||
*
|
|
||||||
* Copyright 2015 Hong Jen Yee (PCMan) <pcman.tw@gmail.com>
|
|
||||||
* Copyright 2012-2014 Andriy Grytsenko (LStranger) <andrej@rep.kiev.ua>
|
|
||||||
*
|
|
||||||
* 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 "fm-search.h"
|
|
||||||
#include <string.h>
|
|
||||||
|
|
||||||
struct _FmSearch
|
|
||||||
{
|
|
||||||
gboolean recursive;
|
|
||||||
gboolean show_hidden;
|
|
||||||
char* name_patterns;
|
|
||||||
gboolean name_ci;
|
|
||||||
gboolean name_regex;
|
|
||||||
char* content_pattern;
|
|
||||||
gboolean content_ci;
|
|
||||||
gboolean content_regex;
|
|
||||||
GList* mime_types;
|
|
||||||
GList* search_path_list;
|
|
||||||
guint64 max_size;
|
|
||||||
guint64 min_size;
|
|
||||||
char* max_mtime;
|
|
||||||
char* min_mtime;
|
|
||||||
};
|
|
||||||
|
|
||||||
FmSearch* fm_search_new (void)
|
|
||||||
{
|
|
||||||
FmSearch* search = (FmSearch*)g_slice_new0(FmSearch);
|
|
||||||
return search;
|
|
||||||
}
|
|
||||||
|
|
||||||
void fm_search_free(FmSearch* search)
|
|
||||||
{
|
|
||||||
g_list_free_full(search->mime_types, (GDestroyNotify)g_free);
|
|
||||||
g_list_free_full(search->search_path_list, (GDestroyNotify)g_free);
|
|
||||||
g_free(search->name_patterns);
|
|
||||||
g_free(search->content_pattern);
|
|
||||||
g_free(search->max_mtime);
|
|
||||||
g_free(search->min_mtime);
|
|
||||||
g_slice_free(FmSearch, search);
|
|
||||||
}
|
|
||||||
|
|
||||||
gboolean fm_search_get_recursive(FmSearch* search)
|
|
||||||
{
|
|
||||||
return search->recursive;
|
|
||||||
}
|
|
||||||
|
|
||||||
void fm_search_set_recursive(FmSearch* search, gboolean recursive)
|
|
||||||
{
|
|
||||||
search->recursive = recursive;
|
|
||||||
}
|
|
||||||
|
|
||||||
gboolean fm_search_get_show_hidden(FmSearch* search)
|
|
||||||
{
|
|
||||||
return search->show_hidden;
|
|
||||||
}
|
|
||||||
|
|
||||||
void fm_search_set_show_hidden(FmSearch* search, gboolean show_hidden)
|
|
||||||
{
|
|
||||||
search->show_hidden = show_hidden;
|
|
||||||
}
|
|
||||||
|
|
||||||
const char* fm_search_get_name_patterns(FmSearch* search)
|
|
||||||
{
|
|
||||||
return search->name_patterns;
|
|
||||||
}
|
|
||||||
|
|
||||||
void fm_search_set_name_patterns(FmSearch* search, const char* name_patterns)
|
|
||||||
{
|
|
||||||
g_free(search->name_patterns);
|
|
||||||
search->name_patterns = g_strdup(name_patterns);
|
|
||||||
}
|
|
||||||
|
|
||||||
gboolean fm_search_get_name_ci(FmSearch* search)
|
|
||||||
{
|
|
||||||
return search->name_ci;
|
|
||||||
}
|
|
||||||
|
|
||||||
void fm_search_set_name_ci(FmSearch* search, gboolean name_ci)
|
|
||||||
{
|
|
||||||
search->name_ci = name_ci;
|
|
||||||
}
|
|
||||||
|
|
||||||
gboolean fm_search_get_name_regex(FmSearch* search)
|
|
||||||
{
|
|
||||||
return search->name_regex;
|
|
||||||
}
|
|
||||||
|
|
||||||
void fm_search_set_name_regex(FmSearch* search, gboolean name_regex)
|
|
||||||
{
|
|
||||||
search->name_regex = name_regex;
|
|
||||||
}
|
|
||||||
|
|
||||||
const char* fm_search_get_content_pattern(FmSearch* search)
|
|
||||||
{
|
|
||||||
return search->content_pattern;
|
|
||||||
}
|
|
||||||
|
|
||||||
void fm_search_set_content_pattern(FmSearch* search, const char* content_pattern)
|
|
||||||
{
|
|
||||||
g_free(search->content_pattern);
|
|
||||||
search->content_pattern = g_strdup(content_pattern);
|
|
||||||
}
|
|
||||||
|
|
||||||
gboolean fm_search_get_content_ci(FmSearch* search)
|
|
||||||
{
|
|
||||||
return search->content_ci;
|
|
||||||
}
|
|
||||||
|
|
||||||
void fm_search_set_content_ci(FmSearch* search, gboolean content_ci)
|
|
||||||
{
|
|
||||||
search->content_ci = content_ci;
|
|
||||||
}
|
|
||||||
|
|
||||||
gboolean fm_search_get_content_regex(FmSearch* search)
|
|
||||||
{
|
|
||||||
return search->content_regex;
|
|
||||||
}
|
|
||||||
|
|
||||||
void fm_search_set_content_regex(FmSearch* search, gboolean content_regex)
|
|
||||||
{
|
|
||||||
search->content_regex = content_regex;
|
|
||||||
}
|
|
||||||
|
|
||||||
void fm_search_add_dir(FmSearch* search, const char* dir)
|
|
||||||
{
|
|
||||||
GList* l = g_list_find_custom(search->search_path_list, dir, (GCompareFunc)strcmp);
|
|
||||||
if(!l)
|
|
||||||
search->search_path_list = g_list_prepend(search->search_path_list, g_strdup(dir));
|
|
||||||
}
|
|
||||||
|
|
||||||
void fm_search_remove_dir(FmSearch* search, const char* dir)
|
|
||||||
{
|
|
||||||
GList* l = g_list_find_custom(search->search_path_list, dir, (GCompareFunc)strcmp);
|
|
||||||
if(G_LIKELY(l))
|
|
||||||
{
|
|
||||||
g_free(l->data);
|
|
||||||
search->search_path_list = g_list_delete_link(search->search_path_list, l);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
GList* fm_search_get_dirs(FmSearch* search)
|
|
||||||
{
|
|
||||||
return search->search_path_list;
|
|
||||||
}
|
|
||||||
|
|
||||||
void fm_search_add_mime_type(FmSearch* search, const char* mime_type)
|
|
||||||
{
|
|
||||||
GList* l = g_list_find_custom(search->mime_types, mime_type, (GCompareFunc)strcmp);
|
|
||||||
if(!l)
|
|
||||||
search->mime_types = g_list_prepend(search->mime_types, g_strdup(mime_type));
|
|
||||||
}
|
|
||||||
|
|
||||||
void fm_search_remove_mime_type(FmSearch* search, const char* mime_type)
|
|
||||||
{
|
|
||||||
GList* l = g_list_find_custom(search->mime_types, mime_type, (GCompareFunc)strcmp);
|
|
||||||
if(G_LIKELY(l))
|
|
||||||
{
|
|
||||||
g_free(l->data);
|
|
||||||
search->mime_types = g_list_delete_link(search->mime_types, l);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
GList* fm_search_get_mime_types(FmSearch* search)
|
|
||||||
{
|
|
||||||
return search->mime_types;
|
|
||||||
}
|
|
||||||
|
|
||||||
guint64 fm_search_get_max_size(FmSearch* search)
|
|
||||||
{
|
|
||||||
return search->max_size;
|
|
||||||
}
|
|
||||||
|
|
||||||
void fm_search_set_max_size(FmSearch* search, guint64 size)
|
|
||||||
{
|
|
||||||
search->max_size = size;
|
|
||||||
}
|
|
||||||
|
|
||||||
guint64 fm_search_get_min_size(FmSearch* search)
|
|
||||||
{
|
|
||||||
return search->min_size;
|
|
||||||
}
|
|
||||||
|
|
||||||
void fm_search_set_min_size(FmSearch* search, guint64 size)
|
|
||||||
{
|
|
||||||
search->min_size = size;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* format of mtime: YYYY-MM-DD */
|
|
||||||
const char* fm_search_get_max_mtime(FmSearch* search)
|
|
||||||
{
|
|
||||||
return search->max_mtime;
|
|
||||||
}
|
|
||||||
|
|
||||||
void fm_search_set_max_mtime(FmSearch* search, const char* mtime)
|
|
||||||
{
|
|
||||||
g_free(search->max_mtime);
|
|
||||||
search->max_mtime = g_strdup(mtime);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* format of mtime: YYYY-MM-DD */
|
|
||||||
const char* fm_search_get_min_mtime(FmSearch* search)
|
|
||||||
{
|
|
||||||
return search->min_mtime;
|
|
||||||
}
|
|
||||||
|
|
||||||
void fm_search_set_min_mtime(FmSearch* search, const char* mtime)
|
|
||||||
{
|
|
||||||
g_free(search->min_mtime);
|
|
||||||
search->min_mtime = g_strdup(mtime);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* really build the path */
|
|
||||||
FmPath* fm_search_dup_path(FmSearch* search)
|
|
||||||
{
|
|
||||||
FmPath* search_path = NULL;
|
|
||||||
GString* search_str = g_string_sized_new(1024);
|
|
||||||
/* build the search:// URI to perform the search */
|
|
||||||
g_string_append(search_str, "search://");
|
|
||||||
|
|
||||||
if(search->search_path_list) /* we need to have at least one dir path */
|
|
||||||
{
|
|
||||||
char *escaped;
|
|
||||||
/* add paths */
|
|
||||||
GList* l;
|
|
||||||
for(l = search->search_path_list; ; )
|
|
||||||
{
|
|
||||||
char *path_str = (char*)l->data;
|
|
||||||
/* escape possible '?' and ',' */
|
|
||||||
escaped = g_uri_escape_string(path_str, "!$&'()*+:;=/@", TRUE);
|
|
||||||
g_string_append(search_str, escaped);
|
|
||||||
g_free(escaped);
|
|
||||||
|
|
||||||
l = l->next;
|
|
||||||
if(!l) /* no more items */
|
|
||||||
break;
|
|
||||||
g_string_append_c(search_str, ','); /* separator for paths */
|
|
||||||
}
|
|
||||||
|
|
||||||
g_string_append_c(search_str, '?');
|
|
||||||
g_string_append_printf(search_str, "recursive=%c", search->recursive ? '1' : '0');
|
|
||||||
g_string_append_printf(search_str, "&show_hidden=%c", search->show_hidden ? '1' : '0');
|
|
||||||
if(search->name_patterns && *search->name_patterns)
|
|
||||||
{
|
|
||||||
/* escape ampersands in pattern */
|
|
||||||
escaped = g_uri_escape_string(search->name_patterns, ":/?#[]@!$'()*+,;", TRUE);
|
|
||||||
if(search->name_regex)
|
|
||||||
g_string_append_printf(search_str, "&name_regex=%s", escaped);
|
|
||||||
else
|
|
||||||
g_string_append_printf(search_str, "&name=%s", escaped);
|
|
||||||
if(search->name_ci)
|
|
||||||
g_string_append_printf(search_str, "&name_ci=%c", search->name_ci ? '1' : '0');
|
|
||||||
g_free(escaped);
|
|
||||||
}
|
|
||||||
|
|
||||||
if(search->content_pattern && *search->content_pattern)
|
|
||||||
{
|
|
||||||
/* escape ampersands in pattern */
|
|
||||||
escaped = g_uri_escape_string(search->content_pattern, ":/?#[]@!$'()*+,;^<>{}", TRUE);
|
|
||||||
if(search->content_regex)
|
|
||||||
g_string_append_printf(search_str, "&content_regex=%s", escaped);
|
|
||||||
else
|
|
||||||
g_string_append_printf(search_str, "&content=%s", escaped);
|
|
||||||
g_free(escaped);
|
|
||||||
if(search->content_ci)
|
|
||||||
g_string_append_printf(search_str, "&content_ci=%c", search->content_ci ? '1' : '0');
|
|
||||||
}
|
|
||||||
|
|
||||||
/* search for the files of specific mime-types */
|
|
||||||
if(search->mime_types)
|
|
||||||
{
|
|
||||||
GList* l;
|
|
||||||
g_string_append(search_str, "&mime_types=");
|
|
||||||
for(l = search->mime_types; l; l=l->next)
|
|
||||||
{
|
|
||||||
const char* mime_type = (const char*)l->data;
|
|
||||||
g_string_append(search_str, mime_type);
|
|
||||||
if(l->next)
|
|
||||||
g_string_append_c(search_str, ';');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if(search->min_size)
|
|
||||||
g_string_append_printf(search_str, "&min_size=%llu", (unsigned long long)search->min_size);
|
|
||||||
|
|
||||||
if(search->max_size)
|
|
||||||
g_string_append_printf(search_str, "&max_size=%llu", (unsigned long long)search->max_size);
|
|
||||||
|
|
||||||
if(search->min_mtime)
|
|
||||||
g_string_append_printf(search_str, "&min_mtime=%s", search->min_mtime);
|
|
||||||
|
|
||||||
if(search->max_mtime)
|
|
||||||
g_string_append_printf(search_str, "&max_mtime=%s", search->max_mtime);
|
|
||||||
|
|
||||||
search_path = fm_path_new_for_uri(search_str->str);
|
|
||||||
g_string_free(search_str, TRUE);
|
|
||||||
}
|
|
||||||
return search_path;
|
|
||||||
}
|
|
||||||
@ -1,89 +0,0 @@
|
|||||||
/*
|
|
||||||
* fm-search-uri.h
|
|
||||||
*
|
|
||||||
* Copyright 2015 Hong Jen Yee (PCMan) <pcman.tw@gmail.com>
|
|
||||||
* Copyright 2012-2014 Andriy Grytsenko (LStranger) <andrej@rep.kiev.ua>
|
|
||||||
*
|
|
||||||
* 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
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* FmSearch implements a tool used to generate a search:// URI used by libfm to search for files.
|
|
||||||
* This API might become part of libfm in the future.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef _FM_SEARCH_H_
|
|
||||||
#define _FM_SEARCH_H_
|
|
||||||
|
|
||||||
#include <libfm/fm.h>
|
|
||||||
|
|
||||||
G_BEGIN_DECLS
|
|
||||||
|
|
||||||
typedef struct _FmSearch FmSearch;
|
|
||||||
|
|
||||||
FmSearch* fm_search_new(void);
|
|
||||||
void fm_search_free(FmSearch* search);
|
|
||||||
|
|
||||||
FmPath* fm_search_dup_path(FmSearch* search);
|
|
||||||
|
|
||||||
gboolean fm_search_get_recursive(FmSearch* search);
|
|
||||||
void fm_search_set_recursive(FmSearch* search, gboolean recursive);
|
|
||||||
|
|
||||||
gboolean fm_search_get_show_hidden(FmSearch* search);
|
|
||||||
void fm_search_set_show_hidden(FmSearch* search, gboolean show_hidden);
|
|
||||||
|
|
||||||
const char* fm_search_get_name_patterns(FmSearch* search);
|
|
||||||
void fm_search_set_name_patterns(FmSearch* search, const char* name_patterns);
|
|
||||||
|
|
||||||
gboolean fm_search_get_name_ci(FmSearch* search);
|
|
||||||
void fm_search_set_name_ci(FmSearch* search, gboolean name_ci);
|
|
||||||
|
|
||||||
gboolean fm_search_get_name_regex(FmSearch* search);
|
|
||||||
void fm_search_set_name_regex(FmSearch* search, gboolean name_regex);
|
|
||||||
|
|
||||||
const char* fm_search_get_content_pattern(FmSearch* search);
|
|
||||||
void fm_search_set_content_pattern(FmSearch* search, const char* content_pattern);
|
|
||||||
|
|
||||||
gboolean fm_search_get_content_ci(FmSearch* search);
|
|
||||||
void fm_search_set_content_ci(FmSearch* search, gboolean content_ci);
|
|
||||||
|
|
||||||
gboolean fm_search_get_content_regex(FmSearch* search);
|
|
||||||
void fm_search_set_content_regex(FmSearch* search, gboolean content_regex);
|
|
||||||
|
|
||||||
void fm_search_add_dir(FmSearch* search, const char* dir);
|
|
||||||
void fm_search_remove_dir(FmSearch* search, const char* dir);
|
|
||||||
GList* fm_search_get_dirs(FmSearch* search);
|
|
||||||
|
|
||||||
void fm_search_add_mime_type(FmSearch* search, const char* mime_type);
|
|
||||||
void fm_search_remove_mime_type(FmSearch* search, const char* mime_type);
|
|
||||||
GList* fm_search_get_mime_types(FmSearch* search);
|
|
||||||
|
|
||||||
guint64 fm_search_get_max_size(FmSearch* search);
|
|
||||||
void fm_search_set_max_size(FmSearch* search, guint64 size);
|
|
||||||
|
|
||||||
guint64 fm_search_get_min_size(FmSearch* search);
|
|
||||||
void fm_search_set_min_size(FmSearch* search, guint64 size);
|
|
||||||
|
|
||||||
/* format of mtime: YYYY-MM-DD */
|
|
||||||
const char* fm_search_get_max_mtime(FmSearch* search);
|
|
||||||
void fm_search_set_max_mtime(FmSearch* search, const char* mtime);
|
|
||||||
|
|
||||||
/* format of mtime: YYYY-MM-DD */
|
|
||||||
const char* fm_search_get_min_mtime(FmSearch* search);
|
|
||||||
void fm_search_set_min_mtime(FmSearch* search, const char* mtime);
|
|
||||||
|
|
||||||
G_END_DECLS
|
|
||||||
|
|
||||||
#endif /* _FM_SEARCH_H_ */
|
|
||||||
@ -1,230 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (C) 2012 - 2015 Hong Jen Yee (PCMan) <pcman.tw@gmail.com>
|
|
||||||
*
|
|
||||||
* 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 "folderitemdelegate.h"
|
|
||||||
#include "foldermodel.h"
|
|
||||||
#include <QPainter>
|
|
||||||
#include <QModelIndex>
|
|
||||||
#include <QStyleOptionViewItemV4>
|
|
||||||
#include <QApplication>
|
|
||||||
#include <QIcon>
|
|
||||||
#include <QTextLayout>
|
|
||||||
#include <QTextOption>
|
|
||||||
#include <QTextLine>
|
|
||||||
#include <QDebug>
|
|
||||||
|
|
||||||
namespace Fm {
|
|
||||||
|
|
||||||
FolderItemDelegate::FolderItemDelegate(QAbstractItemView* view, QObject* parent):
|
|
||||||
QStyledItemDelegate(parent ? parent : view),
|
|
||||||
symlinkIcon_(QIcon::fromTheme("emblem-symbolic-link")),
|
|
||||||
view_(view) {
|
|
||||||
}
|
|
||||||
|
|
||||||
FolderItemDelegate::~FolderItemDelegate() {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
QSize FolderItemDelegate::sizeHint(const QStyleOptionViewItem& option, const QModelIndex& index) const {
|
|
||||||
QVariant value = index.data(Qt::SizeHintRole);
|
|
||||||
if(value.isValid())
|
|
||||||
return qvariant_cast<QSize>(value);
|
|
||||||
if(option.decorationPosition == QStyleOptionViewItem::Top ||
|
|
||||||
option.decorationPosition == QStyleOptionViewItem::Bottom) {
|
|
||||||
|
|
||||||
QStyleOptionViewItemV4 opt = option;
|
|
||||||
initStyleOption(&opt, index);
|
|
||||||
opt.decorationAlignment = Qt::AlignHCenter|Qt::AlignTop;
|
|
||||||
opt.displayAlignment = Qt::AlignTop|Qt::AlignHCenter;
|
|
||||||
|
|
||||||
Q_ASSERT(gridSize_ != QSize());
|
|
||||||
QRectF textRect(0, 0, gridSize_.width(), gridSize_.height() - opt.decorationSize.height());
|
|
||||||
drawText(nullptr, 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);
|
|
||||||
}
|
|
||||||
return QStyledItemDelegate::sizeHint(option, index);
|
|
||||||
}
|
|
||||||
|
|
||||||
QIcon::Mode FolderItemDelegate::iconModeFromState(const QStyle::State state) {
|
|
||||||
|
|
||||||
if(state & QStyle::State_Enabled)
|
|
||||||
return (state & QStyle::State_Selected) ? QIcon::Selected : QIcon::Normal;
|
|
||||||
|
|
||||||
return QIcon::Disabled;
|
|
||||||
}
|
|
||||||
|
|
||||||
// special thanks to Razor-qt developer Alec Moskvin(amoskvin) for providing the fix!
|
|
||||||
void FolderItemDelegate::paint(QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index) const {
|
|
||||||
Q_ASSERT(index.isValid());
|
|
||||||
FmFileInfo* file = static_cast<FmFileInfo*>(index.data(FolderModel::FileInfoRole).value<void*>());
|
|
||||||
bool isSymlink = file && fm_file_info_is_symlink(file);
|
|
||||||
|
|
||||||
if(option.decorationPosition == QStyleOptionViewItem::Top ||
|
|
||||||
option.decorationPosition == QStyleOptionViewItem::Bottom) {
|
|
||||||
painter->save();
|
|
||||||
painter->setClipRect(option.rect);
|
|
||||||
|
|
||||||
QStyleOptionViewItemV4 opt = option;
|
|
||||||
initStyleOption(&opt, index);
|
|
||||||
opt.decorationAlignment = Qt::AlignHCenter|Qt::AlignTop;
|
|
||||||
opt.displayAlignment = Qt::AlignTop|Qt::AlignHCenter;
|
|
||||||
|
|
||||||
// draw the icon
|
|
||||||
QIcon::Mode iconMode = iconModeFromState(opt.state);
|
|
||||||
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
|
|
||||||
if(isSymlink)
|
|
||||||
painter->drawPixmap(iconPos, symlinkIcon_.pixmap(opt.decorationSize / 2, iconMode));
|
|
||||||
|
|
||||||
// draw the text
|
|
||||||
// The text rect dimensions should be exactly as they were in sizeHint()
|
|
||||||
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);
|
|
||||||
painter->restore();
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
// let QStyledItemDelegate does its default painting
|
|
||||||
QStyledItemDelegate::paint(painter, option, index);
|
|
||||||
|
|
||||||
// draw emblems if needed
|
|
||||||
if(isSymlink) {
|
|
||||||
QStyleOptionViewItemV4 opt = option;
|
|
||||||
initStyleOption(&opt, index);
|
|
||||||
QIcon::Mode iconMode = iconModeFromState(opt.state);
|
|
||||||
QPoint iconPos(opt.rect.x(), opt.rect.y() + (opt.rect.height() - opt.decorationSize.height()) / 2);
|
|
||||||
// draw some emblems for the item if needed
|
|
||||||
// we only support symlink emblem at the moment
|
|
||||||
painter->drawPixmap(iconPos, symlinkIcon_.pixmap(opt.decorationSize / 2, iconMode));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// if painter is nullptr, the method calculate the bounding rectangle of the text and save it to textRect
|
|
||||||
void FolderItemDelegate::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());
|
|
||||||
if(visibleLines == 1) // this is the only visible line
|
|
||||||
width = textRect.width();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
height += line.height();
|
|
||||||
width = qMax(width, line.naturalTextWidth());
|
|
||||||
++ visibleLines;
|
|
||||||
}
|
|
||||||
layout.endLayout();
|
|
||||||
width = qMax(width, (qreal)opt.fontMetrics.width(elidedText));
|
|
||||||
|
|
||||||
// draw background for selected item
|
|
||||||
QRectF boundRect = layout.boundingRect();
|
|
||||||
//qDebug() << "bound rect: " << boundRect << "width: " << width;
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
QPalette::ColorGroup cg = opt.state & QStyle::State_Enabled ? QPalette::Normal : QPalette::Disabled;
|
|
||||||
if(opt.state & QStyle::State_Selected) {
|
|
||||||
if(!opt.widget)
|
|
||||||
painter->fillRect(selRect, opt.palette.highlight());
|
|
||||||
painter->setPen(opt.palette.color(cg, QPalette::HighlightedText));
|
|
||||||
}
|
|
||||||
else
|
|
||||||
painter->setPen(opt.palette.color(cg, QPalette::Text));
|
|
||||||
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 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());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if(opt.state & QStyle::State_HasFocus) {
|
|
||||||
// draw focus rect
|
|
||||||
QStyleOptionFocusRect o;
|
|
||||||
o.QStyleOption::operator=(opt);
|
|
||||||
o.rect = selRect.toRect(); // subElementRect(SE_ItemViewItemFocusRect, vopt, widget);
|
|
||||||
o.state |= QStyle::State_KeyboardFocusChange;
|
|
||||||
o.state |= QStyle::State_Item;
|
|
||||||
QPalette::ColorGroup cg = (opt.state & QStyle::State_Enabled)
|
|
||||||
? QPalette::Normal : QPalette::Disabled;
|
|
||||||
o.backgroundColor = opt.palette.color(cg, (opt.state & QStyle::State_Selected)
|
|
||||||
? QPalette::Highlight : QPalette::Window);
|
|
||||||
if (const QWidget* widget = opt.widget) {
|
|
||||||
QStyle* style = widget->style() ? widget->style() : qApp->style();
|
|
||||||
style->drawPrimitive(QStyle::PE_FrameFocusRect, &o, painter, widget);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
} // namespace Fm
|
|
||||||
@ -1,59 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (C) 2012 - 2015 Hong Jen Yee (PCMan) <pcman.tw@gmail.com>
|
|
||||||
*
|
|
||||||
* 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 FM_FOLDERITEMDELEGATE_H
|
|
||||||
#define FM_FOLDERITEMDELEGATE_H
|
|
||||||
|
|
||||||
#include "libfmqtglobals.h"
|
|
||||||
#include <QStyledItemDelegate>
|
|
||||||
#include <QAbstractItemView>
|
|
||||||
|
|
||||||
namespace Fm {
|
|
||||||
|
|
||||||
class LIBFM_QT_API FolderItemDelegate : public QStyledItemDelegate {
|
|
||||||
Q_OBJECT
|
|
||||||
public:
|
|
||||||
explicit FolderItemDelegate(QAbstractItemView* view, QObject* parent = nullptr);
|
|
||||||
virtual ~FolderItemDelegate();
|
|
||||||
|
|
||||||
inline void setGridSize(QSize size) {
|
|
||||||
gridSize_ = size;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline QSize gridSize() const {
|
|
||||||
return gridSize_;
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual QSize sizeHint(const QStyleOptionViewItem & option, const QModelIndex & index) const;
|
|
||||||
virtual void paint(QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index) const;
|
|
||||||
|
|
||||||
private:
|
|
||||||
void drawText(QPainter* painter, QStyleOptionViewItemV4& opt, QRectF& textRect) const;
|
|
||||||
static QIcon::Mode iconModeFromState(QStyle::State state);
|
|
||||||
|
|
||||||
private:
|
|
||||||
QAbstractItemView* view_;
|
|
||||||
QIcon symlinkIcon_;
|
|
||||||
QSize gridSize_;
|
|
||||||
};
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif // FM_FOLDERITEMDELEGATE_H
|
|
||||||
@ -1,232 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (C) 2012 - 2015 Hong Jen Yee (PCMan) <pcman.tw@gmail.com>
|
|
||||||
* Copyright (C) 2012 - 2014 Andriy Grytsenko (LStranger) <andrej@rep.kiev.ua>
|
|
||||||
*
|
|
||||||
* 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 "foldermenu.h"
|
|
||||||
#include "createnewmenu.h"
|
|
||||||
#include "filepropsdialog.h"
|
|
||||||
#include "folderview.h"
|
|
||||||
#include "utilities.h"
|
|
||||||
#include <cstring> // for memset
|
|
||||||
|
|
||||||
namespace Fm {
|
|
||||||
|
|
||||||
FolderMenu::FolderMenu(FolderView* view, QWidget* parent):
|
|
||||||
QMenu(parent),
|
|
||||||
view_(view) {
|
|
||||||
|
|
||||||
ProxyFolderModel* model = view_->model();
|
|
||||||
|
|
||||||
createAction_ = new QAction(tr("Create &New"), this);
|
|
||||||
addAction(createAction_);
|
|
||||||
|
|
||||||
createAction_->setMenu(new CreateNewMenu(view_, view_->path(), this));
|
|
||||||
|
|
||||||
separator1_ = addSeparator();
|
|
||||||
|
|
||||||
pasteAction_ = new QAction(QIcon::fromTheme("edit-paste"), tr("&Paste"), this);
|
|
||||||
addAction(pasteAction_);
|
|
||||||
connect(pasteAction_, &QAction::triggered, this, &FolderMenu::onPasteActionTriggered);
|
|
||||||
|
|
||||||
separator2_ = addSeparator();
|
|
||||||
|
|
||||||
selectAllAction_ = new QAction(tr("Select &All"), this);
|
|
||||||
addAction(selectAllAction_);
|
|
||||||
connect(selectAllAction_, &QAction::triggered, this, &FolderMenu::onSelectAllActionTriggered);
|
|
||||||
|
|
||||||
invertSelectionAction_ = new QAction(tr("Invert Selection"), this);
|
|
||||||
addAction(invertSelectionAction_);
|
|
||||||
connect(invertSelectionAction_, &QAction::triggered, this, &FolderMenu::onInvertSelectionActionTriggered);
|
|
||||||
|
|
||||||
separator3_ = addSeparator();
|
|
||||||
|
|
||||||
sortAction_ = new QAction(tr("Sorting"), this);
|
|
||||||
addAction(sortAction_);
|
|
||||||
createSortMenu();
|
|
||||||
sortAction_->setMenu(sortMenu_);
|
|
||||||
|
|
||||||
showHiddenAction_ = new QAction(tr("Show Hidden"), this);
|
|
||||||
addAction(showHiddenAction_);
|
|
||||||
showHiddenAction_->setCheckable(true);
|
|
||||||
showHiddenAction_->setChecked(model->showHidden());
|
|
||||||
connect(showHiddenAction_, &QAction::triggered, this, &FolderMenu::onShowHiddenActionTriggered);
|
|
||||||
|
|
||||||
separator4_ = addSeparator();
|
|
||||||
|
|
||||||
propertiesAction_ = new QAction(tr("Folder Pr&operties"), this);
|
|
||||||
addAction(propertiesAction_);
|
|
||||||
connect(propertiesAction_, &QAction::triggered, this, &FolderMenu::onPropertiesActionTriggered);
|
|
||||||
}
|
|
||||||
|
|
||||||
FolderMenu::~FolderMenu() {
|
|
||||||
}
|
|
||||||
|
|
||||||
void FolderMenu::addSortMenuItem(QString title, int id) {
|
|
||||||
QAction* action = new QAction(title, this);
|
|
||||||
sortMenu_->addAction(action);
|
|
||||||
action->setCheckable(true);
|
|
||||||
sortActionGroup_->addAction(action);
|
|
||||||
connect(action, &QAction::triggered, this, &FolderMenu::onSortActionTriggered);
|
|
||||||
sortActions_[id] = action;
|
|
||||||
}
|
|
||||||
|
|
||||||
void FolderMenu::createSortMenu() {
|
|
||||||
ProxyFolderModel* model = view_->model();
|
|
||||||
|
|
||||||
sortMenu_ = new QMenu(this);
|
|
||||||
sortActionGroup_ = new QActionGroup(sortMenu_);
|
|
||||||
sortActionGroup_->setExclusive(true);
|
|
||||||
|
|
||||||
std::memset(sortActions_, 0, sizeof(sortActions_));
|
|
||||||
|
|
||||||
addSortMenuItem(tr("By File Name"), FolderModel::ColumnFileName);
|
|
||||||
addSortMenuItem(tr("By Modification Time"), FolderModel::ColumnFileMTime);
|
|
||||||
addSortMenuItem(tr("By File Size"), FolderModel::ColumnFileSize);
|
|
||||||
addSortMenuItem(tr("By File Type"), FolderModel::ColumnFileType);
|
|
||||||
addSortMenuItem(tr("By File Owner"), FolderModel::ColumnFileOwner);
|
|
||||||
|
|
||||||
int col = model->sortColumn();
|
|
||||||
|
|
||||||
if(col >= 0 && col < FolderModel::NumOfColumns) {
|
|
||||||
sortActions_[col]->setChecked(true);;
|
|
||||||
}
|
|
||||||
|
|
||||||
sortMenu_->addSeparator();
|
|
||||||
|
|
||||||
QActionGroup* group = new QActionGroup(this);
|
|
||||||
group->setExclusive(true);
|
|
||||||
actionAscending_ = new QAction(tr("Ascending"), this);
|
|
||||||
actionAscending_->setCheckable(true);
|
|
||||||
sortMenu_->addAction(actionAscending_);
|
|
||||||
group->addAction(actionAscending_);
|
|
||||||
|
|
||||||
actionDescending_ = new QAction(tr("Descending"), this);
|
|
||||||
actionDescending_->setCheckable(true);
|
|
||||||
sortMenu_->addAction(actionDescending_);
|
|
||||||
group->addAction(actionDescending_);
|
|
||||||
|
|
||||||
if(model->sortOrder() == Qt::AscendingOrder)
|
|
||||||
actionAscending_->setChecked(true);
|
|
||||||
else
|
|
||||||
actionDescending_->setChecked(true);
|
|
||||||
|
|
||||||
connect(actionAscending_, &QAction::triggered, this, &FolderMenu::onSortOrderActionTriggered);
|
|
||||||
connect(actionDescending_, &QAction::triggered, this, &FolderMenu::onSortOrderActionTriggered);
|
|
||||||
|
|
||||||
sortMenu_->addSeparator();
|
|
||||||
|
|
||||||
QAction* actionFolderFirst = new QAction(tr("Folder First"), this);
|
|
||||||
sortMenu_->addAction(actionFolderFirst);
|
|
||||||
actionFolderFirst->setCheckable(true);
|
|
||||||
|
|
||||||
if(model->folderFirst())
|
|
||||||
actionFolderFirst->setChecked(true);
|
|
||||||
|
|
||||||
connect(actionFolderFirst, &QAction::triggered, this, &FolderMenu::onFolderFirstActionTriggered);
|
|
||||||
|
|
||||||
QAction* actionCaseSensitive = new QAction(tr("Case Sensitive"), this);
|
|
||||||
sortMenu_->addAction(actionCaseSensitive);
|
|
||||||
actionCaseSensitive->setCheckable(true);
|
|
||||||
|
|
||||||
if(model->sortCaseSensitivity() == Qt::CaseSensitive)
|
|
||||||
actionCaseSensitive->setChecked(true);
|
|
||||||
|
|
||||||
connect(actionCaseSensitive, &QAction::triggered, this, &FolderMenu::onCaseSensitiveActionTriggered);
|
|
||||||
}
|
|
||||||
|
|
||||||
void FolderMenu::onPasteActionTriggered() {
|
|
||||||
FmPath* folderPath = view_->path();
|
|
||||||
|
|
||||||
if(folderPath)
|
|
||||||
pasteFilesFromClipboard(folderPath);
|
|
||||||
}
|
|
||||||
|
|
||||||
void FolderMenu::onSelectAllActionTriggered() {
|
|
||||||
view_->selectAll();
|
|
||||||
}
|
|
||||||
|
|
||||||
void FolderMenu::onInvertSelectionActionTriggered() {
|
|
||||||
view_->invertSelection();
|
|
||||||
}
|
|
||||||
|
|
||||||
void FolderMenu::onSortActionTriggered(bool checked) {
|
|
||||||
ProxyFolderModel* model = view_->model();
|
|
||||||
|
|
||||||
if(model) {
|
|
||||||
QAction* action = static_cast<QAction*>(sender());
|
|
||||||
|
|
||||||
for(int col = 0; col < FolderModel::NumOfColumns; ++col) {
|
|
||||||
if(action == sortActions_[col]) {
|
|
||||||
model->sort(col, model->sortOrder());
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void FolderMenu::onSortOrderActionTriggered(bool checked) {
|
|
||||||
ProxyFolderModel* model = view_->model();
|
|
||||||
|
|
||||||
if(model) {
|
|
||||||
QAction* action = static_cast<QAction*>(sender());
|
|
||||||
Qt::SortOrder order;
|
|
||||||
|
|
||||||
if(action == actionAscending_)
|
|
||||||
order = Qt::AscendingOrder;
|
|
||||||
else
|
|
||||||
order = Qt::DescendingOrder;
|
|
||||||
|
|
||||||
model->sort(model->sortColumn(), order);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void FolderMenu::onShowHiddenActionTriggered(bool checked) {
|
|
||||||
ProxyFolderModel* model = view_->model();
|
|
||||||
|
|
||||||
if(model) {
|
|
||||||
qDebug("show hidden: %d", checked);
|
|
||||||
model->setShowHidden(checked);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void FolderMenu::onCaseSensitiveActionTriggered(bool checked) {
|
|
||||||
ProxyFolderModel* model = view_->model();
|
|
||||||
|
|
||||||
if(model) {
|
|
||||||
model->setSortCaseSensitivity(checked ? Qt::CaseSensitive : Qt::CaseInsensitive);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void FolderMenu::onFolderFirstActionTriggered(bool checked) {
|
|
||||||
ProxyFolderModel* model = view_->model();
|
|
||||||
|
|
||||||
if(model) {
|
|
||||||
model->setFolderFirst(checked);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void FolderMenu::onPropertiesActionTriggered() {
|
|
||||||
FmFileInfo* folderInfo = view_->folderInfo();
|
|
||||||
|
|
||||||
if(folderInfo)
|
|
||||||
FilePropsDialog::showForFile(folderInfo);
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace Fm
|
|
||||||
127
src/foldermenu.h
127
src/foldermenu.h
@ -1,127 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (C) 2012 - 2015 Hong Jen Yee (PCMan) <pcman.tw@gmail.com>
|
|
||||||
*
|
|
||||||
* 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 FM_FOLDERMENU_H
|
|
||||||
#define FM_FOLDERMENU_H
|
|
||||||
|
|
||||||
#include "libfmqtglobals.h"
|
|
||||||
#include <QMenu>
|
|
||||||
#include <libfm/fm.h>
|
|
||||||
#include "foldermodel.h"
|
|
||||||
|
|
||||||
class QAction;
|
|
||||||
|
|
||||||
namespace Fm {
|
|
||||||
|
|
||||||
class FolderView;
|
|
||||||
|
|
||||||
class LIBFM_QT_API FolderMenu : public QMenu {
|
|
||||||
Q_OBJECT
|
|
||||||
|
|
||||||
public:
|
|
||||||
explicit FolderMenu(FolderView* view, QWidget* parent = 0);
|
|
||||||
virtual ~FolderMenu();
|
|
||||||
|
|
||||||
QAction* createAction() {
|
|
||||||
return createAction_;
|
|
||||||
}
|
|
||||||
|
|
||||||
QAction* separator1() {
|
|
||||||
return separator1_;
|
|
||||||
}
|
|
||||||
|
|
||||||
QAction* pasteAction() {
|
|
||||||
return pasteAction_;
|
|
||||||
}
|
|
||||||
|
|
||||||
QAction* separator2() {
|
|
||||||
return separator2_;
|
|
||||||
}
|
|
||||||
|
|
||||||
QAction* selectAllAction() {
|
|
||||||
return selectAllAction_;
|
|
||||||
}
|
|
||||||
|
|
||||||
QAction* invertSelectionAction() {
|
|
||||||
return invertSelectionAction_;
|
|
||||||
}
|
|
||||||
|
|
||||||
QAction* separator3() {
|
|
||||||
return separator3_;
|
|
||||||
}
|
|
||||||
|
|
||||||
QAction* sortAction() {
|
|
||||||
return sortAction_;
|
|
||||||
}
|
|
||||||
|
|
||||||
QAction* showHiddenAction() {
|
|
||||||
return showHiddenAction_;
|
|
||||||
}
|
|
||||||
|
|
||||||
QAction* separator4() {
|
|
||||||
return separator4_;
|
|
||||||
}
|
|
||||||
|
|
||||||
QAction* propertiesAction() {
|
|
||||||
return propertiesAction_;
|
|
||||||
}
|
|
||||||
|
|
||||||
FolderView* view() {
|
|
||||||
return view_;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected Q_SLOTS:
|
|
||||||
void onPasteActionTriggered();
|
|
||||||
void onSelectAllActionTriggered();
|
|
||||||
void onInvertSelectionActionTriggered();
|
|
||||||
void onSortActionTriggered(bool checked);
|
|
||||||
void onSortOrderActionTriggered(bool checked);
|
|
||||||
void onShowHiddenActionTriggered(bool checked);
|
|
||||||
void onCaseSensitiveActionTriggered(bool checked);
|
|
||||||
void onFolderFirstActionTriggered(bool checked);
|
|
||||||
void onPropertiesActionTriggered();
|
|
||||||
|
|
||||||
private:
|
|
||||||
void createSortMenu();
|
|
||||||
void addSortMenuItem(QString title, int id);
|
|
||||||
|
|
||||||
private:
|
|
||||||
FolderView* view_;
|
|
||||||
QAction* createAction_;
|
|
||||||
QAction* separator1_;
|
|
||||||
QAction* pasteAction_;
|
|
||||||
QAction* separator2_;
|
|
||||||
QAction* selectAllAction_;
|
|
||||||
QAction* invertSelectionAction_;
|
|
||||||
QAction* separator3_;
|
|
||||||
QAction* sortAction_;
|
|
||||||
QActionGroup* sortActionGroup_;
|
|
||||||
QMenu* sortMenu_;
|
|
||||||
QAction* sortActions_[FolderModel::NumOfColumns];
|
|
||||||
QAction* actionAscending_;
|
|
||||||
QAction* actionDescending_;
|
|
||||||
QAction* showHiddenAction_;
|
|
||||||
QAction* separator4_;
|
|
||||||
QAction* propertiesAction_;
|
|
||||||
};
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif // FM_FOLDERMENU_H
|
|
||||||
@ -1,559 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (C) 2012 - 2015 Hong Jen Yee (PCMan) <pcman.tw@gmail.com>
|
|
||||||
*
|
|
||||||
* 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 "foldermodel.h"
|
|
||||||
#include "icontheme.h"
|
|
||||||
#include <iostream>
|
|
||||||
#include <QtAlgorithms>
|
|
||||||
#include <QVector>
|
|
||||||
#include <qmimedata.h>
|
|
||||||
#include <QMimeData>
|
|
||||||
#include <QByteArray>
|
|
||||||
#include <QPixmap>
|
|
||||||
#include <QPainter>
|
|
||||||
#include "utilities.h"
|
|
||||||
#include "fileoperation.h"
|
|
||||||
#include "thumbnailloader.h"
|
|
||||||
|
|
||||||
namespace Fm {
|
|
||||||
|
|
||||||
FolderModel::FolderModel() :
|
|
||||||
folder_(nullptr) {
|
|
||||||
/*
|
|
||||||
ColumnIcon,
|
|
||||||
ColumnName,
|
|
||||||
ColumnFileType,
|
|
||||||
ColumnMTime,
|
|
||||||
NumOfColumns
|
|
||||||
*/
|
|
||||||
thumbnailRefCounts.reserve(4);
|
|
||||||
|
|
||||||
// reload all icons when the icon theme is changed
|
|
||||||
connect(IconTheme::instance(), &IconTheme::changed, this, &FolderModel::updateIcons);
|
|
||||||
}
|
|
||||||
|
|
||||||
FolderModel::~FolderModel() {
|
|
||||||
qDebug("delete FolderModel");
|
|
||||||
|
|
||||||
if(folder_)
|
|
||||||
setFolder(nullptr);
|
|
||||||
|
|
||||||
// if the thumbnail requests list is not empty, cancel them
|
|
||||||
if(!thumbnailResults.empty()) {
|
|
||||||
Q_FOREACH(FmThumbnailLoader* res, thumbnailResults) {
|
|
||||||
ThumbnailLoader::cancel(res);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void FolderModel::setFolder(FmFolder* new_folder) {
|
|
||||||
if(folder_) {
|
|
||||||
removeAll(); // remove old items
|
|
||||||
g_signal_handlers_disconnect_by_func(folder_, gpointer(onStartLoading), this);
|
|
||||||
g_signal_handlers_disconnect_by_func(folder_, gpointer(onFinishLoading), this);
|
|
||||||
g_signal_handlers_disconnect_by_func(folder_, gpointer(onFilesAdded), this);
|
|
||||||
g_signal_handlers_disconnect_by_func(folder_, gpointer(onFilesChanged), this);
|
|
||||||
g_signal_handlers_disconnect_by_func(folder_, gpointer(onFilesRemoved), this);
|
|
||||||
g_object_unref(folder_);
|
|
||||||
}
|
|
||||||
if(new_folder) {
|
|
||||||
folder_ = FM_FOLDER(g_object_ref(new_folder));
|
|
||||||
g_signal_connect(folder_, "start-loading", G_CALLBACK(onStartLoading), this);
|
|
||||||
g_signal_connect(folder_, "finish-loading", G_CALLBACK(onFinishLoading), this);
|
|
||||||
g_signal_connect(folder_, "files-added", G_CALLBACK(onFilesAdded), this);
|
|
||||||
g_signal_connect(folder_, "files-changed", G_CALLBACK(onFilesChanged), this);
|
|
||||||
g_signal_connect(folder_, "files-removed", G_CALLBACK(onFilesRemoved), this);
|
|
||||||
// handle the case if the folder is already loaded
|
|
||||||
if(fm_folder_is_loaded(folder_))
|
|
||||||
insertFiles(0, fm_folder_get_files(folder_));
|
|
||||||
}
|
|
||||||
else
|
|
||||||
folder_ = nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
void FolderModel::onStartLoading(FmFolder* folder, gpointer user_data) {
|
|
||||||
FolderModel* model = static_cast<FolderModel*>(user_data);
|
|
||||||
// remove all items
|
|
||||||
model->removeAll();
|
|
||||||
}
|
|
||||||
|
|
||||||
void FolderModel::onFinishLoading(FmFolder* folder, gpointer user_data) {
|
|
||||||
Q_UNUSED(folder)
|
|
||||||
Q_UNUSED(user_data)
|
|
||||||
}
|
|
||||||
|
|
||||||
void FolderModel::onFilesAdded(FmFolder* folder, GSList* files, gpointer user_data) {
|
|
||||||
FolderModel* model = static_cast<FolderModel*>(user_data);
|
|
||||||
int n_files = g_slist_length(files);
|
|
||||||
model->beginInsertRows(QModelIndex(), model->items.count(), model->items.count() + n_files - 1);
|
|
||||||
for(GSList* l = files; l; l = l->next) {
|
|
||||||
FmFileInfo* info = FM_FILE_INFO(l->data);
|
|
||||||
FolderModelItem item(info);
|
|
||||||
/*
|
|
||||||
if(fm_file_info_is_hidden(info)) {
|
|
||||||
model->hiddenItems.append(item);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
model->items.append(item);
|
|
||||||
}
|
|
||||||
model->endInsertRows();
|
|
||||||
}
|
|
||||||
|
|
||||||
//static
|
|
||||||
void FolderModel::onFilesChanged(FmFolder* folder, GSList* files, gpointer user_data) {
|
|
||||||
FolderModel* model = static_cast<FolderModel*>(user_data);
|
|
||||||
for(GSList* l = files; l; l = l->next) {
|
|
||||||
FmFileInfo* info = FM_FILE_INFO(l->data);
|
|
||||||
int row;
|
|
||||||
QList<FolderModelItem>::iterator it = model->findItemByFileInfo(info, &row);
|
|
||||||
if(it != model->items.end()) {
|
|
||||||
FolderModelItem& item = *it;
|
|
||||||
// try to update the item
|
|
||||||
item.displayName = QString::fromUtf8(fm_file_info_get_disp_name(info));
|
|
||||||
item.updateIcon();
|
|
||||||
item.thumbnails.clear();
|
|
||||||
QModelIndex index = model->createIndex(row, 0, &item);
|
|
||||||
Q_EMIT model->dataChanged(index, index);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//static
|
|
||||||
void FolderModel::onFilesRemoved(FmFolder* folder, GSList* files, gpointer user_data) {
|
|
||||||
FolderModel* model = static_cast<FolderModel*>(user_data);
|
|
||||||
for(GSList* l = files; l; l = l->next) {
|
|
||||||
FmFileInfo* info = FM_FILE_INFO(l->data);
|
|
||||||
const char* name = fm_file_info_get_name(info);
|
|
||||||
int row;
|
|
||||||
QList<FolderModelItem>::iterator it = model->findItemByName(name, &row);
|
|
||||||
if(it != model->items.end()) {
|
|
||||||
model->beginRemoveRows(QModelIndex(), row, row);
|
|
||||||
model->items.erase(it);
|
|
||||||
model->endRemoveRows();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void FolderModel::insertFiles(int row, FmFileInfoList* files) {
|
|
||||||
int n_files = fm_file_info_list_get_length(files);
|
|
||||||
beginInsertRows(QModelIndex(), row, row + n_files - 1);
|
|
||||||
for(GList* l = fm_file_info_list_peek_head_link(files); l; l = l->next) {
|
|
||||||
FolderModelItem item(FM_FILE_INFO(l->data));
|
|
||||||
items.append(item);
|
|
||||||
}
|
|
||||||
endInsertRows();
|
|
||||||
}
|
|
||||||
|
|
||||||
void FolderModel::removeAll() {
|
|
||||||
if(items.empty())
|
|
||||||
return;
|
|
||||||
beginRemoveRows(QModelIndex(), 0, items.size() - 1);
|
|
||||||
items.clear();
|
|
||||||
endRemoveRows();
|
|
||||||
}
|
|
||||||
|
|
||||||
int FolderModel::rowCount(const QModelIndex & parent) const {
|
|
||||||
if(parent.isValid())
|
|
||||||
return 0;
|
|
||||||
return items.size();
|
|
||||||
}
|
|
||||||
|
|
||||||
int FolderModel::columnCount (const QModelIndex & parent = QModelIndex()) const {
|
|
||||||
if(parent.isValid())
|
|
||||||
return 0;
|
|
||||||
return NumOfColumns;
|
|
||||||
}
|
|
||||||
|
|
||||||
FolderModelItem* FolderModel::itemFromIndex(const QModelIndex& index) const {
|
|
||||||
return reinterpret_cast<FolderModelItem*>(index.internalPointer());
|
|
||||||
}
|
|
||||||
|
|
||||||
FmFileInfo* FolderModel::fileInfoFromIndex(const QModelIndex& index) const {
|
|
||||||
FolderModelItem* item = itemFromIndex(index);
|
|
||||||
return item ? item->info : nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
QVariant FolderModel::data(const QModelIndex & index, int role/* = Qt::DisplayRole*/) const {
|
|
||||||
if(!index.isValid() || index.row() > items.size() || index.column() >= NumOfColumns) {
|
|
||||||
return QVariant();
|
|
||||||
}
|
|
||||||
FolderModelItem* item = itemFromIndex(index);
|
|
||||||
FmFileInfo* info = item->info;
|
|
||||||
|
|
||||||
switch(role) {
|
|
||||||
case Qt::ToolTipRole:
|
|
||||||
return QVariant(item->displayName);
|
|
||||||
case Qt::DisplayRole: {
|
|
||||||
switch(index.column()) {
|
|
||||||
case ColumnFileName: {
|
|
||||||
return QVariant(item->displayName);
|
|
||||||
}
|
|
||||||
case ColumnFileType: {
|
|
||||||
FmMimeType* mime = fm_file_info_get_mime_type(info);
|
|
||||||
const char* desc = fm_mime_type_get_desc(mime);
|
|
||||||
return QString::fromUtf8(desc);
|
|
||||||
}
|
|
||||||
case ColumnFileMTime: {
|
|
||||||
const char* name = fm_file_info_get_disp_mtime(info);
|
|
||||||
return QString::fromUtf8(name);
|
|
||||||
}
|
|
||||||
case ColumnFileSize: {
|
|
||||||
const char* name = fm_file_info_get_disp_size(info);
|
|
||||||
return QString::fromUtf8(name);
|
|
||||||
}
|
|
||||||
case ColumnFileOwner: {
|
|
||||||
const char* name = fm_file_info_get_disp_owner(info);
|
|
||||||
return QString::fromUtf8(name);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
case Qt::DecorationRole: {
|
|
||||||
if(index.column() == 0) {
|
|
||||||
// QPixmap pix = IconTheme::loadIcon(fm_file_info_get_icon(info), iconSize_);
|
|
||||||
return QVariant(item->icon);
|
|
||||||
// return QVariant(pix);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case FileInfoRole:
|
|
||||||
return qVariantFromValue((void*)info);
|
|
||||||
}
|
|
||||||
return QVariant();
|
|
||||||
}
|
|
||||||
|
|
||||||
QVariant FolderModel::headerData(int section, Qt::Orientation orientation, int role/* = Qt::DisplayRole*/) const {
|
|
||||||
if(role == Qt::DisplayRole) {
|
|
||||||
if(orientation == Qt::Horizontal) {
|
|
||||||
QString title;
|
|
||||||
switch(section) {
|
|
||||||
case ColumnFileName:
|
|
||||||
title = tr("Name");
|
|
||||||
break;
|
|
||||||
case ColumnFileType:
|
|
||||||
title = tr("Type");
|
|
||||||
break;
|
|
||||||
case ColumnFileSize:
|
|
||||||
title = tr("Size");
|
|
||||||
break;
|
|
||||||
case ColumnFileMTime:
|
|
||||||
title = tr("Modified");
|
|
||||||
break;
|
|
||||||
case ColumnFileOwner:
|
|
||||||
title = tr("Owner");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
return QVariant(title);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return QVariant();
|
|
||||||
}
|
|
||||||
|
|
||||||
QModelIndex FolderModel::index(int row, int column, const QModelIndex & parent) const {
|
|
||||||
if(row <0 || row >= items.size() || column < 0 || column >= NumOfColumns)
|
|
||||||
return QModelIndex();
|
|
||||||
const FolderModelItem& item = items.at(row);
|
|
||||||
return createIndex(row, column, (void*)&item);
|
|
||||||
}
|
|
||||||
|
|
||||||
QModelIndex FolderModel::parent(const QModelIndex & index) const {
|
|
||||||
return QModelIndex();
|
|
||||||
}
|
|
||||||
|
|
||||||
Qt::ItemFlags FolderModel::flags(const QModelIndex& index) const {
|
|
||||||
// FIXME: should not return same flags unconditionally for all columns
|
|
||||||
Qt::ItemFlags flags;
|
|
||||||
if(index.isValid()) {
|
|
||||||
flags = Qt::ItemIsEnabled|Qt::ItemIsSelectable;
|
|
||||||
if(index.column() == ColumnFileName)
|
|
||||||
flags |= (Qt::ItemIsDragEnabled|Qt::ItemIsDropEnabled);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
flags = Qt::ItemIsDropEnabled;
|
|
||||||
}
|
|
||||||
return flags;
|
|
||||||
}
|
|
||||||
|
|
||||||
// FIXME: this is very inefficient and should be replaced with a
|
|
||||||
// more reasonable implementation later.
|
|
||||||
QList<FolderModelItem>::iterator FolderModel::findItemByPath(FmPath* path, int* row) {
|
|
||||||
QList<FolderModelItem>::iterator it = items.begin();
|
|
||||||
int i = 0;
|
|
||||||
while(it != items.end()) {
|
|
||||||
FolderModelItem& item = *it;
|
|
||||||
FmPath* item_path = fm_file_info_get_path(item.info);
|
|
||||||
if(fm_path_equal(item_path, path)) {
|
|
||||||
*row = i;
|
|
||||||
return it;
|
|
||||||
}
|
|
||||||
++it;
|
|
||||||
++i;
|
|
||||||
}
|
|
||||||
return items.end();
|
|
||||||
}
|
|
||||||
|
|
||||||
// FIXME: this is very inefficient and should be replaced with a
|
|
||||||
// more reasonable implementation later.
|
|
||||||
QList<FolderModelItem>::iterator FolderModel::findItemByName(const char* name, int* row) {
|
|
||||||
QList<FolderModelItem>::iterator it = items.begin();
|
|
||||||
int i = 0;
|
|
||||||
while(it != items.end()) {
|
|
||||||
FolderModelItem& item = *it;
|
|
||||||
const char* item_name = fm_file_info_get_name(item.info);
|
|
||||||
if(strcmp(name, item_name) == 0) {
|
|
||||||
*row = i;
|
|
||||||
return it;
|
|
||||||
}
|
|
||||||
++it;
|
|
||||||
++i;
|
|
||||||
}
|
|
||||||
return items.end();
|
|
||||||
}
|
|
||||||
|
|
||||||
QList< FolderModelItem >::iterator FolderModel::findItemByFileInfo(FmFileInfo* info, int* row) {
|
|
||||||
QList<FolderModelItem>::iterator it = items.begin();
|
|
||||||
int i = 0;
|
|
||||||
while(it != items.end()) {
|
|
||||||
FolderModelItem& item = *it;
|
|
||||||
if(item.info == info) {
|
|
||||||
*row = i;
|
|
||||||
return it;
|
|
||||||
}
|
|
||||||
++it;
|
|
||||||
++i;
|
|
||||||
}
|
|
||||||
return items.end();
|
|
||||||
}
|
|
||||||
|
|
||||||
QStringList FolderModel::mimeTypes() const {
|
|
||||||
qDebug("FolderModel::mimeTypes");
|
|
||||||
QStringList types = QAbstractItemModel::mimeTypes();
|
|
||||||
// now types contains "application/x-qabstractitemmodeldatalist"
|
|
||||||
|
|
||||||
// add support for freedesktop Xdnd direct save (XDS) protocol.
|
|
||||||
// http://www.freedesktop.org/wiki/Specifications/XDS/#index4h2
|
|
||||||
// the real implementation is in FolderView::childDropEvent().
|
|
||||||
types << "XdndDirectSave0";
|
|
||||||
types << "text/uri-list";
|
|
||||||
// types << "x-special/gnome-copied-files";
|
|
||||||
return types;
|
|
||||||
}
|
|
||||||
|
|
||||||
QMimeData* FolderModel::mimeData(const QModelIndexList& indexes) const {
|
|
||||||
QMimeData* data = QAbstractItemModel::mimeData(indexes);
|
|
||||||
qDebug("FolderModel::mimeData");
|
|
||||||
// build a uri list
|
|
||||||
QByteArray urilist;
|
|
||||||
urilist.reserve(4096);
|
|
||||||
|
|
||||||
for(const auto &index : indexes) {
|
|
||||||
FolderModelItem* item = itemFromIndex(index);
|
|
||||||
if(item) {
|
|
||||||
FmPath* path = fm_file_info_get_path(item->info);
|
|
||||||
char* uri = fm_path_to_uri(path);
|
|
||||||
urilist.append(uri);
|
|
||||||
urilist.append('\n');
|
|
||||||
g_free(uri);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
data->setData("text/uri-list", urilist);
|
|
||||||
|
|
||||||
return data;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool FolderModel::dropMimeData(const QMimeData* data, Qt::DropAction action, int row, int column, const QModelIndex& parent) {
|
|
||||||
qDebug("FolderModel::dropMimeData");
|
|
||||||
if(!folder_)
|
|
||||||
return false;
|
|
||||||
FmPath* destPath;
|
|
||||||
if(parent.isValid()) { // drop on an item
|
|
||||||
FmFileInfo* info;
|
|
||||||
if(row == -1 && column == -1)
|
|
||||||
info = fileInfoFromIndex(parent);
|
|
||||||
else {
|
|
||||||
QModelIndex itemIndex = parent.child(row, column);
|
|
||||||
info = fileInfoFromIndex(itemIndex);
|
|
||||||
}
|
|
||||||
if(info)
|
|
||||||
destPath = fm_file_info_get_path(info);
|
|
||||||
else
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
else { // drop on blank area of the folder
|
|
||||||
destPath = path();
|
|
||||||
}
|
|
||||||
|
|
||||||
// FIXME: should we put this in dropEvent handler of FolderView instead?
|
|
||||||
if(data->hasUrls()) {
|
|
||||||
qDebug("drop action: %d", action);
|
|
||||||
FmPathList* srcPaths = pathListFromQUrls(data->urls());
|
|
||||||
switch(action) {
|
|
||||||
case Qt::CopyAction:
|
|
||||||
FileOperation::copyFiles(srcPaths, destPath);
|
|
||||||
break;
|
|
||||||
case Qt::MoveAction:
|
|
||||||
FileOperation::moveFiles(srcPaths, destPath);
|
|
||||||
break;
|
|
||||||
case Qt::LinkAction:
|
|
||||||
FileOperation::symlinkFiles(srcPaths, destPath);
|
|
||||||
default:
|
|
||||||
fm_path_list_unref(srcPaths);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
fm_path_list_unref(srcPaths);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
else if(data->hasFormat("application/x-qabstractitemmodeldatalist")) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return QAbstractListModel::dropMimeData(data, action, row, column, parent);
|
|
||||||
}
|
|
||||||
|
|
||||||
Qt::DropActions FolderModel::supportedDropActions() const {
|
|
||||||
qDebug("FolderModel::supportedDropActions");
|
|
||||||
return Qt::CopyAction|Qt::MoveAction|Qt::LinkAction;
|
|
||||||
}
|
|
||||||
|
|
||||||
// ask the model to load thumbnails of the specified size
|
|
||||||
void FolderModel::cacheThumbnails(const int size) {
|
|
||||||
QVector<QPair<int, int>>::iterator it = thumbnailRefCounts.begin();
|
|
||||||
while (it != thumbnailRefCounts.end()) {
|
|
||||||
if (it->first == size) {
|
|
||||||
++it->second;
|
|
||||||
return;
|
|
||||||
} else ++it;
|
|
||||||
}
|
|
||||||
thumbnailRefCounts.append(QPair<int, int>(size, 1));
|
|
||||||
}
|
|
||||||
|
|
||||||
// ask the model to free cached thumbnails of the specified size
|
|
||||||
void FolderModel::releaseThumbnails(int size) {
|
|
||||||
QVector<QPair<int, int> >::iterator it;
|
|
||||||
for(it = thumbnailRefCounts.begin(); it != thumbnailRefCounts.end(); ++it) {
|
|
||||||
if(it->first == size) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if(it != thumbnailRefCounts.end()) {
|
|
||||||
--it->second;
|
|
||||||
if(it->second == 0) {
|
|
||||||
thumbnailRefCounts.erase(it);
|
|
||||||
|
|
||||||
// remove thumbnails that ara queued for loading from thumbnailResults
|
|
||||||
QLinkedList<FmThumbnailLoader*>::iterator it;
|
|
||||||
for(it = thumbnailResults.begin(); it != thumbnailResults.end();) {
|
|
||||||
QLinkedList<FmThumbnailLoader*>::iterator next = it + 1;
|
|
||||||
FmThumbnailLoader* res = *it;
|
|
||||||
if(ThumbnailLoader::size(res) == size) {
|
|
||||||
ThumbnailLoader::cancel(res);
|
|
||||||
thumbnailResults.erase(it);
|
|
||||||
}
|
|
||||||
it = next;
|
|
||||||
}
|
|
||||||
|
|
||||||
// remove all cached thumbnails of the specified size
|
|
||||||
QList<FolderModelItem>::iterator itemIt;
|
|
||||||
for(itemIt = items.begin(); itemIt != items.end(); ++itemIt) {
|
|
||||||
FolderModelItem& item = *itemIt;
|
|
||||||
item.removeThumbnail(size);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void FolderModel::onThumbnailLoaded(FmThumbnailLoader* res, gpointer user_data) {
|
|
||||||
FolderModel* pThis = reinterpret_cast<FolderModel*>(user_data);
|
|
||||||
QLinkedList<FmThumbnailLoader*>::iterator it;
|
|
||||||
for(it = pThis->thumbnailResults.begin(); it != pThis->thumbnailResults.end(); ++it) {
|
|
||||||
if(*it == res) { // the thumbnail result is in our list
|
|
||||||
pThis->thumbnailResults.erase(it); // remove it from the list
|
|
||||||
FmFileInfo* info = ThumbnailLoader::fileInfo(res);
|
|
||||||
int row = -1;
|
|
||||||
// find the model item this thumbnail belongs to
|
|
||||||
QList<FolderModelItem>::iterator it = pThis->findItemByFileInfo(info, &row);
|
|
||||||
if(it != pThis->items.end()) {
|
|
||||||
// the file is found in our model
|
|
||||||
FolderModelItem& item = *it;
|
|
||||||
QModelIndex index = pThis->createIndex(row, 0, (void*)&item);
|
|
||||||
// store the image in the folder model item.
|
|
||||||
int size = ThumbnailLoader::size(res);
|
|
||||||
QImage image = ThumbnailLoader::image(res);
|
|
||||||
FolderModelItem::Thumbnail* thumbnail = item.findThumbnail(size);
|
|
||||||
thumbnail->image = image;
|
|
||||||
// qDebug("thumbnail loaded for: %s, size: %d", item.displayName.toUtf8().constData(), size);
|
|
||||||
if(image.isNull())
|
|
||||||
thumbnail->status = FolderModelItem::ThumbnailFailed;
|
|
||||||
else {
|
|
||||||
thumbnail->status = FolderModelItem::ThumbnailLoaded;
|
|
||||||
// FIXME: due to bugs in Qt's QStyledItemDelegate, if the image width and height
|
|
||||||
// are not the same, painting errors will happen. It's quite unfortunate.
|
|
||||||
// Let's do some padding to make its width and height equals.
|
|
||||||
// This greatly decrease performance :-(
|
|
||||||
// Later if we can re-implement our own item delegate, this can be avoided.
|
|
||||||
QPixmap pixmap = QPixmap(size, size);
|
|
||||||
pixmap.fill(QColor(0, 0, 0, 0)); // fill the pixmap with transparent color (alpha:0)
|
|
||||||
QPainter painter(&pixmap);
|
|
||||||
int x = (size - image.width()) / 2;
|
|
||||||
int y = (size - image.height()) / 2;
|
|
||||||
painter.drawImage(QPoint(x, y), image); // draw the image to the pixmap at center.
|
|
||||||
// FIXME: should we cache QPixmap instead for performance reason?
|
|
||||||
thumbnail->image = pixmap.toImage(); // convert it back to image
|
|
||||||
|
|
||||||
// tell the world that we have the thumbnail loaded
|
|
||||||
Q_EMIT pThis->thumbnailLoaded(index, size);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// get a thumbnail of size at the index
|
|
||||||
// if a thumbnail is not yet loaded, this will initiate loading of the thumbnail.
|
|
||||||
QImage FolderModel::thumbnailFromIndex(const QModelIndex& index, int size) {
|
|
||||||
FolderModelItem* item = itemFromIndex(index);
|
|
||||||
if(item) {
|
|
||||||
FolderModelItem::Thumbnail* thumbnail = item->findThumbnail(size);
|
|
||||||
// qDebug("FolderModel::thumbnailFromIndex: %d, %s", thumbnail->status, item->displayName.toUtf8().data());
|
|
||||||
switch(thumbnail->status) {
|
|
||||||
case FolderModelItem::ThumbnailNotChecked: {
|
|
||||||
// load the thumbnail
|
|
||||||
FmThumbnailLoader* res = ThumbnailLoader::load(item->info, size, onThumbnailLoaded, this);
|
|
||||||
thumbnailResults.push_back(res);
|
|
||||||
thumbnail->status = FolderModelItem::ThumbnailLoading;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case FolderModelItem::ThumbnailLoaded:
|
|
||||||
return thumbnail->image;
|
|
||||||
default:;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return QImage();
|
|
||||||
}
|
|
||||||
|
|
||||||
void FolderModel::updateIcons() {
|
|
||||||
QList<FolderModelItem>::iterator it = items.begin();
|
|
||||||
for(;it != items.end(); ++it) {
|
|
||||||
(*it).updateIcon();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
} // namespace Fm
|
|
||||||
@ -1,121 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (C) 2012 - 2015 Hong Jen Yee (PCMan) <pcman.tw@gmail.com>
|
|
||||||
*
|
|
||||||
* 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 FM_FOLDERMODEL_H
|
|
||||||
#define FM_FOLDERMODEL_H
|
|
||||||
|
|
||||||
#include "libfmqtglobals.h"
|
|
||||||
#include <QAbstractListModel>
|
|
||||||
#include <QIcon>
|
|
||||||
#include <QImage>
|
|
||||||
#include <libfm/fm.h>
|
|
||||||
#include <QList>
|
|
||||||
#include <QVector>
|
|
||||||
#include <QLinkedList>
|
|
||||||
#include <QPair>
|
|
||||||
#include "foldermodelitem.h"
|
|
||||||
|
|
||||||
namespace Fm {
|
|
||||||
|
|
||||||
class LIBFM_QT_API FolderModel : public QAbstractListModel {
|
|
||||||
Q_OBJECT
|
|
||||||
public:
|
|
||||||
|
|
||||||
enum Role {
|
|
||||||
FileInfoRole = Qt::UserRole
|
|
||||||
};
|
|
||||||
|
|
||||||
enum ColumnId {
|
|
||||||
ColumnFileName,
|
|
||||||
ColumnFileType,
|
|
||||||
ColumnFileSize,
|
|
||||||
ColumnFileMTime,
|
|
||||||
ColumnFileOwner,
|
|
||||||
NumOfColumns
|
|
||||||
};
|
|
||||||
|
|
||||||
public:
|
|
||||||
FolderModel();
|
|
||||||
virtual ~FolderModel();
|
|
||||||
|
|
||||||
FmFolder* folder() {
|
|
||||||
return folder_;
|
|
||||||
}
|
|
||||||
void setFolder(FmFolder* new_folder);
|
|
||||||
|
|
||||||
FmPath* path() {
|
|
||||||
return folder_ ? fm_folder_get_path(folder_) : NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
int rowCount(const QModelIndex & parent = QModelIndex()) const;
|
|
||||||
int columnCount (const QModelIndex & parent) const;
|
|
||||||
QVariant data(const QModelIndex & index, int role) const;
|
|
||||||
QVariant headerData(int section, Qt::Orientation orientation, int role) const;
|
|
||||||
QModelIndex index(int row, int column, const QModelIndex & parent = QModelIndex()) const;
|
|
||||||
QModelIndex parent( const QModelIndex & index ) const;
|
|
||||||
// void sort(int column, Qt::SortOrder order = Qt::AscendingOrder);
|
|
||||||
|
|
||||||
Qt::ItemFlags flags(const QModelIndex & index) const;
|
|
||||||
|
|
||||||
virtual QStringList mimeTypes() const;
|
|
||||||
virtual QMimeData* mimeData(const QModelIndexList & indexes) const;
|
|
||||||
virtual Qt::DropActions supportedDropActions() const;
|
|
||||||
virtual bool dropMimeData(const QMimeData* data, Qt::DropAction action, int row, int column, const QModelIndex& parent);
|
|
||||||
|
|
||||||
FmFileInfo* fileInfoFromIndex(const QModelIndex& index) const;
|
|
||||||
FolderModelItem* itemFromIndex(const QModelIndex& index) const;
|
|
||||||
QImage thumbnailFromIndex(const QModelIndex& index, int size);
|
|
||||||
|
|
||||||
void cacheThumbnails(int size);
|
|
||||||
void releaseThumbnails(int size);
|
|
||||||
|
|
||||||
Q_SIGNALS:
|
|
||||||
void thumbnailLoaded(const QModelIndex& index, int size);
|
|
||||||
|
|
||||||
public Q_SLOTS:
|
|
||||||
void updateIcons();
|
|
||||||
|
|
||||||
protected:
|
|
||||||
static void onStartLoading(FmFolder* folder, gpointer user_data);
|
|
||||||
static void onFinishLoading(FmFolder* folder, gpointer user_data);
|
|
||||||
static void onFilesAdded(FmFolder* folder, GSList* files, gpointer user_data);
|
|
||||||
static void onFilesChanged(FmFolder* folder, GSList* files, gpointer user_data);
|
|
||||||
static void onFilesRemoved(FmFolder* folder, GSList* files, gpointer user_data);
|
|
||||||
static void onThumbnailLoaded(FmThumbnailLoader *res, gpointer user_data);
|
|
||||||
|
|
||||||
void insertFiles(int row, FmFileInfoList* files);
|
|
||||||
void removeAll();
|
|
||||||
QList<FolderModelItem>::iterator findItemByPath(FmPath* path, int* row);
|
|
||||||
QList<FolderModelItem>::iterator findItemByName(const char* name, int* row);
|
|
||||||
QList<FolderModelItem>::iterator findItemByFileInfo(FmFileInfo* info, int* row);
|
|
||||||
|
|
||||||
private:
|
|
||||||
FmFolder* folder_;
|
|
||||||
// FIXME: should we use a hash table here so item lookup becomes much faster?
|
|
||||||
QList<FolderModelItem> items;
|
|
||||||
|
|
||||||
// record what size of thumbnails we should cache in an array of <size, refCount> pairs.
|
|
||||||
QVector<QPair<int, int> > thumbnailRefCounts;
|
|
||||||
QLinkedList<FmThumbnailLoader*> thumbnailResults;
|
|
||||||
};
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif // FM_FOLDERMODEL_H
|
|
||||||
@ -1,96 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (C) 2012 - 2015 Hong Jen Yee (PCMan) <pcman.tw@gmail.com>
|
|
||||||
*
|
|
||||||
* 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 "foldermodelitem.h"
|
|
||||||
|
|
||||||
namespace Fm {
|
|
||||||
|
|
||||||
FolderModelItem::FolderModelItem(FmFileInfo* _info):
|
|
||||||
info(fm_file_info_ref(_info)) {
|
|
||||||
displayName = QString::fromUtf8(fm_file_info_get_disp_name(info));
|
|
||||||
icon = IconTheme::icon(fm_file_info_get_icon(_info));
|
|
||||||
thumbnails.reserve(2);
|
|
||||||
}
|
|
||||||
|
|
||||||
FolderModelItem::FolderModelItem(const FolderModelItem& other) {
|
|
||||||
info = other.info ? fm_file_info_ref(other.info) : NULL;
|
|
||||||
displayName = QString::fromUtf8(fm_file_info_get_disp_name(info));
|
|
||||||
icon = other.icon;
|
|
||||||
thumbnails = other.thumbnails;
|
|
||||||
}
|
|
||||||
|
|
||||||
FolderModelItem::~FolderModelItem() {
|
|
||||||
if(info)
|
|
||||||
fm_file_info_unref(info);
|
|
||||||
}
|
|
||||||
|
|
||||||
// find thumbnail of the specified size
|
|
||||||
// The returned thumbnail item is temporary and short-lived
|
|
||||||
// If you need to use the struct later, copy it to your own struct to keep it.
|
|
||||||
FolderModelItem::Thumbnail* FolderModelItem::findThumbnail(int size) {
|
|
||||||
QVector<Thumbnail>::iterator it;
|
|
||||||
for(it = thumbnails.begin(); it != thumbnails.end(); ++it) {
|
|
||||||
if(it->size == size) { // an image of the same size is found
|
|
||||||
return it;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if(it == thumbnails.end()) {
|
|
||||||
Thumbnail thumbnail;
|
|
||||||
thumbnail.status = ThumbnailNotChecked;
|
|
||||||
thumbnail.size = size;
|
|
||||||
thumbnails.append(thumbnail);
|
|
||||||
}
|
|
||||||
return &thumbnails.back();
|
|
||||||
}
|
|
||||||
|
|
||||||
// remove cached thumbnail of the specified size
|
|
||||||
void FolderModelItem::removeThumbnail(int size) {
|
|
||||||
QVector<Thumbnail>::iterator it;
|
|
||||||
for(it = thumbnails.begin(); it != thumbnails.end(); ++it) {
|
|
||||||
if(it->size == size) { // an image of the same size is found
|
|
||||||
thumbnails.erase(it);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#if 0
|
|
||||||
// cache the thumbnail of the specified size in the folder item
|
|
||||||
void FolderModelItem::setThumbnail(int size, QImage image) {
|
|
||||||
QVector<Thumbnail>::iterator it;
|
|
||||||
for(it = thumbnails.begin(); it != thumbnails.end(); ++it) {
|
|
||||||
if(it->size == size) { // an image of the same size already exists
|
|
||||||
it->image = image; // replace it
|
|
||||||
it->status = ThumbnailLoaded;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if(it == thumbnails.end()) { // the image is not found
|
|
||||||
Thumbnail thumbnail;
|
|
||||||
thumbnail.size = size;
|
|
||||||
thumbnail.status = ThumbnailLoaded;
|
|
||||||
thumbnail.image = image;
|
|
||||||
thumbnails.append(thumbnail); // add a new entry
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
} // namespace Fm
|
|
||||||
@ -1,71 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (C) 2012 - 2015 Hong Jen Yee (PCMan) <pcman.tw@gmail.com>
|
|
||||||
*
|
|
||||||
* 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 FM_FOLDERMODELITEM_H
|
|
||||||
#define FM_FOLDERMODELITEM_H
|
|
||||||
|
|
||||||
#include "libfmqtglobals.h"
|
|
||||||
#include <libfm/fm.h>
|
|
||||||
#include <QImage>
|
|
||||||
#include <QString>
|
|
||||||
#include <QIcon>
|
|
||||||
#include <QVector>
|
|
||||||
#include "icontheme.h"
|
|
||||||
|
|
||||||
namespace Fm {
|
|
||||||
|
|
||||||
class LIBFM_QT_API FolderModelItem {
|
|
||||||
public:
|
|
||||||
|
|
||||||
enum ThumbnailStatus {
|
|
||||||
ThumbnailNotChecked,
|
|
||||||
ThumbnailLoading,
|
|
||||||
ThumbnailLoaded,
|
|
||||||
ThumbnailFailed
|
|
||||||
};
|
|
||||||
|
|
||||||
struct Thumbnail {
|
|
||||||
int size;
|
|
||||||
ThumbnailStatus status;
|
|
||||||
QImage image;
|
|
||||||
};
|
|
||||||
|
|
||||||
public:
|
|
||||||
FolderModelItem(FmFileInfo* _info);
|
|
||||||
FolderModelItem(const FolderModelItem& other);
|
|
||||||
virtual ~FolderModelItem();
|
|
||||||
|
|
||||||
Thumbnail* findThumbnail(int size);
|
|
||||||
// void setThumbnail(int size, QImage image);
|
|
||||||
void removeThumbnail(int size);
|
|
||||||
|
|
||||||
void updateIcon() {
|
|
||||||
icon = IconTheme::icon(fm_file_info_get_icon(info));
|
|
||||||
}
|
|
||||||
|
|
||||||
QString displayName;
|
|
||||||
QIcon icon;
|
|
||||||
FmFileInfo* info;
|
|
||||||
QVector<Thumbnail> thumbnails;
|
|
||||||
};
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif // FM_FOLDERMODELITEM_H
|
|
||||||
1030
src/folderview.cpp
1030
src/folderview.cpp
File diff suppressed because it is too large
Load Diff
179
src/folderview.h
179
src/folderview.h
@ -1,179 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (C) 2012 - 2015 Hong Jen Yee (PCMan) <pcman.tw@gmail.com>
|
|
||||||
*
|
|
||||||
* 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 FM_FOLDERVIEW_H
|
|
||||||
#define FM_FOLDERVIEW_H
|
|
||||||
|
|
||||||
#include "libfmqtglobals.h"
|
|
||||||
#include <QWidget>
|
|
||||||
#include <QListView>
|
|
||||||
#include <QTreeView>
|
|
||||||
#include <QMouseEvent>
|
|
||||||
#include <libfm/fm.h>
|
|
||||||
#include "foldermodel.h"
|
|
||||||
#include "proxyfoldermodel.h"
|
|
||||||
|
|
||||||
class QTimer;
|
|
||||||
|
|
||||||
namespace Fm {
|
|
||||||
|
|
||||||
class FileMenu;
|
|
||||||
class FolderMenu;
|
|
||||||
class FileLauncher;
|
|
||||||
class FolderViewStyle;
|
|
||||||
|
|
||||||
class LIBFM_QT_API FolderView : public QWidget {
|
|
||||||
Q_OBJECT
|
|
||||||
|
|
||||||
public:
|
|
||||||
|
|
||||||
enum ViewMode {
|
|
||||||
FirstViewMode = 1,
|
|
||||||
IconMode = FirstViewMode,
|
|
||||||
CompactMode,
|
|
||||||
DetailedListMode,
|
|
||||||
ThumbnailMode,
|
|
||||||
LastViewMode = ThumbnailMode,
|
|
||||||
NumViewModes = (LastViewMode - FirstViewMode + 1)
|
|
||||||
};
|
|
||||||
|
|
||||||
enum ClickType {
|
|
||||||
ActivatedClick,
|
|
||||||
MiddleClick,
|
|
||||||
ContextMenuClick
|
|
||||||
};
|
|
||||||
|
|
||||||
friend class FolderViewTreeView;
|
|
||||||
friend class FolderViewListView;
|
|
||||||
|
|
||||||
explicit FolderView(ViewMode _mode = IconMode, QWidget* parent = 0);
|
|
||||||
virtual ~FolderView();
|
|
||||||
|
|
||||||
void setViewMode(ViewMode _mode);
|
|
||||||
ViewMode viewMode() const;
|
|
||||||
|
|
||||||
void setIconSize(ViewMode mode, QSize size);
|
|
||||||
QSize iconSize(ViewMode mode) const;
|
|
||||||
|
|
||||||
QAbstractItemView* childView() const;
|
|
||||||
|
|
||||||
ProxyFolderModel* model() const;
|
|
||||||
void setModel(ProxyFolderModel* _model);
|
|
||||||
|
|
||||||
FmFolder* folder() {
|
|
||||||
return model_ ? static_cast<FolderModel*>(model_->sourceModel())->folder() : NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
FmFileInfo* folderInfo() {
|
|
||||||
FmFolder* _folder = folder();
|
|
||||||
return _folder ? fm_folder_get_info(_folder) : NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
FmPath* path() {
|
|
||||||
FmFolder* _folder = folder();
|
|
||||||
return _folder ? fm_folder_get_path(_folder) : NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
QItemSelectionModel* selectionModel() const;
|
|
||||||
FmFileInfoList* selectedFiles() const;
|
|
||||||
FmPathList* selectedFilePaths() const;
|
|
||||||
QModelIndex indexFromFolderPath(FmPath* folderPath) const;
|
|
||||||
|
|
||||||
void selectAll();
|
|
||||||
|
|
||||||
void invertSelection();
|
|
||||||
|
|
||||||
void setFileLauncher(FileLauncher* launcher) {
|
|
||||||
fileLauncher_ = launcher;
|
|
||||||
}
|
|
||||||
|
|
||||||
FileLauncher* fileLauncher() {
|
|
||||||
return fileLauncher_;
|
|
||||||
}
|
|
||||||
|
|
||||||
int autoSelectionDelay() const {
|
|
||||||
return autoSelectionDelay_;
|
|
||||||
}
|
|
||||||
|
|
||||||
void setAutoSelectionDelay(int delay);
|
|
||||||
|
|
||||||
protected:
|
|
||||||
virtual bool event(QEvent* event);
|
|
||||||
virtual void contextMenuEvent(QContextMenuEvent* event);
|
|
||||||
virtual void childMousePressEvent(QMouseEvent* event);
|
|
||||||
virtual void childDragEnterEvent(QDragEnterEvent* event);
|
|
||||||
virtual void childDragMoveEvent(QDragMoveEvent* e);
|
|
||||||
virtual void childDragLeaveEvent(QDragLeaveEvent* e);
|
|
||||||
virtual void childDropEvent(QDropEvent* e);
|
|
||||||
|
|
||||||
void emitClickedAt(ClickType type, const QPoint& pos);
|
|
||||||
|
|
||||||
QModelIndexList selectedRows ( int column = 0 ) const;
|
|
||||||
QModelIndexList selectedIndexes() const;
|
|
||||||
|
|
||||||
virtual void prepareFileMenu(Fm::FileMenu* menu);
|
|
||||||
virtual void prepareFolderMenu(Fm::FolderMenu* menu);
|
|
||||||
|
|
||||||
virtual bool eventFilter(QObject* watched, QEvent* event);
|
|
||||||
|
|
||||||
void updateGridSize(); // called when view mode, icon size, font size or cell margin is changed
|
|
||||||
|
|
||||||
QSize getMargins() const {
|
|
||||||
return itemDelegateMargins_;
|
|
||||||
}
|
|
||||||
|
|
||||||
// sets the cell margins in the icon and thumbnail modes
|
|
||||||
// and calls updateGridSize() when needed
|
|
||||||
void setMargins(QSize size);
|
|
||||||
|
|
||||||
public Q_SLOTS:
|
|
||||||
void onItemActivated(QModelIndex index);
|
|
||||||
void onSelectionChanged(const QItemSelection & selected, const QItemSelection & deselected);
|
|
||||||
virtual void onFileClicked(int type, FmFileInfo* fileInfo);
|
|
||||||
|
|
||||||
private Q_SLOTS:
|
|
||||||
void onAutoSelectionTimeout();
|
|
||||||
void onSelChangedTimeout();
|
|
||||||
|
|
||||||
Q_SIGNALS:
|
|
||||||
void clicked(int type, FmFileInfo* file);
|
|
||||||
void clickedBack();
|
|
||||||
void clickedForward();
|
|
||||||
void selChanged(int n_sel);
|
|
||||||
void sortChanged();
|
|
||||||
|
|
||||||
private:
|
|
||||||
|
|
||||||
QAbstractItemView* view;
|
|
||||||
ProxyFolderModel* model_;
|
|
||||||
ViewMode mode;
|
|
||||||
QSize iconSize_[NumViewModes];
|
|
||||||
FileLauncher* fileLauncher_;
|
|
||||||
int autoSelectionDelay_;
|
|
||||||
QTimer* autoSelectionTimer_;
|
|
||||||
QModelIndex lastAutoSelectionIndex_;
|
|
||||||
QTimer* selChangedTimer_;
|
|
||||||
// the cell margins in the icon and thumbnail modes
|
|
||||||
QSize itemDelegateMargins_;
|
|
||||||
};
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif // FM_FOLDERVIEW_H
|
|
||||||
@ -1,113 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (C) 2012 - 2015 Hong Jen Yee (PCMan) <pcman.tw@gmail.com>
|
|
||||||
*
|
|
||||||
* 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 FM_FOLDERVIEW_P_H
|
|
||||||
#define FM_FOLDERVIEW_P_H
|
|
||||||
|
|
||||||
#include <QListView>
|
|
||||||
#include <QTreeView>
|
|
||||||
#include <QMouseEvent>
|
|
||||||
#include "folderview.h"
|
|
||||||
|
|
||||||
class QTimer;
|
|
||||||
|
|
||||||
namespace Fm {
|
|
||||||
|
|
||||||
// override these classes for implementing FolderView
|
|
||||||
class FolderViewListView : public QListView {
|
|
||||||
Q_OBJECT
|
|
||||||
public:
|
|
||||||
friend class FolderView;
|
|
||||||
FolderViewListView(QWidget* parent = 0);
|
|
||||||
virtual ~FolderViewListView();
|
|
||||||
virtual void startDrag(Qt::DropActions supportedActions);
|
|
||||||
virtual void mousePressEvent(QMouseEvent* event);
|
|
||||||
virtual void mouseReleaseEvent(QMouseEvent* event);
|
|
||||||
virtual void mouseDoubleClickEvent(QMouseEvent* event);
|
|
||||||
virtual void dragEnterEvent(QDragEnterEvent* event);
|
|
||||||
virtual void dragMoveEvent(QDragMoveEvent* e);
|
|
||||||
virtual void dragLeaveEvent(QDragLeaveEvent* e);
|
|
||||||
virtual void dropEvent(QDropEvent* e);
|
|
||||||
|
|
||||||
virtual QModelIndex indexAt(const QPoint & point) const;
|
|
||||||
|
|
||||||
inline void setPositionForIndex(const QPoint & position, const QModelIndex & index) {
|
|
||||||
QListView::setPositionForIndex(position, index);
|
|
||||||
}
|
|
||||||
|
|
||||||
inline QRect rectForIndex(const QModelIndex & index) const {
|
|
||||||
return QListView::rectForIndex(index);
|
|
||||||
}
|
|
||||||
|
|
||||||
inline QStyleOptionViewItem getViewOptions() {
|
|
||||||
return viewOptions();
|
|
||||||
}
|
|
||||||
|
|
||||||
Q_SIGNALS:
|
|
||||||
void activatedFiltered(const QModelIndex &index);
|
|
||||||
|
|
||||||
private Q_SLOTS:
|
|
||||||
void activation(const QModelIndex &index);
|
|
||||||
|
|
||||||
private:
|
|
||||||
bool activationAllowed_;
|
|
||||||
};
|
|
||||||
|
|
||||||
class FolderViewTreeView : public QTreeView {
|
|
||||||
Q_OBJECT
|
|
||||||
public:
|
|
||||||
friend class FolderView;
|
|
||||||
FolderViewTreeView(QWidget* parent = 0);
|
|
||||||
virtual ~FolderViewTreeView();
|
|
||||||
virtual void setModel(QAbstractItemModel* model);
|
|
||||||
virtual void mousePressEvent(QMouseEvent* event);
|
|
||||||
virtual void mouseReleaseEvent(QMouseEvent* event);
|
|
||||||
virtual void mouseDoubleClickEvent(QMouseEvent* event);
|
|
||||||
virtual void dragEnterEvent(QDragEnterEvent* event);
|
|
||||||
virtual void dragMoveEvent(QDragMoveEvent* e);
|
|
||||||
virtual void dragLeaveEvent(QDragLeaveEvent* e);
|
|
||||||
virtual void dropEvent(QDropEvent* e);
|
|
||||||
|
|
||||||
virtual void rowsInserted(const QModelIndex& parent,int start, int end);
|
|
||||||
virtual void rowsAboutToBeRemoved(const QModelIndex& parent,int start, int end);
|
|
||||||
virtual void dataChanged(const QModelIndex& topLeft, const QModelIndex& bottomRight);
|
|
||||||
virtual void reset();
|
|
||||||
|
|
||||||
virtual void resizeEvent(QResizeEvent* event);
|
|
||||||
void queueLayoutColumns();
|
|
||||||
|
|
||||||
Q_SIGNALS:
|
|
||||||
void activatedFiltered(const QModelIndex &index);
|
|
||||||
|
|
||||||
private Q_SLOTS:
|
|
||||||
void layoutColumns();
|
|
||||||
void activation(const QModelIndex &index);
|
|
||||||
void onSortFilterChanged();
|
|
||||||
|
|
||||||
private:
|
|
||||||
bool doingLayout_;
|
|
||||||
QTimer* layoutTimer_;
|
|
||||||
bool activationAllowed_;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
} // namespace Fm
|
|
||||||
|
|
||||||
#endif // FM_FOLDERVIEW_P_H
|
|
||||||
@ -1,58 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (C) 2013 - 2015 Hong Jen Yee (PCMan) <pcman.tw@gmail.com>
|
|
||||||
*
|
|
||||||
* 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 "fontbutton.h"
|
|
||||||
#include <QFontDialog>
|
|
||||||
#include <X11/X.h>
|
|
||||||
|
|
||||||
namespace Fm {
|
|
||||||
|
|
||||||
FontButton::FontButton(QWidget* parent): QPushButton(parent) {
|
|
||||||
connect(this, &QPushButton::clicked, this, &FontButton::onClicked);
|
|
||||||
}
|
|
||||||
|
|
||||||
FontButton::~FontButton() {
|
|
||||||
}
|
|
||||||
|
|
||||||
void FontButton::onClicked() {
|
|
||||||
QFontDialog dlg(font_);
|
|
||||||
if(dlg.exec() == QDialog::Accepted) {
|
|
||||||
setFont(dlg.selectedFont());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void FontButton::setFont(QFont font) {
|
|
||||||
font_ = font;
|
|
||||||
QString text = font.family();
|
|
||||||
if(font.bold()) {
|
|
||||||
text += " ";
|
|
||||||
text += tr("Bold");
|
|
||||||
}
|
|
||||||
if(font.italic()) {
|
|
||||||
text += " ";
|
|
||||||
text += tr("Italic");
|
|
||||||
}
|
|
||||||
text += QString(" %1").arg(font.pointSize());
|
|
||||||
setText(text);
|
|
||||||
Q_EMIT changed();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
} // namespace Fm
|
|
||||||
@ -1,54 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (C) 2013 - 2015 Hong Jen Yee (PCMan) <pcman.tw@gmail.com>
|
|
||||||
*
|
|
||||||
* 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 FM_FONTBUTTON_H
|
|
||||||
#define FM_FONTBUTTON_H
|
|
||||||
|
|
||||||
#include "libfmqtglobals.h"
|
|
||||||
#include <QPushButton>
|
|
||||||
|
|
||||||
|
|
||||||
namespace Fm {
|
|
||||||
|
|
||||||
class LIBFM_QT_API FontButton : public QPushButton {
|
|
||||||
Q_OBJECT
|
|
||||||
public:
|
|
||||||
explicit FontButton(QWidget* parent = 0);
|
|
||||||
virtual ~FontButton();
|
|
||||||
|
|
||||||
QFont font() {
|
|
||||||
return font_;
|
|
||||||
}
|
|
||||||
|
|
||||||
void setFont(QFont font);
|
|
||||||
|
|
||||||
Q_SIGNALS:
|
|
||||||
void changed();
|
|
||||||
|
|
||||||
private Q_SLOTS:
|
|
||||||
void onClicked();
|
|
||||||
|
|
||||||
private:
|
|
||||||
QFont font_;
|
|
||||||
};
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif // FM_FONTBUTTON_H
|
|
||||||
@ -1,146 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (C) 2012 - 2015 Hong Jen Yee (PCMan) <pcman.tw@gmail.com>
|
|
||||||
*
|
|
||||||
* 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 "icontheme.h"
|
|
||||||
#include <libfm/fm.h>
|
|
||||||
#include <QList>
|
|
||||||
#include <QIcon>
|
|
||||||
#include <QtGlobal>
|
|
||||||
#include <QApplication>
|
|
||||||
#include <QDesktopWidget>
|
|
||||||
|
|
||||||
namespace Fm {
|
|
||||||
|
|
||||||
static IconTheme* theIconTheme = NULL; // the global single instance of IconTheme.
|
|
||||||
static const char* fallbackNames[] = {"unknown", "application-octet-stream", NULL};
|
|
||||||
|
|
||||||
static void fmIconDataDestroy(gpointer data) {
|
|
||||||
QIcon* picon = reinterpret_cast<QIcon*>(data);
|
|
||||||
delete picon;
|
|
||||||
}
|
|
||||||
|
|
||||||
IconTheme::IconTheme():
|
|
||||||
currentThemeName_(QIcon::themeName()) {
|
|
||||||
// NOTE: only one instance is allowed
|
|
||||||
Q_ASSERT(theIconTheme == NULL);
|
|
||||||
Q_ASSERT(qApp != NULL); // QApplication should exists before contructing IconTheme.
|
|
||||||
|
|
||||||
theIconTheme = this;
|
|
||||||
fm_icon_set_user_data_destroy(reinterpret_cast<GDestroyNotify>(fmIconDataDestroy));
|
|
||||||
fallbackIcon_ = iconFromNames(fallbackNames);
|
|
||||||
|
|
||||||
// We need to get notified when there is a QEvent::StyleChange event so
|
|
||||||
// we can check if the current icon theme name is changed.
|
|
||||||
// To do this, we can filter QApplication object itself to intercept
|
|
||||||
// signals of all widgets, but this may be too inefficient.
|
|
||||||
// So, we only filter the events on QDesktopWidget instead.
|
|
||||||
qApp->desktop()->installEventFilter(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
IconTheme::~IconTheme() {
|
|
||||||
}
|
|
||||||
|
|
||||||
IconTheme* IconTheme::instance() {
|
|
||||||
return theIconTheme;
|
|
||||||
}
|
|
||||||
|
|
||||||
// check if the icon theme name is changed and emit "changed()" signal if any change is detected.
|
|
||||||
void IconTheme::checkChanged() {
|
|
||||||
if(QIcon::themeName() != theIconTheme->currentThemeName_) {
|
|
||||||
// if the icon theme is changed
|
|
||||||
theIconTheme->currentThemeName_ = QIcon::themeName();
|
|
||||||
// invalidate the cached data
|
|
||||||
fm_icon_reset_user_data_cache(fm_qdata_id);
|
|
||||||
|
|
||||||
theIconTheme->fallbackIcon_ = iconFromNames(fallbackNames);
|
|
||||||
Q_EMIT theIconTheme->changed();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
QIcon IconTheme::iconFromNames(const char* const* names) {
|
|
||||||
const gchar* const* name;
|
|
||||||
// qDebug("names: %p", names);
|
|
||||||
for(name = names; *name; ++name) {
|
|
||||||
// qDebug("icon name=%s", *name);
|
|
||||||
QString qname = *name;
|
|
||||||
QIcon qicon = QIcon::fromTheme(qname);
|
|
||||||
if(!qicon.isNull()) {
|
|
||||||
return qicon;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return QIcon();
|
|
||||||
}
|
|
||||||
|
|
||||||
QIcon IconTheme::convertFromGIcon(GIcon* gicon) {
|
|
||||||
if(G_IS_THEMED_ICON(gicon)) {
|
|
||||||
const gchar * const * names = g_themed_icon_get_names(G_THEMED_ICON(gicon));
|
|
||||||
QIcon icon = iconFromNames(names);
|
|
||||||
if(!icon.isNull())
|
|
||||||
return icon;
|
|
||||||
}
|
|
||||||
else if(G_IS_FILE_ICON(gicon)) {
|
|
||||||
GFile* file = g_file_icon_get_file(G_FILE_ICON(gicon));
|
|
||||||
char* fpath = g_file_get_path(file);
|
|
||||||
QString path = fpath;
|
|
||||||
g_free(fpath);
|
|
||||||
return QIcon(path);
|
|
||||||
}
|
|
||||||
return theIconTheme->fallbackIcon_;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
//static
|
|
||||||
QIcon IconTheme::icon(FmIcon* fmicon) {
|
|
||||||
// check if we have a cached version
|
|
||||||
QIcon* picon = reinterpret_cast<QIcon*>(fm_icon_get_user_data(fmicon));
|
|
||||||
if(!picon) { // we don't have a cache yet
|
|
||||||
picon = new QIcon(); // what a waste!
|
|
||||||
*picon = convertFromGIcon(G_ICON(fmicon));
|
|
||||||
fm_icon_set_user_data(fmicon, picon); // store it in FmIcon
|
|
||||||
}
|
|
||||||
return *picon;
|
|
||||||
}
|
|
||||||
|
|
||||||
//static
|
|
||||||
QIcon IconTheme::icon(GIcon* gicon) {
|
|
||||||
if(G_IS_THEMED_ICON(gicon)) {
|
|
||||||
FmIcon* fmicon = fm_icon_from_gicon(gicon);
|
|
||||||
QIcon qicon = icon(fmicon);
|
|
||||||
fm_icon_unref(fmicon);
|
|
||||||
return qicon;
|
|
||||||
}
|
|
||||||
else if(G_IS_FILE_ICON(gicon)) {
|
|
||||||
// we do not map GFileIcon to FmIcon deliberately.
|
|
||||||
return convertFromGIcon(gicon);
|
|
||||||
}
|
|
||||||
return theIconTheme->fallbackIcon_;
|
|
||||||
}
|
|
||||||
|
|
||||||
// this method is called whenever there is an event on the QDesktopWidget object.
|
|
||||||
bool IconTheme::eventFilter(QObject* obj, QEvent* event) {
|
|
||||||
// we're only interested in the StyleChange event.
|
|
||||||
if(event->type() == QEvent::StyleChange) {
|
|
||||||
checkChanged(); // check if the icon theme is changed
|
|
||||||
}
|
|
||||||
return QObject::eventFilter(obj, event);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
} // namespace Fm
|
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user