Compare commits
No commits in common. "ubuntu/questing" and "debian/0.11.0-7" have entirely different histories.
ubuntu/que
...
debian/0.1
10
.gitignore
vendored
10
.gitignore
vendored
@ -1,8 +1,2 @@
|
|||||||
debian/*.debhelper
|
build
|
||||||
debian/*.log
|
*.kdev4
|
||||||
debian/*.substvars
|
|
||||||
debian/debhelper-build-stamp
|
|
||||||
debian/files
|
|
||||||
|
|
||||||
debian/pcmanfm-qt/
|
|
||||||
|
|
||||||
|
6
AUTHORS
Normal file
6
AUTHORS
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
Upstream Authors:
|
||||||
|
LXQt team: http://lxqt.org
|
||||||
|
Hong Jen Yee (PCMan) <pcman.tw@gmail.com>
|
||||||
|
|
||||||
|
Copyright:
|
||||||
|
Copyright (c) 2013-2016 LXQt team
|
102
CMakeLists.txt
Normal file
102
CMakeLists.txt
Normal file
@ -0,0 +1,102 @@
|
|||||||
|
cmake_minimum_required(VERSION 3.0.2)
|
||||||
|
project(pcmanfm-qt)
|
||||||
|
|
||||||
|
# CMP0063: Honor visibility properties for all target types.
|
||||||
|
if (POLICY CMP0063)
|
||||||
|
cmake_policy (SET CMP0063 NEW)
|
||||||
|
endif (POLICY CMP0063)
|
||||||
|
|
||||||
|
set(PCMANFM_QT_VERSION_MAJOR 0)
|
||||||
|
set(PCMANFM_QT_VERSION_MINOR 11)
|
||||||
|
set(PCMANFM_QT_VERSION_PATCH 0)
|
||||||
|
set(PCMANFM_QT_VERSION ${PCMANFM_QT_VERSION_MAJOR}.${PCMANFM_QT_VERSION_MINOR}.${PCMANFM_QT_VERSION_PATCH})
|
||||||
|
|
||||||
|
list(APPEND CMAKE_MODULE_PATH "${PROJECT_SOURCE_DIR}/cmake")
|
||||||
|
|
||||||
|
find_package(Qt5Widgets 5.2 REQUIRED)
|
||||||
|
find_package(Qt5DBus 5.2 REQUIRED)
|
||||||
|
find_package(Qt5LinguistTools 5.2 REQUIRED)
|
||||||
|
find_package(Qt5X11Extras 5.2 REQUIRED)
|
||||||
|
find_package(fm-qt REQUIRED)
|
||||||
|
|
||||||
|
find_package(PkgConfig REQUIRED)
|
||||||
|
pkg_check_modules(LIB_XCB REQUIRED xcb)
|
||||||
|
|
||||||
|
option(UPDATE_TRANSLATIONS "Update source translation translations/*.ts files" OFF)
|
||||||
|
include(GNUInstallDirs)
|
||||||
|
include(LXQtTranslateTs)
|
||||||
|
include(LXQtTranslateDesktop)
|
||||||
|
|
||||||
|
# set visibility to hidden to hide symbols, unless they're exported manually in the code
|
||||||
|
set(CMAKE_CXX_VISIBILITY_PRESET hidden)
|
||||||
|
set(CMAKE_VISIBILITY_INLINES_HIDDEN 1)
|
||||||
|
|
||||||
|
if (CMAKE_VERSION VERSION_LESS "3.1")
|
||||||
|
include(CheckCXXCompilerFlag)
|
||||||
|
CHECK_CXX_COMPILER_FLAG("-std=c++11" COMPILER_SUPPORTS_CXX11)
|
||||||
|
if(COMPILER_SUPPORTS_CXX11)
|
||||||
|
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
|
||||||
|
else()
|
||||||
|
CHECK_CXX_COMPILER_FLAG("-std=c++0x" COMPILER_SUPPORTS_CXX0X)
|
||||||
|
# -std=c++0x is deprecated but some tools e.g. qmake or older gcc are still using it
|
||||||
|
if(COMPILER_SUPPORTS_CXX0X)
|
||||||
|
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++0x")
|
||||||
|
else()
|
||||||
|
message(FATAL_ERROR "Compiler ${CMAKE_CXX_COMPILER} does not support c++11/c++0x")
|
||||||
|
endif()
|
||||||
|
endif()
|
||||||
|
else()
|
||||||
|
set(CMAKE_CXX_STANDARD 11)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
if (CMAKE_COMPILER_IS_GNUCXX OR CMAKE_CXX_COMPILER_ID STREQUAL "Clang")
|
||||||
|
# set visibility to hidden to hide symbols, unless they're exported manually in the code
|
||||||
|
set(CMAKE_CXX_FLAGS "-fno-exceptions ${CMAKE_CXX_FLAGS}")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
set(CMAKE_AUTOMOC TRUE)
|
||||||
|
set(CMAKE_INCLUDE_CURRENT_DIR ON)
|
||||||
|
|
||||||
|
add_subdirectory(pcmanfm)
|
||||||
|
|
||||||
|
# manpage for pcmanfm-qt
|
||||||
|
configure_file(
|
||||||
|
"${CMAKE_CURRENT_SOURCE_DIR}/pcmanfm-qt.1.in"
|
||||||
|
"${CMAKE_CURRENT_BINARY_DIR}/pcmanfm-qt.1"
|
||||||
|
@ONLY
|
||||||
|
)
|
||||||
|
install(FILES
|
||||||
|
"${CMAKE_CURRENT_BINARY_DIR}/pcmanfm-qt.1"
|
||||||
|
DESTINATION "${CMAKE_INSTALL_MANDIR}/man1"
|
||||||
|
)
|
||||||
|
|
||||||
|
# add Doxygen support to generate API docs
|
||||||
|
# References:
|
||||||
|
# http://majewsky.wordpress.com/2010/08/14/tip-of-the-day-cmake-and-doxygen/
|
||||||
|
# http://www.bluequartz.net/projects/EIM_Segmentation/SoftwareDocumentation/html/usewithcmakeproject.html
|
||||||
|
option(BUILD_DOCUMENTATION "Use Doxygen to create the HTML based API documentation" OFF)
|
||||||
|
if(BUILD_DOCUMENTATION)
|
||||||
|
find_package(Doxygen REQUIRED)
|
||||||
|
configure_file("${CMAKE_CURRENT_SOURCE_DIR}/Doxyfile.in" "${CMAKE_CURRENT_BINARY_DIR}/Doxyfile" @ONLY)
|
||||||
|
add_custom_target(doc ALL
|
||||||
|
${DOXYGEN_EXECUTABLE} "${CMAKE_CURRENT_BINARY_DIR}/Doxyfile"
|
||||||
|
WORKING_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}"
|
||||||
|
COMMENT "Generating API documentation with Doxygen" VERBATIM
|
||||||
|
)
|
||||||
|
install(DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/docs" DESTINATION "${CMAKE_INSTALL_DOCDIR}")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
# building tarball with CPack -------------------------------------------------
|
||||||
|
# To create a source distribution, type:
|
||||||
|
# make package_source
|
||||||
|
include(InstallRequiredSystemLibraries)
|
||||||
|
set(CPACK_RESOURCE_FILE_LICENSE "${CMAKE_CURRENT_SOURCE_DIR}/LICENSE")
|
||||||
|
set(CPACK_RESOURCE_FILE_README "${CMAKE_CURRENT_SOURCE_DIR}/README.md")
|
||||||
|
set(CPACK_PACKAGE_VENDOR "")
|
||||||
|
set(CPACK_PACKAGE_VERSION_MAJOR ${PCMANFM_QT_VERSION_MAJOR})
|
||||||
|
set(CPACK_PACKAGE_VERSION_MINOR ${PCMANFM_QT_VERSION_MINOR})
|
||||||
|
set(CPACK_PACKAGE_VERSION_PATCH ${PCMANFM_QT_VERSION_PATCH})
|
||||||
|
set(CPACK_GENERATOR TBZ2)
|
||||||
|
set(CPACK_SOURCE_GENERATOR TBZ2)
|
||||||
|
set(CPACK_SOURCE_IGNORE_FILES /build/;.gitignore;.*~;.git;.kdev4;temp)
|
||||||
|
include(CPack)
|
1890
Doxyfile.in
Normal file
1890
Doxyfile.in
Normal file
File diff suppressed because it is too large
Load Diff
280
LICENSE
Normal file
280
LICENSE
Normal file
@ -0,0 +1,280 @@
|
|||||||
|
GNU GENERAL PUBLIC LICENSE
|
||||||
|
Version 2, June 1991
|
||||||
|
|
||||||
|
Copyright (C) 1989, 1991 Free Software Foundation, Inc.,
|
||||||
|
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
|
Everyone is permitted to copy and distribute verbatim copies
|
||||||
|
of this license document, but changing it is not allowed.
|
||||||
|
|
||||||
|
Preamble
|
||||||
|
|
||||||
|
The licenses for most software are designed to take away your
|
||||||
|
freedom to share and change it. By contrast, the GNU General Public
|
||||||
|
License is intended to guarantee your freedom to share and change free
|
||||||
|
software--to make sure the software is free for all its users. This
|
||||||
|
General Public License applies to most of the Free Software
|
||||||
|
Foundation's software and to any other program whose authors commit to
|
||||||
|
using it. (Some other Free Software Foundation software is covered by
|
||||||
|
the GNU Lesser General Public License instead.) You can apply it to
|
||||||
|
your programs, too.
|
||||||
|
|
||||||
|
When we speak of free software, we are referring to freedom, not
|
||||||
|
price. Our General Public Licenses are designed to make sure that you
|
||||||
|
have the freedom to distribute copies of free software (and charge for
|
||||||
|
this service if you wish), that you receive source code or can get it
|
||||||
|
if you want it, that you can change the software or use pieces of it
|
||||||
|
in new free programs; and that you know you can do these things.
|
||||||
|
|
||||||
|
To protect your rights, we need to make restrictions that forbid
|
||||||
|
anyone to deny you these rights or to ask you to surrender the rights.
|
||||||
|
These restrictions translate to certain responsibilities for you if you
|
||||||
|
distribute copies of the software, or if you modify it.
|
||||||
|
|
||||||
|
For example, if you distribute copies of such a program, whether
|
||||||
|
gratis or for a fee, you must give the recipients all the rights that
|
||||||
|
you have. You must make sure that they, too, receive or can get the
|
||||||
|
source code. And you must show them these terms so they know their
|
||||||
|
rights.
|
||||||
|
|
||||||
|
We protect your rights with two steps: (1) copyright the software, and
|
||||||
|
(2) offer you this license which gives you legal permission to copy,
|
||||||
|
distribute and/or modify the software.
|
||||||
|
|
||||||
|
Also, for each author's protection and ours, we want to make certain
|
||||||
|
that everyone understands that there is no warranty for this free
|
||||||
|
software. If the software is modified by someone else and passed on, we
|
||||||
|
want its recipients to know that what they have is not the original, so
|
||||||
|
that any problems introduced by others will not reflect on the original
|
||||||
|
authors' reputations.
|
||||||
|
|
||||||
|
Finally, any free program is threatened constantly by software
|
||||||
|
patents. We wish to avoid the danger that redistributors of a free
|
||||||
|
program will individually obtain patent licenses, in effect making the
|
||||||
|
program proprietary. To prevent this, we have made it clear that any
|
||||||
|
patent must be licensed for everyone's free use or not licensed at all.
|
||||||
|
|
||||||
|
The precise terms and conditions for copying, distribution and
|
||||||
|
modification follow.
|
||||||
|
|
||||||
|
GNU GENERAL PUBLIC LICENSE
|
||||||
|
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
||||||
|
|
||||||
|
0. This License applies to any program or other work which contains
|
||||||
|
a notice placed by the copyright holder saying it may be distributed
|
||||||
|
under the terms of this General Public License. The "Program", below,
|
||||||
|
refers to any such program or work, and a "work based on the Program"
|
||||||
|
means either the Program or any derivative work under copyright law:
|
||||||
|
that is to say, a work containing the Program or a portion of it,
|
||||||
|
either verbatim or with modifications and/or translated into another
|
||||||
|
language. (Hereinafter, translation is included without limitation in
|
||||||
|
the term "modification".) Each licensee is addressed as "you".
|
||||||
|
|
||||||
|
Activities other than copying, distribution and modification are not
|
||||||
|
covered by this License; they are outside its scope. The act of
|
||||||
|
running the Program is not restricted, and the output from the Program
|
||||||
|
is covered only if its contents constitute a work based on the
|
||||||
|
Program (independent of having been made by running the Program).
|
||||||
|
Whether that is true depends on what the Program does.
|
||||||
|
|
||||||
|
1. You may copy and distribute verbatim copies of the Program's
|
||||||
|
source code as you receive it, in any medium, provided that you
|
||||||
|
conspicuously and appropriately publish on each copy an appropriate
|
||||||
|
copyright notice and disclaimer of warranty; keep intact all the
|
||||||
|
notices that refer to this License and to the absence of any warranty;
|
||||||
|
and give any other recipients of the Program a copy of this License
|
||||||
|
along with the Program.
|
||||||
|
|
||||||
|
You may charge a fee for the physical act of transferring a copy, and
|
||||||
|
you may at your option offer warranty protection in exchange for a fee.
|
||||||
|
|
||||||
|
2. You may modify your copy or copies of the Program or any portion
|
||||||
|
of it, thus forming a work based on the Program, and copy and
|
||||||
|
distribute such modifications or work under the terms of Section 1
|
||||||
|
above, provided that you also meet all of these conditions:
|
||||||
|
|
||||||
|
a) You must cause the modified files to carry prominent notices
|
||||||
|
stating that you changed the files and the date of any change.
|
||||||
|
|
||||||
|
b) You must cause any work that you distribute or publish, that in
|
||||||
|
whole or in part contains or is derived from the Program or any
|
||||||
|
part thereof, to be licensed as a whole at no charge to all third
|
||||||
|
parties under the terms of this License.
|
||||||
|
|
||||||
|
c) If the modified program normally reads commands interactively
|
||||||
|
when run, you must cause it, when started running for such
|
||||||
|
interactive use in the most ordinary way, to print or display an
|
||||||
|
announcement including an appropriate copyright notice and a
|
||||||
|
notice that there is no warranty (or else, saying that you provide
|
||||||
|
a warranty) and that users may redistribute the program under
|
||||||
|
these conditions, and telling the user how to view a copy of this
|
||||||
|
License. (Exception: if the Program itself is interactive but
|
||||||
|
does not normally print such an announcement, your work based on
|
||||||
|
the Program is not required to print an announcement.)
|
||||||
|
|
||||||
|
These requirements apply to the modified work as a whole. If
|
||||||
|
identifiable sections of that work are not derived from the Program,
|
||||||
|
and can be reasonably considered independent and separate works in
|
||||||
|
themselves, then this License, and its terms, do not apply to those
|
||||||
|
sections when you distribute them as separate works. But when you
|
||||||
|
distribute the same sections as part of a whole which is a work based
|
||||||
|
on the Program, the distribution of the whole must be on the terms of
|
||||||
|
this License, whose permissions for other licensees extend to the
|
||||||
|
entire whole, and thus to each and every part regardless of who wrote it.
|
||||||
|
|
||||||
|
Thus, it is not the intent of this section to claim rights or contest
|
||||||
|
your rights to work written entirely by you; rather, the intent is to
|
||||||
|
exercise the right to control the distribution of derivative or
|
||||||
|
collective works based on the Program.
|
||||||
|
|
||||||
|
In addition, mere aggregation of another work not based on the Program
|
||||||
|
with the Program (or with a work based on the Program) on a volume of
|
||||||
|
a storage or distribution medium does not bring the other work under
|
||||||
|
the scope of this License.
|
||||||
|
|
||||||
|
3. You may copy and distribute the Program (or a work based on it,
|
||||||
|
under Section 2) in object code or executable form under the terms of
|
||||||
|
Sections 1 and 2 above provided that you also do one of the following:
|
||||||
|
|
||||||
|
a) Accompany it with the complete corresponding machine-readable
|
||||||
|
source code, which must be distributed under the terms of Sections
|
||||||
|
1 and 2 above on a medium customarily used for software interchange; or,
|
||||||
|
|
||||||
|
b) Accompany it with a written offer, valid for at least three
|
||||||
|
years, to give any third party, for a charge no more than your
|
||||||
|
cost of physically performing source distribution, a complete
|
||||||
|
machine-readable copy of the corresponding source code, to be
|
||||||
|
distributed under the terms of Sections 1 and 2 above on a medium
|
||||||
|
customarily used for software interchange; or,
|
||||||
|
|
||||||
|
c) Accompany it with the information you received as to the offer
|
||||||
|
to distribute corresponding source code. (This alternative is
|
||||||
|
allowed only for noncommercial distribution and only if you
|
||||||
|
received the program in object code or executable form with such
|
||||||
|
an offer, in accord with Subsection b above.)
|
||||||
|
|
||||||
|
The source code for a work means the preferred form of the work for
|
||||||
|
making modifications to it. For an executable work, complete source
|
||||||
|
code means all the source code for all modules it contains, plus any
|
||||||
|
associated interface definition files, plus the scripts used to
|
||||||
|
control compilation and installation of the executable. However, as a
|
||||||
|
special exception, the source code distributed need not include
|
||||||
|
anything that is normally distributed (in either source or binary
|
||||||
|
form) with the major components (compiler, kernel, and so on) of the
|
||||||
|
operating system on which the executable runs, unless that component
|
||||||
|
itself accompanies the executable.
|
||||||
|
|
||||||
|
If distribution of executable or object code is made by offering
|
||||||
|
access to copy from a designated place, then offering equivalent
|
||||||
|
access to copy the source code from the same place counts as
|
||||||
|
distribution of the source code, even though third parties are not
|
||||||
|
compelled to copy the source along with the object code.
|
||||||
|
|
||||||
|
4. You may not copy, modify, sublicense, or distribute the Program
|
||||||
|
except as expressly provided under this License. Any attempt
|
||||||
|
otherwise to copy, modify, sublicense or distribute the Program is
|
||||||
|
void, and will automatically terminate your rights under this License.
|
||||||
|
However, parties who have received copies, or rights, from you under
|
||||||
|
this License will not have their licenses terminated so long as such
|
||||||
|
parties remain in full compliance.
|
||||||
|
|
||||||
|
5. You are not required to accept this License, since you have not
|
||||||
|
signed it. However, nothing else grants you permission to modify or
|
||||||
|
distribute the Program or its derivative works. These actions are
|
||||||
|
prohibited by law if you do not accept this License. Therefore, by
|
||||||
|
modifying or distributing the Program (or any work based on the
|
||||||
|
Program), you indicate your acceptance of this License to do so, and
|
||||||
|
all its terms and conditions for copying, distributing or modifying
|
||||||
|
the Program or works based on it.
|
||||||
|
|
||||||
|
6. Each time you redistribute the Program (or any work based on the
|
||||||
|
Program), the recipient automatically receives a license from the
|
||||||
|
original licensor to copy, distribute or modify the Program subject to
|
||||||
|
these terms and conditions. You may not impose any further
|
||||||
|
restrictions on the recipients' exercise of the rights granted herein.
|
||||||
|
You are not responsible for enforcing compliance by third parties to
|
||||||
|
this License.
|
||||||
|
|
||||||
|
7. If, as a consequence of a court judgment or allegation of patent
|
||||||
|
infringement or for any other reason (not limited to patent issues),
|
||||||
|
conditions are imposed on you (whether by court order, agreement or
|
||||||
|
otherwise) that contradict the conditions of this License, they do not
|
||||||
|
excuse you from the conditions of this License. If you cannot
|
||||||
|
distribute so as to satisfy simultaneously your obligations under this
|
||||||
|
License and any other pertinent obligations, then as a consequence you
|
||||||
|
may not distribute the Program at all. For example, if a patent
|
||||||
|
license would not permit royalty-free redistribution of the Program by
|
||||||
|
all those who receive copies directly or indirectly through you, then
|
||||||
|
the only way you could satisfy both it and this License would be to
|
||||||
|
refrain entirely from distribution of the Program.
|
||||||
|
|
||||||
|
If any portion of this section is held invalid or unenforceable under
|
||||||
|
any particular circumstance, the balance of the section is intended to
|
||||||
|
apply and the section as a whole is intended to apply in other
|
||||||
|
circumstances.
|
||||||
|
|
||||||
|
It is not the purpose of this section to induce you to infringe any
|
||||||
|
patents or other property right claims or to contest validity of any
|
||||||
|
such claims; this section has the sole purpose of protecting the
|
||||||
|
integrity of the free software distribution system, which is
|
||||||
|
implemented by public license practices. Many people have made
|
||||||
|
generous contributions to the wide range of software distributed
|
||||||
|
through that system in reliance on consistent application of that
|
||||||
|
system; it is up to the author/donor to decide if he or she is willing
|
||||||
|
to distribute software through any other system and a licensee cannot
|
||||||
|
impose that choice.
|
||||||
|
|
||||||
|
This section is intended to make thoroughly clear what is believed to
|
||||||
|
be a consequence of the rest of this License.
|
||||||
|
|
||||||
|
8. If the distribution and/or use of the Program is restricted in
|
||||||
|
certain countries either by patents or by copyrighted interfaces, the
|
||||||
|
original copyright holder who places the Program under this License
|
||||||
|
may add an explicit geographical distribution limitation excluding
|
||||||
|
those countries, so that distribution is permitted only in or among
|
||||||
|
countries not thus excluded. In such case, this License incorporates
|
||||||
|
the limitation as if written in the body of this License.
|
||||||
|
|
||||||
|
9. The Free Software Foundation may publish revised and/or new versions
|
||||||
|
of the General Public License from time to time. Such new versions will
|
||||||
|
be similar in spirit to the present version, but may differ in detail to
|
||||||
|
address new problems or concerns.
|
||||||
|
|
||||||
|
Each version is given a distinguishing version number. If the Program
|
||||||
|
specifies a version number of this License which applies to it and "any
|
||||||
|
later version", you have the option of following the terms and conditions
|
||||||
|
either of that version or of any later version published by the Free
|
||||||
|
Software Foundation. If the Program does not specify a version number of
|
||||||
|
this License, you may choose any version ever published by the Free Software
|
||||||
|
Foundation.
|
||||||
|
|
||||||
|
10. If you wish to incorporate parts of the Program into other free
|
||||||
|
programs whose distribution conditions are different, write to the author
|
||||||
|
to ask for permission. For software which is copyrighted by the Free
|
||||||
|
Software Foundation, write to the Free Software Foundation; we sometimes
|
||||||
|
make exceptions for this. Our decision will be guided by the two goals
|
||||||
|
of preserving the free status of all derivatives of our free software and
|
||||||
|
of promoting the sharing and reuse of software generally.
|
||||||
|
|
||||||
|
NO WARRANTY
|
||||||
|
|
||||||
|
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
|
||||||
|
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
|
||||||
|
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
|
||||||
|
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
|
||||||
|
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||||
|
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
|
||||||
|
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
|
||||||
|
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
|
||||||
|
REPAIR OR CORRECTION.
|
||||||
|
|
||||||
|
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
|
||||||
|
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
|
||||||
|
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
|
||||||
|
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
|
||||||
|
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
|
||||||
|
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
|
||||||
|
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
|
||||||
|
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
|
||||||
|
POSSIBILITY OF SUCH DAMAGES.
|
||||||
|
|
||||||
|
END OF TERMS AND CONDITIONS
|
20
README.md
Normal file
20
README.md
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
# PCManFM-Qt
|
||||||
|
|
||||||
|
The Qt port of the LXDE file manager PCManFM.
|
||||||
|
|
||||||
|
Issue tracker:
|
||||||
|
https://github.com/lxde/pcmanfm-qt/issues
|
||||||
|
|
||||||
|
LXQt website:
|
||||||
|
http://lxqt.org
|
||||||
|
|
||||||
|
LXDE website:
|
||||||
|
http://lxde.org
|
||||||
|
|
||||||
|
|
||||||
|
# License
|
||||||
|
|
||||||
|
PCManFM is licensed under the terms of the
|
||||||
|
[GPLv2](https://www.gnu.org/licenses/gpl-2.0.en.html) or any later version.
|
||||||
|
|
||||||
|
See the LICENSE file for the full text of the license.
|
107
cmake/LXQtTranslateDesktop.cmake
Normal file
107
cmake/LXQtTranslateDesktop.cmake
Normal file
@ -0,0 +1,107 @@
|
|||||||
|
#=============================================================================
|
||||||
|
# The lxqt_translate_desktop() function was copied from the the
|
||||||
|
# LXQt LxQtTranste.cmake
|
||||||
|
#
|
||||||
|
# Original Author: Alexander Sokolov <sokoloff.a@gmail.com>
|
||||||
|
#
|
||||||
|
# funtion lxqt_translate_desktop(_RESULT
|
||||||
|
# SOURCES <sources>
|
||||||
|
# [TRANSLATION_DIR] translation_directory
|
||||||
|
# )
|
||||||
|
# Output:
|
||||||
|
# _RESULT The generated .desktop (.desktop) files
|
||||||
|
#
|
||||||
|
# Input:
|
||||||
|
#
|
||||||
|
# SOURCES List of input desktop files (.destktop.in) to be translated
|
||||||
|
# (merged), relative to the CMakeList.txt.
|
||||||
|
#
|
||||||
|
# TRANSLATION_DIR Optional path to the directory with the .ts files,
|
||||||
|
# relative to the CMakeList.txt. Defaults to
|
||||||
|
# "translations".
|
||||||
|
#
|
||||||
|
#=============================================================================
|
||||||
|
|
||||||
|
function(lxqt_translate_desktop _RESULT)
|
||||||
|
# Parse arguments ***************************************
|
||||||
|
set(oneValueArgs TRANSLATION_DIR)
|
||||||
|
set(multiValueArgs SOURCES)
|
||||||
|
|
||||||
|
cmake_parse_arguments(_ARGS "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN})
|
||||||
|
|
||||||
|
# check for unknown arguments
|
||||||
|
set(_UNPARSED_ARGS ${_ARGS_UNPARSED_ARGUMENTS})
|
||||||
|
if (NOT ${_UNPARSED_ARGS} STREQUAL "")
|
||||||
|
MESSAGE(FATAL_ERROR
|
||||||
|
"Unknown arguments '${_UNPARSED_ARGS}'.\n"
|
||||||
|
"See lxqt_translate_desktop() documenation for more information.\n"
|
||||||
|
)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
if (NOT DEFINED _ARGS_SOURCES)
|
||||||
|
set(${_RESULT} "" PARENT_SCOPE)
|
||||||
|
return()
|
||||||
|
else()
|
||||||
|
set(_sources ${_ARGS_SOURCES})
|
||||||
|
endif()
|
||||||
|
|
||||||
|
if (NOT DEFINED _ARGS_TRANSLATION_DIR)
|
||||||
|
set(_translationDir "translations")
|
||||||
|
else()
|
||||||
|
set(_translationDir ${_ARGS_TRANSLATION_DIR})
|
||||||
|
endif()
|
||||||
|
|
||||||
|
|
||||||
|
get_filename_component (_translationDir ${_translationDir} ABSOLUTE)
|
||||||
|
|
||||||
|
foreach (_inFile ${_sources})
|
||||||
|
get_filename_component(_inFile ${_inFile} ABSOLUTE)
|
||||||
|
get_filename_component(_fileName ${_inFile} NAME_WE)
|
||||||
|
#Extract the real extension ............
|
||||||
|
get_filename_component(_fileExt ${_inFile} EXT)
|
||||||
|
string(REPLACE ".in" "" _fileExt ${_fileExt})
|
||||||
|
#.......................................
|
||||||
|
set(_outFile "${CMAKE_CURRENT_BINARY_DIR}/${_fileName}${_fileExt}")
|
||||||
|
|
||||||
|
file(GLOB _translations
|
||||||
|
${_translationDir}/${_fileName}_*${_fileExt}
|
||||||
|
${_translationDir}/local/${_fileName}_*${_fileExt}
|
||||||
|
)
|
||||||
|
|
||||||
|
set(_pattern "'\\[.*]\\s*='")
|
||||||
|
if (_translations)
|
||||||
|
add_custom_command(OUTPUT ${_outFile}
|
||||||
|
COMMAND grep -a -v "'#TRANSLATIONS_DIR='" ${_inFile} > ${_outFile}
|
||||||
|
COMMAND grep -a -h ${_pattern} ${_translations} >> ${_outFile}
|
||||||
|
COMMENT "Generating ${_fileName}${_fileExt}"
|
||||||
|
)
|
||||||
|
else()
|
||||||
|
add_custom_command(OUTPUT ${_outFile}
|
||||||
|
COMMAND grep -a -v "'#TRANSLATIONS_DIR='" ${_inFile} > ${_outFile}
|
||||||
|
COMMENT "Generating ${_fileName}${_fileExt}"
|
||||||
|
)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
set(__result ${__result} ${_outFile})
|
||||||
|
|
||||||
|
|
||||||
|
# TX file ***********************************************
|
||||||
|
set(_txFile "${CMAKE_BINARY_DIR}/tx/${_fileName}${_fileExt}.tx.sh")
|
||||||
|
string(REPLACE "${CMAKE_SOURCE_DIR}/" "" _tx_translationDir ${_translationDir})
|
||||||
|
string(REPLACE "${CMAKE_SOURCE_DIR}/" "" _tx_inFile ${_inFile})
|
||||||
|
string(REPLACE "." "" _fileType ${_fileExt})
|
||||||
|
|
||||||
|
file(WRITE ${_txFile}
|
||||||
|
"[ -f ${_inFile} ] || exit 0\n"
|
||||||
|
"echo '[lxde-qt.${_fileName}_${_fileType}]'\n"
|
||||||
|
"echo 'type = DESKTOP'\n"
|
||||||
|
"echo 'source_lang = en'\n"
|
||||||
|
"echo 'source_file = ${_tx_inFile}'\n"
|
||||||
|
"echo 'file_filter = ${_tx_translationDir}/${_fileName}_<lang>${_fileExt}'\n"
|
||||||
|
"echo ''\n"
|
||||||
|
)
|
||||||
|
|
||||||
|
endforeach()
|
||||||
|
|
||||||
|
set(${_RESULT} ${__result} PARENT_SCOPE)
|
||||||
|
endfunction(lxqt_translate_desktop)
|
131
cmake/LXQtTranslateTs.cmake
Normal file
131
cmake/LXQtTranslateTs.cmake
Normal file
@ -0,0 +1,131 @@
|
|||||||
|
#=============================================================================
|
||||||
|
# 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()
|
112
cmake/Qt5PatchedLinguistToolsMacros.cmake
Normal file
112
cmake/Qt5PatchedLinguistToolsMacros.cmake
Normal file
@ -0,0 +1,112 @@
|
|||||||
|
#=============================================================================
|
||||||
|
# Copyright 2005-2011 Kitware, Inc.
|
||||||
|
# All rights reserved.
|
||||||
|
#
|
||||||
|
# Redistribution and use in source and binary forms, with or without
|
||||||
|
# modification, are permitted provided that the following conditions
|
||||||
|
# are met:
|
||||||
|
#
|
||||||
|
# * Redistributions of source code must retain the above copyright
|
||||||
|
# notice, this list of conditions and the following disclaimer.
|
||||||
|
#
|
||||||
|
# * Redistributions in binary form must reproduce the above copyright
|
||||||
|
# notice, this list of conditions and the following disclaimer in the
|
||||||
|
# documentation and/or other materials provided with the distribution.
|
||||||
|
#
|
||||||
|
# * Neither the name of Kitware, Inc. nor the names of its
|
||||||
|
# contributors may be used to endorse or promote products derived
|
||||||
|
# from this software without specific prior written permission.
|
||||||
|
#
|
||||||
|
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
# HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
#=============================================================================
|
||||||
|
|
||||||
|
include(CMakeParseArguments)
|
||||||
|
|
||||||
|
function(QT5_PATCHED_CREATE_TRANSLATION _qm_files)
|
||||||
|
set(options)
|
||||||
|
set(oneValueArgs)
|
||||||
|
set(multiValueArgs OPTIONS)
|
||||||
|
|
||||||
|
cmake_parse_arguments(_LUPDATE "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN})
|
||||||
|
set(_lupdate_files ${_LUPDATE_UNPARSED_ARGUMENTS})
|
||||||
|
set(_lupdate_options ${_LUPDATE_OPTIONS})
|
||||||
|
|
||||||
|
set(_my_sources)
|
||||||
|
set(_my_tsfiles)
|
||||||
|
foreach(_file ${_lupdate_files})
|
||||||
|
get_filename_component(_ext ${_file} EXT)
|
||||||
|
get_filename_component(_abs_FILE ${_file} ABSOLUTE)
|
||||||
|
if(_ext MATCHES "ts")
|
||||||
|
list(APPEND _my_tsfiles ${_abs_FILE})
|
||||||
|
else()
|
||||||
|
list(APPEND _my_sources ${_abs_FILE})
|
||||||
|
endif()
|
||||||
|
endforeach()
|
||||||
|
foreach(_ts_file ${_my_tsfiles})
|
||||||
|
if(_my_sources)
|
||||||
|
# make a list file to call lupdate on, so we don't make our commands too
|
||||||
|
# long for some systems
|
||||||
|
# get_filename_component(_ts_name ${_ts_file} NAME_WE)
|
||||||
|
|
||||||
|
get_filename_component(_name ${_ts_file} NAME)
|
||||||
|
string(REGEX REPLACE "^(.+)(\\.[^.]+)$" "\\1" _ts_name ${_name})
|
||||||
|
|
||||||
|
set(_ts_lst_file "${CMAKE_CURRENT_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/${_ts_name}_lst_file")
|
||||||
|
set(_lst_file_srcs)
|
||||||
|
foreach(_lst_file_src ${_my_sources})
|
||||||
|
set(_lst_file_srcs "${_lst_file_src}\n${_lst_file_srcs}")
|
||||||
|
endforeach()
|
||||||
|
|
||||||
|
get_directory_property(_inc_DIRS INCLUDE_DIRECTORIES)
|
||||||
|
foreach(_pro_include ${_inc_DIRS})
|
||||||
|
get_filename_component(_abs_include "${_pro_include}" ABSOLUTE)
|
||||||
|
set(_lst_file_srcs "-I${_pro_include}\n${_lst_file_srcs}")
|
||||||
|
endforeach()
|
||||||
|
|
||||||
|
file(WRITE ${_ts_lst_file} "${_lst_file_srcs}")
|
||||||
|
endif()
|
||||||
|
add_custom_command(OUTPUT ${_ts_file}
|
||||||
|
COMMAND ${Qt5_LUPDATE_EXECUTABLE}
|
||||||
|
ARGS ${_lupdate_options} "@${_ts_lst_file}" -ts ${_ts_file}
|
||||||
|
DEPENDS ${_my_sources} ${_ts_lst_file} VERBATIM)
|
||||||
|
endforeach()
|
||||||
|
qt5_patched_add_translation(${_qm_files} ${_my_tsfiles})
|
||||||
|
set(${_qm_files} ${${_qm_files}} PARENT_SCOPE)
|
||||||
|
endfunction()
|
||||||
|
|
||||||
|
|
||||||
|
function(QT5_PATCHED_ADD_TRANSLATION _qm_files)
|
||||||
|
foreach(_current_FILE ${ARGN})
|
||||||
|
get_filename_component(_abs_FILE ${_current_FILE} ABSOLUTE)
|
||||||
|
# get_filename_component(qm ${_abs_FILE} NAME_WE)
|
||||||
|
|
||||||
|
get_filename_component(_name ${_abs_FILE} NAME)
|
||||||
|
string(REGEX REPLACE "^(.+)(\\.[^.]+)$" "\\1" qm ${_name})
|
||||||
|
|
||||||
|
get_source_file_property(output_location ${_abs_FILE} OUTPUT_LOCATION)
|
||||||
|
if(output_location)
|
||||||
|
file(MAKE_DIRECTORY "${output_location}")
|
||||||
|
set(qm "${output_location}/${qm}.qm")
|
||||||
|
else()
|
||||||
|
set(qm "${CMAKE_CURRENT_BINARY_DIR}/${qm}.qm")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
add_custom_command(OUTPUT ${qm}
|
||||||
|
COMMAND ${Qt5_LRELEASE_EXECUTABLE}
|
||||||
|
ARGS ${_abs_FILE} -qm ${qm}
|
||||||
|
DEPENDS ${_abs_FILE} VERBATIM
|
||||||
|
)
|
||||||
|
list(APPEND ${_qm_files} ${qm})
|
||||||
|
endforeach()
|
||||||
|
set(${_qm_files} ${${_qm_files}} PARENT_SCOPE)
|
||||||
|
endfunction()
|
12
debian/.gitignore
vendored
Normal file
12
debian/.gitignore
vendored
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
/*.debhelper
|
||||||
|
/*.log
|
||||||
|
/*.substvars
|
||||||
|
/files
|
||||||
|
/mangled
|
||||||
|
|
||||||
|
/pcmanfm-qt/
|
||||||
|
/pcmanfm-qt-dbg/
|
||||||
|
/libfm-qt5-2/
|
||||||
|
/libfm-qt5-dev/
|
||||||
|
/libfm-qt5-dbg/
|
||||||
|
/tmp
|
363
debian/changelog
vendored
363
debian/changelog
vendored
@ -1,207 +1,188 @@
|
|||||||
pavucontrol-qt (2.2.0-0ubuntu1) questing; urgency=medium
|
pcmanfm-qt (0.11.0-7) unstable; urgency=medium
|
||||||
|
|
||||||
|
* Fixed VCS fields, use plain /git/
|
||||||
|
* Reworked icon-theme recommends (Closes: #833590)
|
||||||
|
Thanks Pino Toscano <pino@debian.org>
|
||||||
|
|
||||||
|
-- Alf Gaida <agaida@siduction.org> Sun, 07 Aug 2016 11:14:08 +0200
|
||||||
|
|
||||||
|
pcmanfm-qt (0.11.0-6) unstable; urgency=medium
|
||||||
|
|
||||||
|
* Set LC_ALL for reproducible builds.
|
||||||
|
|
||||||
|
-- ChangZhuo Chen (陳昌倬) <czchen@debian.org> Sat, 16 Jul 2016 11:16:41 +0800
|
||||||
|
|
||||||
|
pcmanfm-qt (0.11.0-5) unstable; urgency=medium
|
||||||
|
|
||||||
|
* Backported temporary upstream fix for #826311
|
||||||
|
(https://github.com/lxde/pcmanfm-qt/pull/359)
|
||||||
|
* Bumped standards version to 3.9.8 - no changes needed
|
||||||
|
|
||||||
|
-- Alf Gaida <agaida@siduction.org> Sat, 04 Jun 2016 19:39:22 +0200
|
||||||
|
|
||||||
|
pcmanfm-qt (0.11.0-4) unstable; urgency=medium
|
||||||
|
|
||||||
|
* Added oxygen-icon-theme | oxygen5-icon-theme | gnome-icon-theme
|
||||||
|
to recommends. (Closes: #826311)
|
||||||
|
|
||||||
|
-- Alf Gaida <agaida@siduction.org> Sat, 04 Jun 2016 15:54:21 +0200
|
||||||
|
|
||||||
|
pcmanfm-qt (0.11.0-3) unstable; urgency=low
|
||||||
|
|
||||||
|
* Adding "Depends: dbus-x11". Closes: #820079
|
||||||
|
|
||||||
|
-- Yuan CHAO <yuanchao@gmail.com> Tue, 19 Apr 2016 20:30:00 +0800
|
||||||
|
|
||||||
|
pcmanfm-qt (0.11.0-2) unstable; urgency=medium
|
||||||
|
|
||||||
|
* Merge experimental to unstable
|
||||||
|
|
||||||
|
-- Alf Gaida <agaida@siduction.org> Thu, 31 Mar 2016 22:07:11 +0200
|
||||||
|
|
||||||
|
pcmanfm-qt (0.11.0-1) experimental; urgency=medium
|
||||||
|
|
||||||
|
* New upstream release
|
||||||
|
* Removed grep patch
|
||||||
|
* Bump libfm-qt-dev (>= 0.11.0)
|
||||||
|
|
||||||
|
-- Alf Gaida <agaida@siduction.org> Mon, 28 Mar 2016 18:12:27 +0200
|
||||||
|
|
||||||
|
pcmanfm-qt (0.10.1-2) unstable; urgency=medium
|
||||||
|
|
||||||
|
* Bump Standards to 3.9.7
|
||||||
|
* Fix years in copyright
|
||||||
|
* Add hardending=+all
|
||||||
|
* simplify rules
|
||||||
|
* make pcmanfm-qt reproducible again, thanks to Eduard Sanou for the
|
||||||
|
bugreport and the patch, but it was fixed before (Closes: #815818)
|
||||||
|
|
||||||
|
-- Alf Gaida <agaida@siduction.org> Fri, 26 Feb 2016 00:16:22 +0100
|
||||||
|
|
||||||
|
pcmanfm-qt (0.10.1-1) unstable; urgency=medium
|
||||||
|
|
||||||
* New upstream release.
|
* New upstream release.
|
||||||
- Update build dependencies.
|
* Remove libfm-qt as upstream moved it into another source repository.
|
||||||
* Update copyright file.
|
* Remove dbg package in favor of dbgsym.
|
||||||
* Update Standards-Version to 4.7.2, no changes needed.
|
* Update Vcs-Browser.
|
||||||
|
|
||||||
-- Aaron Rainbolt <arraybolt3@ubuntu.com> Fri, 01 Aug 2025 11:23:16 -0500
|
-- ChangZhuo Chen (陳昌倬) <czchen@debian.org> Sun, 07 Feb 2016 16:13:27 +0800
|
||||||
|
|
||||||
pavucontrol-qt (2.1.0-0ubuntu3) plucky; urgency=medium
|
pcmanfm-qt (0.10.0-2) unstable; urgency=medium
|
||||||
|
|
||||||
* Update Standards-Version to 4.7.1, no changes needed.
|
|
||||||
|
|
||||||
-- Simon Quigley <tsimonq2@ubuntu.com> Fri, 21 Feb 2025 16:58:59 -0600
|
|
||||||
|
|
||||||
pavucontrol-qt (2.1.0-0ubuntu2) plucky; urgency=medium
|
|
||||||
|
|
||||||
* No-change rebuild for lxqt-build-tools C++17 -> C++20.
|
|
||||||
|
|
||||||
-- Simon Quigley <tsimonq2@ubuntu.com> Fri, 03 Jan 2025 04:00:32 -0600
|
|
||||||
|
|
||||||
pavucontrol-qt (2.1.0-0ubuntu1) plucky; urgency=medium
|
|
||||||
|
|
||||||
|
* Merge from experimental.
|
||||||
* New upstream release.
|
* New upstream release.
|
||||||
- Bump build dependencies.
|
* Update minimum version of liblxqt.
|
||||||
|
* Update symbols.
|
||||||
|
* Remove menu file, see CTTE #741573.
|
||||||
|
|
||||||
-- Simon Quigley <tsimonq2@ubuntu.com> Fri, 15 Nov 2024 15:33:29 -0600
|
-- ChangZhuo Chen (陳昌倬) <czchen@debian.org> Sun, 15 Nov 2015 21:14:41 +0800
|
||||||
|
|
||||||
pavucontrol-qt (2.0.0-0ubuntu1) oracular; urgency=medium
|
pcmanfm-qt (0.9.0+20150908-2) unstable; urgency=medium
|
||||||
|
|
||||||
* New upstream release.
|
* Menufile deleted
|
||||||
* Updated copyright file.
|
* debian/rules --fail-missing included --list-missig, so
|
||||||
* Bump Standards-Version to 4.7.0, no changes necessary.
|
--list-missing deleted
|
||||||
* Adjust dependencies.
|
|
||||||
|
|
||||||
-- Aaron Rainbolt <arraybolt3@ubuntu.com> Thu, 27 Jun 2024 23:12:01 -0500
|
-- Alf Gaida <agaida@siduction.org> Fri, 13 Nov 2015 02:37:53 +0100
|
||||||
|
|
||||||
pavucontrol-qt (1.4.0-0ubuntu1) noble; urgency=medium
|
pcmanfm-qt (0.9.0+20150908-1) unstable; urgency=medium
|
||||||
|
|
||||||
* New upstream release.
|
|
||||||
* Overhauled copyright file.
|
|
||||||
|
|
||||||
-- Aaron Rainbolt <arraybolt3@gmail.com> Sun, 12 Nov 2023 12:20:37 -0600
|
|
||||||
|
|
||||||
pavucontrol-qt (1.3.0-0ubuntu1) mantic; urgency=medium
|
|
||||||
|
|
||||||
* New upstream release.
|
|
||||||
* Bump build dependencies.
|
|
||||||
|
|
||||||
-- Simon Quigley <tsimonq2@ubuntu.com> Thu, 03 Aug 2023 10:43:30 -0500
|
|
||||||
|
|
||||||
pavucontrol-qt (1.2.0-1ubuntu3) lunar; urgency=medium
|
|
||||||
|
|
||||||
* Swap "pulseaudio | pipewire-pulse" to "pipewire-pulse | pulseaudio" in
|
|
||||||
debian/control to convince Germinate to grab the right package when the
|
|
||||||
Lubuntu ISO builds.
|
|
||||||
|
|
||||||
-- Aaron Rainbolt <arraybolt3@ubuntu.com> Sun, 02 Apr 2023 15:10:28 -0500
|
|
||||||
|
|
||||||
pavucontrol-qt (1.2.0-1ubuntu2) lunar; urgency=medium
|
|
||||||
|
|
||||||
[ Debian Janitor ]
|
|
||||||
* Set upstream metadata fields: Repository-Browse.
|
|
||||||
|
|
||||||
[ Aaron Rainbolt ]
|
|
||||||
* Revert a sync from Debian.
|
|
||||||
* Bumped Standards-Version to 4.6.2, no changes necessary.
|
|
||||||
* Updated copyright file.
|
|
||||||
|
|
||||||
-- Aaron Rainbolt <arraybolt3@ubuntu.com> Sun, 12 Feb 2023 17:33:26 -0600
|
|
||||||
|
|
||||||
pavucontrol-qt (1.2.0-0ubuntu1) lunar; urgency=medium
|
|
||||||
|
|
||||||
* New upstream release.
|
|
||||||
* Fix the watch file, for real this time.
|
|
||||||
* Lubuntuify the package slightly, to make debhelper happy.
|
|
||||||
* Bump build dependencies in debian/control.
|
|
||||||
|
|
||||||
-- Simon Quigley <tsimonq2@ubuntu.com> Thu, 17 Nov 2022 16:43:15 -0600
|
|
||||||
|
|
||||||
pavucontrol-qt (1.1.0-1) experimental; urgency=medium
|
|
||||||
|
|
||||||
* New upstream release 1.1.0.
|
|
||||||
* Removed obsolete debian/compat file.
|
|
||||||
* Switched to GBP.
|
|
||||||
* Upstreamed non-Ubuntu-specific packaging changes from Ubuntu, modifying
|
|
||||||
the following files:
|
|
||||||
- control
|
|
||||||
- copyright
|
|
||||||
- lintian-overrides
|
|
||||||
- *.install
|
|
||||||
- rules
|
|
||||||
- upstream/*
|
|
||||||
|
|
||||||
-- Aaron Rainbolt <arraybolt3@gmail.com> Sun, 10 Jul 2022 04:35:38 -0500
|
|
||||||
|
|
||||||
pavucontrol-qt (0.16.0-2) unstable; urgency=medium
|
|
||||||
|
|
||||||
* Depend on either pulseaudio or pipewire-pulse (Closes: #995690)
|
|
||||||
|
|
||||||
-- Arto Jantunen <viiru@debian.org> Wed, 03 Nov 2021 12:41:14 +0200
|
|
||||||
|
|
||||||
pavucontrol-qt (0.16.0-1) unstable; urgency=medium
|
|
||||||
|
|
||||||
[ Alf Gaida ]
|
[ Alf Gaida ]
|
||||||
* Switched to gbp
|
* Cherry-picked upstream version 0.9.0+20150908.
|
||||||
* Bumped Standards-Version to 4.4.0, no changes needed
|
* Tar-ignore .gitignore
|
||||||
|
* Fixed control with cme fix
|
||||||
|
* Added upstream signing-key and use it in watch file
|
||||||
|
* Removed automoc build dependency - not needed with Qt5
|
||||||
|
* Fixed symbols for i386 and amd64
|
||||||
|
|
||||||
|
[ ChangZhuo Chen (陳昌倬) ]
|
||||||
|
* Use arch-bits to fix 32 bit architecture symbols.
|
||||||
|
* Add Shih-Yuan Lee (FourDollars) as Uploaders.
|
||||||
|
|
||||||
|
-- ChangZhuo Chen (陳昌倬) <czchen@debian.org> Tue, 15 Sep 2015 23:30:13 +0800
|
||||||
|
|
||||||
|
pcmanfm-qt (0.9.0+20150816-1) unstable; urgency=medium
|
||||||
|
|
||||||
|
[ ChangZhuo Chen (陳昌倬) ]
|
||||||
|
* Import debian directory from Wen.Liao.
|
||||||
|
* Initial release (Closes: #747605)
|
||||||
|
* Merge debian directory.
|
||||||
|
* Backup *.ts.
|
||||||
|
* Fix package-contains-empty-directory.
|
||||||
|
* Don't use variable for command.
|
||||||
|
* Add libfm-qt1 and libfm-qt-dev.
|
||||||
|
* Update copyright.
|
||||||
|
* Add Pre-Depends: ${misc:Pre-Depends} to libfm-qt1.
|
||||||
|
* Create manpage for pcmanfm-qt.
|
||||||
|
* add libfm-qt1.symbols.
|
||||||
|
* Revert "Create manpage for pcmanfm-qt".
|
||||||
|
* Add pcmanfm-qt.manpages.
|
||||||
|
* Fix manpage.
|
||||||
|
* Install include to libfm-qt-dev.
|
||||||
|
* Update package description.
|
||||||
|
* Use patch to install manpage.
|
||||||
|
* Migrate to QT5.
|
||||||
|
* Update d/copyright.
|
||||||
|
* Fix copyright typo.
|
||||||
|
* Revert accidiently ts changed.
|
||||||
|
|
||||||
|
[ Alf Gaida ]
|
||||||
|
* gitignore added.
|
||||||
|
* new upstream translation files.
|
||||||
|
* some cleanup in debian rules.
|
||||||
|
* two missed symbols added.
|
||||||
|
* they need a little bit of beautyfing.
|
||||||
|
* we should not save translations in debian/bak. if there is a real
|
||||||
|
problem with the translations this should be fixed upstream.
|
||||||
|
* add two symbols @czchen - would you be so kind and clean them up.
|
||||||
|
* catch up with upstream Patch descriptions changed.
|
||||||
|
* Imported Upstream version 0.8.0
|
||||||
|
* Min Qt version 5.3.2.
|
||||||
|
* bump standards to 3.9.6.
|
||||||
|
* removed all patches, integrated in upstream.
|
||||||
|
* fix symbols (two symbols added).
|
||||||
|
* fix prefs desktop file.
|
||||||
|
* fix arch for dbg packages.
|
||||||
|
* Imported Upstream version 0.8.0.
|
||||||
|
* Min Qt version 5.3.2.
|
||||||
|
* bump standards to 3.9.6.
|
||||||
|
* removed all patches, integrated in upstream.
|
||||||
|
* fix symbols (two symbols added).
|
||||||
|
* fix prefs desktop file.
|
||||||
|
* fix arch for dbg packages.
|
||||||
|
* patch added released.
|
||||||
|
* fixing arch dependent symbols.
|
||||||
|
* recommend gfvs-backends.
|
||||||
|
* Some cleanup in debian $foo.
|
||||||
|
* some changes in debian $foo.
|
||||||
|
* drop transitional packages.
|
||||||
|
|
||||||
|
[ ChangZhuo Chen (陳昌倬) ]
|
||||||
|
* Unapply Debian patch.
|
||||||
|
* Add debian/source/local-options.
|
||||||
|
* Backup / Restore translations.
|
||||||
|
* Fix override_dh_clean.
|
||||||
|
* Use override_dh_auto_clean to restore translations.
|
||||||
|
* Update symbol control file.
|
||||||
|
* Quote in symbol control file.
|
||||||
|
* Restore upstream file.
|
||||||
|
* Imported Upstream version 0.9.0+20150816.
|
||||||
|
* Add (c++) to symbol control file.
|
||||||
|
* Update changelog.
|
||||||
|
* Update symbol control file.
|
||||||
|
* Fix symbol control file.
|
||||||
|
* Fix Architecture.
|
||||||
|
* Add Multi-Arch: same.
|
||||||
|
|
||||||
|
[ Shih-Yuan Lee (FourDollars) ]
|
||||||
|
* Polish debian/control by 'cme fix dpkg-control'.
|
||||||
|
* Update package description.
|
||||||
|
|
||||||
[ Andrew Lee (李健秋) ]
|
[ Andrew Lee (李健秋) ]
|
||||||
* New upstream release. (Closes: #978181)
|
* Added myself as Uploader.
|
||||||
|
* Removing whitespaces at EOL and EOF.
|
||||||
|
* Refine descriptions.
|
||||||
|
* Don't need to backup/restore translation files, this fixed upstream.
|
||||||
|
* Warpped lines in copyright.
|
||||||
|
|
||||||
-- Andrew Lee (李健秋) <ajqlee@debian.org> Thu, 07 Jan 2021 16:48:22 +0800
|
-- Andrew Lee (李健秋) <ajqlee@debian.org> Mon, 17 Aug 2015 21:04:54 +0800
|
||||||
|
|
||||||
pavucontrol-qt (0.14.1-1) unstable; urgency=medium
|
|
||||||
|
|
||||||
* Cherry-picked upstream release 0.14.1.
|
|
||||||
|
|
||||||
-- Alf Gaida <agaida@siduction.org> Tue, 26 Feb 2019 00:51:28 +0100
|
|
||||||
|
|
||||||
pavucontrol-qt (0.14.0-1) unstable; urgency=medium
|
|
||||||
|
|
||||||
* Cherry-picked upstream release 0.14.0.
|
|
||||||
* Bumped Standards to 4.3.0, no changes needed
|
|
||||||
* Dropped d/compat, use debhelper-compat = 12, no changes needed
|
|
||||||
* Fixed years in d/copyright
|
|
||||||
* Bumped minimum version lxqt-build-tools (>= 0.6.0~)
|
|
||||||
* Removed obsolete PULL_TRANSLATIONS= OFF from dh_auto_configure
|
|
||||||
* Added l10n-package, moved from lxqt-l10n
|
|
||||||
* Added d/upstream/metadata
|
|
||||||
|
|
||||||
-- Alf Gaida <agaida@siduction.org> Sun, 27 Jan 2019 15:25:30 +0100
|
|
||||||
|
|
||||||
pavucontrol-qt (0.4.0-1) unstable; urgency=medium
|
|
||||||
|
|
||||||
* Cherry-picked upstream release 0.4.0
|
|
||||||
* Bump lxqt-build-tools to >= 0.5.0~
|
|
||||||
* Fixed watch file lxde -> lxqt
|
|
||||||
* Moved .gitignore from debian to ./
|
|
||||||
* Cleaned up debian/source/options
|
|
||||||
|
|
||||||
-- Alf Gaida <agaida@siduction.org> Wed, 23 May 2018 20:29:30 +0200
|
|
||||||
|
|
||||||
pavucontrol-qt (0.3.0-4) unstable; urgency=medium
|
|
||||||
|
|
||||||
* Bumped compat to 11
|
|
||||||
* Bumped debhelper to >= 11~
|
|
||||||
* Bumped Standards to 4.1.4, no changes needed
|
|
||||||
* Changed VCS fields for salsa
|
|
||||||
* Changed Homepage, Source and watch to lxqt
|
|
||||||
* Bumped years in copyright
|
|
||||||
* Removed trailing whitespaces in changelog
|
|
||||||
|
|
||||||
-- Alf Gaida <agaida@siduction.org> Sat, 28 Apr 2018 18:21:55 +0200
|
|
||||||
|
|
||||||
pavucontrol-qt (0.3.0-3) unstable; urgency=medium
|
|
||||||
|
|
||||||
* Bumped Standards to 4.1.2, no changes needed
|
|
||||||
* Removed branch from VCS fields
|
|
||||||
* Removed debian/gbp.conf
|
|
||||||
|
|
||||||
-- Alf Gaida <agaida@siduction.org> Thu, 14 Dec 2017 23:51:12 +0100
|
|
||||||
|
|
||||||
pavucontrol-qt (0.3.0-2) unstable; urgency=medium
|
|
||||||
|
|
||||||
* Transition to unstable
|
|
||||||
|
|
||||||
-- Alf Gaida <agaida@siduction.org> Mon, 04 Dec 2017 20:00:17 +0100
|
|
||||||
|
|
||||||
pavucontrol-qt (0.3.0-1) experimental; urgency=medium
|
|
||||||
|
|
||||||
* Cherry-picking new upstream release 0.3.0.
|
|
||||||
* Switched to experimental
|
|
||||||
* Bumped Standards to 0.4.0, no changes needed
|
|
||||||
* Bumped minimum version lxqt-build-tools (>= 0.4.0)
|
|
||||||
* Bumped years in copyright
|
|
||||||
|
|
||||||
-- Alf Gaida <agaida@siduction.org> Sun, 24 Sep 2017 15:19:13 +0200
|
|
||||||
|
|
||||||
pavucontrol-qt (0.2.0-1) unstable; urgency=medium
|
|
||||||
|
|
||||||
* Cherry-picking upstream release 0.2.0.
|
|
||||||
* Removed some no longer needed build dependencies:
|
|
||||||
- cmake
|
|
||||||
- liblxqt0-dev
|
|
||||||
- libqt5xdg-dev
|
|
||||||
- libqt5xdgiconloader-dev
|
|
||||||
- pkg-config
|
|
||||||
- qttools5-dev
|
|
||||||
- qttools5-dev-tools
|
|
||||||
* Added build dependency lxqt-build-tools (>= 0.3.0)
|
|
||||||
* Added dependency pulseaudio (Closes: #847373)
|
|
||||||
* Fixed Recommends: obconf-qt-l10n -> pavucontrol-qt-l10n
|
|
||||||
|
|
||||||
-- Alf Gaida <agaida@siduction.org> Mon, 12 Dec 2016 18:56:14 +0100
|
|
||||||
|
|
||||||
pavucontrol-qt (0.1.0-2) unstable; urgency=medium
|
|
||||||
|
|
||||||
* Moved to unstable
|
|
||||||
* Fixed signing-key, thanks Rohan Garg <rohan@kde.org>
|
|
||||||
|
|
||||||
-- Alf Gaida <agaida@siduction.org> Tue, 18 Oct 2016 20:34:41 +0200
|
|
||||||
|
|
||||||
pavucontrol-qt (0.1.0-1) experimental; urgency=medium
|
|
||||||
|
|
||||||
* Initial release (Closes: #838724)
|
|
||||||
|
|
||||||
-- Alf Gaida <agaida@siduction.org> Sat, 24 Sep 2016 16:18:14 +0200
|
|
||||||
|
1
debian/compat
vendored
Normal file
1
debian/compat
vendored
Normal file
@ -0,0 +1 @@
|
|||||||
|
9
|
81
debian/control
vendored
81
debian/control
vendored
@ -1,52 +1,41 @@
|
|||||||
Source: pavucontrol-qt
|
Source: pcmanfm-qt
|
||||||
Maintainer: Lubuntu Developers <lubuntu-devel@lists.ubuntu.com>
|
Maintainer: LXQt Packaging Team <pkg-lxqt-devel@lists.alioth.debian.org>
|
||||||
Original-Maintainer: LXQt Packaging Team <pkg-lxqt-devel@lists.alioth.debian.org>
|
|
||||||
Uploaders: Alf Gaida <agaida@siduction.org>,
|
Uploaders: Alf Gaida <agaida@siduction.org>,
|
||||||
Andrew Lee (李健秋) <ajqlee@debian.org>,
|
|
||||||
ChangZhuo Chen (陳昌倬) <czchen@debian.org>,
|
ChangZhuo Chen (陳昌倬) <czchen@debian.org>,
|
||||||
Simon Quigley <tsimonq2@debian.org>,
|
Andrew Lee (李健秋) <ajqlee@debian.org>,
|
||||||
Aaron Rainbolt <arraybolt3@gmail.com>
|
Shih-Yuan Lee (FourDollars) <fourdollars@gmail.com>,
|
||||||
Section: utils
|
Yuan CHAO <yuanchao@gmail.com>
|
||||||
|
Section: x11
|
||||||
Priority: optional
|
Priority: optional
|
||||||
Build-Depends: debhelper-compat (= 13),
|
Build-Depends: debhelper (>= 9.20151219),
|
||||||
libkf6windowsystem-dev,
|
cmake (>= 3.0.2),
|
||||||
libpulse-dev,
|
libfm-dev (>= 1.2.0),
|
||||||
lxqt-build-tools (>= 2.2.0),
|
libfm-qt-dev (>= 0.11.0),
|
||||||
qt6-svg-dev (>= 6.6.0),
|
libglib2.0-dev,
|
||||||
xdg-user-dirs
|
liblxqt0-dev (>= 0.10.0),
|
||||||
Standards-Version: 4.7.2
|
libmenu-cache-dev,
|
||||||
Vcs-Browser: https://git.lubuntu.me/Lubuntu/pavucontrol-qt-packaging
|
libqt5x11extras5-dev,
|
||||||
Vcs-Git: https://git.lubuntu.me/Lubuntu/pavucontrol-qt-packaging.git
|
libqt5xdg-dev (>= 1.3.0),
|
||||||
Debian-Vcs-Browser: https://salsa.debian.org/lxqt-team/pavucontrol-qt
|
libx11-dev,
|
||||||
Debian-Vcs-Git: https://salsa.debian.org/lxqt-team/pavucontrol-qt.git
|
pkg-config,
|
||||||
Homepage: https://github.com/lxqt/pavucontrol-qt
|
qttools5-dev,
|
||||||
Rules-Requires-Root: no
|
qttools5-dev-tools
|
||||||
|
Standards-Version: 3.9.8
|
||||||
|
Vcs-Browser: https://anonscm.debian.org/git/pkg-lxqt/pcmanfm-qt.git/?h=debian/sid
|
||||||
|
Vcs-Git: https://anonscm.debian.org/git/pkg-lxqt/pcmanfm-qt.git -b debian/sid
|
||||||
|
Homepage: https://github.com/lxde/pcmanfm-qt
|
||||||
|
|
||||||
Package: pavucontrol-qt
|
Package: pcmanfm-qt
|
||||||
Architecture: any
|
Architecture: any
|
||||||
Depends: pipewire-pulse | pulseaudio, ${misc:Depends}, ${shlibs:Depends}
|
Depends: ${misc:Depends},
|
||||||
Recommends: pavucontrol-qt-l10n
|
${shlibs:Depends},
|
||||||
Description: Qt port of volume control pavucontrol
|
dbus-x11,
|
||||||
Qt port of volume control pavucontrol of sound server PulseAudio. As such it
|
libfm-modules
|
||||||
can be used to adjust all controls provided by PulseAudio as well as some
|
Recommends: gvfs-backends,
|
||||||
additional settings.
|
lxqt-sudo | gksu,
|
||||||
|
breeze-icon-theme |oyxgen-icon-theme | faenza--icon-theme | gnome-icon-theme
|
||||||
|
Description: extremely fast and lightweight file and desktop icon manager
|
||||||
|
PCManFM-Qt is the Qt port of the LXDE file manager PCManFM.
|
||||||
.
|
.
|
||||||
The software belongs to the LXQt project but its usage isn't limited to this
|
Libfm-Qt is a companion library providing components to build desktop file
|
||||||
desktop environment.
|
managers.
|
||||||
.
|
|
||||||
This package contain the application files.
|
|
||||||
|
|
||||||
Package: pavucontrol-qt-l10n
|
|
||||||
Architecture: all
|
|
||||||
Multi-Arch: foreign
|
|
||||||
Section: localization
|
|
||||||
Depends: qt6-translations-l10n, ${misc:Depends}
|
|
||||||
Description: Language package for pavucontrol-qt
|
|
||||||
Qt port of volume control pavucontrol of sound server PulseAudio. As such it
|
|
||||||
can be used to adjust all controls provided by PulseAudio as well as some
|
|
||||||
additional settings.
|
|
||||||
.
|
|
||||||
The software belongs to the LXQt project but its usage isn't limited to this
|
|
||||||
desktop environment.
|
|
||||||
.
|
|
||||||
This package contains the l10n files needed by the pavucontrol-qt.
|
|
||||||
|
81
debian/copyright
vendored
81
debian/copyright
vendored
@ -1,81 +1,32 @@
|
|||||||
Format: https://www.debian.org/doc/packaging-manuals/copyright-format/1.0/
|
Format: http://www.debian.org/doc/packaging-manuals/copyright-format/1.0/
|
||||||
Upstream-Name: pavucontrol-qt
|
Upstream-Name: pcmanfm-qt
|
||||||
Source: https://github.com/lxqt/pavucontrol-qt
|
Source: https://github.com/lxde/pcmanfm-qt
|
||||||
|
|
||||||
Files: *
|
Files: *
|
||||||
Copyright: 2016-2025 LXQt team
|
Copyright: 2013-2016 LXQt team
|
||||||
License: GPL-2.0
|
2013-2016 Hong Jen Yee (PCMan) <pcman.tw@gmail.com>
|
||||||
|
2012-2013 Andriy Grytsenko (LStranger) <andrej@rep.kiev.ua>
|
||||||
Files: src/elidinglabel.cc
|
2014 Kuzma Shapran <kuzma.shapran@gmail.com>
|
||||||
src/elidinglabel.h
|
|
||||||
Copyright: 2016-2023 LXQt team
|
|
||||||
License: GPL-2.0+
|
|
||||||
|
|
||||||
Files: src/cardwidget.cc
|
|
||||||
src/cardwidget.h
|
|
||||||
src/channel.cc
|
|
||||||
src/channel.h
|
|
||||||
src/devicewidget.cc
|
|
||||||
src/devicewidget.h
|
|
||||||
src/mainwindow.cc
|
|
||||||
src/mainwindow.h
|
|
||||||
src/minimalstreamwidget.cc
|
|
||||||
src/minimalstreamwidget.h
|
|
||||||
src/pavucontrol.cc
|
|
||||||
src/pavucontrol.h
|
|
||||||
src/rolewidget.cc
|
|
||||||
src/rolewidget.h
|
|
||||||
src/sinkinputwidget.cc
|
|
||||||
src/sinkinputwidget.h
|
|
||||||
src/sinkwidget.cc
|
|
||||||
src/sinkwidget.h
|
|
||||||
src/sourceoutputwidget.cc
|
|
||||||
src/sourceoutputwidget.h
|
|
||||||
src/sourcewidget.cc
|
|
||||||
src/sourcewidget.h
|
|
||||||
src/streamwidget.cc
|
|
||||||
src/streamwidget.h
|
|
||||||
Copyright: 2008 Sjoerd Simons <sjoerd@luon.net>
|
|
||||||
2006-2009 Lennart Poettering
|
|
||||||
2009-2011 Colin Guthrie <mzcnihpbageby@0pointer.de>
|
|
||||||
2016 Hong Jen Yee (PCMan) <pcman.tw@gmail.com>
|
|
||||||
License: GPL-2.0+
|
License: GPL-2.0+
|
||||||
|
|
||||||
Files: debian/*
|
Files: debian/*
|
||||||
Copyright: 2015 Andrew Lee <ajqlee@debian.org>
|
Copyright: 2014-2015 Wen Liao <wen.cf83@gmail.com>
|
||||||
2015 Shih-Yuan Lee (FourDollars) <fourdollars@gmail.com>
|
2014-2016 ChangZhuo Chen (陳昌倬) <czchen@debian.org>
|
||||||
2014-2016 ChangZhuo Chen <czchen@gmail.com>
|
2013-2016 Alf Gaida <agaida@siduction.org>
|
||||||
2016 Yuan CHAO <yuanchao@gmail.com>
|
2015 Andrew Lee (李健秋) <ajqlee@debian.org>
|
||||||
2014-2019 Alf Gaida <agaida@siduction.org>
|
|
||||||
2021 apt-ghetto <apt-ghetto@protonmail.com>
|
|
||||||
2021-2022 Rik Mills <rikmills@kde.org>
|
|
||||||
2019-2025 Simon Quigley <tsimonq2@ubuntu.com>
|
|
||||||
2023-2025 Aaron Rainbolt <arraybolt3@gmail.com>
|
|
||||||
License: GPL-2.0+
|
License: GPL-2.0+
|
||||||
|
|
||||||
License: GPL-2.0
|
|
||||||
This program is free software; you can redistribute it and/or modify
|
|
||||||
it under the terms of the GNU General Public License as published by
|
|
||||||
the Free Software Foundation; version 2 of the License.
|
|
||||||
.
|
|
||||||
This program is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
GNU General Public License for more details.
|
|
||||||
.
|
|
||||||
On Debian systems, the complete text of the GNU General Public License
|
|
||||||
version 2 can be found in "/usr/share/common-licenses/GPL-2".
|
|
||||||
|
|
||||||
License: GPL-2.0+
|
License: GPL-2.0+
|
||||||
This program is free software; you can redistribute it and/or modify
|
This package is free software; you can redistribute it and/or modify
|
||||||
it under the terms of the GNU General Public License as published by
|
it under the terms of the GNU General Public License as published by
|
||||||
the Free Software Foundation; either version 2 of the License, or
|
the Free Software Foundation; either version 2 of the License, or
|
||||||
(at your option) any later version.
|
(at your option) any later version.
|
||||||
.
|
.
|
||||||
This program is distributed in the hope that it will be useful,
|
This package is distributed in the hope that it will be useful,
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
GNU General Public License for more details.
|
GNU General Public License for more details.
|
||||||
.
|
.
|
||||||
On Debian systems, the complete text of the GNU General Public License
|
On Debian systems, the complete text of the GNU General
|
||||||
version 2 can be found in "/usr/share/common-licenses/GPL-2".
|
Public License version 2 can be found in
|
||||||
|
"/usr/share/common-licenses/GPL-2".
|
||||||
|
5
debian/gbp.conf
vendored
5
debian/gbp.conf
vendored
@ -2,4 +2,7 @@
|
|||||||
debian-branch = debian/sid
|
debian-branch = debian/sid
|
||||||
upstream-branch = upstream/latest
|
upstream-branch = upstream/latest
|
||||||
pristine-tar = True
|
pristine-tar = True
|
||||||
compression = xz
|
|
||||||
|
[import-orig]
|
||||||
|
# Use git cherrypick -n upstream instead.
|
||||||
|
merge = False
|
||||||
|
4
debian/lintian-overrides
vendored
4
debian/lintian-overrides
vendored
@ -1,4 +0,0 @@
|
|||||||
# yes, we know
|
|
||||||
pavucontrol-qt: no-manual-page [usr/bin/pavucontrol-qt]
|
|
||||||
pavucontrol-qt: desktop-entry-lacks-keywords-entry [usr/share/applications/pavucontrol-qt.desktop]
|
|
||||||
|
|
19
debian/patches/fallback-icon-theme.patch
vendored
Normal file
19
debian/patches/fallback-icon-theme.patch
vendored
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
Description: Set oxygen as default fallback
|
||||||
|
until the FIXME is done. That's all i want to do for now.
|
||||||
|
oxygen is merged upstream so the patch become obsolete with the
|
||||||
|
upcoming release.
|
||||||
|
Author: Alf Gaida <agaida@siduction.org>
|
||||||
|
Bug-Debian: https://bugs.debian.org/826311
|
||||||
|
Last-Update: 2016-06-04
|
||||||
|
|
||||||
|
--- pcmanfm-qt-0.11.0.orig/pcmanfm/settings.cpp
|
||||||
|
+++ pcmanfm-qt-0.11.0/pcmanfm/settings.cpp
|
||||||
|
@@ -163,7 +163,7 @@ bool Settings::loadFile(QString filePath
|
||||||
|
if(fallbackIconThemeName_.isEmpty()) {
|
||||||
|
// FIXME: we should choose one from installed icon themes or get
|
||||||
|
// the value from XSETTINGS instead of hard code a fallback value.
|
||||||
|
- fallbackIconThemeName_ = "elementary"; // fallback icon theme name
|
||||||
|
+ fallbackIconThemeName_ = "oxygen"; // fallback icon theme name
|
||||||
|
}
|
||||||
|
suCommand_ = settings.value("SuCommand", "lxqt-sudo %s").toString();
|
||||||
|
setTerminal(settings.value("Terminal", "xterm").toString());
|
1
debian/patches/series
vendored
Normal file
1
debian/patches/series
vendored
Normal file
@ -0,0 +1 @@
|
|||||||
|
fallback-icon-theme.patch
|
1
debian/pavucontrol-qt-l10n.install
vendored
1
debian/pavucontrol-qt-l10n.install
vendored
@ -1 +0,0 @@
|
|||||||
usr/share/pavucontrol-qt/translations/
|
|
2
debian/pavucontrol-qt.install
vendored
2
debian/pavucontrol-qt.install
vendored
@ -1,2 +0,0 @@
|
|||||||
usr/bin/pavucontrol-qt
|
|
||||||
usr/share/applications/pavucontrol-qt.desktop
|
|
15
debian/rules
vendored
15
debian/rules
vendored
@ -1,16 +1,11 @@
|
|||||||
#!/usr/bin/make -f
|
#!/usr/bin/make -f
|
||||||
# export DH_VERBOSE=1
|
#DH_VERBOSE = 1
|
||||||
|
|
||||||
export LC_ALL=C.UTF-8
|
export LC_ALL=C.UTF-8
|
||||||
|
|
||||||
export DEB_BUILD_MAINT_OPTIONS = hardening=+all
|
export DEB_BUILD_MAINT_OPTIONS = hardening=+all
|
||||||
|
export DEB_LDFLAGS_MAINT_APPEND = -Wl,--as-needed
|
||||||
|
|
||||||
%:
|
%:
|
||||||
dh ${@} --buildsystem cmake
|
dh ${@} --buildsystem cmake \
|
||||||
|
--parallel
|
||||||
override_dh_missing:
|
|
||||||
dh_missing --fail-missing
|
|
||||||
|
|
||||||
override_dh_auto_configure:
|
|
||||||
dh_auto_configure -- \
|
|
||||||
-DUPDATE_TRANSLATIONS=OFF \
|
|
||||||
-DCMAKE_BUILD_TYPE=RelWithDebInfo
|
|
||||||
|
2
debian/source/lintian-overrides
vendored
2
debian/source/lintian-overrides
vendored
@ -1,2 +0,0 @@
|
|||||||
# Translations files can be long
|
|
||||||
pavucontrol-qt source: very-long-line-length-in-source-file * > 512 [*.ts:*]
|
|
2
debian/source/options
vendored
2
debian/source/options
vendored
@ -1 +1 @@
|
|||||||
tar-ignore=.gitignore
|
tar-ignore = .gitignore
|
||||||
|
6
debian/upstream/metadata
vendored
6
debian/upstream/metadata
vendored
@ -1,6 +0,0 @@
|
|||||||
Name: pavucontrol-qt
|
|
||||||
Bug-Database: https://github.com/lxqt/pavucontrol-qt/issues
|
|
||||||
Bug-Submit: https://github.com/lxqt/pavucontrol-qt/issues/new
|
|
||||||
Changelog: https://github.com/lxqt/pavucontrol-qt/blob/master/CHANGELOG
|
|
||||||
Repository: https://github.com/lxqt/pavucontrol-qt
|
|
||||||
Repository-Browse: https://github.com/lxqt/pavucontrol-qt
|
|
109
debian/upstream/signing-key.asc
vendored
109
debian/upstream/signing-key.asc
vendored
@ -1,52 +1,63 @@
|
|||||||
-----BEGIN PGP PUBLIC KEY BLOCK-----
|
-----BEGIN PGP PUBLIC KEY BLOCK-----
|
||||||
|
Version: GnuPG v2.0.22 (GNU/Linux)
|
||||||
|
|
||||||
mQINBF6cxrwBEADfl3ydxNfLBbWGPesXty2baQgixZ3D6aCxadI2kX+aikmT8rd0
|
mQINBFJevCYBEACx+Hvy+Vsuf+V5jeLUnzjAmHoy8DfTeGWr3ts30IapLHrfi0+U
|
||||||
ttDKN18cXV52Ssxnj0qhgf4hwnu/b0be6BzqSEyGM+UQR3X2CYpxrMakfW32Q18K
|
WpzNnISO77yTr4VNboVZH+GHM/rnPfieODfB4ZW6CZLlInMSKUXcgQsEqXpyBZhA
|
||||||
X5ec0RPR2ucBq9G0r9t6FYC8FkJ4uQUU3xxrLW3z302S0Makjgzm8BV9WrFQ7oFF
|
Ib/SPy2bOfHly1uRJes0uRDsH5+v/hD74sByfnjQlrvI68O6wvGZmDFMNNPVO8+/
|
||||||
uJQj0BHbHYC4RyaZb2AfxY4Y92BPGTjtGekWqgw6vEXCCnvAbGYVQzvxZt3nw21/
|
OWBSBNkBuVrrZOMSPsLwQGJ4UtUQ4whburaPJG4VZJc5DLbzJGbEuACc0IAEYJS3
|
||||||
1YmV4g7xhGFQPbOf9v3ejFUJeJIGzuJf5NAh7kvfCdUBAGYH0gnj0GpOve4ftnaG
|
7AfXVXn4j4Gc9F3o1xTUnbOBnwGPquWwUIm3FM7Ec2OdkvMt3EwvnkMAfeVrq3iE
|
||||||
sAId2CQwm3oYF4Tu7yBPTOBpkaKkNaT+UdwTyeKERuCZ9ocZWX++/YF9ItRkJ5mM
|
FDD/KZTxdL0BZH3QD8gB7Jm4v4f3Nkobg6JCvCbcH3wBdZW4mASbwWzfRaDC2zHb
|
||||||
zoP1GluWn2atNWpRh/K97gyAGgr2fSmrAA4d1JrVbMujZAHoHAOKwJKqX9jPziPZ
|
ErTglD7PpShLKZZ0pr9okWZEGw4Ku3q8ALi1JXK/ePTmsBlvkVskOJ3Nnd0avgH4
|
||||||
BFHfhcIOzG3ZhXAuumHsd7uwfPBVt20g+G+cOjBghbSSu9EOtMkAZl1g3ybvZixu
|
+Q/vZoKfH8EhNY745rI+8CE9iv6V9XiSUt4CKEWAENt4A8hq6U2vV+jZv3B6AgD7
|
||||||
Jtxa5exZWEmU7vtytEb8eq9Dj5XcGoTDbErE2RpJ/20HPzhyRKg9RN4iGS+0OiHS
|
ZjiI59yD4YuYubu8rCnNizTgh1voVw3ietknn/x2H5yH8fByWZ5uL87C0ky/uma6
|
||||||
oRbDi5IEOizvQjp2bsBmfa3rsoDSOqF2pevp+u8I56I6bU1GFpxxNC5IGvgo2Q79
|
ZGbiiAtM4kdkyDMrfRV5nlEG9EKAGPVu5mjeSCrfkETwZ9OFPz1AuDye4ZEXrrcC
|
||||||
quz0oIk5hs3eLlUdEYsLGwR6pWJaJyf36vuDsq7iLrLyvHI5irAowO4r1QARAQAB
|
iRQ7RX6/GtW18aHER0kzGnfwx5KJzkDrRBY8A2PdXLBcrsN4WpK9EX01PQARAQAB
|
||||||
tCVQZWRyYW0gUG91cmFuZyA8dHN1amFuMjAwMEBnbWFpbC5jb20+iQJOBBMBCAA4
|
tCNKZXJvbWUgTGVjbGFuY2hlIDxqZXJvbWVAbGVjbGFuLmNoPokCPwQTAQIAKQUC
|
||||||
FiEEGd/fOleb1QnbtXLYvnkwB60i334FAl6cxrwCGwMFCwkIBwIGFQoJCAsCBBYC
|
Ul68JgIbAwUJAeEzgAcLCQgHAwIBBhUIAgkKCwQWAgMBAh4BAheAAAoJEDfgrx/a
|
||||||
AwECHgECF4AACgkQvnkwB60i335f9RAAgRpn8gUa/l10UkVAnpM2Cz0MuNMwwCOq
|
SPNzSHIP/1ewXcC0TFBcvDD7MrIP7anyNfiWfW7cxkR8GSamkg6HTa6Ndyr1FFjJ
|
||||||
IfVnuZuPBtYYiTU5Su++/aPZe3fF5B4v61F+XjNi7qeVL2t52X3jZ/iIx9Syasb+
|
OoDFUP37jWhu59CsHxs2D0zRWJktezfvElscRgqbHcdpIznqsGdI8hXCZafhBGVb
|
||||||
vDAIfQ5t6lKXvOptWxf6vteOg6CHbXwpGHbPjUkUS2vQwRikjBnR0SnkrMoXtgSX
|
sdAB2LRawcXGxnXt7XajPcSVwLWRE62caBqohznU2iWvI780WNjEbZoA0LhZwaFF
|
||||||
amPFqsitNrOhEJfeDfo0NzKESZuliWrCFt2v8c5q18G8cCZAvPLBlGuwRl58cDep
|
UUPJm8ea9v0IkZVKUyg9WONZ1U7FEG9SaEiSpI8kJdx1fvCwZVDV/NRO5GqnJaho
|
||||||
3EIibMI/9MUSJbKoiHlK+LcHtG7BQTNis/e7Pe1PkRmExfhxe1lNajtOx8FO72Tq
|
P1LCne4YdwS6pt1/fRgk32IHxxZfHlLzLHxb6v1JmIg72x28qCmGyK9oFBDbbnYu
|
||||||
B6zY6drippM9VaIc1M+zp9BRpsFu8whOmapCqlXHRgAK8xTdQRIGInQFqLWPOxSC
|
6Aq8XbHogOrD5vJM2Pfm2IhV0+JHOjfQbddv8tsAH1M+LI+tToXmg5st1AU3wnTn
|
||||||
f0B6N+EvQvgkyFQ1rW+u91OJBma46uKkhrwf+mDttVRncaIAkgE6e6pqm18yIPFk
|
pda3hjA1avKwkfBPW/osHc8782ViyS9iX2e9iDtMv608guij4NjpGExzGCypHOd8
|
||||||
D42rt/yHcOl+2qkcJS3gPcg5UvlCzqOwg1rKZQIk+TcPuDx3r2UghDEYZN9X6vw3
|
+VXRwJDjvgDynkL206MZ+wn0j5wHsIE8F3Y5Bp1thQOrdDli5MYNQoXhjFmH46XT
|
||||||
zCBufr7ygZNf4tkbnVARFWTR4GzyCseFkWgOVZL9DccAhs8NeMy1WLkUzB75adeR
|
bcr84IgW0+AiXZdoFUqvwtzrWy2Onuw5R3k4OyV4skN4DkWXyAk/V+Y4K39JvTKf
|
||||||
3LONmEL7xOI8FuknKY4e6EcWhmstNIDgXfRe0hwO0VBdW3unoZC/K2ZM/ZuZyMdK
|
H9YuiQ9blNzCu8WiAnjKnh9kNl9E/TyEwI6cHFmIPqF8ST9tJytWHtrKvU9csvXX
|
||||||
TFjvYJrNewmymKge68wo0054bGZn8oz17i2AosJz7kW+ITsxmxhVcpfl4bav9Neq
|
n8XNJmpcv2R1e6N+VuWWm5zUPTouv3AxCacLbm8Lh3ymGsk7ZEyhiQIcBBABAgAG
|
||||||
RpQwhnhK9bC5Ag0EXpzGvAEQANbeRHFbpgQVIqV9WVOVnTj4FIqrTPTPKKa02vJA
|
BQJSsFYyAAoJEBMY76xfu9vO6v0P/3wSj3/kE4nP4HfgcVJSzi+lm1ycpbLDZtgh
|
||||||
7tGpgFapgvjdxnMxJfV6wuwOBUUFLR7DrXlV8EVFAYc5qTIeSQXvJsWw6gQ3+f0D
|
P1G+zJLVmA+E41vEZimeiYQxBAelatJz+CHzQo3LZ2oVChzVrZcVHn9k4P3pib69
|
||||||
z13oGOhZPBIzIKnV/MZI/jhIio8kSPWAuM5hR2X9Hvw3/CLo+H+hZZ6cFYoCxrQS
|
qCVif3/y0Wmecn+u2TWbOvJ7mthfO7T3W7rkW1/9ES7bUaXcXWQ2sjUBVqFkFsVt
|
||||||
tTzcKMkdQizLLa+WNbqUSxg6I/P5k/smUDY9gKW7RtI5t/PupA3WTnsVD6CYWa3Q
|
xgJDo8wcxA+K4Yf06GCbxFwrB7X5GraWIkzqGnyse3XAQn8aORAXmE8Yd0FHOjEZ
|
||||||
c1O/1mUgqT6nQ5N9KCPpjZQRT6D6eIMmePtS85z4PPeYMJxPsKRYWPGRxKhCSdZl
|
Beb9shChnkYc3lEvNY8ioCaYSF9xr/Iz9cwpfPkpqFiVYWadtb+Gqeh6zC7vPmcT
|
||||||
/0wsC8aRtmwYT729e0ZgTAmUnj+rQp5hboF/ZPFjIoXR9G+0HnoY0a/nqVO4lUON
|
zHxrgkq1WwQlSBm724tPt9xuGQoOglqEa23vlQZfv20nyrYjLeYUy6pMCRq7vn/n
|
||||||
AV25GnMFGVyiHHlbH/0gboywwnzEg8BZbk+Z/61oOzBIW09sfG8fn8bsbkpL+nHf
|
nkQOcXF7yQlnqR6xKk0tWsM4e6du0ZvbjBbhHV/kBFVGCLm/upTwoMVm0WJTbr4T
|
||||||
Mi/Vauge6wSfw7I5AfSiwrSDNHmKVsu39koWV6JGxEeFr2MffF+CuaoJCNOr/ZII
|
5XfIZo7eA0lvGtUhe1PgcOidBikHfAIfYxu0BoMXoL4jbcQdR5+YBDEfsS0jPhCl
|
||||||
SYR5ku3Y/lMKyUH1Oas0RWzFrdRcInqYK90A0x083zP4V445MvCwbRPzQAkm9wOP
|
mew2ScW/R/UhUknJUVFTma0KHXzEmKiqeeUCDtwEi6fxdicAYkbcekgkfFiD/w8N
|
||||||
kILLhE5FW+9/O0/9bpx4joJUDLV4d3hFZy7GSHKiZUs1QW6BV75JQKqoi+cVt+/L
|
Lk3Uf+0x2MdKA36nUobFkk38oU+GW37kFWJs3f1YRuQFao896eNW/E8ekVMLNxOl
|
||||||
+o1S8CMNekjqdC2mWRosM3doo51zT/FWNzQA1QcoZP2hORJDfw66y+4wPq6o8y1W
|
nCjnSbabaxDnxPTyW2KlNjf/QUEK4pT6S5QmuCSrle3PQpaSbAZDHzLBIL9gd3m6
|
||||||
jR35ABEBAAGJAjYEGAEIACAWIQQZ3986V5vVCdu1cti+eTAHrSLffgUCXpzGvAIb
|
MH7+SvV4uQINBFJevCYBEADiXDUqstSdhIyuionS2KtE3IeEBIqS7GY8QPRBylIZ
|
||||||
DAAKCRC+eTAHrSLffgbJD/4qW5YOo/BayBhaUh2L7VP7JNlECb/2xNNOFKI1NjNr
|
ACVHFI/1HxChBqYVGFaDEQn3gj5lUUQPubfWaxzjF6+UNVQW4+cxmTocndAwfDbI
|
||||||
nOmgSJLzf74Uhmt5W+iVjmJBHrDceprIPkizmPrn90kIsPIMtHIDNxzUgKZHbnza
|
+E5BLdieFUzbAA05MV5ZjPhTNbSk1jpy4bNy0FILwNqc89Y6SoCbv1r3tZLCrBas
|
||||||
j1vZyAeC+JV79X1hOVpprj1TJwy65lpxXNyYnGqeIOgyFokn9fOHXv8aMQwpNuUr
|
1+AfWknBynx0siGMbLFxtzR6hUkNz9URxt13FrzpUWMpAL8ZQGczOTSaWLrZA5l9
|
||||||
bdUJ1C75jYrvwy/NR1DczIFFYgsbkDGDtjVBjyMc5JAgvUBz37/iVPJfWP6dKVnf
|
xLzJ9ww8uM+C2Xej3/sANxi+kQE2GVMKurPS0TICwVWZxbdW/ytIkO67Rhse0q3t
|
||||||
abRnUVzHgvgK7bnab00SA1TiWvjHURGjo+5rnRtv8X/AgStc2Phjq68TMIgMn0F2
|
vzjdawfCFRxv7XQB2ZJ6irDxbpHiJoojSWCHJadIyCG03iOiaqsSVvi4KnxtUck+
|
||||||
kjUVvfQotNqzo9madNshvUDmsGtAzKh4e0dS1ear7u3nRp4Z7fqSrTEtXKNbEPwZ
|
udOEJUV5sxdzgeRrsDpeaN//KCWW9WjfsSkvOqP6S1gmWpNFdzF5XrzcgvqvSNqo
|
||||||
wdWrWmmQLacNQBSe/FtcMzGF6xIVr4lnrL0bFjqBdQpdTC7vns3QSKk8/GFiEfpv
|
XejfakUTJqsIIEHO0zGuJFVzJNh2hQ/9dhjIspUORhtNKaljNvePiBrj2yqmd9PY
|
||||||
kzXrDbGV7jX2OWDjNHKcmXX2+E1CsNaJgS7zOgZw5jvbvlTLJUwyYNlM1VLI2OFW
|
FlH1KMHe4H+YVIwPiyeNA87Pu+1yNo8gT7mXhGRfibgWjbt146WUJ7+l2StJMApn
|
||||||
Oa86l8pqli+B7rpTbsAE9Ut8qUaWjm87oUNSJbaKgqNnMaE+b/8VJaEeWHgQJwsD
|
eNSCartNaUNPnw96i2l5c9AsJ3SWC6XWpWzOLVj+9XceeA11lu/ogqEMHzx81NjH
|
||||||
bJSJ/O/vzlRtDjOJ1JDlMRLs7TnOFeUh5pgwyaJoidYbJEiGlMGJbI6BjwhDTBFO
|
2TePxwKTKxZnAvDmqryp++IgY2/OgIoIk3ZRdYu/dPijTOYWfCet/9/9kAFr9PeJ
|
||||||
NLJtd3SsRjc7ICtGdCvej59IvCDTjxtkhx5okF03APi1aXpHQrE18/arFD7BpoGO
|
KwARAQABiQIlBBgBAgAPBQJSXrwmAhsMBQkB4TOAAAoJEDfgrx/aSPNzJv0QAKkx
|
||||||
sw==
|
lCKEZ6ahAUuNWslsHnNWaHFHNawEO3NIEtQZGVFk2BYISupizvjZF6MnymO/9UFM
|
||||||
=gSIv
|
pzV6fp3xNdqaKWQBjScOgMgCASRixW2tMAKbJGHZKp3dBixpHgXxy2oOGMS+mQ5m
|
||||||
|
gWy07usq2YesoMD0K/SG6EnoRPHBvrJihArzMFVUY9hD3hk8bhiy8w9bCYFe+gkm
|
||||||
|
zpQl3/KN01kyt5LjzEBcIOw8qIBQe9Pk8PyOK75lPoNME714LatgOsyw2kaSQ9Sv
|
||||||
|
hziRGC5z/fV3PmH7XhSjENPKnCJU51GUMMLaL28t9o7Afh6Q8UV31/JO36vmQXQV
|
||||||
|
+b+0BoGqEmf3AKBASb2Cr2q4pZFjywwSUXHZ9hQyu1tpbE1dS6aI01kM0y270pk7
|
||||||
|
W/ajuzuOxAVL1bJAanL/5+DWM03esZPVdEWhxpWEM40Z6Rhq+Xb2a5xfwCN9PmaQ
|
||||||
|
o9fez0I+yh53s7Ypv0tBj05FPe5L48+pDi6pz5nddN1B0FzF58jVfsBZUjBlY24+
|
||||||
|
VwQeAaWkRXZrSEdtBS5ufsi80x/cNCSTJBWqtborKL1iGgf5MDPYRMSvmZXAeIld
|
||||||
|
pyL/0pbW7iokewyKzpFfo7KEbwLxB+flWaBZ867JpF4yyRj3b4qcvcyV8QnsoB7Z
|
||||||
|
KhxTl3gGwD/t0HUcu85zcfs4GkealYhIWfGaAso2
|
||||||
|
=fF8P
|
||||||
-----END PGP PUBLIC KEY BLOCK-----
|
-----END PGP PUBLIC KEY BLOCK-----
|
||||||
|
8
debian/watch
vendored
8
debian/watch
vendored
@ -1,5 +1,3 @@
|
|||||||
version=4
|
version=3
|
||||||
opts="searchmode=plain, \
|
opts="pgpsigurlmangle=s/$/.asc/" \
|
||||||
pgpsigurlmangle=s/$/.asc/, \
|
https://github.com/lxde/pcmanfm-qt/releases .*/([\d\.]+).tar.gz
|
||||||
uversionmangle=s/(\d+\.\d+\.\d+).*/$1/" \
|
|
||||||
https://api.github.com/repos/lxqt/@PACKAGE@/releases https:\/\/github.com\/lxqt\/@PACKAGE@\/releases\/download\/@ANY_VERSION@\/@PACKAGE@-@ANY_VERSION@.tar.xz
|
|
||||||
|
51
pcmanfm-qt.1.in
Normal file
51
pcmanfm-qt.1.in
Normal file
@ -0,0 +1,51 @@
|
|||||||
|
.TH PCManFM-Qt "1" "September 2014" "@CMAKE_PROJECT_NAME@ @PCMANFM_QT_VERSION@" "User Commands"
|
||||||
|
.SH NAME
|
||||||
|
PCManFM-Qt \- A lightweight Qt-based file manager for X Window.
|
||||||
|
.SH SYNOPSIS
|
||||||
|
pcmanfm\-qt [OPTION...] [FILE1, FILE2,...]
|
||||||
|
.SH DESCRIPTION
|
||||||
|
PCMan File Manager Qt (\fBPCManFM-Qt\fP) is an extremely fast, lightweight, yet
|
||||||
|
feature-rich file manager with tabbed browsing. It is the default file manager
|
||||||
|
for the lightweight desktop environment \fBLXQt\fP.
|
||||||
|
.SH OPTIONS
|
||||||
|
.SS "Help Options:"
|
||||||
|
.TP
|
||||||
|
\fB\-h\fR, \fB\-\-help\fR
|
||||||
|
Show help options
|
||||||
|
.SS "Application Options:"
|
||||||
|
.TP
|
||||||
|
\fB\-p\fR, \fB\-\-profile\fR=\fI\,PROFILE\/\fR
|
||||||
|
Set name of configuration profile
|
||||||
|
.TP
|
||||||
|
\fB\-d\fR, \fB\-\-daemon\-mode\fR
|
||||||
|
Run PCManFM as a daemon
|
||||||
|
.TP
|
||||||
|
\fB\-\-quit\fR
|
||||||
|
Quit PCManFM
|
||||||
|
.TP
|
||||||
|
\fB\-\-desktop\fR
|
||||||
|
Launch desktop manager
|
||||||
|
.TP
|
||||||
|
\fB\-\-desktop\-off\fR
|
||||||
|
Turn off desktop manager if it's running
|
||||||
|
.TP
|
||||||
|
\fB\-\-desktop\-pref\fR=\fI\,NAME\/\fR
|
||||||
|
Open desktop preference dialog on the page with the specified name
|
||||||
|
.TP
|
||||||
|
\fB\-w\fR, \fB\-\-set\-wallpaper\fR=\fI\,FILE\/\fR
|
||||||
|
Set desktop wallpaper from image FILE
|
||||||
|
.TP
|
||||||
|
\fB\-\-wallpaper\-mode\fR=\fI\,MODE\/\fR
|
||||||
|
Set mode of desktop wallpaper. MODE=(color|stretch|fit|center|tile)
|
||||||
|
.TP
|
||||||
|
\fB\-\-show\-pref\fR=\fI\,NAME\/\fR
|
||||||
|
Open Preferences dialog on the page with the specified name
|
||||||
|
.TP
|
||||||
|
\fB\-n\fR, \fB\-\-new\-window\fR
|
||||||
|
Open new window
|
||||||
|
.TP
|
||||||
|
\fB\-f\fR, \fB\-\-find\-files\fR
|
||||||
|
Open Find Files utility
|
||||||
|
.SH "AUTHORS"
|
||||||
|
.B pcmanfm-qt
|
||||||
|
was primarily written by Hong Jen Yee (PCMan) <pcman.tw@gmail.com>.
|
85
pcmanfm/CMakeLists.txt
Normal file
85
pcmanfm/CMakeLists.txt
Normal file
@ -0,0 +1,85 @@
|
|||||||
|
set(pcmanfm_SRCS
|
||||||
|
application.cpp
|
||||||
|
pcmanfm.cpp
|
||||||
|
mainwindow.cpp
|
||||||
|
tabpage.cpp
|
||||||
|
tabbar.cpp
|
||||||
|
view.cpp
|
||||||
|
launcher.cpp
|
||||||
|
preferencesdialog.cpp
|
||||||
|
xdgdir.cpp
|
||||||
|
desktoppreferencesdialog.cpp
|
||||||
|
desktopwindow.cpp
|
||||||
|
desktopitemdelegate.cpp
|
||||||
|
autorundialog.cpp
|
||||||
|
settings.cpp
|
||||||
|
)
|
||||||
|
|
||||||
|
qt5_add_dbus_adaptor(pcmanfm_SRCS
|
||||||
|
org.pcmanfm.Application.xml
|
||||||
|
application.h
|
||||||
|
PCManFM::Application
|
||||||
|
applicationadaptor
|
||||||
|
ApplicationAdaptor
|
||||||
|
)
|
||||||
|
|
||||||
|
set(pcmanfm_UIS
|
||||||
|
main-win.ui
|
||||||
|
about.ui
|
||||||
|
preferences.ui
|
||||||
|
desktop-preferences.ui
|
||||||
|
desktop-folder.ui
|
||||||
|
autorun.ui
|
||||||
|
)
|
||||||
|
|
||||||
|
qt5_wrap_ui(pcmanfm_UIS_H ${pcmanfm_UIS})
|
||||||
|
|
||||||
|
# add translation for pcmanfm-qt
|
||||||
|
lxqt_translate_ts(QM_FILES
|
||||||
|
UPDATE_TRANSLATIONS ${UPDATE_TRANSLATIONS}
|
||||||
|
SOURCES ${pcmanfm_SRCS} ${pcmanfm_UIS}
|
||||||
|
)
|
||||||
|
|
||||||
|
# translate desktop entry files for pcmanfm-qt and desktop preferences
|
||||||
|
lxqt_translate_desktop(DESKTOP_FILES
|
||||||
|
SOURCES
|
||||||
|
pcmanfm-qt.desktop.in
|
||||||
|
pcmanfm-qt-desktop-pref.desktop.in
|
||||||
|
)
|
||||||
|
|
||||||
|
add_executable(pcmanfm-qt
|
||||||
|
${pcmanfm_SRCS}
|
||||||
|
${pcmanfm_UIS_H}
|
||||||
|
${QM_FILES}
|
||||||
|
${DESKTOP_FILES}
|
||||||
|
)
|
||||||
|
set_property(
|
||||||
|
TARGET pcmanfm-qt APPEND
|
||||||
|
PROPERTY COMPILE_DEFINITIONS
|
||||||
|
PCMANFM_DATA_DIR="${CMAKE_INSTALL_PREFIX}/share/pcmanfm-qt"
|
||||||
|
PCMANFM_QT_VERSION="${PCMANFM_QT_VERSION}"
|
||||||
|
)
|
||||||
|
|
||||||
|
target_include_directories(pcmanfm-qt
|
||||||
|
PRIVATE "${LIB_XCB_INDLUDE_DIRS}"
|
||||||
|
"${Qt5Gui_PRIVATE_INCLUDE_DIRS}"
|
||||||
|
)
|
||||||
|
|
||||||
|
target_link_libraries(pcmanfm-qt
|
||||||
|
Qt5::X11Extras
|
||||||
|
Qt5::Widgets
|
||||||
|
Qt5::DBus
|
||||||
|
fm-qt
|
||||||
|
"${LIB_XCB_LIBRARIES}"
|
||||||
|
)
|
||||||
|
|
||||||
|
install(TARGETS pcmanfm-qt RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR})
|
||||||
|
|
||||||
|
# install a desktop entry file for pcmanfm-qt and desktop preferences
|
||||||
|
install(FILES ${DESKTOP_FILES} DESTINATION "${CMAKE_INSTALL_DATADIR}/applications"
|
||||||
|
)
|
||||||
|
|
||||||
|
install(FILES ${QM_FILES} DESTINATION "${CMAKE_INSTALL_DATADIR}/pcmanfm-qt/translations")
|
||||||
|
|
||||||
|
# prevent the generated files from being deleted during make clean
|
||||||
|
set_directory_properties(PROPERTIES CLEAN_NO_CUSTOM true)
|
180
pcmanfm/about.ui
Normal file
180
pcmanfm/about.ui
Normal file
@ -0,0 +1,180 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<ui version="4.0">
|
||||||
|
<class>AboutDialog</class>
|
||||||
|
<widget class="QDialog" name="AboutDialog">
|
||||||
|
<property name="geometry">
|
||||||
|
<rect>
|
||||||
|
<x>0</x>
|
||||||
|
<y>0</y>
|
||||||
|
<width>430</width>
|
||||||
|
<height>325</height>
|
||||||
|
</rect>
|
||||||
|
</property>
|
||||||
|
<property name="windowTitle">
|
||||||
|
<string>About</string>
|
||||||
|
</property>
|
||||||
|
<property name="windowIcon">
|
||||||
|
<iconset theme="help-about">
|
||||||
|
<normaloff/>
|
||||||
|
</iconset>
|
||||||
|
</property>
|
||||||
|
<layout class="QVBoxLayout" name="verticalLayout">
|
||||||
|
<item>
|
||||||
|
<widget class="QLabel" name="label">
|
||||||
|
<property name="text">
|
||||||
|
<string><html><head/><body><p><span style=" font-size:16pt; font-weight:600;">PCManFM</span></p></body></html></string>
|
||||||
|
</property>
|
||||||
|
<property name="textFormat">
|
||||||
|
<enum>Qt::RichText</enum>
|
||||||
|
</property>
|
||||||
|
<property name="alignment">
|
||||||
|
<set>Qt::AlignCenter</set>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QLabel" name="version">
|
||||||
|
<property name="text">
|
||||||
|
<string/>
|
||||||
|
</property>
|
||||||
|
<property name="alignment">
|
||||||
|
<set>Qt::AlignCenter</set>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QLabel" name="label_2">
|
||||||
|
<property name="text">
|
||||||
|
<string>Lightweight file manager</string>
|
||||||
|
</property>
|
||||||
|
<property name="alignment">
|
||||||
|
<set>Qt::AlignCenter</set>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QLabel" name="label_3">
|
||||||
|
<property name="text">
|
||||||
|
<string><html><head/><body><p><a href="http://lxqt.org/"><span style=" text-decoration: underline; color:#0000ff;">http://lxqt.org/</span></a></p></body></html></string>
|
||||||
|
</property>
|
||||||
|
<property name="textFormat">
|
||||||
|
<enum>Qt::RichText</enum>
|
||||||
|
</property>
|
||||||
|
<property name="alignment">
|
||||||
|
<set>Qt::AlignCenter</set>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QTabWidget" name="tabWidget">
|
||||||
|
<property name="currentIndex">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<property name="tabsClosable">
|
||||||
|
<bool>false</bool>
|
||||||
|
</property>
|
||||||
|
<widget class="QWidget" name="tab">
|
||||||
|
<attribute name="title">
|
||||||
|
<string>Authors</string>
|
||||||
|
</attribute>
|
||||||
|
<layout class="QVBoxLayout" name="verticalLayout_4">
|
||||||
|
<item>
|
||||||
|
<widget class="QPlainTextEdit" name="plainTextEdit_2">
|
||||||
|
<property name="readOnly">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
<property name="plainText">
|
||||||
|
<string>Programming:
|
||||||
|
* Hong Jen Yee (PCMan) <pcman.tw@gmail.com>
|
||||||
|
</string>
|
||||||
|
</property>
|
||||||
|
<property name="backgroundVisible">
|
||||||
|
<bool>false</bool>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
<widget class="QWidget" name="tab_2">
|
||||||
|
<attribute name="title">
|
||||||
|
<string>License</string>
|
||||||
|
</attribute>
|
||||||
|
<layout class="QVBoxLayout" name="verticalLayout_3">
|
||||||
|
<item>
|
||||||
|
<widget class="QPlainTextEdit" name="plainTextEdit">
|
||||||
|
<property name="readOnly">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
<property name="plainText">
|
||||||
|
<string>PCMan File Manager
|
||||||
|
|
||||||
|
Copyright (C) 2009 - 2014 洪任諭 (Hong Jen Yee)
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or
|
||||||
|
modify it under the terms of the GNU General Public License
|
||||||
|
as published by the Free Software Foundation; either version 2
|
||||||
|
of the License, or (at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program; if not, write to the Free Software
|
||||||
|
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QDialogButtonBox" name="buttonBox">
|
||||||
|
<property name="orientation">
|
||||||
|
<enum>Qt::Horizontal</enum>
|
||||||
|
</property>
|
||||||
|
<property name="standardButtons">
|
||||||
|
<set>QDialogButtonBox::Close</set>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
<resources/>
|
||||||
|
<connections>
|
||||||
|
<connection>
|
||||||
|
<sender>buttonBox</sender>
|
||||||
|
<signal>accepted()</signal>
|
||||||
|
<receiver>AboutDialog</receiver>
|
||||||
|
<slot>accept()</slot>
|
||||||
|
<hints>
|
||||||
|
<hint type="sourcelabel">
|
||||||
|
<x>248</x>
|
||||||
|
<y>254</y>
|
||||||
|
</hint>
|
||||||
|
<hint type="destinationlabel">
|
||||||
|
<x>157</x>
|
||||||
|
<y>274</y>
|
||||||
|
</hint>
|
||||||
|
</hints>
|
||||||
|
</connection>
|
||||||
|
<connection>
|
||||||
|
<sender>buttonBox</sender>
|
||||||
|
<signal>rejected()</signal>
|
||||||
|
<receiver>AboutDialog</receiver>
|
||||||
|
<slot>reject()</slot>
|
||||||
|
<hints>
|
||||||
|
<hint type="sourcelabel">
|
||||||
|
<x>316</x>
|
||||||
|
<y>260</y>
|
||||||
|
</hint>
|
||||||
|
<hint type="destinationlabel">
|
||||||
|
<x>286</x>
|
||||||
|
<y>274</y>
|
||||||
|
</hint>
|
||||||
|
</hints>
|
||||||
|
</connection>
|
||||||
|
</connections>
|
||||||
|
</ui>
|
844
pcmanfm/application.cpp
Normal file
844
pcmanfm/application.cpp
Normal file
@ -0,0 +1,844 @@
|
|||||||
|
/*
|
||||||
|
|
||||||
|
Copyright (C) 2013 Hong Jen Yee (PCMan) <pcman.tw@gmail.com>
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation; either version 2 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License along
|
||||||
|
with this program; if not, write to the Free Software Foundation, Inc.,
|
||||||
|
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#include "application.h"
|
||||||
|
#include "mainwindow.h"
|
||||||
|
#include "desktopwindow.h"
|
||||||
|
#include <QDBusConnection>
|
||||||
|
#include <QDBusInterface>
|
||||||
|
#include <QDir>
|
||||||
|
#include <QDesktopWidget>
|
||||||
|
#include <QVector>
|
||||||
|
#include <QLocale>
|
||||||
|
#include <QLibraryInfo>
|
||||||
|
#include <QPixmapCache>
|
||||||
|
#include <QFile>
|
||||||
|
#include <QMessageBox>
|
||||||
|
#include <QCommandLineParser>
|
||||||
|
#include <QSocketNotifier>
|
||||||
|
#include <gio/gio.h>
|
||||||
|
#include <sys/socket.h>
|
||||||
|
|
||||||
|
#include "applicationadaptor.h"
|
||||||
|
#include "preferencesdialog.h"
|
||||||
|
#include "desktoppreferencesdialog.h"
|
||||||
|
#include <libfm-qt/mountoperation.h>
|
||||||
|
#include "autorundialog.h"
|
||||||
|
#include "launcher.h"
|
||||||
|
#include <libfm-qt/filesearchdialog.h>
|
||||||
|
|
||||||
|
#include <QScreen>
|
||||||
|
#include <QWindow>
|
||||||
|
|
||||||
|
#include <X11/Xlib.h>
|
||||||
|
|
||||||
|
#include "xdgdir.h"
|
||||||
|
#include <QFileSystemWatcher>
|
||||||
|
|
||||||
|
namespace PCManFM {
|
||||||
|
|
||||||
|
static const char* serviceName = "org.pcmanfm.PCManFM";
|
||||||
|
static const char* ifaceName = "org.pcmanfm.Application";
|
||||||
|
|
||||||
|
int ProxyStyle::styleHint(StyleHint hint, const QStyleOption* option, const QWidget* widget, QStyleHintReturn* returnData) const {
|
||||||
|
Application* app = static_cast<Application*>(qApp);
|
||||||
|
if(hint == QStyle::SH_ItemView_ActivateItemOnSingleClick)
|
||||||
|
return app->settings().singleClick();
|
||||||
|
return QProxyStyle::styleHint(hint, option, widget, returnData);
|
||||||
|
}
|
||||||
|
|
||||||
|
Application::Application(int& argc, char** argv):
|
||||||
|
QApplication(argc, argv),
|
||||||
|
libFm_(),
|
||||||
|
settings_(),
|
||||||
|
profileName_("default"),
|
||||||
|
daemonMode_(false),
|
||||||
|
desktopWindows_(),
|
||||||
|
enableDesktopManager_(false),
|
||||||
|
preferencesDialog_(),
|
||||||
|
volumeMonitor_(NULL),
|
||||||
|
userDirsWatcher_(NULL),
|
||||||
|
lxqtRunning_(false),
|
||||||
|
editBookmarksialog_() {
|
||||||
|
|
||||||
|
argc_ = argc;
|
||||||
|
argv_ = argv;
|
||||||
|
|
||||||
|
setApplicationVersion(PCMANFM_QT_VERSION);
|
||||||
|
|
||||||
|
// QDBusConnection::sessionBus().registerObject("/org/pcmanfm/Application", this);
|
||||||
|
QDBusConnection dbus = QDBusConnection::sessionBus();
|
||||||
|
if(dbus.registerService(serviceName)) {
|
||||||
|
// we successfully registered the service
|
||||||
|
isPrimaryInstance = true;
|
||||||
|
setStyle(new ProxyStyle());
|
||||||
|
desktop()->installEventFilter(this);
|
||||||
|
|
||||||
|
new ApplicationAdaptor(this);
|
||||||
|
dbus.registerObject("/Application", this);
|
||||||
|
|
||||||
|
connect(this, &Application::aboutToQuit, this, &Application::onAboutToQuit);
|
||||||
|
// aboutToQuit() is not signalled on SIGTERM, install signal handler
|
||||||
|
installSigtermHandler();
|
||||||
|
settings_.load(profileName_);
|
||||||
|
|
||||||
|
// decrease the cache size to reduce memory usage
|
||||||
|
QPixmapCache::setCacheLimit(2048);
|
||||||
|
|
||||||
|
if(settings_.useFallbackIconTheme()) {
|
||||||
|
QIcon::setThemeName(settings_.fallbackIconThemeName());
|
||||||
|
Fm::IconTheme::checkChanged();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check if LXQt Session is running. LXQt has it's own Desktop Folder
|
||||||
|
// editor. We just hide our editor when LXQt is running.
|
||||||
|
QDBusInterface* lxqtSessionIface = new QDBusInterface(
|
||||||
|
QStringLiteral("org.lxqt.session"),
|
||||||
|
QStringLiteral("/LXQtSession"));
|
||||||
|
if (lxqtSessionIface) {
|
||||||
|
if (lxqtSessionIface->isValid()) {
|
||||||
|
lxqtRunning_ = true;
|
||||||
|
userDesktopFolder_ = XdgDir::readDesktopDir();
|
||||||
|
initWatch();
|
||||||
|
}
|
||||||
|
delete lxqtSessionIface;
|
||||||
|
lxqtSessionIface = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
// an service of the same name is already registered.
|
||||||
|
// we're not the first instance
|
||||||
|
isPrimaryInstance = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Application::~Application() {
|
||||||
|
desktop()->removeEventFilter(this);
|
||||||
|
|
||||||
|
if(volumeMonitor_) {
|
||||||
|
g_signal_handlers_disconnect_by_func(volumeMonitor_, gpointer(onVolumeAdded), this);
|
||||||
|
g_object_unref(volumeMonitor_);
|
||||||
|
}
|
||||||
|
|
||||||
|
// if(enableDesktopManager_)
|
||||||
|
// removeNativeEventFilter(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Application::initWatch()
|
||||||
|
{
|
||||||
|
QFile file_ (QStandardPaths::writableLocation(QStandardPaths::ConfigLocation) + QStringLiteral("/user-dirs.dirs"));
|
||||||
|
if(! file_.open(QIODevice::ReadOnly | QIODevice::Text)) {
|
||||||
|
qDebug() << Q_FUNC_INFO << "Could not read: " << userDirsFile_;
|
||||||
|
userDirsFile_ = QString();
|
||||||
|
} else {
|
||||||
|
userDirsFile_ = file_.fileName();
|
||||||
|
}
|
||||||
|
|
||||||
|
userDirsWatcher_ = new QFileSystemWatcher(this);
|
||||||
|
userDirsWatcher_->addPath(userDirsFile_);
|
||||||
|
connect(userDirsWatcher_, &QFileSystemWatcher::fileChanged, this, &Application::onUserDirsChanged);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Application::parseCommandLineArgs() {
|
||||||
|
bool keepRunning = false;
|
||||||
|
QCommandLineParser parser;
|
||||||
|
parser.addHelpOption();
|
||||||
|
parser.addVersionOption();
|
||||||
|
|
||||||
|
QCommandLineOption profileOption(QStringList() << "p" << "profile", tr("Name of configuration profile"), tr("PROFILE"));
|
||||||
|
parser.addOption(profileOption);
|
||||||
|
|
||||||
|
QCommandLineOption daemonOption(QStringList() << "d" << "daemon-mode", tr("Run PCManFM as a daemon"));
|
||||||
|
parser.addOption(daemonOption);
|
||||||
|
|
||||||
|
QCommandLineOption quitOption(QStringList() << "q" << "quit", tr("Quit PCManFM"));
|
||||||
|
parser.addOption(quitOption);
|
||||||
|
|
||||||
|
QCommandLineOption desktopOption("desktop", tr("Launch desktop manager"));
|
||||||
|
parser.addOption(desktopOption);
|
||||||
|
|
||||||
|
QCommandLineOption desktopOffOption("desktop-off", tr("Turn off desktop manager if it's running"));
|
||||||
|
parser.addOption(desktopOffOption);
|
||||||
|
|
||||||
|
QCommandLineOption desktopPrefOption("desktop-pref", tr("Open desktop preference dialog on the page with the specified name"), tr("NAME"));
|
||||||
|
parser.addOption(desktopPrefOption);
|
||||||
|
|
||||||
|
QCommandLineOption newWindowOption(QStringList() << "n" << "new-window", tr("Open new window"));
|
||||||
|
parser.addOption(newWindowOption);
|
||||||
|
|
||||||
|
QCommandLineOption findFilesOption(QStringList() << "f" << "find-files", tr("Open Find Files utility"));
|
||||||
|
parser.addOption(findFilesOption);
|
||||||
|
|
||||||
|
QCommandLineOption setWallpaperOption(QStringList() << "w" << "set-wallpaper", tr("Set desktop wallpaper from image FILE"), tr("FILE"));
|
||||||
|
parser.addOption(setWallpaperOption);
|
||||||
|
|
||||||
|
QCommandLineOption wallpaperModeOption("wallpaper-mode", tr("Set mode of desktop wallpaper. MODE=(%1)").arg("color|stretch|fit|center|tile"), tr("MODE"));
|
||||||
|
parser.addOption(wallpaperModeOption);
|
||||||
|
|
||||||
|
QCommandLineOption showPrefOption("show-pref", tr("Open Preferences dialog on the page with the specified name"), tr("NAME"));
|
||||||
|
parser.addOption(showPrefOption);
|
||||||
|
|
||||||
|
parser.addPositionalArgument("files", tr("Files or directories to open"), tr("[FILE1, FILE2,...]"));
|
||||||
|
|
||||||
|
parser.process(arguments());
|
||||||
|
|
||||||
|
if(isPrimaryInstance) {
|
||||||
|
qDebug("isPrimaryInstance");
|
||||||
|
|
||||||
|
if(parser.isSet(daemonOption))
|
||||||
|
daemonMode_ = true;
|
||||||
|
if(parser.isSet(profileOption))
|
||||||
|
profileName_ = parser.value(profileOption);
|
||||||
|
|
||||||
|
// load settings
|
||||||
|
settings_.load(profileName_);
|
||||||
|
|
||||||
|
// desktop icon management
|
||||||
|
if(parser.isSet(desktopOption)) {
|
||||||
|
desktopManager(true);
|
||||||
|
keepRunning = true;
|
||||||
|
}
|
||||||
|
else if(parser.isSet(desktopOffOption))
|
||||||
|
desktopManager(false);
|
||||||
|
|
||||||
|
if(parser.isSet(desktopPrefOption)) { // desktop preference dialog
|
||||||
|
desktopPrefrences(parser.value(desktopPrefOption));
|
||||||
|
keepRunning = true;
|
||||||
|
}
|
||||||
|
else if(parser.isSet(findFilesOption)) { // file searching utility
|
||||||
|
findFiles(parser.positionalArguments());
|
||||||
|
keepRunning = true;
|
||||||
|
}
|
||||||
|
else if(parser.isSet(showPrefOption)) { // preferences dialog
|
||||||
|
preferences(parser.value(showPrefOption));
|
||||||
|
keepRunning = true;
|
||||||
|
}
|
||||||
|
else if(parser.isSet(setWallpaperOption) || parser.isSet(wallpaperModeOption)) // set wall paper
|
||||||
|
setWallpaper(parser.value(setWallpaperOption), parser.value(wallpaperModeOption));
|
||||||
|
else {
|
||||||
|
if(!parser.isSet(desktopOption) && !parser.isSet(desktopOffOption)) {
|
||||||
|
QStringList paths = parser.positionalArguments();
|
||||||
|
if(paths.isEmpty()) {
|
||||||
|
// if no path is specified and we're using daemon mode,
|
||||||
|
// don't open current working directory
|
||||||
|
if(!daemonMode_)
|
||||||
|
paths.push_back(QDir::currentPath());
|
||||||
|
}
|
||||||
|
if(!paths.isEmpty())
|
||||||
|
launchFiles(QDir::currentPath(), paths, parser.isSet(newWindowOption));
|
||||||
|
keepRunning = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
QDBusConnection dbus = QDBusConnection::sessionBus();
|
||||||
|
QDBusInterface iface(serviceName, "/Application", ifaceName, dbus, this);
|
||||||
|
if(parser.isSet(quitOption)) {
|
||||||
|
iface.call("quit");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(parser.isSet(desktopOption))
|
||||||
|
iface.call("desktopManager", true);
|
||||||
|
else if(parser.isSet(desktopOffOption))
|
||||||
|
iface.call("desktopManager", false);
|
||||||
|
|
||||||
|
if(parser.isSet(desktopPrefOption)) { // desktop preference dialog
|
||||||
|
iface.call("desktopPrefrences", parser.value(desktopPrefOption));
|
||||||
|
}
|
||||||
|
else if(parser.isSet(findFilesOption)) { // file searching utility
|
||||||
|
iface.call("findFiles", parser.positionalArguments());
|
||||||
|
}
|
||||||
|
else if(parser.isSet(showPrefOption)) { // preferences dialog
|
||||||
|
iface.call("preferences", parser.value(showPrefOption));
|
||||||
|
}
|
||||||
|
else if(parser.isSet(setWallpaperOption) || parser.isSet(wallpaperModeOption)) { // set wall paper
|
||||||
|
iface.call("setWallpaper", parser.value(setWallpaperOption), parser.value(wallpaperModeOption));
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if(!parser.isSet(desktopOption) && !parser.isSet(desktopOffOption)) {
|
||||||
|
QStringList paths = parser.positionalArguments();
|
||||||
|
if(paths.isEmpty()) {
|
||||||
|
paths.push_back(QDir::currentPath());
|
||||||
|
}
|
||||||
|
iface.call("launchFiles", QDir::currentPath(), paths, parser.isSet(newWindowOption));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return keepRunning;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Application::init() {
|
||||||
|
|
||||||
|
// install the translations built-into Qt itself
|
||||||
|
qtTranslator.load("qt_" + QLocale::system().name(), QLibraryInfo::location(QLibraryInfo::TranslationsPath));
|
||||||
|
installTranslator(&qtTranslator);
|
||||||
|
|
||||||
|
// install libfm-qt translator
|
||||||
|
installTranslator(libFm_.translator());
|
||||||
|
|
||||||
|
// install our own tranlations
|
||||||
|
translator.load("pcmanfm-qt_" + QLocale::system().name(), PCMANFM_DATA_DIR "/translations");
|
||||||
|
installTranslator(&translator);
|
||||||
|
}
|
||||||
|
|
||||||
|
int Application::exec() {
|
||||||
|
|
||||||
|
if(!parseCommandLineArgs())
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if(daemonMode_) // keep running even when there is no window opened.
|
||||||
|
setQuitOnLastWindowClosed(false);
|
||||||
|
|
||||||
|
volumeMonitor_ = g_volume_monitor_get();
|
||||||
|
// delay the volume manager a little because in newer versions of glib/gio there's a problem.
|
||||||
|
// when the first volume monitor object is created, it discovers volumes asynchonously.
|
||||||
|
// g_volume_monitor_get() immediately returns while the monitor is still discovering devices.
|
||||||
|
// So initially g_volume_monitor_get_volumes() returns nothing, but shortly after that
|
||||||
|
// we get volume-added signals for all of the volumes. This is not what we want.
|
||||||
|
// So, we wait for 3 seconds here to let it finish device discovery.
|
||||||
|
QTimer::singleShot(3000, this, SLOT(initVolumeManager()));
|
||||||
|
|
||||||
|
return QCoreApplication::exec();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Application::onUserDirsChanged()
|
||||||
|
{
|
||||||
|
qDebug() << Q_FUNC_INFO;
|
||||||
|
bool file_deleted = !userDirsWatcher_->files().contains(userDirsFile_);
|
||||||
|
if(file_deleted) {
|
||||||
|
// if our config file is already deleted, reinstall a new watcher
|
||||||
|
userDirsWatcher_->addPath(userDirsFile_);
|
||||||
|
}
|
||||||
|
|
||||||
|
const QString d = XdgDir::readDesktopDir();
|
||||||
|
if (d != userDesktopFolder_) {
|
||||||
|
userDesktopFolder_ = d;
|
||||||
|
const QDir dir(d);
|
||||||
|
if (dir.exists()) {
|
||||||
|
const int N = desktopWindows_.size();
|
||||||
|
for(int i = 0; i < N; ++i) {
|
||||||
|
desktopWindows_.at(i)->setDesktopFolder();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
qWarning("Application::onUserDirsChanged: %s doesn't exist",
|
||||||
|
userDesktopFolder_.toUtf8().constData());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Application::onAboutToQuit() {
|
||||||
|
qDebug("aboutToQuit");
|
||||||
|
settings_.save();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Application::eventFilter(QObject* watched, QEvent* event) {
|
||||||
|
if(watched == desktop()) {
|
||||||
|
switch(event->type()) {
|
||||||
|
case QEvent::StyleChange:
|
||||||
|
case QEvent::ThemeChange:
|
||||||
|
setStyle(new ProxyStyle());
|
||||||
|
};
|
||||||
|
}
|
||||||
|
return QObject::eventFilter(watched, event);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Application::onLastWindowClosed() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void Application::onSaveStateRequest(QSessionManager& manager) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void Application::desktopManager(bool enabled) {
|
||||||
|
// TODO: turn on or turn off desktpo management (desktop icons & wallpaper)
|
||||||
|
qDebug("desktopManager: %d", enabled);
|
||||||
|
QDesktopWidget* desktopWidget = desktop();
|
||||||
|
if(enabled) {
|
||||||
|
if(!enableDesktopManager_) {
|
||||||
|
// installNativeEventFilter(this);
|
||||||
|
Q_FOREACH(QScreen* screen, screens()) {
|
||||||
|
connect(screen, &QScreen::virtualGeometryChanged, this, &Application::onVirtualGeometryChanged);
|
||||||
|
connect(screen, &QObject::destroyed, this, &Application::onScreenDestroyed);
|
||||||
|
}
|
||||||
|
connect(this, &QApplication::screenAdded, this, &Application::onScreenAdded);
|
||||||
|
connect(desktopWidget, &QDesktopWidget::resized, this, &Application::onScreenResized);
|
||||||
|
connect(desktopWidget, &QDesktopWidget::screenCountChanged, this, &Application::onScreenCountChanged);
|
||||||
|
|
||||||
|
// NOTE: there are two modes
|
||||||
|
// When virtual desktop is used (all screens are combined to form a large virtual desktop),
|
||||||
|
// we only create one DesktopWindow. Otherwise, we create one for each screen.
|
||||||
|
if(desktopWidget->isVirtualDesktop()) {
|
||||||
|
DesktopWindow* window = createDesktopWindow(-1);
|
||||||
|
desktopWindows_.push_back(window);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
int n = desktopWidget->numScreens();
|
||||||
|
desktopWindows_.reserve(n);
|
||||||
|
for(int i = 0; i < n; ++i) {
|
||||||
|
DesktopWindow* window = createDesktopWindow(i);
|
||||||
|
desktopWindows_.push_back(window);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if(enableDesktopManager_) {
|
||||||
|
disconnect(desktopWidget, &QDesktopWidget::resized, this, &Application::onScreenResized);
|
||||||
|
disconnect(desktopWidget, &QDesktopWidget::screenCountChanged, this, &Application::onScreenCountChanged);
|
||||||
|
int n = desktopWindows_.size();
|
||||||
|
for(int i = 0; i < n; ++i) {
|
||||||
|
DesktopWindow* window = desktopWindows_.at(i);
|
||||||
|
delete window;
|
||||||
|
}
|
||||||
|
desktopWindows_.clear();
|
||||||
|
Q_FOREACH(QScreen* screen, screens()) {
|
||||||
|
disconnect(screen, &QScreen::virtualGeometryChanged, this, &Application::onVirtualGeometryChanged);
|
||||||
|
disconnect(screen, &QObject::destroyed, this, &Application::onScreenDestroyed);
|
||||||
|
}
|
||||||
|
disconnect(this, &QApplication::screenAdded, this, &Application::onScreenAdded);
|
||||||
|
// removeNativeEventFilter(this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
enableDesktopManager_ = enabled;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Application::desktopPrefrences(QString page) {
|
||||||
|
// show desktop preference window
|
||||||
|
if(!desktopPreferencesDialog_) {
|
||||||
|
desktopPreferencesDialog_ = new DesktopPreferencesDialog();
|
||||||
|
|
||||||
|
// Should be used only one time
|
||||||
|
desktopPreferencesDialog_->setEditDesktopFolder(!lxqtRunning_);
|
||||||
|
}
|
||||||
|
desktopPreferencesDialog_.data()->selectPage(page);
|
||||||
|
desktopPreferencesDialog_.data()->show();
|
||||||
|
desktopPreferencesDialog_.data()->raise();
|
||||||
|
desktopPreferencesDialog_.data()->activateWindow();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Application::onFindFileAccepted() {
|
||||||
|
Fm::FileSearchDialog* dlg = static_cast<Fm::FileSearchDialog*>(sender());
|
||||||
|
Fm::Path uri = dlg->searchUri();
|
||||||
|
// FIXME: we should be able to open it in an existing window
|
||||||
|
FmPathList* paths = fm_path_list_new();
|
||||||
|
fm_path_list_push_tail(paths, uri.data());
|
||||||
|
Launcher(NULL).launchPaths(NULL, paths);
|
||||||
|
fm_path_list_unref(paths);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Application::findFiles(QStringList paths) {
|
||||||
|
// launch file searching utility.
|
||||||
|
Fm::FileSearchDialog* dlg = new Fm::FileSearchDialog(paths);
|
||||||
|
connect(dlg, &QDialog::accepted, this, &Application::onFindFileAccepted);
|
||||||
|
dlg->setAttribute(Qt::WA_DeleteOnClose);
|
||||||
|
dlg->show();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Application::launchFiles(QString cwd, QStringList paths, bool inNewWindow) {
|
||||||
|
FmPathList* pathList = fm_path_list_new();
|
||||||
|
FmPath* cwd_path = NULL;
|
||||||
|
QStringList::iterator it;
|
||||||
|
Q_FOREACH(const QString& it, paths) {
|
||||||
|
QByteArray pathName = it.toLocal8Bit();
|
||||||
|
FmPath* path = NULL;
|
||||||
|
if(pathName[0] == '/') // absolute path
|
||||||
|
path = fm_path_new_for_path(pathName.constData());
|
||||||
|
else if(pathName.contains(":/")) // URI
|
||||||
|
path = fm_path_new_for_uri(pathName.constData());
|
||||||
|
else if(pathName == "~") // special case for home dir
|
||||||
|
path = fm_path_ref(fm_path_get_home());
|
||||||
|
else // basename
|
||||||
|
{
|
||||||
|
if(Q_UNLIKELY(!cwd_path))
|
||||||
|
cwd_path = fm_path_new_for_str(cwd.toLocal8Bit().constData());
|
||||||
|
path = fm_path_new_relative(cwd_path, pathName.constData());
|
||||||
|
}
|
||||||
|
fm_path_list_push_tail(pathList, path);
|
||||||
|
fm_path_unref(path);
|
||||||
|
}
|
||||||
|
if(cwd_path)
|
||||||
|
fm_path_unref(cwd_path);
|
||||||
|
|
||||||
|
Launcher(NULL).launchPaths(NULL, pathList);
|
||||||
|
fm_path_list_unref(pathList);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Application::openFolders(FmFileInfoList* files) {
|
||||||
|
Launcher(NULL).launchFiles(NULL, files);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Application::openFolderInTerminal(FmPath* path) {
|
||||||
|
if(!settings_.terminal().isEmpty()) {
|
||||||
|
char* cwd_str;
|
||||||
|
if(fm_path_is_native(path))
|
||||||
|
cwd_str = fm_path_to_str(path);
|
||||||
|
else { // gio will map remote filesystems to local FUSE-mounted paths here.
|
||||||
|
GFile* gf = fm_path_to_gfile(path);
|
||||||
|
cwd_str = g_file_get_path(gf);
|
||||||
|
g_object_unref(gf);
|
||||||
|
}
|
||||||
|
GError* err = NULL;
|
||||||
|
if(!fm_terminal_launch(cwd_str, &err)) {
|
||||||
|
QMessageBox::critical(NULL, tr("Error"), QString::fromUtf8(err->message));
|
||||||
|
g_error_free(err);
|
||||||
|
}
|
||||||
|
g_free(cwd_str);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
// show an error message and ask the user to set the command
|
||||||
|
QMessageBox::critical(NULL, tr("Error"), tr("Terminal emulator is not set."));
|
||||||
|
preferences("advanced");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Application::preferences(QString page) {
|
||||||
|
// open preference dialog
|
||||||
|
if(!preferencesDialog_) {
|
||||||
|
preferencesDialog_ = new PreferencesDialog(page);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
preferencesDialog_.data()->selectPage(page);
|
||||||
|
}
|
||||||
|
preferencesDialog_.data()->show();
|
||||||
|
preferencesDialog_.data()->raise();
|
||||||
|
preferencesDialog_.data()->activateWindow();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Application::setWallpaper(QString path, QString modeString) {
|
||||||
|
static const char* valid_wallpaper_modes[] = {"color", "stretch", "fit", "center", "tile"};
|
||||||
|
DesktopWindow::WallpaperMode mode = settings_.wallpaperMode();
|
||||||
|
bool changed = false;
|
||||||
|
|
||||||
|
if(!path.isEmpty() && path != settings_.wallpaper()) {
|
||||||
|
if(QFile(path).exists()) {
|
||||||
|
settings_.setWallpaper(path);
|
||||||
|
changed = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// convert mode string to value
|
||||||
|
for(int i = 0; i < G_N_ELEMENTS(valid_wallpaper_modes); ++i) {
|
||||||
|
if(modeString == valid_wallpaper_modes[i]) {
|
||||||
|
mode = (DesktopWindow::WallpaperMode)i;
|
||||||
|
if(mode != settings_.wallpaperMode())
|
||||||
|
changed = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// FIXME: support different wallpapers on different screen.
|
||||||
|
// update wallpaper
|
||||||
|
if(changed) {
|
||||||
|
if(enableDesktopManager_) {
|
||||||
|
Q_FOREACH(DesktopWindow * desktopWindow, desktopWindows_) {
|
||||||
|
if(!path.isEmpty())
|
||||||
|
desktopWindow->setWallpaperFile(path);
|
||||||
|
if(mode != settings_.wallpaperMode())
|
||||||
|
desktopWindow->setWallpaperMode(mode);
|
||||||
|
desktopWindow->updateWallpaper();
|
||||||
|
}
|
||||||
|
settings_.save(); // save the settings to the config file
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Application::onScreenResized(int num) {
|
||||||
|
if(desktop()->isVirtualDesktop()) {
|
||||||
|
// in virtual desktop mode, we only have one desktop window. that is the first one.
|
||||||
|
DesktopWindow* window = desktopWindows_.at(0);
|
||||||
|
window->setGeometry(desktop()->geometry());
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
DesktopWindow* window = desktopWindows_.at(num);
|
||||||
|
QRect rect = desktop()->screenGeometry(num);
|
||||||
|
window->setGeometry(rect);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
DesktopWindow* Application::createDesktopWindow(int screenNum) {
|
||||||
|
DesktopWindow* window = new DesktopWindow(screenNum);
|
||||||
|
if(screenNum == -1) { // one large virtual desktop only
|
||||||
|
QRect rect = desktop()->geometry();
|
||||||
|
window->setGeometry(rect);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
QRect rect = desktop()->screenGeometry(screenNum);
|
||||||
|
window->setGeometry(rect);
|
||||||
|
}
|
||||||
|
window->updateFromSettings(settings_);
|
||||||
|
window->show();
|
||||||
|
return window;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Application::onScreenCountChanged(int newCount) {
|
||||||
|
QDesktopWidget* desktopWidget = desktop();
|
||||||
|
bool oldVirtual = (desktopWindows_.size() == 1 && desktopWindows_.at(0)->screenNum() == -1);
|
||||||
|
bool isVirtual = desktopWidget->isVirtualDesktop();
|
||||||
|
|
||||||
|
if(oldVirtual && isVirtual) {
|
||||||
|
// if we are using virtual desktop mode previously, and the new mode is sitll virtual
|
||||||
|
// no further change is needed, only do relayout.
|
||||||
|
desktopWindows_.at(0)->queueRelayout();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// we used non-virtual mode originally, but now we're switched to virtual mode
|
||||||
|
if(isVirtual)
|
||||||
|
newCount = 1; // we only want one desktop window for all screens in virtual mode
|
||||||
|
|
||||||
|
if(newCount > desktopWindows_.size()) {
|
||||||
|
// add more desktop windows
|
||||||
|
for(int i = desktopWindows_.size(); i < newCount; ++i) {
|
||||||
|
DesktopWindow* desktop = createDesktopWindow(i);
|
||||||
|
desktopWindows_.push_back(desktop);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if(newCount < desktopWindows_.size()) {
|
||||||
|
// delete excessive desktop windows
|
||||||
|
for(int i = newCount; i < desktopWindows_.size(); ++i) {
|
||||||
|
DesktopWindow* desktop = desktopWindows_.at(i);
|
||||||
|
delete desktop;
|
||||||
|
}
|
||||||
|
desktopWindows_.resize(newCount);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(newCount == 1) { // now only 1 screen is in use
|
||||||
|
DesktopWindow* desktop = desktopWindows_.at(0);
|
||||||
|
if(isVirtual)
|
||||||
|
desktop->setScreenNum(-1);
|
||||||
|
else // non-virtual mode, and we only have 1 screen
|
||||||
|
desktop->setScreenNum(0);
|
||||||
|
desktop->updateWallpaper();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// called when Settings is changed to update UI
|
||||||
|
void Application::updateFromSettings() {
|
||||||
|
// if(iconTheme.isEmpty())
|
||||||
|
// Fm::IconTheme::setThemeName(settings_.fallbackIconThemeName());
|
||||||
|
|
||||||
|
// update main windows and desktop windows
|
||||||
|
QWidgetList windows = this->topLevelWidgets();
|
||||||
|
QWidgetList::iterator it;
|
||||||
|
for(it = windows.begin(); it != windows.end(); ++it) {
|
||||||
|
QWidget* window = *it;
|
||||||
|
if(window->inherits("PCManFM::MainWindow")) {
|
||||||
|
MainWindow* mainWindow = static_cast<MainWindow*>(window);
|
||||||
|
mainWindow->updateFromSettings(settings_);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(desktopManagerEnabled())
|
||||||
|
updateDesktopsFromSettings();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Application::updateDesktopsFromSettings() {
|
||||||
|
QVector<DesktopWindow*>::iterator it;
|
||||||
|
for(it = desktopWindows_.begin(); it != desktopWindows_.end(); ++it) {
|
||||||
|
DesktopWindow* desktopWindow = static_cast<DesktopWindow*>(*it);
|
||||||
|
desktopWindow->updateFromSettings(settings_);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Application::editBookmarks() {
|
||||||
|
if(!editBookmarksialog_) {
|
||||||
|
FmBookmarks* bookmarks = fm_bookmarks_dup();
|
||||||
|
editBookmarksialog_ = new Fm::EditBookmarksDialog(bookmarks);
|
||||||
|
g_object_unref(bookmarks);
|
||||||
|
}
|
||||||
|
editBookmarksialog_.data()->show();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Application::initVolumeManager() {
|
||||||
|
|
||||||
|
g_signal_connect(volumeMonitor_, "volume-added", G_CALLBACK(onVolumeAdded), this);
|
||||||
|
|
||||||
|
if(settings_.mountOnStartup()) {
|
||||||
|
/* try to automount all volumes */
|
||||||
|
GList* vols = g_volume_monitor_get_volumes(volumeMonitor_);
|
||||||
|
for(GList* l = vols; l; l = l->next) {
|
||||||
|
GVolume* volume = G_VOLUME(l->data);
|
||||||
|
if(g_volume_should_automount(volume))
|
||||||
|
autoMountVolume(volume, false);
|
||||||
|
g_object_unref(volume);
|
||||||
|
}
|
||||||
|
g_list_free(vols);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Application::autoMountVolume(GVolume* volume, bool interactive) {
|
||||||
|
if(!g_volume_should_automount(volume) || !g_volume_can_mount(volume))
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
GMount* mount = g_volume_get_mount(volume);
|
||||||
|
if(!mount) { // not mounted, automount is needed
|
||||||
|
// try automount
|
||||||
|
Fm::MountOperation* op = new Fm::MountOperation(interactive);
|
||||||
|
op->mount(volume);
|
||||||
|
if(!op->wait())
|
||||||
|
return false;
|
||||||
|
if(!interactive)
|
||||||
|
return true;
|
||||||
|
mount = g_volume_get_mount(volume);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(mount) {
|
||||||
|
if(interactive && settings_.autoRun()) { // show autorun dialog
|
||||||
|
AutoRunDialog* dlg = new AutoRunDialog(volume, mount);
|
||||||
|
dlg->show();
|
||||||
|
}
|
||||||
|
g_object_unref(mount);
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// static
|
||||||
|
void Application::onVolumeAdded(GVolumeMonitor* monitor, GVolume* volume, Application* pThis) {
|
||||||
|
if(pThis->settings_.mountRemovable())
|
||||||
|
pThis->autoMountVolume(volume, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
bool Application::nativeEventFilter(const QByteArray & eventType, void * message, long * result) {
|
||||||
|
if(eventType == "xcb_generic_event_t") { // XCB event
|
||||||
|
// filter all native X11 events (xcb)
|
||||||
|
xcb_generic_event_t* generic_event = reinterpret_cast<xcb_generic_event_t*>(message);
|
||||||
|
// qDebug("XCB event: %d", generic_event->response_type & ~0x80);
|
||||||
|
Q_FOREACH(DesktopWindow * window, desktopWindows_) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
void Application::onScreenAdded(QScreen* newScreen) {
|
||||||
|
if(enableDesktopManager_) {
|
||||||
|
connect(newScreen, &QScreen::virtualGeometryChanged, this, &Application::onVirtualGeometryChanged);
|
||||||
|
connect(newScreen, &QObject::destroyed, this, &Application::onScreenDestroyed);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Application::onScreenDestroyed(QObject* screenObj) {
|
||||||
|
// NOTE by PCMan: This is a workaround for Qt 5 bug #40681.
|
||||||
|
// With this very dirty workaround, we can fix lxde/lxde-qt bug #204, #205, and #206.
|
||||||
|
// Qt 5 has two new regression bugs which breaks lxqt-panel in a multihead environment.
|
||||||
|
// #40681: Regression bug: QWidget::winId() returns old value and QEvent::WinIdChange event is not emitted sometimes. (multihead setup)
|
||||||
|
// #40791: Regression: QPlatformWindow, QWindow, and QWidget::winId() are out of sync.
|
||||||
|
// Explanations for the workaround:
|
||||||
|
// Internally, Qt mantains a list of QScreens and update it when XRandR configuration changes.
|
||||||
|
// When the user turn off an monitor with xrandr --output <xxx> --off, this will destroy the QScreen
|
||||||
|
// object which represent the output. If the QScreen being destroyed contains our panel widget,
|
||||||
|
// Qt will call QWindow::setScreen(0) on the internal windowHandle() of our panel widget to move it
|
||||||
|
// to the primary screen. However, moving a window to a different screen is more than just changing
|
||||||
|
// its position. With XRandR, all screens are actually part of the same virtual desktop. However,
|
||||||
|
// this is not the case in other setups, such as Xinerama and moving a window to another screen is
|
||||||
|
// not possible unless you destroy the widget and create it again for a new screen.
|
||||||
|
// Therefore, Qt destroy the widget and re-create it when moving our panel to a new screen.
|
||||||
|
// Unfortunately, destroying the window also destroy the child windows embedded into it,
|
||||||
|
// using XEMBED such as the tray icons. (#206)
|
||||||
|
// Second, when the window is re-created, the winId of the QWidget is changed, but Qt failed to
|
||||||
|
// generate QEvent::WinIdChange event so we have no way to know that. We have to set
|
||||||
|
// some X11 window properties using the native winId() to make it a dock, but this stop working
|
||||||
|
// because we cannot get the correct winId(), so this causes #204 and #205.
|
||||||
|
//
|
||||||
|
// The workaround is very simple. Just completely destroy the window before Qt has a chance to do
|
||||||
|
// QWindow::setScreen() for it. Later, we recreate the window ourselves. So this can bypassing the Qt bugs.
|
||||||
|
if(enableDesktopManager_) {
|
||||||
|
bool reloadNeeded = false;
|
||||||
|
// FIXME: add workarounds for Qt5 bug #40681 and #40791 here.
|
||||||
|
Q_FOREACH(DesktopWindow* desktop, desktopWindows_) {
|
||||||
|
if(desktop->windowHandle()->screen() == screenObj) {
|
||||||
|
desktop->destroy(); // destroy the underlying native window
|
||||||
|
reloadNeeded = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(reloadNeeded)
|
||||||
|
QTimer::singleShot(0, this, SLOT(reloadDesktopsAsNeeded()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Application::reloadDesktopsAsNeeded() {
|
||||||
|
if(enableDesktopManager_) {
|
||||||
|
// workarounds for Qt5 bug #40681 and #40791 here.
|
||||||
|
Q_FOREACH(DesktopWindow* desktop, desktopWindows_) {
|
||||||
|
if(!desktop->windowHandle()) {
|
||||||
|
desktop->create(); // re-create the underlying native window
|
||||||
|
desktop->queueRelayout();
|
||||||
|
desktop->show();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// This slot is for Qt 5 onlt, but the stupid Qt moc cannot do conditional compilation
|
||||||
|
// so we have to define it for Qt 4 as well.
|
||||||
|
void Application::onVirtualGeometryChanged(const QRect& rect) {
|
||||||
|
// NOTE: the following is a workaround for Qt bug 32567.
|
||||||
|
// https://bugreports.qt-project.org/browse/QTBUG-32567
|
||||||
|
// Though the status of the bug report is closed, it's not yet fixed for X11.
|
||||||
|
// In theory, QDesktopWidget should emit "workAreaResized()" signal when the work area
|
||||||
|
// of any screen is changed, but in fact it does not do it.
|
||||||
|
// However, QScreen provided since Qt5 does not have the bug and
|
||||||
|
// virtualGeometryChanged() is emitted correctly when the workAreas changed.
|
||||||
|
// So we use it in Qt5.
|
||||||
|
if(enableDesktopManager_) {
|
||||||
|
// qDebug() << "onVirtualGeometryChanged";
|
||||||
|
Q_FOREACH(DesktopWindow* desktop, desktopWindows_) {
|
||||||
|
desktop->queueRelayout();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int sigterm_fd[2];
|
||||||
|
|
||||||
|
static void sigtermHandler(int) {
|
||||||
|
char c = 1;
|
||||||
|
::write(sigterm_fd[0], &c, sizeof(c));
|
||||||
|
}
|
||||||
|
|
||||||
|
void Application::installSigtermHandler() {
|
||||||
|
if(::socketpair(AF_UNIX, SOCK_STREAM, 0, sigterm_fd) == 0) {
|
||||||
|
QSocketNotifier* notifier = new QSocketNotifier(sigterm_fd[1], QSocketNotifier::Read, this);
|
||||||
|
connect(notifier, &QSocketNotifier::activated, this, &Application::onSigtermNotified);
|
||||||
|
|
||||||
|
struct sigaction action;
|
||||||
|
action.sa_handler = sigtermHandler;
|
||||||
|
::sigemptyset(&action.sa_mask);
|
||||||
|
action.sa_flags = SA_RESTART;
|
||||||
|
if(::sigaction(SIGTERM, &action, 0) != 0) {
|
||||||
|
qWarning("Couldn't install SIGTERM handler");
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
qWarning("Couldn't create SIGTERM socketpair");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Application::onSigtermNotified() {
|
||||||
|
if (QSocketNotifier* notifier = qobject_cast<QSocketNotifier*>(sender())) {
|
||||||
|
notifier->setEnabled(false);
|
||||||
|
char c;
|
||||||
|
::read(sigterm_fd[1], &c, sizeof(c));
|
||||||
|
quit();
|
||||||
|
notifier->setEnabled(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace PCManFM
|
151
pcmanfm/application.h
Normal file
151
pcmanfm/application.h
Normal file
@ -0,0 +1,151 @@
|
|||||||
|
/*
|
||||||
|
|
||||||
|
Copyright (C) 2013 Hong Jen Yee (PCMan) <pcman.tw@gmail.com>
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation; either version 2 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License along
|
||||||
|
with this program; if not, write to the Free Software Foundation, Inc.,
|
||||||
|
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef PCMANFM_APPLICATION_H
|
||||||
|
#define PCMANFM_APPLICATION_H
|
||||||
|
|
||||||
|
#include <QApplication>
|
||||||
|
#include "settings.h"
|
||||||
|
#include <libfm-qt/libfmqt.h>
|
||||||
|
#include <libfm-qt/editbookmarksdialog.h>
|
||||||
|
#include <QVector>
|
||||||
|
#include <QPointer>
|
||||||
|
#include <QProxyStyle>
|
||||||
|
#include <QTranslator>
|
||||||
|
#include <gio/gio.h>
|
||||||
|
|
||||||
|
class QScreen;
|
||||||
|
|
||||||
|
class QFileSystemWatcher;
|
||||||
|
|
||||||
|
namespace PCManFM {
|
||||||
|
|
||||||
|
class DesktopWindow;
|
||||||
|
class PreferencesDialog;
|
||||||
|
class DesktopPreferencesDialog;
|
||||||
|
|
||||||
|
class ProxyStyle: public QProxyStyle {
|
||||||
|
Q_OBJECT
|
||||||
|
public:
|
||||||
|
ProxyStyle() : QProxyStyle() {}
|
||||||
|
virtual ~ProxyStyle() {}
|
||||||
|
virtual int styleHint(StyleHint hint, const QStyleOption * option = 0, const QWidget * widget = 0, QStyleHintReturn * returnData = 0) const;
|
||||||
|
};
|
||||||
|
|
||||||
|
class Application : public QApplication {
|
||||||
|
Q_OBJECT
|
||||||
|
Q_PROPERTY(bool desktopManagerEnabled READ desktopManagerEnabled)
|
||||||
|
|
||||||
|
public:
|
||||||
|
Application(int& argc, char** argv);
|
||||||
|
virtual ~Application();
|
||||||
|
|
||||||
|
void init();
|
||||||
|
int exec();
|
||||||
|
|
||||||
|
Settings& settings() {
|
||||||
|
return settings_;
|
||||||
|
}
|
||||||
|
|
||||||
|
Fm::LibFmQt& libFm() {
|
||||||
|
return libFm_;
|
||||||
|
}
|
||||||
|
|
||||||
|
// public interface exported via dbus
|
||||||
|
void launchFiles(QString cwd, QStringList paths, bool inNewWindow);
|
||||||
|
void setWallpaper(QString path, QString modeString);
|
||||||
|
void preferences(QString page);
|
||||||
|
void desktopPrefrences(QString page);
|
||||||
|
void editBookmarks();
|
||||||
|
void desktopManager(bool enabled);
|
||||||
|
void findFiles(QStringList paths = QStringList());
|
||||||
|
|
||||||
|
bool desktopManagerEnabled() {
|
||||||
|
return enableDesktopManager_;
|
||||||
|
}
|
||||||
|
|
||||||
|
void updateFromSettings();
|
||||||
|
void updateDesktopsFromSettings();
|
||||||
|
|
||||||
|
void openFolderInTerminal(FmPath* path);
|
||||||
|
void openFolders(FmFileInfoList* files);
|
||||||
|
|
||||||
|
QString profileName() {
|
||||||
|
return profileName_;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected Q_SLOTS:
|
||||||
|
void onAboutToQuit();
|
||||||
|
void onSigtermNotified();
|
||||||
|
|
||||||
|
void onLastWindowClosed();
|
||||||
|
void onSaveStateRequest(QSessionManager & manager);
|
||||||
|
void onScreenResized(int num);
|
||||||
|
void onScreenCountChanged(int newCount);
|
||||||
|
void initVolumeManager();
|
||||||
|
|
||||||
|
void onVirtualGeometryChanged(const QRect& rect);
|
||||||
|
void onScreenDestroyed(QObject* screenObj);
|
||||||
|
void onScreenAdded(QScreen* newScreen);
|
||||||
|
void reloadDesktopsAsNeeded();
|
||||||
|
|
||||||
|
void onFindFileAccepted();
|
||||||
|
|
||||||
|
protected:
|
||||||
|
virtual bool eventFilter(QObject* watched, QEvent* event);
|
||||||
|
bool parseCommandLineArgs();
|
||||||
|
DesktopWindow* createDesktopWindow(int screenNum);
|
||||||
|
bool autoMountVolume(GVolume* volume, bool interactive = true);
|
||||||
|
|
||||||
|
static void onVolumeAdded(GVolumeMonitor* monitor, GVolume* volume, Application* pThis);
|
||||||
|
|
||||||
|
private Q_SLOTS:
|
||||||
|
void onUserDirsChanged();
|
||||||
|
|
||||||
|
private:
|
||||||
|
void initWatch();
|
||||||
|
void installSigtermHandler();
|
||||||
|
|
||||||
|
bool isPrimaryInstance;
|
||||||
|
Fm::LibFmQt libFm_;
|
||||||
|
Settings settings_;
|
||||||
|
QString profileName_;
|
||||||
|
bool daemonMode_;
|
||||||
|
bool enableDesktopManager_;
|
||||||
|
QVector<DesktopWindow*> desktopWindows_;
|
||||||
|
QPointer<PreferencesDialog> preferencesDialog_;
|
||||||
|
QPointer<DesktopPreferencesDialog> desktopPreferencesDialog_;
|
||||||
|
QPointer<Fm::EditBookmarksDialog> editBookmarksialog_;
|
||||||
|
QTranslator translator;
|
||||||
|
QTranslator qtTranslator;
|
||||||
|
GVolumeMonitor* volumeMonitor_;
|
||||||
|
|
||||||
|
QFileSystemWatcher *userDirsWatcher_;
|
||||||
|
QString userDirsFile_;
|
||||||
|
QString userDesktopFolder_;
|
||||||
|
bool lxqtRunning_;
|
||||||
|
|
||||||
|
int argc_;
|
||||||
|
char** argv_;
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // PCMANFM_APPLICATION_H
|
117
pcmanfm/autorun.ui
Normal file
117
pcmanfm/autorun.ui
Normal file
@ -0,0 +1,117 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<ui version="4.0">
|
||||||
|
<class>AutoRunDialog</class>
|
||||||
|
<widget class="QDialog" name="AutoRunDialog">
|
||||||
|
<property name="geometry">
|
||||||
|
<rect>
|
||||||
|
<x>0</x>
|
||||||
|
<y>0</y>
|
||||||
|
<width>334</width>
|
||||||
|
<height>312</height>
|
||||||
|
</rect>
|
||||||
|
</property>
|
||||||
|
<property name="windowTitle">
|
||||||
|
<string>Removable medium is inserted</string>
|
||||||
|
</property>
|
||||||
|
<property name="windowIcon">
|
||||||
|
<iconset theme="drive-removable-media">
|
||||||
|
<normaloff>../../../.designer/backup</normaloff>../../../.designer/backup</iconset>
|
||||||
|
</property>
|
||||||
|
<layout class="QFormLayout" name="formLayout_2">
|
||||||
|
<item row="0" column="0">
|
||||||
|
<widget class="QLabel" name="icon">
|
||||||
|
<property name="text">
|
||||||
|
<string/>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="0" column="1">
|
||||||
|
<layout class="QFormLayout" name="formLayout">
|
||||||
|
<item row="0" column="0" colspan="2">
|
||||||
|
<widget class="QLabel" name="label">
|
||||||
|
<property name="text">
|
||||||
|
<string><b>Removable medium is inserted</b></string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="1" column="0">
|
||||||
|
<widget class="QLabel" name="label_2">
|
||||||
|
<property name="text">
|
||||||
|
<string>Type of medium:</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="1" column="1">
|
||||||
|
<widget class="QLabel" name="mediumType">
|
||||||
|
<property name="text">
|
||||||
|
<string>Detecting...</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</item>
|
||||||
|
<item row="1" column="0" colspan="2">
|
||||||
|
<widget class="QLabel" name="label_3">
|
||||||
|
<property name="text">
|
||||||
|
<string>Please select the action you want to perform:</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="2" column="0" colspan="2">
|
||||||
|
<widget class="QListWidget" name="listWidget">
|
||||||
|
<property name="sizePolicy">
|
||||||
|
<sizepolicy hsizetype="Expanding" vsizetype="Expanding">
|
||||||
|
<horstretch>0</horstretch>
|
||||||
|
<verstretch>1</verstretch>
|
||||||
|
</sizepolicy>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="3" column="0" colspan="2">
|
||||||
|
<widget class="QDialogButtonBox" name="buttonBox">
|
||||||
|
<property name="orientation">
|
||||||
|
<enum>Qt::Horizontal</enum>
|
||||||
|
</property>
|
||||||
|
<property name="standardButtons">
|
||||||
|
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
<resources/>
|
||||||
|
<connections>
|
||||||
|
<connection>
|
||||||
|
<sender>buttonBox</sender>
|
||||||
|
<signal>accepted()</signal>
|
||||||
|
<receiver>AutoRunDialog</receiver>
|
||||||
|
<slot>accept()</slot>
|
||||||
|
<hints>
|
||||||
|
<hint type="sourcelabel">
|
||||||
|
<x>248</x>
|
||||||
|
<y>254</y>
|
||||||
|
</hint>
|
||||||
|
<hint type="destinationlabel">
|
||||||
|
<x>157</x>
|
||||||
|
<y>274</y>
|
||||||
|
</hint>
|
||||||
|
</hints>
|
||||||
|
</connection>
|
||||||
|
<connection>
|
||||||
|
<sender>buttonBox</sender>
|
||||||
|
<signal>rejected()</signal>
|
||||||
|
<receiver>AutoRunDialog</receiver>
|
||||||
|
<slot>reject()</slot>
|
||||||
|
<hints>
|
||||||
|
<hint type="sourcelabel">
|
||||||
|
<x>316</x>
|
||||||
|
<y>260</y>
|
||||||
|
</hint>
|
||||||
|
<hint type="destinationlabel">
|
||||||
|
<x>286</x>
|
||||||
|
<y>274</y>
|
||||||
|
</hint>
|
||||||
|
</hints>
|
||||||
|
</connection>
|
||||||
|
</connections>
|
||||||
|
</ui>
|
139
pcmanfm/autorundialog.cpp
Normal file
139
pcmanfm/autorundialog.cpp
Normal file
@ -0,0 +1,139 @@
|
|||||||
|
/*
|
||||||
|
|
||||||
|
Copyright (C) 2013 Hong Jen Yee (PCMan) <pcman.tw@gmail.com>
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation; either version 2 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License along
|
||||||
|
with this program; if not, write to the Free Software Foundation, Inc.,
|
||||||
|
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#include "autorundialog.h"
|
||||||
|
#include <libfm-qt/icontheme.h>
|
||||||
|
#include <QListWidgetItem>
|
||||||
|
#include "application.h"
|
||||||
|
#include "mainwindow.h"
|
||||||
|
|
||||||
|
namespace PCManFM {
|
||||||
|
|
||||||
|
AutoRunDialog::AutoRunDialog(GVolume* volume, GMount* mount, QWidget* parent, Qt::WindowFlags f):
|
||||||
|
cancellable(g_cancellable_new()),
|
||||||
|
applications(NULL),
|
||||||
|
mount_(G_MOUNT(g_object_ref(mount))),
|
||||||
|
QDialog(parent, f) {
|
||||||
|
|
||||||
|
setAttribute(Qt::WA_DeleteOnClose);
|
||||||
|
ui.setupUi(this);
|
||||||
|
|
||||||
|
GIcon* gicon = g_volume_get_icon(volume);
|
||||||
|
QIcon icon = Fm::IconTheme::icon(gicon);
|
||||||
|
ui.icon->setPixmap(icon.pixmap(QSize(48, 48)));
|
||||||
|
|
||||||
|
// add actions
|
||||||
|
QListWidgetItem* item = new QListWidgetItem(QIcon::fromTheme("system-file-manager"), tr("Open in file manager"));
|
||||||
|
ui.listWidget->addItem(item);
|
||||||
|
|
||||||
|
g_mount_guess_content_type(mount, TRUE, cancellable, (GAsyncReadyCallback)onContentTypeFinished, this);
|
||||||
|
}
|
||||||
|
|
||||||
|
AutoRunDialog::~AutoRunDialog() {
|
||||||
|
g_list_foreach(applications, (GFunc)g_object_unref, NULL);
|
||||||
|
g_list_free(applications);
|
||||||
|
|
||||||
|
if(mount_)
|
||||||
|
g_object_unref(mount_);
|
||||||
|
|
||||||
|
if(cancellable) {
|
||||||
|
g_cancellable_cancel(cancellable);
|
||||||
|
g_object_unref(cancellable);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void AutoRunDialog::accept() {
|
||||||
|
QListWidgetItem* item = ui.listWidget->selectedItems().first();
|
||||||
|
if(item) {
|
||||||
|
GFile* gf = g_mount_get_root(mount_);
|
||||||
|
void* p = item->data(Qt::UserRole).value<void*>();
|
||||||
|
if(p) { // run the selected application
|
||||||
|
GAppInfo* app = G_APP_INFO(p);
|
||||||
|
GList* filelist = g_list_prepend(NULL, gf);
|
||||||
|
g_app_info_launch(app, filelist, NULL, NULL);
|
||||||
|
g_list_free(filelist);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
// the default action, open the mounted folder in the file manager
|
||||||
|
Application* app = static_cast<Application*>(qApp);
|
||||||
|
Settings& settings = app->settings();
|
||||||
|
FmPath* path = fm_path_new_for_gfile(gf);
|
||||||
|
// open the path in a new window
|
||||||
|
// FIXME: or should we open it in a new tab? Make this optional later
|
||||||
|
MainWindow* win = new MainWindow(path);
|
||||||
|
fm_path_unref(path);
|
||||||
|
win->resize(settings.windowWidth(), settings.windowHeight());
|
||||||
|
if(settings.windowMaximized()) {
|
||||||
|
win->setWindowState(win->windowState() | Qt::WindowMaximized);
|
||||||
|
}
|
||||||
|
win->show();
|
||||||
|
}
|
||||||
|
g_object_unref(gf);
|
||||||
|
}
|
||||||
|
QDialog::accept();
|
||||||
|
}
|
||||||
|
|
||||||
|
// static
|
||||||
|
void AutoRunDialog::onContentTypeFinished(GMount* mount, GAsyncResult* res, AutoRunDialog* pThis) {
|
||||||
|
if(pThis->cancellable) {
|
||||||
|
g_object_unref(pThis->cancellable);
|
||||||
|
pThis->cancellable = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
char** types = g_mount_guess_content_type_finish(mount, res, NULL);
|
||||||
|
char* desc = NULL;
|
||||||
|
|
||||||
|
if(types) {
|
||||||
|
if(types[0]) {
|
||||||
|
for(char** type = types; *type; ++type) {
|
||||||
|
GList* l = g_app_info_get_all_for_type(*type);
|
||||||
|
if(l)
|
||||||
|
pThis->applications = g_list_concat(pThis->applications, l);
|
||||||
|
}
|
||||||
|
desc = g_content_type_get_description(types[0]);
|
||||||
|
}
|
||||||
|
g_strfreev(types);
|
||||||
|
|
||||||
|
if(pThis->applications) {
|
||||||
|
int pos = 0;
|
||||||
|
for(GList* l = pThis->applications; l; l = l->next, ++pos) {
|
||||||
|
GAppInfo* app = G_APP_INFO(l->data);
|
||||||
|
GIcon* gicon = g_app_info_get_icon(app);
|
||||||
|
QIcon icon = Fm::IconTheme::icon(gicon);
|
||||||
|
QString text = QString::fromUtf8(g_app_info_get_name(app));
|
||||||
|
QListWidgetItem* item = new QListWidgetItem(icon, text);
|
||||||
|
item->setData(Qt::UserRole, qVariantFromValue<void*>(app));
|
||||||
|
pThis->ui.listWidget->insertItem(pos, item);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(desc) {
|
||||||
|
pThis->ui.mediumType->setText(QString::fromUtf8(desc));
|
||||||
|
g_free(desc);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
pThis->ui.mediumType->setText(tr("Removable Disk"));
|
||||||
|
|
||||||
|
// select the first item
|
||||||
|
pThis->ui.listWidget->item(0)->setSelected(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace PCManFM
|
54
pcmanfm/autorundialog.h
Normal file
54
pcmanfm/autorundialog.h
Normal file
@ -0,0 +1,54 @@
|
|||||||
|
/*
|
||||||
|
|
||||||
|
Copyright (C) 2013 Hong Jen Yee (PCMan) <pcman.tw@gmail.com>
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation; either version 2 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License along
|
||||||
|
with this program; if not, write to the Free Software Foundation, Inc.,
|
||||||
|
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef PCMANFM_AUTORUNDIALOG_H
|
||||||
|
#define PCMANFM_AUTORUNDIALOG_H
|
||||||
|
|
||||||
|
#include <QDialog>
|
||||||
|
#include "ui_autorun.h"
|
||||||
|
#include <gio/gio.h>
|
||||||
|
|
||||||
|
namespace PCManFM {
|
||||||
|
|
||||||
|
class AutoRunDialog : public QDialog {
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
explicit AutoRunDialog(GVolume* volume, GMount* mount, QWidget* parent = 0, Qt::WindowFlags f = 0);
|
||||||
|
virtual ~AutoRunDialog();
|
||||||
|
|
||||||
|
virtual void accept();
|
||||||
|
|
||||||
|
private Q_SLOTS:
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
static void onContentTypeFinished(GMount* mount, GAsyncResult* res, AutoRunDialog* pThis);
|
||||||
|
|
||||||
|
private:
|
||||||
|
Ui::AutoRunDialog ui;
|
||||||
|
GCancellable* cancellable;
|
||||||
|
GList* applications;
|
||||||
|
GMount* mount_;
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // PCMANFM_AUTORUNDIALOG_H
|
60
pcmanfm/desktop-folder.ui
Normal file
60
pcmanfm/desktop-folder.ui
Normal file
@ -0,0 +1,60 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<ui version="4.0">
|
||||||
|
<class>DesktopFolder</class>
|
||||||
|
<widget class="QWidget" name="DesktopFolder">
|
||||||
|
<property name="geometry">
|
||||||
|
<rect>
|
||||||
|
<x>0</x>
|
||||||
|
<y>0</y>
|
||||||
|
<width>352</width>
|
||||||
|
<height>81</height>
|
||||||
|
</rect>
|
||||||
|
</property>
|
||||||
|
<property name="windowTitle">
|
||||||
|
<string>Form</string>
|
||||||
|
</property>
|
||||||
|
<layout class="QVBoxLayout" name="verticalLayout">
|
||||||
|
<item>
|
||||||
|
<widget class="QGroupBox" name="groupBox_3">
|
||||||
|
<property name="enabled">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
<property name="title">
|
||||||
|
<string>Desktop</string>
|
||||||
|
</property>
|
||||||
|
<layout class="QHBoxLayout" name="horizontalLayout_4">
|
||||||
|
<item>
|
||||||
|
<widget class="QLabel" name="label_7">
|
||||||
|
<property name="text">
|
||||||
|
<string>Desktop folder:</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QLineEdit" name="desktopFolder">
|
||||||
|
<property name="toolTip">
|
||||||
|
<string>Image file</string>
|
||||||
|
</property>
|
||||||
|
<property name="statusTip">
|
||||||
|
<string/>
|
||||||
|
</property>
|
||||||
|
<property name="placeholderText">
|
||||||
|
<string>Folder path</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QPushButton" name="browseDesktopFolder">
|
||||||
|
<property name="text">
|
||||||
|
<string>&Browse</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
<resources/>
|
||||||
|
<connections/>
|
||||||
|
</ui>
|
391
pcmanfm/desktop-preferences.ui
Normal file
391
pcmanfm/desktop-preferences.ui
Normal file
@ -0,0 +1,391 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<ui version="4.0">
|
||||||
|
<class>DesktopPreferencesDialog</class>
|
||||||
|
<widget class="QDialog" name="DesktopPreferencesDialog">
|
||||||
|
<property name="geometry">
|
||||||
|
<rect>
|
||||||
|
<x>0</x>
|
||||||
|
<y>0</y>
|
||||||
|
<width>534</width>
|
||||||
|
<height>434</height>
|
||||||
|
</rect>
|
||||||
|
</property>
|
||||||
|
<property name="windowTitle">
|
||||||
|
<string>Desktop Preferences</string>
|
||||||
|
</property>
|
||||||
|
<layout class="QVBoxLayout" name="verticalLayout">
|
||||||
|
<item>
|
||||||
|
<widget class="QTabWidget" name="tabWidget">
|
||||||
|
<property name="currentIndex">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<widget class="QWidget" name="generalPage">
|
||||||
|
<attribute name="title">
|
||||||
|
<string>General</string>
|
||||||
|
</attribute>
|
||||||
|
<layout class="QVBoxLayout" name="verticalLayout_2">
|
||||||
|
<item>
|
||||||
|
<widget class="QGroupBox" name="groupBox_2">
|
||||||
|
<property name="title">
|
||||||
|
<string>Background</string>
|
||||||
|
</property>
|
||||||
|
<layout class="QGridLayout" name="gridLayout">
|
||||||
|
<item row="2" column="1" colspan="2">
|
||||||
|
<widget class="QComboBox" name="wallpaperMode">
|
||||||
|
<property name="sizePolicy">
|
||||||
|
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Fixed">
|
||||||
|
<horstretch>0</horstretch>
|
||||||
|
<verstretch>0</verstretch>
|
||||||
|
</sizepolicy>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="2" column="0">
|
||||||
|
<widget class="QLabel" name="label">
|
||||||
|
<property name="sizePolicy">
|
||||||
|
<sizepolicy hsizetype="Fixed" vsizetype="Preferred">
|
||||||
|
<horstretch>0</horstretch>
|
||||||
|
<verstretch>0</verstretch>
|
||||||
|
</sizepolicy>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>Wallpaper mode:</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="3" column="0">
|
||||||
|
<widget class="QLabel" name="label_6">
|
||||||
|
<property name="sizePolicy">
|
||||||
|
<sizepolicy hsizetype="Expanding" vsizetype="Preferred">
|
||||||
|
<horstretch>0</horstretch>
|
||||||
|
<verstretch>0</verstretch>
|
||||||
|
</sizepolicy>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>Wallpaper image file:</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="5" column="1">
|
||||||
|
<widget class="Fm::ColorButton" name="backgroundColor">
|
||||||
|
<property name="sizePolicy">
|
||||||
|
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
|
||||||
|
<horstretch>0</horstretch>
|
||||||
|
<verstretch>0</verstretch>
|
||||||
|
</sizepolicy>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string/>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="5" column="0">
|
||||||
|
<widget class="QLabel" name="label_5">
|
||||||
|
<property name="text">
|
||||||
|
<string>Select background color:</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="4" column="0" colspan="3">
|
||||||
|
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||||
|
<item>
|
||||||
|
<widget class="QLineEdit" name="imageFile">
|
||||||
|
<property name="toolTip">
|
||||||
|
<string>Image file</string>
|
||||||
|
</property>
|
||||||
|
<property name="statusTip">
|
||||||
|
<string/>
|
||||||
|
</property>
|
||||||
|
<property name="placeholderText">
|
||||||
|
<string>Image file path</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QPushButton" name="browse">
|
||||||
|
<property name="text">
|
||||||
|
<string>&Browse</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QGroupBox" name="groupBox">
|
||||||
|
<property name="title">
|
||||||
|
<string>Label Text</string>
|
||||||
|
</property>
|
||||||
|
<layout class="QGridLayout" name="gridLayout_2">
|
||||||
|
<item row="1" column="1">
|
||||||
|
<widget class="Fm::ColorButton" name="textColor">
|
||||||
|
<property name="sizePolicy">
|
||||||
|
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
|
||||||
|
<horstretch>0</horstretch>
|
||||||
|
<verstretch>0</verstretch>
|
||||||
|
</sizepolicy>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string/>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="3" column="1">
|
||||||
|
<widget class="Fm::ColorButton" name="shadowColor">
|
||||||
|
<property name="sizePolicy">
|
||||||
|
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
|
||||||
|
<horstretch>0</horstretch>
|
||||||
|
<verstretch>0</verstretch>
|
||||||
|
</sizepolicy>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string/>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="1" column="0">
|
||||||
|
<widget class="QLabel" name="label_3">
|
||||||
|
<property name="sizePolicy">
|
||||||
|
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
|
||||||
|
<horstretch>0</horstretch>
|
||||||
|
<verstretch>0</verstretch>
|
||||||
|
</sizepolicy>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>Select text color:</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="3" column="0">
|
||||||
|
<widget class="QLabel" name="label_4">
|
||||||
|
<property name="sizePolicy">
|
||||||
|
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
|
||||||
|
<horstretch>0</horstretch>
|
||||||
|
<verstretch>0</verstretch>
|
||||||
|
</sizepolicy>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>Select shadow color:</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="0" column="0">
|
||||||
|
<widget class="QLabel" name="label_2">
|
||||||
|
<property name="sizePolicy">
|
||||||
|
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
|
||||||
|
<horstretch>0</horstretch>
|
||||||
|
<verstretch>0</verstretch>
|
||||||
|
</sizepolicy>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>Select font:</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="0" column="1">
|
||||||
|
<widget class="Fm::FontButton" name="font">
|
||||||
|
<property name="sizePolicy">
|
||||||
|
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
|
||||||
|
<horstretch>0</horstretch>
|
||||||
|
<verstretch>0</verstretch>
|
||||||
|
</sizepolicy>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string/>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QGroupBox" name="groupBox_3">
|
||||||
|
<property name="title">
|
||||||
|
<string>Spacing</string>
|
||||||
|
</property>
|
||||||
|
<layout class="QGridLayout" name="gridLayout_3">
|
||||||
|
<item row="0" column="0">
|
||||||
|
<widget class="QLabel" name="label_7">
|
||||||
|
<property name="text">
|
||||||
|
<string>Minimum item margins:</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="0" column="1">
|
||||||
|
<widget class="QSpinBox" name="hMargin">
|
||||||
|
<property name="toolTip">
|
||||||
|
<string>3 px by default.</string>
|
||||||
|
</property>
|
||||||
|
<property name="suffix">
|
||||||
|
<string> px</string>
|
||||||
|
</property>
|
||||||
|
<property name="maximum">
|
||||||
|
<number>48</number>
|
||||||
|
</property>
|
||||||
|
<property name="value">
|
||||||
|
<number>3</number>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="0" column="2">
|
||||||
|
<widget class="QLabel" name="label_8">
|
||||||
|
<property name="text">
|
||||||
|
<string>x</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="0" column="3">
|
||||||
|
<widget class="QSpinBox" name="vMargin">
|
||||||
|
<property name="toolTip">
|
||||||
|
<string>1 px by default.
|
||||||
|
A space is also reserved for 3 lines of text.</string>
|
||||||
|
</property>
|
||||||
|
<property name="suffix">
|
||||||
|
<string> px</string>
|
||||||
|
</property>
|
||||||
|
<property name="maximum">
|
||||||
|
<number>48</number>
|
||||||
|
</property>
|
||||||
|
<property name="value">
|
||||||
|
<number>1</number>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="0" column="4">
|
||||||
|
<widget class="QCheckBox" name="lockMargins">
|
||||||
|
<property name="text">
|
||||||
|
<string>Lock</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="0" column="5">
|
||||||
|
<spacer name="horizontalSpacer">
|
||||||
|
<property name="orientation">
|
||||||
|
<enum>Qt::Horizontal</enum>
|
||||||
|
</property>
|
||||||
|
<property name="sizeHint" stdset="0">
|
||||||
|
<size>
|
||||||
|
<width>20</width>
|
||||||
|
<height>5</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
</spacer>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<spacer name="verticalSpacer_2">
|
||||||
|
<property name="orientation">
|
||||||
|
<enum>Qt::Vertical</enum>
|
||||||
|
</property>
|
||||||
|
<property name="sizeHint" stdset="0">
|
||||||
|
<size>
|
||||||
|
<width>20</width>
|
||||||
|
<height>10</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
</spacer>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
<widget class="QWidget" name="advancedPage">
|
||||||
|
<attribute name="title">
|
||||||
|
<string>Advanced</string>
|
||||||
|
</attribute>
|
||||||
|
<layout class="QVBoxLayout" name="advancedPageLayout">
|
||||||
|
<item>
|
||||||
|
<widget class="QGroupBox" name="groupBox_4">
|
||||||
|
<property name="title">
|
||||||
|
<string>Window Manager</string>
|
||||||
|
</property>
|
||||||
|
<layout class="QHBoxLayout" name="horizontalLayout_3">
|
||||||
|
<item>
|
||||||
|
<widget class="QCheckBox" name="showWmMenu">
|
||||||
|
<property name="text">
|
||||||
|
<string>Show menus provided by window managers when desktop is clicked</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<spacer name="verticalSpacer">
|
||||||
|
<property name="orientation">
|
||||||
|
<enum>Qt::Vertical</enum>
|
||||||
|
</property>
|
||||||
|
<property name="sizeHint" stdset="0">
|
||||||
|
<size>
|
||||||
|
<width>20</width>
|
||||||
|
<height>40</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
</spacer>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QDialogButtonBox" name="buttonBox">
|
||||||
|
<property name="orientation">
|
||||||
|
<enum>Qt::Horizontal</enum>
|
||||||
|
</property>
|
||||||
|
<property name="standardButtons">
|
||||||
|
<set>QDialogButtonBox::Apply|QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
<customwidgets>
|
||||||
|
<customwidget>
|
||||||
|
<class>Fm::ColorButton</class>
|
||||||
|
<extends>QPushButton</extends>
|
||||||
|
<header location="global">libfm-qt/colorbutton.h</header>
|
||||||
|
</customwidget>
|
||||||
|
<customwidget>
|
||||||
|
<class>Fm::FontButton</class>
|
||||||
|
<extends>QPushButton</extends>
|
||||||
|
<header location="global">libfm-qt/fontbutton.h</header>
|
||||||
|
</customwidget>
|
||||||
|
</customwidgets>
|
||||||
|
<resources/>
|
||||||
|
<connections>
|
||||||
|
<connection>
|
||||||
|
<sender>buttonBox</sender>
|
||||||
|
<signal>accepted()</signal>
|
||||||
|
<receiver>DesktopPreferencesDialog</receiver>
|
||||||
|
<slot>accept()</slot>
|
||||||
|
<hints>
|
||||||
|
<hint type="sourcelabel">
|
||||||
|
<x>248</x>
|
||||||
|
<y>254</y>
|
||||||
|
</hint>
|
||||||
|
<hint type="destinationlabel">
|
||||||
|
<x>157</x>
|
||||||
|
<y>274</y>
|
||||||
|
</hint>
|
||||||
|
</hints>
|
||||||
|
</connection>
|
||||||
|
<connection>
|
||||||
|
<sender>buttonBox</sender>
|
||||||
|
<signal>rejected()</signal>
|
||||||
|
<receiver>DesktopPreferencesDialog</receiver>
|
||||||
|
<slot>reject()</slot>
|
||||||
|
<hints>
|
||||||
|
<hint type="sourcelabel">
|
||||||
|
<x>316</x>
|
||||||
|
<y>260</y>
|
||||||
|
</hint>
|
||||||
|
<hint type="destinationlabel">
|
||||||
|
<x>286</x>
|
||||||
|
<y>274</y>
|
||||||
|
</hint>
|
||||||
|
</hints>
|
||||||
|
</connection>
|
||||||
|
</connections>
|
||||||
|
</ui>
|
206
pcmanfm/desktopitemdelegate.cpp
Normal file
206
pcmanfm/desktopitemdelegate.cpp
Normal file
@ -0,0 +1,206 @@
|
|||||||
|
/*
|
||||||
|
|
||||||
|
Copyright (C) 2013 Hong Jen Yee (PCMan) <pcman.tw@gmail.com>
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation; either version 2 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License along
|
||||||
|
with this program; if not, write to the Free Software Foundation, Inc.,
|
||||||
|
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#include "desktopitemdelegate.h"
|
||||||
|
#include <libfm-qt/foldermodel.h>
|
||||||
|
#include <QApplication>
|
||||||
|
#include <QListView>
|
||||||
|
#include <QPainter>
|
||||||
|
#include <QIcon>
|
||||||
|
#include <QTextLayout>
|
||||||
|
#include <QTextOption>
|
||||||
|
#include <QTextLine>
|
||||||
|
|
||||||
|
namespace PCManFM {
|
||||||
|
|
||||||
|
DesktopItemDelegate::DesktopItemDelegate(QListView* view, QObject* parent):
|
||||||
|
QStyledItemDelegate(parent ? parent : view),
|
||||||
|
view_(view),
|
||||||
|
symlinkIcon_(QIcon::fromTheme("emblem-symbolic-link")),
|
||||||
|
shadowColor_(0, 0, 0),
|
||||||
|
margins_(QSize(3, 3)) {
|
||||||
|
}
|
||||||
|
|
||||||
|
// FIXME: we need to figure out a way to derive from Fm::FolderItemDelegate to avoid code duplication.
|
||||||
|
void DesktopItemDelegate::paint(QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index) const {
|
||||||
|
Q_ASSERT(index.isValid());
|
||||||
|
QStyleOptionViewItemV4 opt = option;
|
||||||
|
initStyleOption(&opt, index);
|
||||||
|
|
||||||
|
painter->save();
|
||||||
|
painter->setClipRect(option.rect);
|
||||||
|
|
||||||
|
opt.decorationAlignment = Qt::AlignHCenter | Qt::AlignTop;
|
||||||
|
opt.displayAlignment = Qt::AlignTop | Qt::AlignHCenter;
|
||||||
|
|
||||||
|
// draw the icon
|
||||||
|
QIcon::Mode iconMode;
|
||||||
|
if(opt.state & QStyle::State_Enabled) {
|
||||||
|
if(opt.state & QStyle::State_Selected)
|
||||||
|
iconMode = QIcon::Selected;
|
||||||
|
else {
|
||||||
|
iconMode = QIcon::Normal;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
iconMode = QIcon::Disabled;
|
||||||
|
QPoint iconPos(opt.rect.x() + (opt.rect.width() - opt.decorationSize.width()) / 2, opt.rect.y());
|
||||||
|
QPixmap pixmap = opt.icon.pixmap(opt.decorationSize, iconMode);
|
||||||
|
painter->drawPixmap(iconPos, pixmap);
|
||||||
|
|
||||||
|
// draw some emblems for the item if needed
|
||||||
|
// we only support symlink emblem at the moment
|
||||||
|
FmFileInfo* file = static_cast<FmFileInfo*>(index.data(Fm::FolderModel::FileInfoRole).value<void*>());
|
||||||
|
if(file) {
|
||||||
|
if(fm_file_info_is_symlink(file)) {
|
||||||
|
painter->drawPixmap(iconPos, symlinkIcon_.pixmap(opt.decorationSize / 2, iconMode));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// draw text
|
||||||
|
QSize gridSize = view_->gridSize() - 2 * margins_;
|
||||||
|
QRectF textRect(opt.rect.x() - (gridSize.width() - opt.rect.width()) / 2,
|
||||||
|
opt.rect.y() + opt.decorationSize.height(),
|
||||||
|
gridSize.width(),
|
||||||
|
gridSize.height() - opt.decorationSize.height());
|
||||||
|
drawText(painter, opt, textRect);
|
||||||
|
|
||||||
|
if(opt.state & QStyle::State_HasFocus) {
|
||||||
|
// FIXME: draw focus rect
|
||||||
|
}
|
||||||
|
painter->restore();
|
||||||
|
}
|
||||||
|
|
||||||
|
void DesktopItemDelegate::drawText(QPainter* painter, QStyleOptionViewItemV4& opt, QRectF& textRect) const {
|
||||||
|
QTextLayout layout(opt.text, opt.font);
|
||||||
|
|
||||||
|
QTextOption textOption;
|
||||||
|
textOption.setAlignment(opt.displayAlignment);
|
||||||
|
textOption.setWrapMode(QTextOption::WrapAtWordBoundaryOrAnywhere);
|
||||||
|
textOption.setTextDirection(opt.direction);
|
||||||
|
layout.setTextOption(textOption);
|
||||||
|
qreal height = 0;
|
||||||
|
qreal width = 0;
|
||||||
|
int visibleLines = 0;
|
||||||
|
layout.beginLayout();
|
||||||
|
QString elidedText;
|
||||||
|
textRect.adjust(2, 2, -2, -2); // a 2-px margin is considered at FolderView::updateGridSize()
|
||||||
|
for(;;) {
|
||||||
|
QTextLine line = layout.createLine();
|
||||||
|
if(!line.isValid())
|
||||||
|
break;
|
||||||
|
line.setLineWidth(textRect.width());
|
||||||
|
height += opt.fontMetrics.leading();
|
||||||
|
line.setPosition(QPointF(0, height));
|
||||||
|
if((height + line.height() + textRect.y()) > textRect.bottom()) {
|
||||||
|
// if part of this line falls outside the textRect, ignore it and quit.
|
||||||
|
QTextLine lastLine = layout.lineAt(visibleLines - 1);
|
||||||
|
elidedText = opt.text.mid(lastLine.textStart());
|
||||||
|
elidedText = opt.fontMetrics.elidedText(elidedText, opt.textElideMode, textRect.width());
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
height += line.height();
|
||||||
|
width = qMax(width, line.naturalTextWidth());
|
||||||
|
++ visibleLines;
|
||||||
|
}
|
||||||
|
layout.endLayout();
|
||||||
|
width = qMax(width, (qreal)opt.fontMetrics.width(elidedText));
|
||||||
|
QRectF boundRect = layout.boundingRect();
|
||||||
|
boundRect.setWidth(width);
|
||||||
|
boundRect.setHeight(height);
|
||||||
|
boundRect.moveTo(textRect.x() + (textRect.width() - width)/2, textRect.y());
|
||||||
|
|
||||||
|
QRectF selRect = boundRect.adjusted(-2, -2, 2, 2);
|
||||||
|
|
||||||
|
if(!painter) { // no painter, calculate the bounding rect only
|
||||||
|
textRect = selRect;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (opt.state & QStyle::State_Selected || opt.state & QStyle::State_MouseOver) {
|
||||||
|
if (const QWidget* widget = opt.widget) { // let the style engine do it
|
||||||
|
QStyle* style = widget->style() ? widget->style() : qApp->style();
|
||||||
|
QStyleOptionViewItemV4 o(opt);
|
||||||
|
o.text = QString();
|
||||||
|
o.rect = selRect.toAlignedRect().intersected(opt.rect); // due to clipping and rounding, we might lose 1px
|
||||||
|
o.showDecorationSelected = true;
|
||||||
|
style->drawPrimitive(QStyle::PE_PanelItemViewItem, &o, painter, widget);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if((opt.state & QStyle::State_Selected)) {
|
||||||
|
// qDebug("w: %f, h:%f, m:%f", boundRect.width(), boundRect.height(), layout.minimumWidth());
|
||||||
|
if(!opt.widget)
|
||||||
|
painter->fillRect(selRect, opt.palette.highlight());
|
||||||
|
painter->setPen(opt.palette.color(QPalette::Normal, QPalette::HighlightedText));
|
||||||
|
}
|
||||||
|
else { // only draw shadow for non-selected items
|
||||||
|
// draw shadow, FIXME: is it possible to use QGraphicsDropShadowEffect here?
|
||||||
|
QPen prevPen = painter->pen();
|
||||||
|
painter->setPen(QPen(shadowColor_));
|
||||||
|
for(int i = 0; i < visibleLines; ++i) {
|
||||||
|
QTextLine line = layout.lineAt(i);
|
||||||
|
if(i == (visibleLines - 1) && !elidedText.isEmpty()) { // the last line, draw elided text
|
||||||
|
QPointF pos(boundRect.x() + line.position().x() + 1, boundRect.y() + line.y() + line.ascent() + 1);
|
||||||
|
painter->drawText(pos, elidedText);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
line.draw(painter, textRect.topLeft() + QPointF(1, 1));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
painter->setPen(prevPen);
|
||||||
|
}
|
||||||
|
|
||||||
|
// draw text
|
||||||
|
for(int i = 0; i < visibleLines; ++i) {
|
||||||
|
QTextLine line = layout.lineAt(i);
|
||||||
|
if(i == (visibleLines - 1) && !elidedText.isEmpty()) { // the last line, draw elided text
|
||||||
|
QPointF pos(boundRect.x() + line.position().x(), boundRect.y() + line.y() + line.ascent());
|
||||||
|
painter->drawText(pos, elidedText);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
line.draw(painter, textRect.topLeft());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
QSize DesktopItemDelegate::sizeHint(const QStyleOptionViewItem& option, const QModelIndex& index) const {
|
||||||
|
QVariant value = index.data(Qt::SizeHintRole);
|
||||||
|
if(value.isValid())
|
||||||
|
return qvariant_cast<QSize>(value);
|
||||||
|
QStyleOptionViewItemV4 opt = option;
|
||||||
|
initStyleOption(&opt, index);
|
||||||
|
opt.decorationAlignment = Qt::AlignHCenter|Qt::AlignTop;
|
||||||
|
opt.displayAlignment = Qt::AlignTop|Qt::AlignHCenter;
|
||||||
|
|
||||||
|
QSize gridSize = view_->gridSize() - 2 * margins_;
|
||||||
|
Q_ASSERT(gridSize != QSize());
|
||||||
|
QRectF textRect(0, 0, gridSize.width(), gridSize.height() - opt.decorationSize.height());
|
||||||
|
drawText(NULL, opt, textRect); // passing NULL for painter will calculate the bounding rect only.
|
||||||
|
int width = qMax((int)textRect.width(), opt.decorationSize.width());
|
||||||
|
int height = opt.decorationSize.height() + textRect.height();
|
||||||
|
return QSize(width, height);
|
||||||
|
}
|
||||||
|
|
||||||
|
DesktopItemDelegate::~DesktopItemDelegate() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace PCManFM
|
64
pcmanfm/desktopitemdelegate.h
Normal file
64
pcmanfm/desktopitemdelegate.h
Normal file
@ -0,0 +1,64 @@
|
|||||||
|
/*
|
||||||
|
|
||||||
|
Copyright (C) 2013 Hong Jen Yee (PCMan) <pcman.tw@gmail.com>
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation; either version 2 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License along
|
||||||
|
with this program; if not, write to the Free Software Foundation, Inc.,
|
||||||
|
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef PCMANFM_DESKTOPITEMDELEGATE_H
|
||||||
|
#define PCMANFM_DESKTOPITEMDELEGATE_H
|
||||||
|
|
||||||
|
#include <QStyledItemDelegate>
|
||||||
|
#include <QColor>
|
||||||
|
|
||||||
|
class QListView;
|
||||||
|
class QTextOption;
|
||||||
|
class QTextLayout;
|
||||||
|
|
||||||
|
namespace PCManFM {
|
||||||
|
|
||||||
|
class DesktopItemDelegate : public QStyledItemDelegate
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
public:
|
||||||
|
explicit DesktopItemDelegate(QListView* view, QObject* parent = 0);
|
||||||
|
virtual void paint(QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index) const;
|
||||||
|
virtual QSize sizeHint(const QStyleOptionViewItem& option, const QModelIndex& index) const;
|
||||||
|
virtual ~DesktopItemDelegate();
|
||||||
|
|
||||||
|
void setShadowColor(const QColor& shadowColor) {
|
||||||
|
shadowColor_ = shadowColor;
|
||||||
|
}
|
||||||
|
const QColor& shadowColor() const {
|
||||||
|
return shadowColor_;
|
||||||
|
}
|
||||||
|
void setMargins(QSize margins) {
|
||||||
|
margins_ = margins.expandedTo(QSize(0, 0));
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
void drawText(QPainter* painter, QStyleOptionViewItemV4& opt, QRectF& textRect) const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
QListView* view_;
|
||||||
|
QIcon symlinkIcon_;
|
||||||
|
QColor shadowColor_;
|
||||||
|
QSize margins_;
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // PCMANFM_DESKTOPITEMDELEGATE_H
|
216
pcmanfm/desktoppreferencesdialog.cpp
Normal file
216
pcmanfm/desktoppreferencesdialog.cpp
Normal file
@ -0,0 +1,216 @@
|
|||||||
|
/*
|
||||||
|
|
||||||
|
Copyright (C) 2013 Hong Jen Yee (PCMan) <pcman.tw@gmail.com>
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation; either version 2 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License along
|
||||||
|
with this program; if not, write to the Free Software Foundation, Inc.,
|
||||||
|
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "desktoppreferencesdialog.h"
|
||||||
|
#include "desktopwindow.h"
|
||||||
|
#include "settings.h"
|
||||||
|
#include "application.h"
|
||||||
|
#include "xdgdir.h"
|
||||||
|
#include <QFileDialog>
|
||||||
|
#include <QImageReader>
|
||||||
|
#include <QFile>
|
||||||
|
#include <QDir>
|
||||||
|
#include <QSaveFile>
|
||||||
|
#include <QRegExp>
|
||||||
|
#include <QDebug>
|
||||||
|
#include <QStandardPaths>
|
||||||
|
|
||||||
|
namespace PCManFM {
|
||||||
|
|
||||||
|
DesktopPreferencesDialog::DesktopPreferencesDialog(QWidget* parent, Qt::WindowFlags f):
|
||||||
|
QDialog(parent, f),
|
||||||
|
editDesktopFolderEnabled(false),
|
||||||
|
desktopFolderWidget(0),
|
||||||
|
desktopFolder() {
|
||||||
|
|
||||||
|
|
||||||
|
setAttribute(Qt::WA_DeleteOnClose);
|
||||||
|
|
||||||
|
Settings& settings = static_cast<Application*>(qApp)->settings();
|
||||||
|
ui.setupUi(this);
|
||||||
|
|
||||||
|
// setup wallpaper modes
|
||||||
|
connect(ui.wallpaperMode, static_cast<void (QComboBox::*)(int)>(&QComboBox::currentIndexChanged), this, &DesktopPreferencesDialog::onWallpaperModeChanged);
|
||||||
|
ui.wallpaperMode->addItem(tr("Fill with background color only"), DesktopWindow::WallpaperNone);
|
||||||
|
ui.wallpaperMode->addItem(tr("Stretch to fill the entire screen"), DesktopWindow::WallpaperStretch);
|
||||||
|
ui.wallpaperMode->addItem(tr("Stretch to fit the screen"), DesktopWindow::WallpaperFit);
|
||||||
|
ui.wallpaperMode->addItem(tr("Center on the screen"), DesktopWindow::WallpaperCenter);
|
||||||
|
ui.wallpaperMode->addItem(tr("Tile the image to fill the entire screen"), DesktopWindow::WallpaperTile);
|
||||||
|
int i;
|
||||||
|
switch(settings.wallpaperMode()) {
|
||||||
|
case DesktopWindow::WallpaperNone:
|
||||||
|
i = 0;
|
||||||
|
break;
|
||||||
|
case DesktopWindow::WallpaperStretch:
|
||||||
|
i = 1;
|
||||||
|
break;
|
||||||
|
case DesktopWindow::WallpaperFit:
|
||||||
|
i = 2;
|
||||||
|
break;
|
||||||
|
case DesktopWindow::WallpaperCenter:
|
||||||
|
i = 3;
|
||||||
|
break;
|
||||||
|
case DesktopWindow::WallpaperTile:
|
||||||
|
i = 4;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
i = 0;
|
||||||
|
}
|
||||||
|
ui.wallpaperMode->setCurrentIndex(i);
|
||||||
|
|
||||||
|
connect(ui.browse, &QPushButton::clicked, this, &DesktopPreferencesDialog::onBrowseClicked);
|
||||||
|
qDebug("wallpaper: %s", settings.wallpaper().toUtf8().data());
|
||||||
|
ui.imageFile->setText(settings.wallpaper());
|
||||||
|
|
||||||
|
ui.font->setFont(settings.desktopFont());
|
||||||
|
|
||||||
|
ui.backgroundColor->setColor(settings.desktopBgColor());
|
||||||
|
ui.textColor->setColor(settings.desktopFgColor());
|
||||||
|
ui.shadowColor->setColor(settings.desktopShadowColor());
|
||||||
|
ui.showWmMenu->setChecked(settings.showWmMenu());
|
||||||
|
|
||||||
|
connect(ui.buttonBox->button(QDialogButtonBox::Apply), &QPushButton::clicked,
|
||||||
|
this, &DesktopPreferencesDialog::onApplyClicked);
|
||||||
|
|
||||||
|
ui.hMargin->setValue(settings.desktopCellMargins().width());
|
||||||
|
ui.vMargin->setValue(settings.desktopCellMargins().height());
|
||||||
|
connect(ui.lockMargins, &QAbstractButton::clicked, this, &DesktopPreferencesDialog::lockMargins);
|
||||||
|
}
|
||||||
|
|
||||||
|
DesktopPreferencesDialog::~DesktopPreferencesDialog() {
|
||||||
|
}
|
||||||
|
|
||||||
|
void DesktopPreferencesDialog::setupDesktopFolderUi()
|
||||||
|
{
|
||||||
|
desktopFolderWidget = new QWidget();
|
||||||
|
uiDesktopFolder.setupUi(desktopFolderWidget);
|
||||||
|
ui.advancedPageLayout->insertWidget(1, desktopFolderWidget);
|
||||||
|
uiDesktopFolder.verticalLayout->setMargin(0);
|
||||||
|
|
||||||
|
desktopFolder = XdgDir::readDesktopDir();
|
||||||
|
qDebug("desktop folder: %s", desktopFolder.toStdString().c_str());
|
||||||
|
|
||||||
|
uiDesktopFolder.desktopFolder->setText(desktopFolder);
|
||||||
|
|
||||||
|
connect(uiDesktopFolder.browseDesktopFolder, &QPushButton::clicked,
|
||||||
|
this, &DesktopPreferencesDialog::onBrowseDesktopFolderClicked);
|
||||||
|
}
|
||||||
|
|
||||||
|
void DesktopPreferencesDialog::lockMargins(bool lock) {
|
||||||
|
ui.vMargin->setDisabled(lock);
|
||||||
|
if(lock) {
|
||||||
|
ui.vMargin->setValue(ui.hMargin->value());
|
||||||
|
connect(ui.hMargin, static_cast<void (QSpinBox::*)(int)>(&QSpinBox::valueChanged), ui.vMargin, &QSpinBox::setValue);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
disconnect(ui.hMargin, static_cast<void (QSpinBox::*)(int)>(&QSpinBox::valueChanged), ui.vMargin, &QSpinBox::setValue);
|
||||||
|
}
|
||||||
|
|
||||||
|
void DesktopPreferencesDialog::applySettings()
|
||||||
|
{
|
||||||
|
Settings& settings = static_cast<Application*>(qApp)->settings();
|
||||||
|
|
||||||
|
if (editDesktopFolderEnabled)
|
||||||
|
XdgDir::setDesktopDir(uiDesktopFolder.desktopFolder->text());
|
||||||
|
|
||||||
|
settings.setWallpaper(ui.imageFile->text());
|
||||||
|
int mode = ui.wallpaperMode->itemData(ui.wallpaperMode->currentIndex()).toInt();
|
||||||
|
settings.setWallpaperMode(mode);
|
||||||
|
settings.setDesktopFont(ui.font->font());
|
||||||
|
settings.setDesktopBgColor(ui.backgroundColor->color());
|
||||||
|
settings.setDesktopFgColor(ui.textColor->color());
|
||||||
|
settings.setDesktopShadowColor(ui.shadowColor->color());
|
||||||
|
settings.setShowWmMenu(ui.showWmMenu->isChecked());
|
||||||
|
settings.setDesktopCellMargins(QSize(ui.hMargin->value(), ui.vMargin->value()));
|
||||||
|
|
||||||
|
settings.save();
|
||||||
|
}
|
||||||
|
|
||||||
|
void DesktopPreferencesDialog::onApplyClicked()
|
||||||
|
{
|
||||||
|
applySettings();
|
||||||
|
static_cast<Application*>(qApp)->updateDesktopsFromSettings();
|
||||||
|
}
|
||||||
|
|
||||||
|
void DesktopPreferencesDialog::accept() {
|
||||||
|
applySettings();
|
||||||
|
static_cast<Application*>(qApp)->updateDesktopsFromSettings();
|
||||||
|
QDialog::accept();
|
||||||
|
}
|
||||||
|
|
||||||
|
void DesktopPreferencesDialog::onWallpaperModeChanged(int index) {
|
||||||
|
int mode = ui.wallpaperMode->itemData(index).toInt();
|
||||||
|
|
||||||
|
bool enable = (mode != DesktopWindow::WallpaperNone);
|
||||||
|
ui.imageFile->setEnabled(enable);
|
||||||
|
ui.browse->setEnabled(enable);
|
||||||
|
}
|
||||||
|
|
||||||
|
void DesktopPreferencesDialog::onBrowseClicked() {
|
||||||
|
QFileDialog dlg;
|
||||||
|
dlg.setAcceptMode(QFileDialog::AcceptOpen);
|
||||||
|
dlg.setFileMode(QFileDialog::ExistingFile);
|
||||||
|
// compose a name fileter from QImageReader
|
||||||
|
QString filter;
|
||||||
|
filter.reserve(256);
|
||||||
|
filter = tr("Image Files");
|
||||||
|
filter += " (";
|
||||||
|
QList<QByteArray> formats = QImageReader::supportedImageFormats();
|
||||||
|
Q_FOREACH(QByteArray format, formats) {
|
||||||
|
filter += "*.";
|
||||||
|
filter += format.toLower();
|
||||||
|
filter += ' ';
|
||||||
|
}
|
||||||
|
filter += ')';
|
||||||
|
dlg.setNameFilter(filter);
|
||||||
|
dlg.setNameFilterDetailsVisible(false);
|
||||||
|
if(dlg.exec() == QDialog::Accepted) {
|
||||||
|
QString filename;
|
||||||
|
filename = dlg.selectedFiles().first();
|
||||||
|
ui.imageFile->setText(filename);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void DesktopPreferencesDialog::onBrowseDesktopFolderClicked()
|
||||||
|
{
|
||||||
|
QFileDialog dlg;
|
||||||
|
dlg.setAcceptMode(QFileDialog::AcceptOpen);
|
||||||
|
dlg.setAcceptMode(QFileDialog::AcceptOpen);
|
||||||
|
dlg.setFileMode(QFileDialog::DirectoryOnly);
|
||||||
|
if (dlg.exec() == QDialog::Accepted) {
|
||||||
|
QString dir;
|
||||||
|
dir = dlg.selectedFiles().first();
|
||||||
|
uiDesktopFolder.desktopFolder->setText(dir);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void DesktopPreferencesDialog::selectPage(QString name) {
|
||||||
|
QWidget* page = findChild<QWidget*>(name + "Page");
|
||||||
|
if(page)
|
||||||
|
ui.tabWidget->setCurrentWidget(page);
|
||||||
|
}
|
||||||
|
|
||||||
|
void DesktopPreferencesDialog::setEditDesktopFolder(const bool enabled)
|
||||||
|
{
|
||||||
|
editDesktopFolderEnabled = enabled;
|
||||||
|
if (editDesktopFolderEnabled)
|
||||||
|
setupDesktopFolderUi();
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace PCManFM
|
67
pcmanfm/desktoppreferencesdialog.h
Normal file
67
pcmanfm/desktoppreferencesdialog.h
Normal file
@ -0,0 +1,67 @@
|
|||||||
|
/*
|
||||||
|
|
||||||
|
Copyright (C) 2013 Hong Jen Yee (PCMan) <pcman.tw@gmail.com>
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation; either version 2 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License along
|
||||||
|
with this program; if not, write to the Free Software Foundation, Inc.,
|
||||||
|
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef PCMANFM_DESKTOPPREFERENCESDIALOG_H
|
||||||
|
#define PCMANFM_DESKTOPPREFERENCESDIALOG_H
|
||||||
|
|
||||||
|
#include <QDialog>
|
||||||
|
#include "ui_desktop-preferences.h"
|
||||||
|
|
||||||
|
#include "ui_desktop-folder.h"
|
||||||
|
|
||||||
|
namespace PCManFM {
|
||||||
|
|
||||||
|
class DesktopPreferencesDialog : public QDialog {
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
explicit DesktopPreferencesDialog(QWidget* parent = 0, Qt::WindowFlags f = 0);
|
||||||
|
virtual ~DesktopPreferencesDialog();
|
||||||
|
|
||||||
|
virtual void accept();
|
||||||
|
|
||||||
|
void selectPage(QString name);
|
||||||
|
|
||||||
|
// Should only be used one time.
|
||||||
|
void setEditDesktopFolder(const bool enabled);
|
||||||
|
|
||||||
|
protected Q_SLOTS:
|
||||||
|
void onApplyClicked();
|
||||||
|
void onWallpaperModeChanged(int index);
|
||||||
|
void onBrowseClicked();
|
||||||
|
void onBrowseDesktopFolderClicked();
|
||||||
|
void lockMargins(bool lock);
|
||||||
|
|
||||||
|
void applySettings();
|
||||||
|
|
||||||
|
private:
|
||||||
|
Ui::DesktopPreferencesDialog ui;
|
||||||
|
Ui::DesktopFolder uiDesktopFolder;
|
||||||
|
|
||||||
|
bool editDesktopFolderEnabled;
|
||||||
|
QWidget* desktopFolderWidget;
|
||||||
|
QString desktopFolder;
|
||||||
|
|
||||||
|
void setupDesktopFolderUi();
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // PCMANFM_DESKTOPPREFERENCESDIALOG_H
|
897
pcmanfm/desktopwindow.cpp
Normal file
897
pcmanfm/desktopwindow.cpp
Normal file
@ -0,0 +1,897 @@
|
|||||||
|
/*
|
||||||
|
|
||||||
|
Copyright (C) 2013 Hong Jen Yee (PCMan) <pcman.tw@gmail.com>
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation; either version 2 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License along
|
||||||
|
with this program; if not, write to the Free Software Foundation, Inc.,
|
||||||
|
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "desktopwindow.h"
|
||||||
|
#include <QWidget>
|
||||||
|
#include <QDesktopWidget>
|
||||||
|
#include <QPainter>
|
||||||
|
#include <QImage>
|
||||||
|
#include <QImageReader>
|
||||||
|
#include <QFile>
|
||||||
|
#include <QPixmap>
|
||||||
|
#include <QPalette>
|
||||||
|
#include <QBrush>
|
||||||
|
#include <QLayout>
|
||||||
|
#include <QDebug>
|
||||||
|
#include <QTimer>
|
||||||
|
#include <QSettings>
|
||||||
|
#include <QStringBuilder>
|
||||||
|
#include <QDir>
|
||||||
|
#include <QShortcut>
|
||||||
|
#include <QDropEvent>
|
||||||
|
#include <QMimeData>
|
||||||
|
|
||||||
|
#include "./application.h"
|
||||||
|
#include "mainwindow.h"
|
||||||
|
#include "desktopitemdelegate.h"
|
||||||
|
#include <libfm-qt/foldermenu.h>
|
||||||
|
#include <libfm-qt/filemenu.h>
|
||||||
|
#include <libfm-qt/cachedfoldermodel.h>
|
||||||
|
#include <libfm-qt/folderview_p.h>
|
||||||
|
#include <libfm-qt/fileoperation.h>
|
||||||
|
#include <libfm-qt/filepropsdialog.h>
|
||||||
|
#include <libfm-qt/utilities.h>
|
||||||
|
#include <libfm-qt/path.h>
|
||||||
|
#include "xdgdir.h"
|
||||||
|
|
||||||
|
#include <QX11Info>
|
||||||
|
#include <QScreen>
|
||||||
|
#include <xcb/xcb.h>
|
||||||
|
#include <X11/Xlib.h>
|
||||||
|
|
||||||
|
namespace PCManFM {
|
||||||
|
|
||||||
|
DesktopWindow::DesktopWindow(int screenNum):
|
||||||
|
View(Fm::FolderView::IconMode),
|
||||||
|
screenNum_(screenNum),
|
||||||
|
folder_(NULL),
|
||||||
|
model_(NULL),
|
||||||
|
proxyModel_(NULL),
|
||||||
|
fileLauncher_(NULL),
|
||||||
|
showWmMenu_(false),
|
||||||
|
wallpaperMode_(WallpaperNone),
|
||||||
|
relayoutTimer_(NULL) {
|
||||||
|
|
||||||
|
QDesktopWidget* desktopWidget = QApplication::desktop();
|
||||||
|
setWindowFlags(Qt::Window | Qt::FramelessWindowHint);
|
||||||
|
setAttribute(Qt::WA_X11NetWmWindowTypeDesktop);
|
||||||
|
setAttribute(Qt::WA_DeleteOnClose);
|
||||||
|
|
||||||
|
// set our custom file launcher
|
||||||
|
View::setFileLauncher(&fileLauncher_);
|
||||||
|
|
||||||
|
listView_ = static_cast<Fm::FolderViewListView*>(childView());
|
||||||
|
listView_->setMovement(QListView::Snap);
|
||||||
|
listView_->setResizeMode(QListView::Adjust);
|
||||||
|
listView_->setFlow(QListView::TopToBottom);
|
||||||
|
|
||||||
|
// NOTE: When XRnadR is in use, the all screens are actually combined to form a
|
||||||
|
// large virtual desktop and only one DesktopWindow needs to be created and screenNum is -1.
|
||||||
|
// In some older multihead setups, such as xinerama, every physical screen
|
||||||
|
// is treated as a separate desktop so many instances of DesktopWindow may be created.
|
||||||
|
// In this case we only want to show desktop icons on the primary screen.
|
||||||
|
if(desktopWidget->isVirtualDesktop() || screenNum_ == desktopWidget->primaryScreen()) {
|
||||||
|
loadItemPositions();
|
||||||
|
Settings& settings = static_cast<Application* >(qApp)->settings();
|
||||||
|
|
||||||
|
model_ = Fm::CachedFolderModel::modelFromPath(fm_path_get_desktop());
|
||||||
|
folder_ = reinterpret_cast<FmFolder*>(g_object_ref(model_->folder()));
|
||||||
|
|
||||||
|
proxyModel_ = new Fm::ProxyFolderModel();
|
||||||
|
proxyModel_->setSourceModel(model_);
|
||||||
|
proxyModel_->setShowThumbnails(settings.showThumbnails());
|
||||||
|
proxyModel_->sort(Fm::FolderModel::ColumnFileMTime);
|
||||||
|
setModel(proxyModel_);
|
||||||
|
|
||||||
|
connect(proxyModel_, &Fm::ProxyFolderModel::rowsInserted, this, &DesktopWindow::onRowsInserted);
|
||||||
|
connect(proxyModel_, &Fm::ProxyFolderModel::rowsAboutToBeRemoved, this, &DesktopWindow::onRowsAboutToBeRemoved);
|
||||||
|
connect(proxyModel_, &Fm::ProxyFolderModel::layoutChanged, this, &DesktopWindow::onLayoutChanged);
|
||||||
|
connect(listView_, &QListView::indexesMoved, this, &DesktopWindow::onIndexesMoved);
|
||||||
|
}
|
||||||
|
|
||||||
|
// set our own delegate
|
||||||
|
delegate_ = new DesktopItemDelegate(listView_);
|
||||||
|
listView_->setItemDelegateForColumn(Fm::FolderModel::ColumnFileName, delegate_);
|
||||||
|
|
||||||
|
// remove frame
|
||||||
|
listView_->setFrameShape(QFrame::NoFrame);
|
||||||
|
// inhibit scrollbars FIXME: this should be optional in the future
|
||||||
|
listView_->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
|
||||||
|
listView_->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
|
||||||
|
|
||||||
|
connect(this, &DesktopWindow::openDirRequested, this, &DesktopWindow::onOpenDirRequested);
|
||||||
|
|
||||||
|
listView_->installEventFilter(this);
|
||||||
|
|
||||||
|
// setup shortcuts
|
||||||
|
QShortcut* shortcut;
|
||||||
|
shortcut = new QShortcut(QKeySequence(Qt::CTRL + Qt::Key_X), this); // cut
|
||||||
|
connect(shortcut, &QShortcut::activated, this, &DesktopWindow::onCutActivated);
|
||||||
|
|
||||||
|
shortcut = new QShortcut(QKeySequence(Qt::CTRL + Qt::Key_C), this); // copy
|
||||||
|
connect(shortcut, &QShortcut::activated, this, &DesktopWindow::onCopyActivated);
|
||||||
|
|
||||||
|
shortcut = new QShortcut(QKeySequence(Qt::CTRL + Qt::Key_V), this); // paste
|
||||||
|
connect(shortcut, &QShortcut::activated, this, &DesktopWindow::onPasteActivated);
|
||||||
|
|
||||||
|
shortcut = new QShortcut(QKeySequence(Qt::CTRL + Qt::Key_A), this); // select all
|
||||||
|
connect(shortcut, &QShortcut::activated, listView_, &QListView::selectAll);
|
||||||
|
|
||||||
|
shortcut = new QShortcut(QKeySequence(Qt::Key_Delete), this); // delete
|
||||||
|
connect(shortcut, &QShortcut::activated, this, &DesktopWindow::onDeleteActivated);
|
||||||
|
|
||||||
|
shortcut = new QShortcut(QKeySequence(Qt::Key_F2), this); // rename
|
||||||
|
connect(shortcut, &QShortcut::activated, this, &DesktopWindow::onRenameActivated);
|
||||||
|
|
||||||
|
shortcut = new QShortcut(QKeySequence(Qt::ALT + Qt::Key_Return), this); // rename
|
||||||
|
connect(shortcut, &QShortcut::activated, this, &DesktopWindow::onFilePropertiesActivated);
|
||||||
|
|
||||||
|
shortcut = new QShortcut(QKeySequence(Qt::SHIFT + Qt::Key_Delete), this); // force delete
|
||||||
|
connect(shortcut, &QShortcut::activated, this, &DesktopWindow::onDeleteActivated);
|
||||||
|
}
|
||||||
|
|
||||||
|
DesktopWindow::~DesktopWindow() {
|
||||||
|
listView_->removeEventFilter(this);
|
||||||
|
|
||||||
|
if(relayoutTimer_)
|
||||||
|
delete relayoutTimer_;
|
||||||
|
|
||||||
|
if(proxyModel_)
|
||||||
|
delete proxyModel_;
|
||||||
|
|
||||||
|
if(model_)
|
||||||
|
model_->unref();
|
||||||
|
|
||||||
|
if(folder_)
|
||||||
|
g_object_unref(folder_);
|
||||||
|
}
|
||||||
|
|
||||||
|
void DesktopWindow::setBackground(const QColor& color) {
|
||||||
|
bgColor_ = color;
|
||||||
|
}
|
||||||
|
|
||||||
|
void DesktopWindow::setForeground(const QColor& color) {
|
||||||
|
QPalette p = listView_->palette();
|
||||||
|
p.setBrush(QPalette::Text, color);
|
||||||
|
listView_->setPalette(p);
|
||||||
|
fgColor_ = color;
|
||||||
|
}
|
||||||
|
|
||||||
|
void DesktopWindow::setShadow(const QColor& color) {
|
||||||
|
shadowColor_ = color;
|
||||||
|
delegate_->setShadowColor(color);
|
||||||
|
}
|
||||||
|
|
||||||
|
void DesktopWindow::onOpenDirRequested(FmPath* path, int target) {
|
||||||
|
// open in new window unconditionally.
|
||||||
|
Application* app = static_cast<Application*>(qApp);
|
||||||
|
MainWindow* newWin = new MainWindow(path);
|
||||||
|
// apply window size from app->settings
|
||||||
|
newWin->resize(app->settings().windowWidth(), app->settings().windowHeight());
|
||||||
|
newWin->show();
|
||||||
|
}
|
||||||
|
|
||||||
|
void DesktopWindow::resizeEvent(QResizeEvent* event) {
|
||||||
|
QWidget::resizeEvent(event);
|
||||||
|
|
||||||
|
// resize wall paper if needed
|
||||||
|
if(isVisible() && wallpaperMode_ != WallpaperNone && wallpaperMode_ != WallpaperTile) {
|
||||||
|
updateWallpaper();
|
||||||
|
update();
|
||||||
|
}
|
||||||
|
queueRelayout(100); // Qt use a 100 msec delay for relayout internally so we use it, too.
|
||||||
|
}
|
||||||
|
|
||||||
|
void DesktopWindow::setDesktopFolder() {
|
||||||
|
FmPath *path = fm_path_new_for_path(XdgDir::readDesktopDir().toStdString().c_str());
|
||||||
|
model_ = Fm::CachedFolderModel::modelFromPath(path);
|
||||||
|
proxyModel_->setSourceModel(model_);
|
||||||
|
}
|
||||||
|
|
||||||
|
void DesktopWindow::setWallpaperFile(QString filename) {
|
||||||
|
wallpaperFile_ = filename;
|
||||||
|
}
|
||||||
|
|
||||||
|
void DesktopWindow::setWallpaperMode(WallpaperMode mode) {
|
||||||
|
wallpaperMode_ = mode;
|
||||||
|
}
|
||||||
|
|
||||||
|
QImage DesktopWindow::loadWallpaperFile(QSize requiredSize) {
|
||||||
|
// NOTE: for ease of programming, we only use the cache for the primary screen.
|
||||||
|
bool useCache = (screenNum_ == -1 || screenNum_ == 0);
|
||||||
|
QFile info;
|
||||||
|
QString cacheFileName;
|
||||||
|
if(useCache) {
|
||||||
|
// see if we have a scaled version cached on disk
|
||||||
|
cacheFileName = QString::fromLocal8Bit(qgetenv("XDG_CACHE_HOME"));
|
||||||
|
if(cacheFileName.isEmpty())
|
||||||
|
cacheFileName = QDir::homePath() % QLatin1String("/.cache");
|
||||||
|
Application* app = static_cast<Application*>(qApp);
|
||||||
|
cacheFileName += QLatin1String("/pcmanfm-qt/") % app->profileName();
|
||||||
|
QDir().mkpath(cacheFileName); // ensure that the cache dir exists
|
||||||
|
cacheFileName += QLatin1String("/wallpaper.cache");
|
||||||
|
|
||||||
|
// read info file
|
||||||
|
QString origin;
|
||||||
|
info.setFileName(cacheFileName % ".info");
|
||||||
|
if(info.open(QIODevice::ReadOnly)) {
|
||||||
|
// FIXME: we need to compare mtime to see if the cache is out of date
|
||||||
|
origin = QString::fromLocal8Bit(info.readLine());
|
||||||
|
info.close();
|
||||||
|
if(!origin.isEmpty()) {
|
||||||
|
// try to see if we can get the size of the cached image.
|
||||||
|
QImageReader reader(cacheFileName);
|
||||||
|
reader.setAutoDetectImageFormat(true);
|
||||||
|
QSize cachedSize = reader.size();
|
||||||
|
qDebug() << "size of cached file" << cachedSize << ", requiredSize:" << requiredSize;
|
||||||
|
if(cachedSize.isValid()) {
|
||||||
|
if(cachedSize == requiredSize) { // see if the cached wallpaper has the size we want
|
||||||
|
QImage image = reader.read(); // return the loaded image
|
||||||
|
qDebug() << "origin" << origin;
|
||||||
|
if(origin == wallpaperFile_)
|
||||||
|
return image;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
qDebug() << "no cached wallpaper. generate a new one!";
|
||||||
|
}
|
||||||
|
|
||||||
|
// we don't have a cached scaled image, load the original file
|
||||||
|
QImage image(wallpaperFile_);
|
||||||
|
qDebug() << "size of original image" << image.size();
|
||||||
|
if(image.isNull() || image.size() == requiredSize) // if the original size is what we want
|
||||||
|
return image;
|
||||||
|
|
||||||
|
// scale the original image
|
||||||
|
QImage scaled = image.scaled(requiredSize.width(), requiredSize.height(), Qt::IgnoreAspectRatio, Qt::SmoothTransformation);
|
||||||
|
// FIXME: should we save the scaled image if its size is larger than the original image?
|
||||||
|
|
||||||
|
if(useCache) {
|
||||||
|
// write the path of the original image to the .info file
|
||||||
|
if(info.open(QIODevice::WriteOnly)) {
|
||||||
|
info.write(wallpaperFile_.toLocal8Bit());
|
||||||
|
info.close();
|
||||||
|
|
||||||
|
// write the scaled cache image to disk
|
||||||
|
const char* format; // we keep jpg format for *.jpg files, and use png format for others.
|
||||||
|
if(wallpaperFile_.endsWith(QLatin1String(".jpg"), Qt::CaseInsensitive) || wallpaperFile_.endsWith(QLatin1String(".jpeg"), Qt::CaseInsensitive))
|
||||||
|
format = "JPG";
|
||||||
|
else
|
||||||
|
format = "PNG";
|
||||||
|
scaled.save(cacheFileName, format);
|
||||||
|
}
|
||||||
|
qDebug() << "wallpaper cached saved to " << cacheFileName;
|
||||||
|
// FIXME: we might delay the write of the cached image?
|
||||||
|
}
|
||||||
|
return scaled;
|
||||||
|
}
|
||||||
|
|
||||||
|
// really generate the background pixmap according to current settings and apply it.
|
||||||
|
void DesktopWindow::updateWallpaper() {
|
||||||
|
// reset the brush
|
||||||
|
// QPalette palette(listView_->palette());
|
||||||
|
QPalette palette(Fm::FolderView::palette());
|
||||||
|
|
||||||
|
if(wallpaperMode_ == WallpaperNone) { // use background color only
|
||||||
|
palette.setBrush(QPalette::Base, bgColor_);
|
||||||
|
}
|
||||||
|
else { // use wallpaper
|
||||||
|
QPixmap pixmap;
|
||||||
|
QImage image;
|
||||||
|
if(wallpaperMode_ == WallpaperTile) { // use the original size
|
||||||
|
image = QImage(wallpaperFile_);
|
||||||
|
pixmap = QPixmap::fromImage(image);
|
||||||
|
}
|
||||||
|
else if(wallpaperMode_ == WallpaperStretch) {
|
||||||
|
image = loadWallpaperFile(size());
|
||||||
|
pixmap = QPixmap::fromImage(image);
|
||||||
|
}
|
||||||
|
else { // WallpaperCenter || WallpaperFit
|
||||||
|
if(wallpaperMode_ == WallpaperCenter) {
|
||||||
|
image = QImage(wallpaperFile_); // load original image
|
||||||
|
}
|
||||||
|
else if(wallpaperMode_ == WallpaperFit) {
|
||||||
|
// calculate the desired size
|
||||||
|
QSize origSize = QImageReader(wallpaperFile_).size(); // get the size of the original file
|
||||||
|
if(origSize.isValid()) {
|
||||||
|
QSize desiredSize = origSize;
|
||||||
|
desiredSize.scale(width(), height(), Qt::KeepAspectRatio);
|
||||||
|
image = loadWallpaperFile(desiredSize); // load the scaled image
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(!image.isNull()) {
|
||||||
|
pixmap = QPixmap(size());
|
||||||
|
QPainter painter(&pixmap);
|
||||||
|
pixmap.fill(bgColor_);
|
||||||
|
int x = (width() - image.width()) / 2;
|
||||||
|
int y = (height() - image.height()) / 2;
|
||||||
|
painter.drawImage(x, y, image);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
wallpaperPixmap_ = pixmap;
|
||||||
|
if(!pixmap.isNull()) {
|
||||||
|
QBrush brush(pixmap);
|
||||||
|
palette.setBrush(QPalette::Base, brush);
|
||||||
|
}
|
||||||
|
else // if the image is not loaded, fallback to use background color only
|
||||||
|
palette.setBrush(QPalette::Base, bgColor_);
|
||||||
|
}
|
||||||
|
|
||||||
|
//FIXME: we should set the pixmap to X11 root window?
|
||||||
|
setPalette(palette);
|
||||||
|
}
|
||||||
|
|
||||||
|
void DesktopWindow::updateFromSettings(Settings& settings) {
|
||||||
|
setDesktopFolder();
|
||||||
|
setWallpaperFile(settings.wallpaper());
|
||||||
|
setWallpaperMode(settings.wallpaperMode());
|
||||||
|
setFont(settings.desktopFont());
|
||||||
|
setIconSize(Fm::FolderView::IconMode, QSize(settings.bigIconSize(), settings.bigIconSize()));
|
||||||
|
setMargins(settings.desktopCellMargins());
|
||||||
|
// setIconSize and setMargins may trigger relayout of items by QListView, so we need to do the layout again.
|
||||||
|
queueRelayout();
|
||||||
|
setForeground(settings.desktopFgColor());
|
||||||
|
setBackground(settings.desktopBgColor());
|
||||||
|
setShadow(settings.desktopShadowColor());
|
||||||
|
showWmMenu_ = settings.showWmMenu();
|
||||||
|
updateWallpaper();
|
||||||
|
update();
|
||||||
|
}
|
||||||
|
|
||||||
|
void DesktopWindow::onFileClicked(int type, FmFileInfo* fileInfo) {
|
||||||
|
if(!fileInfo && showWmMenu_)
|
||||||
|
return; // do not show the popup if we want to use the desktop menu provided by the WM.
|
||||||
|
View::onFileClicked(type, fileInfo);
|
||||||
|
}
|
||||||
|
|
||||||
|
void DesktopWindow::prepareFileMenu(Fm::FileMenu* menu) {
|
||||||
|
// qDebug("DesktopWindow::prepareFileMenu");
|
||||||
|
PCManFM::View::prepareFileMenu(menu);
|
||||||
|
QAction* action = new QAction(tr("Stic&k to Current Position"), menu);
|
||||||
|
action->setCheckable(true);
|
||||||
|
menu->insertSeparator(menu->separator2());
|
||||||
|
menu->insertAction(menu->separator2(), action);
|
||||||
|
|
||||||
|
FmFileInfoList* files = menu->files();
|
||||||
|
// select exactly one item
|
||||||
|
if(fm_file_info_list_get_length(files) == 1) {
|
||||||
|
FmFileInfo* file = menu->firstFile();
|
||||||
|
if(customItemPos_.find(fm_file_info_get_name(file)) != customItemPos_.end()) {
|
||||||
|
// the file item has a custom position
|
||||||
|
action->setChecked(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
connect(action, &QAction::toggled, this, &DesktopWindow::onStickToCurrentPos);
|
||||||
|
}
|
||||||
|
|
||||||
|
void DesktopWindow::prepareFolderMenu(Fm::FolderMenu* menu) {
|
||||||
|
PCManFM::View::prepareFolderMenu(menu);
|
||||||
|
// remove file properties action
|
||||||
|
menu->removeAction(menu->propertiesAction());
|
||||||
|
// add an action for desktop preferences instead
|
||||||
|
QAction* action = menu->addAction(tr("Desktop Preferences"));
|
||||||
|
connect(action, &QAction::triggered, this, &DesktopWindow::onDesktopPreferences);
|
||||||
|
}
|
||||||
|
|
||||||
|
void DesktopWindow::onDesktopPreferences() {
|
||||||
|
static_cast<Application* >(qApp)->desktopPrefrences(QString());
|
||||||
|
}
|
||||||
|
|
||||||
|
void DesktopWindow::onRowsInserted(const QModelIndex& parent, int start, int end) {
|
||||||
|
queueRelayout();
|
||||||
|
}
|
||||||
|
|
||||||
|
void DesktopWindow::onRowsAboutToBeRemoved(const QModelIndex& parent, int start, int end) {
|
||||||
|
Q_UNUSED(parent);
|
||||||
|
Q_UNUSED(start);
|
||||||
|
Q_UNUSED(end);
|
||||||
|
if(!customItemPos_.isEmpty()) {
|
||||||
|
// also delete stored custom item positions for the items currently being removed.
|
||||||
|
// Here we can't rely on ProxyFolderModel::fileInfoFromIndex() because, although rows
|
||||||
|
// aren't removed yet, files are already removed.
|
||||||
|
QHash<QByteArray, QPoint> _customItemPos = customItemPos_;
|
||||||
|
char* dektopPath = fm_path_to_str(fm_path_get_desktop());
|
||||||
|
QString desktopDir = QString(dektopPath) + QString("/");
|
||||||
|
g_free(dektopPath);
|
||||||
|
QHash<QByteArray, QPoint>::iterator it;
|
||||||
|
for(it = _customItemPos.begin(); it != _customItemPos.end(); ++it) {
|
||||||
|
const QByteArray& name = it.key();
|
||||||
|
if(!QFile::exists(desktopDir + QString::fromUtf8(name, name.length())))
|
||||||
|
customItemPos_.remove(it.key());
|
||||||
|
}
|
||||||
|
if(customItemPos_ != _customItemPos)
|
||||||
|
saveItemPositions();
|
||||||
|
}
|
||||||
|
queueRelayout();
|
||||||
|
}
|
||||||
|
|
||||||
|
void DesktopWindow::onLayoutChanged() {
|
||||||
|
queueRelayout();
|
||||||
|
}
|
||||||
|
|
||||||
|
void DesktopWindow::onIndexesMoved(const QModelIndexList& indexes) {
|
||||||
|
// remember the custom position for the items
|
||||||
|
Q_FOREACH(const QModelIndex& index, indexes) {
|
||||||
|
// Under some circumstances, Qt might emit indexMoved for
|
||||||
|
// every single cells in the same row. (when QAbstractItemView::SelectItems is set)
|
||||||
|
// So indexes list may contain several indixes for the same row.
|
||||||
|
// Since we only care about rows, not individual cells,
|
||||||
|
// let's handle column 0 of every row here.
|
||||||
|
if(index.column() == 0) {
|
||||||
|
FmFileInfo* file = proxyModel_->fileInfoFromIndex(index);
|
||||||
|
QRect itemRect = listView_->rectForIndex(index);
|
||||||
|
QPoint tl = itemRect.topLeft();
|
||||||
|
QRect workArea = qApp->desktop()->availableGeometry(screenNum_);
|
||||||
|
workArea.adjust(12, 12, -12, -12);
|
||||||
|
if(customItemPos_.keys(tl).isEmpty() // don't put items on each other
|
||||||
|
&& tl.x() >= workArea.x() && tl.y() >= workArea.y()
|
||||||
|
&& tl.x() + listView_->gridSize().width() <= workArea.right() + 1 // for historical reasons (-> Qt doc)
|
||||||
|
&& tl.y() + listView_->gridSize().height() <= workArea.bottom() + 1) { // as above
|
||||||
|
QByteArray name = fm_file_info_get_name(file);
|
||||||
|
customItemPos_[name] = tl;
|
||||||
|
// qDebug() << "indexMoved:" << name << index << itemRect;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
saveItemPositions();
|
||||||
|
queueRelayout();
|
||||||
|
}
|
||||||
|
|
||||||
|
void DesktopWindow::removeBottomGap() {
|
||||||
|
/************************************************************
|
||||||
|
NOTE: Desktop is an area bounded from below while icons snap
|
||||||
|
to its grid srarting from above. Therefore, we try to adjust
|
||||||
|
the vertical cell margin to prevent relatively large gaps
|
||||||
|
from taking shape at the desktop bottom.
|
||||||
|
************************************************************/
|
||||||
|
QSize cellMargins = getMargins();
|
||||||
|
int workAreaHeight = qApp->desktop()->availableGeometry(screenNum_).height()
|
||||||
|
- 24; // a 12-pix margin will be considered everywhere
|
||||||
|
int cellHeight = listView_->gridSize().height() + listView_->spacing();
|
||||||
|
int iconNumber = workAreaHeight / cellHeight;
|
||||||
|
int bottomGap = workAreaHeight % cellHeight;
|
||||||
|
/*******************************************
|
||||||
|
First try to make room for an extra icon...
|
||||||
|
*******************************************/
|
||||||
|
// If one pixel is subtracted from the vertical margin, cellHeight
|
||||||
|
// will decrease by 2 while bottomGap will increase by 2*iconNumber.
|
||||||
|
// So, we can add an icon to the bottom once this inequality holds:
|
||||||
|
// bottomGap + 2*n*iconNumber >= cellHeight - 2*n
|
||||||
|
// From here, we get our "subtrahend":
|
||||||
|
qreal exactNumber = ((qreal)cellHeight - (qreal)bottomGap)
|
||||||
|
/ (2.0 * (qreal)iconNumber + 2.0);
|
||||||
|
int subtrahend = (int)exactNumber + ((int)exactNumber == exactNumber ? 0 : 1);
|
||||||
|
Settings& settings = static_cast<Application*>(qApp)->settings();
|
||||||
|
int minCellHeight = settings.desktopCellMargins().height();
|
||||||
|
if(subtrahend > 0
|
||||||
|
&& cellMargins.height() - subtrahend >= minCellHeight) {
|
||||||
|
cellMargins -= QSize(0, subtrahend);
|
||||||
|
}
|
||||||
|
/***************************************************
|
||||||
|
... but if that can't be done, try to spread icons!
|
||||||
|
***************************************************/
|
||||||
|
else
|
||||||
|
cellMargins += QSize(0, (bottomGap / iconNumber) / 2);
|
||||||
|
// set the new margins (if they're changed)
|
||||||
|
delegate_->setMargins(cellMargins);
|
||||||
|
setMargins(cellMargins);
|
||||||
|
// in case the text shadow is reset to (0,0,0,0)
|
||||||
|
setShadow(settings.desktopShadowColor());
|
||||||
|
}
|
||||||
|
|
||||||
|
// QListView does item layout in a very inflexible way, so let's do our custom layout again.
|
||||||
|
// FIXME: this is very inefficient, but due to the design flaw of QListView, this is currently the only workaround.
|
||||||
|
void DesktopWindow::relayoutItems() {
|
||||||
|
loadItemPositions(); // something may have changed
|
||||||
|
// qDebug("relayoutItems()");
|
||||||
|
if(relayoutTimer_) {
|
||||||
|
// this slot might be called from the timer, so we cannot delete it directly here.
|
||||||
|
relayoutTimer_->deleteLater();
|
||||||
|
relayoutTimer_ = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
QDesktopWidget* desktop = qApp->desktop();
|
||||||
|
int screen = 0;
|
||||||
|
int row = 0;
|
||||||
|
int rowCount = proxyModel_->rowCount();
|
||||||
|
for(;;) {
|
||||||
|
if(desktop->isVirtualDesktop()) {
|
||||||
|
if(screen >= desktop->numScreens())
|
||||||
|
break;
|
||||||
|
}else {
|
||||||
|
screen = screenNum_;
|
||||||
|
}
|
||||||
|
QRect workArea = desktop->availableGeometry(screen);
|
||||||
|
workArea.adjust(12, 12, -12, -12); // add a 12 pixel margin to the work area
|
||||||
|
// qDebug() << "workArea" << screen << workArea;
|
||||||
|
// FIXME: we use an internal class declared in a private header here, which is pretty bad.
|
||||||
|
QSize grid = listView_->gridSize();
|
||||||
|
QPoint pos = workArea.topLeft();
|
||||||
|
for(; row < rowCount; ++row) {
|
||||||
|
QModelIndex index = proxyModel_->index(row, 0);
|
||||||
|
int itemWidth = delegate_->sizeHint(listView_->getViewOptions(), index).width();
|
||||||
|
FmFileInfo* file = proxyModel_->fileInfoFromIndex(index);
|
||||||
|
QByteArray name = fm_file_info_get_name(file);
|
||||||
|
QHash<QByteArray, QPoint>::iterator it = customItemPos_.find(name);
|
||||||
|
if(it != customItemPos_.end()) { // the item has a custom position
|
||||||
|
QPoint customPos = *it;
|
||||||
|
// center the contents vertically
|
||||||
|
listView_->setPositionForIndex(customPos + QPoint((grid.width() - itemWidth) / 2, 0), index);
|
||||||
|
// qDebug() << "set custom pos:" << name << row << index << customPos;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
// check if the current pos is alredy occupied by a custom item
|
||||||
|
bool used = false;
|
||||||
|
for(it = customItemPos_.begin(); it != customItemPos_.end(); ++it) {
|
||||||
|
QPoint customPos = *it;
|
||||||
|
if(QRect(customPos, grid).contains(pos)) {
|
||||||
|
used = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(used) { // go to next pos
|
||||||
|
--row;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
// center the contents vertically
|
||||||
|
listView_->setPositionForIndex(pos + QPoint((grid.width() - itemWidth) / 2, 0), index);
|
||||||
|
// qDebug() << "set pos" << name << row << index << pos;
|
||||||
|
}
|
||||||
|
// move to next cell in the column
|
||||||
|
pos.setY(pos.y() + grid.height() + listView_->spacing());
|
||||||
|
if(pos.y() + grid.height() > workArea.bottom() + 1) {
|
||||||
|
// if the next position may exceed the bottom of work area, go to the top of next column
|
||||||
|
pos.setX(pos.x() + grid.width() + listView_->spacing());
|
||||||
|
pos.setY(workArea.top());
|
||||||
|
|
||||||
|
// check if the new column exceeds the right margin of work area
|
||||||
|
if(pos.x() + grid.width() > workArea.right() + 1) {
|
||||||
|
if(desktop->isVirtualDesktop()) {
|
||||||
|
// in virtual desktop mode, go to next screen
|
||||||
|
++screen;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(row >= rowCount)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void DesktopWindow::loadItemPositions() {
|
||||||
|
// load custom item positions
|
||||||
|
customItemPos_.clear();
|
||||||
|
Settings& settings = static_cast<Application*>(qApp)->settings();
|
||||||
|
QString configFile = QString("%1/desktop-items-%2.conf").arg(settings.profileDir(settings.profileName())).arg(screenNum_);
|
||||||
|
QSettings file(configFile, QSettings::IniFormat);
|
||||||
|
QSize grid = listView_->gridSize();
|
||||||
|
QRect workArea = qApp->desktop()->availableGeometry(screenNum_);
|
||||||
|
workArea.adjust(12, 12, -12, -12);
|
||||||
|
char* dektopPath = fm_path_to_str(fm_path_get_desktop());
|
||||||
|
QString desktopDir = QString(dektopPath) + QString("/");
|
||||||
|
g_free(dektopPath);
|
||||||
|
Q_FOREACH(const QString& name, file.childGroups()) {
|
||||||
|
if(!QFile::exists(desktopDir + name.toUtf8())) {
|
||||||
|
// the file may have been removed from outside LXQT
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
file.beginGroup(name);
|
||||||
|
QVariant var = file.value("pos");
|
||||||
|
if(var.isValid()) {
|
||||||
|
QPoint customPos = var.toPoint();
|
||||||
|
if (customPos.x() >= workArea.x() && customPos.y() >= workArea.y()
|
||||||
|
&& customPos.x() + listView_->gridSize().width() <= workArea.right() + 1
|
||||||
|
&& customPos.y() + listView_->gridSize().height() <= workArea.bottom() + 1)
|
||||||
|
{
|
||||||
|
// correct positions that are't aligned to the grid
|
||||||
|
qreal w = qAbs((qreal)customPos.x() - (qreal)workArea.x())
|
||||||
|
/ (qreal)(grid.width() + listView_->spacing());
|
||||||
|
qreal h = qAbs(customPos.y() - (qreal)workArea.y())
|
||||||
|
/ (qreal)(grid.height() + listView_->spacing());
|
||||||
|
customPos.setX(workArea.x() + qRound(w) * (grid.width() + listView_->spacing()));
|
||||||
|
customPos.setY(workArea.y() + qRound(h) * (grid.height() + listView_->spacing()));
|
||||||
|
while(customItemPos_.values().contains(customPos)) {
|
||||||
|
customPos.setY(customPos.y() + grid.height() + listView_->spacing());
|
||||||
|
if(customPos.y() + grid.height() > workArea.bottom() + 1) {
|
||||||
|
customPos.setX(customPos.x() + grid.width() + listView_->spacing());
|
||||||
|
customPos.setY(workArea.top());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
customItemPos_[name.toUtf8()] = customPos;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
file.endGroup();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void DesktopWindow::saveItemPositions() {
|
||||||
|
Settings& settings = static_cast<Application*>(qApp)->settings();
|
||||||
|
// store custom item positions
|
||||||
|
QString configFile = QString("%1/desktop-items-%2.conf").arg(settings.profileDir(settings.profileName())).arg(screenNum_);
|
||||||
|
// FIXME: using QSettings here is inefficient and it's not friendly to UTF-8.
|
||||||
|
QSettings file(configFile, QSettings::IniFormat);
|
||||||
|
file.clear(); // remove all existing entries
|
||||||
|
|
||||||
|
// FIXME: we have to remove dead entries not associated to any files?
|
||||||
|
QHash<QByteArray, QPoint>::iterator it;
|
||||||
|
for(it = customItemPos_.begin(); it != customItemPos_.end(); ++it) {
|
||||||
|
const QByteArray& name = it.key();
|
||||||
|
QPoint pos = it.value();
|
||||||
|
file.beginGroup(QString::fromUtf8(name, name.length()));
|
||||||
|
file.setValue("pos", pos);
|
||||||
|
file.endGroup();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void DesktopWindow::onStickToCurrentPos(bool toggled) {
|
||||||
|
QAction* action = static_cast<QAction*>(sender());
|
||||||
|
Fm::FileMenu* menu = static_cast<Fm::FileMenu*>(action->parent());
|
||||||
|
|
||||||
|
QModelIndexList indexes = listView_->selectionModel()->selectedIndexes();
|
||||||
|
if(!indexes.isEmpty()) {
|
||||||
|
FmFileInfo* file = menu->firstFile();
|
||||||
|
QByteArray name = fm_file_info_get_name(file);
|
||||||
|
QModelIndex index = indexes.first();
|
||||||
|
if(toggled) { // remember to current custom position
|
||||||
|
QRect itemRect = listView_->rectForIndex(index);
|
||||||
|
customItemPos_[name] = itemRect.topLeft();
|
||||||
|
saveItemPositions();
|
||||||
|
}
|
||||||
|
else { // cancel custom position and perform relayout
|
||||||
|
QHash<QByteArray, QPoint>::iterator it = customItemPos_.find(name);
|
||||||
|
if(it != customItemPos_.end()) {
|
||||||
|
customItemPos_.erase(it);
|
||||||
|
saveItemPositions();
|
||||||
|
relayoutItems();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void DesktopWindow::queueRelayout(int delay) {
|
||||||
|
// qDebug() << "queueRelayout";
|
||||||
|
removeBottomGap();
|
||||||
|
if(!relayoutTimer_) {
|
||||||
|
relayoutTimer_ = new QTimer();
|
||||||
|
relayoutTimer_->setSingleShot(true);
|
||||||
|
connect(relayoutTimer_, &QTimer::timeout, this, &DesktopWindow::relayoutItems);
|
||||||
|
relayoutTimer_->start(delay);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// slots for file operations
|
||||||
|
|
||||||
|
void DesktopWindow::onCutActivated() {
|
||||||
|
if(FmPathList* paths = selectedFilePaths()) {
|
||||||
|
Fm::cutFilesToClipboard(paths);
|
||||||
|
fm_path_list_unref(paths);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void DesktopWindow::onCopyActivated() {
|
||||||
|
if(FmPathList* paths = selectedFilePaths()) {
|
||||||
|
Fm::copyFilesToClipboard(paths);
|
||||||
|
fm_path_list_unref(paths);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void DesktopWindow::onPasteActivated() {
|
||||||
|
Fm::pasteFilesFromClipboard(path());
|
||||||
|
}
|
||||||
|
|
||||||
|
void DesktopWindow::onDeleteActivated() {
|
||||||
|
if(FmPathList* paths = selectedFilePaths()) {
|
||||||
|
Settings& settings = static_cast<Application*>(qApp)->settings();
|
||||||
|
bool shiftPressed = (qApp->keyboardModifiers() & Qt::ShiftModifier ? true : false);
|
||||||
|
if(settings.useTrash() && !shiftPressed)
|
||||||
|
Fm::FileOperation::trashFiles(paths, settings.confirmTrash());
|
||||||
|
else
|
||||||
|
Fm::FileOperation::deleteFiles(paths, settings.confirmDelete());
|
||||||
|
fm_path_list_unref(paths);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void DesktopWindow::onRenameActivated() {
|
||||||
|
if(FmFileInfoList* files = selectedFiles()) {
|
||||||
|
for(GList* l = fm_file_info_list_peek_head_link(files); l; l = l->next) {
|
||||||
|
FmFileInfo* info = FM_FILE_INFO(l->data);
|
||||||
|
Fm::renameFile(info, NULL);
|
||||||
|
fm_file_info_list_unref(files);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void DesktopWindow::onFilePropertiesActivated() {
|
||||||
|
if(FmFileInfoList* files = selectedFiles()) {
|
||||||
|
Fm::FilePropsDialog::showForFiles(files);
|
||||||
|
fm_file_info_list_unref(files);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void forwardMouseEventToRoot(QMouseEvent* event) {
|
||||||
|
xcb_ungrab_pointer(QX11Info::connection(), event->timestamp());
|
||||||
|
// forward the event to the root window
|
||||||
|
xcb_button_press_event_t xcb_event;
|
||||||
|
uint32_t mask = 0;
|
||||||
|
xcb_event.state = 0;
|
||||||
|
switch(event->type()) {
|
||||||
|
case QEvent::MouseButtonPress:
|
||||||
|
xcb_event.response_type = XCB_BUTTON_PRESS;
|
||||||
|
mask = XCB_EVENT_MASK_BUTTON_PRESS;
|
||||||
|
break;
|
||||||
|
case QEvent::MouseButtonRelease:
|
||||||
|
xcb_event.response_type = XCB_BUTTON_RELEASE;
|
||||||
|
mask = XCB_EVENT_MASK_BUTTON_RELEASE;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// convert Qt button to XCB button
|
||||||
|
switch(event->button()) {
|
||||||
|
case Qt::LeftButton:
|
||||||
|
xcb_event.detail = 1;
|
||||||
|
xcb_event.state |= XCB_BUTTON_MASK_1;
|
||||||
|
break;
|
||||||
|
case Qt::MiddleButton:
|
||||||
|
xcb_event.detail = 2;
|
||||||
|
xcb_event.state |= XCB_BUTTON_MASK_2;
|
||||||
|
break;
|
||||||
|
case Qt::RightButton:
|
||||||
|
xcb_event.detail = 3;
|
||||||
|
xcb_event.state |= XCB_BUTTON_MASK_3;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
xcb_event.detail = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// convert Qt modifiers to XCB states
|
||||||
|
if(event->modifiers() & Qt::ShiftModifier)
|
||||||
|
xcb_event.state |= XCB_MOD_MASK_SHIFT;
|
||||||
|
if(event->modifiers() & Qt::ControlModifier)
|
||||||
|
xcb_event.state |= XCB_MOD_MASK_SHIFT;
|
||||||
|
if(event->modifiers() & Qt::AltModifier)
|
||||||
|
xcb_event.state |= XCB_MOD_MASK_1;
|
||||||
|
|
||||||
|
xcb_event.sequence = 0;
|
||||||
|
xcb_event.time = event->timestamp();
|
||||||
|
|
||||||
|
WId root = QX11Info::appRootWindow(QX11Info::appScreen());
|
||||||
|
xcb_event.event = root;
|
||||||
|
xcb_event.root = root;
|
||||||
|
xcb_event.child = 0;
|
||||||
|
|
||||||
|
xcb_event.root_x = event->globalX();
|
||||||
|
xcb_event.root_y = event->globalY();
|
||||||
|
xcb_event.event_x = event->x();
|
||||||
|
xcb_event.event_y = event->y();
|
||||||
|
xcb_event.same_screen = 1;
|
||||||
|
|
||||||
|
xcb_send_event(QX11Info::connection(), 0, root, mask, (char*)&xcb_event);
|
||||||
|
xcb_flush(QX11Info::connection());
|
||||||
|
}
|
||||||
|
|
||||||
|
bool DesktopWindow::event(QEvent* event)
|
||||||
|
{
|
||||||
|
switch(event->type()) {
|
||||||
|
case QEvent::WinIdChange: {
|
||||||
|
qDebug() << "winid change:" << effectiveWinId();
|
||||||
|
if(effectiveWinId() == 0)
|
||||||
|
break;
|
||||||
|
// set freedesktop.org EWMH hints properly
|
||||||
|
if(QX11Info::isPlatformX11() && QX11Info::connection()) {
|
||||||
|
xcb_connection_t* con = QX11Info::connection();
|
||||||
|
const char* atom_name = "_NET_WM_WINDOW_TYPE_DESKTOP";
|
||||||
|
xcb_atom_t atom = xcb_intern_atom_reply(con, xcb_intern_atom(con, 0, strlen(atom_name), atom_name), NULL)->atom;
|
||||||
|
const char* prop_atom_name = "_NET_WM_WINDOW_TYPE";
|
||||||
|
xcb_atom_t prop_atom = xcb_intern_atom_reply(con, xcb_intern_atom(con, 0, strlen(prop_atom_name), prop_atom_name), NULL)->atom;
|
||||||
|
xcb_atom_t XA_ATOM = 4;
|
||||||
|
xcb_change_property(con, XCB_PROP_MODE_REPLACE, effectiveWinId(), prop_atom, XA_ATOM, 32, 1, &atom);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
#undef FontChange // FontChange is defined in the headers of XLib and clashes with Qt, let's undefine it.
|
||||||
|
case QEvent::StyleChange:
|
||||||
|
case QEvent::FontChange:
|
||||||
|
queueRelayout();
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return QWidget::event(event);
|
||||||
|
}
|
||||||
|
|
||||||
|
#undef FontChange // this seems to be defined in Xlib headers as a macro, undef it!
|
||||||
|
|
||||||
|
bool DesktopWindow::eventFilter(QObject * watched, QEvent * event) {
|
||||||
|
if(watched == listView_) {
|
||||||
|
switch(event->type()) {
|
||||||
|
case QEvent::StyleChange:
|
||||||
|
case QEvent::FontChange:
|
||||||
|
if(model_)
|
||||||
|
queueRelayout();
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if(watched == listView_->viewport()) {
|
||||||
|
switch(event->type()) {
|
||||||
|
case QEvent::MouseButtonPress:
|
||||||
|
case QEvent::MouseButtonRelease:
|
||||||
|
if(showWmMenu_) {
|
||||||
|
QMouseEvent* e = static_cast<QMouseEvent*>(event);
|
||||||
|
// If we want to show the desktop menus provided by the window manager instead of ours,
|
||||||
|
// we have to forward the mouse events we received to the root window.
|
||||||
|
// check if the user click on blank area
|
||||||
|
QModelIndex index = listView_->indexAt(e->pos());
|
||||||
|
if(!index.isValid() && e->button() != Qt::LeftButton) {
|
||||||
|
forwardMouseEventToRoot(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void DesktopWindow::childDropEvent(QDropEvent* e) {
|
||||||
|
bool moveItem = false;
|
||||||
|
if(e->source() == listView_ && e->keyboardModifiers() == Qt::NoModifier) {
|
||||||
|
// drag source is our list view, and no other modifier keys are pressed
|
||||||
|
// => we're dragging desktop items
|
||||||
|
const QMimeData *mimeData = e->mimeData();
|
||||||
|
if(mimeData->hasFormat("application/x-qabstractitemmodeldatalist")) {
|
||||||
|
QModelIndex dropIndex = listView_->indexAt(e->pos());
|
||||||
|
if(dropIndex.isValid()) { // drop on an item
|
||||||
|
QModelIndexList selected = selectedIndexes(); // the dragged items
|
||||||
|
if(selected.contains(dropIndex)) { // drop on self, ignore
|
||||||
|
moveItem = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else { // drop on a blank area
|
||||||
|
moveItem = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(moveItem)
|
||||||
|
e->accept();
|
||||||
|
else
|
||||||
|
Fm::FolderView::childDropEvent(e);
|
||||||
|
}
|
||||||
|
|
||||||
|
void DesktopWindow::closeEvent(QCloseEvent *event) {
|
||||||
|
// prevent the desktop window from being closed.
|
||||||
|
event->ignore();
|
||||||
|
}
|
||||||
|
|
||||||
|
void DesktopWindow::setScreenNum(int num) {
|
||||||
|
if(screenNum_ != num) {
|
||||||
|
screenNum_ = num;
|
||||||
|
queueRelayout();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace PCManFM
|
142
pcmanfm/desktopwindow.h
Normal file
142
pcmanfm/desktopwindow.h
Normal file
@ -0,0 +1,142 @@
|
|||||||
|
/*
|
||||||
|
|
||||||
|
Copyright (C) 2013 Hong Jen Yee (PCMan) <pcman.tw@gmail.com>
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation; either version 2 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License along
|
||||||
|
with this program; if not, write to the Free Software Foundation, Inc.,
|
||||||
|
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef PCMANFM_DESKTOPWINDOW_H
|
||||||
|
#define PCMANFM_DESKTOPWINDOW_H
|
||||||
|
|
||||||
|
#include "view.h"
|
||||||
|
#include "launcher.h"
|
||||||
|
#include <QHash>
|
||||||
|
#include <QPoint>
|
||||||
|
#include <QByteArray>
|
||||||
|
#include <xcb/xcb.h>
|
||||||
|
|
||||||
|
namespace Fm {
|
||||||
|
class CachedFolderModel;
|
||||||
|
class ProxyFolderModel;
|
||||||
|
class FolderViewListView;
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace PCManFM {
|
||||||
|
|
||||||
|
class DesktopItemDelegate;
|
||||||
|
class Settings;
|
||||||
|
|
||||||
|
class DesktopWindow : public View {
|
||||||
|
Q_OBJECT
|
||||||
|
public:
|
||||||
|
friend class Application;
|
||||||
|
|
||||||
|
enum WallpaperMode {
|
||||||
|
WallpaperNone,
|
||||||
|
WallpaperStretch,
|
||||||
|
WallpaperFit,
|
||||||
|
WallpaperCenter,
|
||||||
|
WallpaperTile
|
||||||
|
};
|
||||||
|
|
||||||
|
explicit DesktopWindow(int screenNum);
|
||||||
|
virtual ~DesktopWindow();
|
||||||
|
|
||||||
|
void setForeground(const QColor& color);
|
||||||
|
void setShadow(const QColor& color);
|
||||||
|
void setBackground(const QColor& color);
|
||||||
|
void setDesktopFolder();
|
||||||
|
void setWallpaperFile(QString filename);
|
||||||
|
void setWallpaperMode(WallpaperMode mode = WallpaperStretch);
|
||||||
|
|
||||||
|
// void setWallpaperAlpha(qreal alpha);
|
||||||
|
void updateWallpaper();
|
||||||
|
void updateFromSettings(Settings& settings);
|
||||||
|
|
||||||
|
void queueRelayout(int delay = 0);
|
||||||
|
|
||||||
|
int screenNum() const {
|
||||||
|
return screenNum_;
|
||||||
|
}
|
||||||
|
|
||||||
|
void setScreenNum(int num);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
virtual void prepareFolderMenu(Fm::FolderMenu* menu);
|
||||||
|
virtual void prepareFileMenu(Fm::FileMenu* menu);
|
||||||
|
virtual void resizeEvent(QResizeEvent* event);
|
||||||
|
virtual void onFileClicked(int type, FmFileInfo* fileInfo);
|
||||||
|
|
||||||
|
void loadItemPositions();
|
||||||
|
void saveItemPositions();
|
||||||
|
|
||||||
|
QImage loadWallpaperFile(QSize requiredSize);
|
||||||
|
|
||||||
|
virtual bool event(QEvent* event);
|
||||||
|
virtual bool eventFilter(QObject * watched, QEvent * event);
|
||||||
|
|
||||||
|
virtual void childDropEvent(QDropEvent* e);
|
||||||
|
virtual void closeEvent(QCloseEvent *event);
|
||||||
|
|
||||||
|
protected Q_SLOTS:
|
||||||
|
void onOpenDirRequested(FmPath* path, int target);
|
||||||
|
void onDesktopPreferences();
|
||||||
|
|
||||||
|
void onRowsAboutToBeRemoved(const QModelIndex& parent, int start, int end);
|
||||||
|
void onRowsInserted(const QModelIndex& parent, int start, int end);
|
||||||
|
void onLayoutChanged();
|
||||||
|
void onIndexesMoved(const QModelIndexList& indexes);
|
||||||
|
|
||||||
|
void relayoutItems();
|
||||||
|
void onStickToCurrentPos(bool toggled);
|
||||||
|
|
||||||
|
// void updateWorkArea();
|
||||||
|
|
||||||
|
// file operations
|
||||||
|
void onCutActivated();
|
||||||
|
void onCopyActivated();
|
||||||
|
void onPasteActivated();
|
||||||
|
void onRenameActivated();
|
||||||
|
void onDeleteActivated();
|
||||||
|
void onFilePropertiesActivated();
|
||||||
|
|
||||||
|
private:
|
||||||
|
void removeBottomGap();
|
||||||
|
|
||||||
|
private:
|
||||||
|
Fm::ProxyFolderModel* proxyModel_;
|
||||||
|
Fm::CachedFolderModel* model_;
|
||||||
|
FmFolder* folder_;
|
||||||
|
Fm::FolderViewListView* listView_;
|
||||||
|
|
||||||
|
QColor fgColor_;
|
||||||
|
QColor bgColor_;
|
||||||
|
QColor shadowColor_;
|
||||||
|
QString wallpaperFile_;
|
||||||
|
WallpaperMode wallpaperMode_;
|
||||||
|
QPixmap wallpaperPixmap_;
|
||||||
|
DesktopItemDelegate* delegate_;
|
||||||
|
Launcher fileLauncher_;
|
||||||
|
bool showWmMenu_;
|
||||||
|
|
||||||
|
int screenNum_;
|
||||||
|
QHash<QByteArray, QPoint> customItemPos_;
|
||||||
|
QTimer* relayoutTimer_;
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // PCMANFM_DESKTOPWINDOW_H
|
517
pcmanfm/file-search.ui
Normal file
517
pcmanfm/file-search.ui
Normal file
@ -0,0 +1,517 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<ui version="4.0">
|
||||||
|
<class>FindFilesDialog</class>
|
||||||
|
<widget class="QDialog" name="FindFilesDialog">
|
||||||
|
<property name="geometry">
|
||||||
|
<rect>
|
||||||
|
<x>0</x>
|
||||||
|
<y>0</y>
|
||||||
|
<width>431</width>
|
||||||
|
<height>416</height>
|
||||||
|
</rect>
|
||||||
|
</property>
|
||||||
|
<property name="windowTitle">
|
||||||
|
<string>Find Files</string>
|
||||||
|
</property>
|
||||||
|
<layout class="QVBoxLayout" name="verticalLayout">
|
||||||
|
<item>
|
||||||
|
<widget class="QTabWidget" name="tabWidget">
|
||||||
|
<property name="currentIndex">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<widget class="QWidget" name="tab">
|
||||||
|
<attribute name="title">
|
||||||
|
<string>Name/Location</string>
|
||||||
|
</attribute>
|
||||||
|
<layout class="QVBoxLayout" name="verticalLayout_4">
|
||||||
|
<item>
|
||||||
|
<widget class="QGroupBox" name="groupBox">
|
||||||
|
<property name="title">
|
||||||
|
<string>File name patterns</string>
|
||||||
|
</property>
|
||||||
|
<layout class="QFormLayout" name="formLayout">
|
||||||
|
<item row="0" column="0">
|
||||||
|
<widget class="QLabel" name="label">
|
||||||
|
<property name="text">
|
||||||
|
<string>Pattern:</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="0" column="1">
|
||||||
|
<widget class="QLineEdit" name="lineEdit"/>
|
||||||
|
</item>
|
||||||
|
<item row="1" column="0" colspan="2">
|
||||||
|
<widget class="QCheckBox" name="checkBox">
|
||||||
|
<property name="text">
|
||||||
|
<string>Case insensitive</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="2" column="0" colspan="2">
|
||||||
|
<widget class="QCheckBox" name="checkBox_2">
|
||||||
|
<property name="text">
|
||||||
|
<string>Use regular expression</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QGroupBox" name="groupBox_2">
|
||||||
|
<property name="title">
|
||||||
|
<string>Places to search</string>
|
||||||
|
</property>
|
||||||
|
<layout class="QVBoxLayout" name="verticalLayout_3">
|
||||||
|
<item>
|
||||||
|
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||||
|
<item>
|
||||||
|
<widget class="QListWidget" name="listWidget"/>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<layout class="QVBoxLayout" name="verticalLayout_2">
|
||||||
|
<item>
|
||||||
|
<widget class="QPushButton" name="pushButton">
|
||||||
|
<property name="text">
|
||||||
|
<string>Add</string>
|
||||||
|
</property>
|
||||||
|
<property name="icon">
|
||||||
|
<iconset theme="list-add">
|
||||||
|
<normaloff/>
|
||||||
|
</iconset>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QPushButton" name="pushButton_2">
|
||||||
|
<property name="text">
|
||||||
|
<string>Remove</string>
|
||||||
|
</property>
|
||||||
|
<property name="icon">
|
||||||
|
<iconset theme="list-remove">
|
||||||
|
<normaloff/>
|
||||||
|
</iconset>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<spacer name="verticalSpacer">
|
||||||
|
<property name="orientation">
|
||||||
|
<enum>Qt::Vertical</enum>
|
||||||
|
</property>
|
||||||
|
<property name="sizeHint" stdset="0">
|
||||||
|
<size>
|
||||||
|
<width>20</width>
|
||||||
|
<height>40</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
</spacer>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QCheckBox" name="checkBox_3">
|
||||||
|
<property name="text">
|
||||||
|
<string>Search in sub directories</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QCheckBox" name="checkBox_4">
|
||||||
|
<property name="text">
|
||||||
|
<string>Search hidden files</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
<widget class="QWidget" name="tab_2">
|
||||||
|
<attribute name="title">
|
||||||
|
<string>File Type</string>
|
||||||
|
</attribute>
|
||||||
|
<layout class="QVBoxLayout" name="verticalLayout_6">
|
||||||
|
<item>
|
||||||
|
<widget class="QGroupBox" name="groupBox_3">
|
||||||
|
<property name="title">
|
||||||
|
<string>File Type</string>
|
||||||
|
</property>
|
||||||
|
<layout class="QVBoxLayout" name="verticalLayout_5">
|
||||||
|
<item>
|
||||||
|
<widget class="QLabel" name="label_2">
|
||||||
|
<property name="text">
|
||||||
|
<string>Only search for files of following types:</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QCheckBox" name="checkBox_5">
|
||||||
|
<property name="text">
|
||||||
|
<string>Text files</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QCheckBox" name="checkBox_6">
|
||||||
|
<property name="text">
|
||||||
|
<string>Image files</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QCheckBox" name="checkBox_7">
|
||||||
|
<property name="text">
|
||||||
|
<string>Audio files</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QCheckBox" name="checkBox_8">
|
||||||
|
<property name="text">
|
||||||
|
<string>Video files</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QCheckBox" name="checkBox_9">
|
||||||
|
<property name="text">
|
||||||
|
<string>Documents</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<spacer name="verticalSpacer_2">
|
||||||
|
<property name="orientation">
|
||||||
|
<enum>Qt::Vertical</enum>
|
||||||
|
</property>
|
||||||
|
<property name="sizeHint" stdset="0">
|
||||||
|
<size>
|
||||||
|
<width>20</width>
|
||||||
|
<height>40</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
</spacer>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
<widget class="QWidget" name="tab_4">
|
||||||
|
<attribute name="title">
|
||||||
|
<string>Content</string>
|
||||||
|
</attribute>
|
||||||
|
<layout class="QVBoxLayout" name="verticalLayout_8">
|
||||||
|
<item>
|
||||||
|
<widget class="QGroupBox" name="groupBox_4">
|
||||||
|
<property name="title">
|
||||||
|
<string>File contains</string>
|
||||||
|
</property>
|
||||||
|
<layout class="QVBoxLayout" name="verticalLayout_7">
|
||||||
|
<item>
|
||||||
|
<widget class="QLineEdit" name="lineEdit_2"/>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QCheckBox" name="checkBox_10">
|
||||||
|
<property name="text">
|
||||||
|
<string>Case insensitive</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QCheckBox" name="checkBox_11">
|
||||||
|
<property name="text">
|
||||||
|
<string>Use regular expression</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<spacer name="verticalSpacer_3">
|
||||||
|
<property name="orientation">
|
||||||
|
<enum>Qt::Vertical</enum>
|
||||||
|
</property>
|
||||||
|
<property name="sizeHint" stdset="0">
|
||||||
|
<size>
|
||||||
|
<width>20</width>
|
||||||
|
<height>40</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
</spacer>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
<widget class="QWidget" name="tab_3">
|
||||||
|
<attribute name="title">
|
||||||
|
<string>Properties</string>
|
||||||
|
</attribute>
|
||||||
|
<layout class="QVBoxLayout" name="verticalLayout_9">
|
||||||
|
<item>
|
||||||
|
<widget class="QGroupBox" name="groupBox_5">
|
||||||
|
<property name="title">
|
||||||
|
<string>File Size</string>
|
||||||
|
</property>
|
||||||
|
<layout class="QFormLayout" name="formLayout_3">
|
||||||
|
<item row="0" column="0">
|
||||||
|
<widget class="QCheckBox" name="checkBox_12">
|
||||||
|
<property name="text">
|
||||||
|
<string>Bigger than:</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="0" column="1">
|
||||||
|
<layout class="QHBoxLayout" name="horizontalLayout_2">
|
||||||
|
<item>
|
||||||
|
<widget class="QSpinBox" name="spinBox">
|
||||||
|
<property name="enabled">
|
||||||
|
<bool>false</bool>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QComboBox" name="comboBox">
|
||||||
|
<property name="enabled">
|
||||||
|
<bool>false</bool>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</item>
|
||||||
|
<item row="1" column="0">
|
||||||
|
<widget class="QCheckBox" name="checkBox_13">
|
||||||
|
<property name="text">
|
||||||
|
<string>Smaller than:</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="1" column="1">
|
||||||
|
<layout class="QHBoxLayout" name="horizontalLayout_3">
|
||||||
|
<item>
|
||||||
|
<widget class="QSpinBox" name="spinBox_2">
|
||||||
|
<property name="enabled">
|
||||||
|
<bool>false</bool>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QComboBox" name="comboBox_2">
|
||||||
|
<property name="enabled">
|
||||||
|
<bool>false</bool>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QGroupBox" name="groupBox_6">
|
||||||
|
<property name="title">
|
||||||
|
<string>Last Modified Time</string>
|
||||||
|
</property>
|
||||||
|
<layout class="QFormLayout" name="formLayout_2">
|
||||||
|
<item row="0" column="0">
|
||||||
|
<widget class="QCheckBox" name="checkBox_14">
|
||||||
|
<property name="text">
|
||||||
|
<string>Earlier than:</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="0" column="1">
|
||||||
|
<widget class="QDateTimeEdit" name="dateTimeEdit">
|
||||||
|
<property name="enabled">
|
||||||
|
<bool>false</bool>
|
||||||
|
</property>
|
||||||
|
<property name="calendarPopup">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="1" column="0">
|
||||||
|
<widget class="QCheckBox" name="checkBox_15">
|
||||||
|
<property name="text">
|
||||||
|
<string>Later than:</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="1" column="1">
|
||||||
|
<widget class="QDateTimeEdit" name="dateTimeEdit_2">
|
||||||
|
<property name="enabled">
|
||||||
|
<bool>false</bool>
|
||||||
|
</property>
|
||||||
|
<property name="calendarPopup">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<spacer name="verticalSpacer_4">
|
||||||
|
<property name="orientation">
|
||||||
|
<enum>Qt::Vertical</enum>
|
||||||
|
</property>
|
||||||
|
<property name="sizeHint" stdset="0">
|
||||||
|
<size>
|
||||||
|
<width>20</width>
|
||||||
|
<height>40</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
</spacer>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QDialogButtonBox" name="buttonBox">
|
||||||
|
<property name="orientation">
|
||||||
|
<enum>Qt::Horizontal</enum>
|
||||||
|
</property>
|
||||||
|
<property name="standardButtons">
|
||||||
|
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
<resources/>
|
||||||
|
<connections>
|
||||||
|
<connection>
|
||||||
|
<sender>buttonBox</sender>
|
||||||
|
<signal>accepted()</signal>
|
||||||
|
<receiver>FindFilesDialog</receiver>
|
||||||
|
<slot>accept()</slot>
|
||||||
|
<hints>
|
||||||
|
<hint type="sourcelabel">
|
||||||
|
<x>222</x>
|
||||||
|
<y>344</y>
|
||||||
|
</hint>
|
||||||
|
<hint type="destinationlabel">
|
||||||
|
<x>157</x>
|
||||||
|
<y>274</y>
|
||||||
|
</hint>
|
||||||
|
</hints>
|
||||||
|
</connection>
|
||||||
|
<connection>
|
||||||
|
<sender>buttonBox</sender>
|
||||||
|
<signal>rejected()</signal>
|
||||||
|
<receiver>FindFilesDialog</receiver>
|
||||||
|
<slot>reject()</slot>
|
||||||
|
<hints>
|
||||||
|
<hint type="sourcelabel">
|
||||||
|
<x>290</x>
|
||||||
|
<y>350</y>
|
||||||
|
</hint>
|
||||||
|
<hint type="destinationlabel">
|
||||||
|
<x>286</x>
|
||||||
|
<y>274</y>
|
||||||
|
</hint>
|
||||||
|
</hints>
|
||||||
|
</connection>
|
||||||
|
<connection>
|
||||||
|
<sender>checkBox_14</sender>
|
||||||
|
<signal>toggled(bool)</signal>
|
||||||
|
<receiver>dateTimeEdit</receiver>
|
||||||
|
<slot>setEnabled(bool)</slot>
|
||||||
|
<hints>
|
||||||
|
<hint type="sourcelabel">
|
||||||
|
<x>129</x>
|
||||||
|
<y>166</y>
|
||||||
|
</hint>
|
||||||
|
<hint type="destinationlabel">
|
||||||
|
<x>294</x>
|
||||||
|
<y>170</y>
|
||||||
|
</hint>
|
||||||
|
</hints>
|
||||||
|
</connection>
|
||||||
|
<connection>
|
||||||
|
<sender>checkBox_15</sender>
|
||||||
|
<signal>toggled(bool)</signal>
|
||||||
|
<receiver>dateTimeEdit_2</receiver>
|
||||||
|
<slot>setEnabled(bool)</slot>
|
||||||
|
<hints>
|
||||||
|
<hint type="sourcelabel">
|
||||||
|
<x>91</x>
|
||||||
|
<y>188</y>
|
||||||
|
</hint>
|
||||||
|
<hint type="destinationlabel">
|
||||||
|
<x>302</x>
|
||||||
|
<y>195</y>
|
||||||
|
</hint>
|
||||||
|
</hints>
|
||||||
|
</connection>
|
||||||
|
<connection>
|
||||||
|
<sender>checkBox_12</sender>
|
||||||
|
<signal>toggled(bool)</signal>
|
||||||
|
<receiver>spinBox</receiver>
|
||||||
|
<slot>setEnabled(bool)</slot>
|
||||||
|
<hints>
|
||||||
|
<hint type="sourcelabel">
|
||||||
|
<x>102</x>
|
||||||
|
<y>73</y>
|
||||||
|
</hint>
|
||||||
|
<hint type="destinationlabel">
|
||||||
|
<x>184</x>
|
||||||
|
<y>77</y>
|
||||||
|
</hint>
|
||||||
|
</hints>
|
||||||
|
</connection>
|
||||||
|
<connection>
|
||||||
|
<sender>checkBox_12</sender>
|
||||||
|
<signal>toggled(bool)</signal>
|
||||||
|
<receiver>comboBox</receiver>
|
||||||
|
<slot>setEnabled(bool)</slot>
|
||||||
|
<hints>
|
||||||
|
<hint type="sourcelabel">
|
||||||
|
<x>49</x>
|
||||||
|
<y>72</y>
|
||||||
|
</hint>
|
||||||
|
<hint type="destinationlabel">
|
||||||
|
<x>357</x>
|
||||||
|
<y>76</y>
|
||||||
|
</hint>
|
||||||
|
</hints>
|
||||||
|
</connection>
|
||||||
|
<connection>
|
||||||
|
<sender>checkBox_13</sender>
|
||||||
|
<signal>toggled(bool)</signal>
|
||||||
|
<receiver>spinBox_2</receiver>
|
||||||
|
<slot>setEnabled(bool)</slot>
|
||||||
|
<hints>
|
||||||
|
<hint type="sourcelabel">
|
||||||
|
<x>123</x>
|
||||||
|
<y>101</y>
|
||||||
|
</hint>
|
||||||
|
<hint type="destinationlabel">
|
||||||
|
<x>186</x>
|
||||||
|
<y>104</y>
|
||||||
|
</hint>
|
||||||
|
</hints>
|
||||||
|
</connection>
|
||||||
|
<connection>
|
||||||
|
<sender>checkBox_13</sender>
|
||||||
|
<signal>toggled(bool)</signal>
|
||||||
|
<receiver>comboBox_2</receiver>
|
||||||
|
<slot>setEnabled(bool)</slot>
|
||||||
|
<hints>
|
||||||
|
<hint type="sourcelabel">
|
||||||
|
<x>53</x>
|
||||||
|
<y>98</y>
|
||||||
|
</hint>
|
||||||
|
<hint type="destinationlabel">
|
||||||
|
<x>339</x>
|
||||||
|
<y>108</y>
|
||||||
|
</hint>
|
||||||
|
</hints>
|
||||||
|
</connection>
|
||||||
|
</connections>
|
||||||
|
</ui>
|
64
pcmanfm/launcher.cpp
Normal file
64
pcmanfm/launcher.cpp
Normal file
@ -0,0 +1,64 @@
|
|||||||
|
/*
|
||||||
|
* <one line to give the library's name and an idea of what it does.>
|
||||||
|
* Copyright (C) 2014 <copyright holder> <email>
|
||||||
|
*
|
||||||
|
* This library is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU Lesser General Public
|
||||||
|
* License as published by the Free Software Foundation; either
|
||||||
|
* version 2.1 of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This library is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public
|
||||||
|
* License along with this library; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "launcher.h"
|
||||||
|
#include "mainwindow.h"
|
||||||
|
#include "application.h"
|
||||||
|
|
||||||
|
namespace PCManFM {
|
||||||
|
|
||||||
|
Launcher::Launcher(PCManFM::MainWindow* mainWindow):
|
||||||
|
Fm::FileLauncher(),
|
||||||
|
mainWindow_(mainWindow) {
|
||||||
|
|
||||||
|
Application* app = static_cast<Application*>(qApp);
|
||||||
|
setQuickExec(app->settings().quickExec());
|
||||||
|
}
|
||||||
|
|
||||||
|
Launcher::~Launcher() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Launcher::openFolder(GAppLaunchContext* ctx, GList* folder_infos, GError** err) {
|
||||||
|
GList* l = folder_infos;
|
||||||
|
FmFileInfo* fi = FM_FILE_INFO(l->data);
|
||||||
|
Application* app = static_cast<Application*>(qApp);
|
||||||
|
MainWindow* mainWindow = mainWindow_;
|
||||||
|
if(!mainWindow) {
|
||||||
|
mainWindow = new MainWindow(fm_file_info_get_path(fi));
|
||||||
|
mainWindow->resize(app->settings().windowWidth(), app->settings().windowHeight());
|
||||||
|
|
||||||
|
if(app->settings().windowMaximized()) {
|
||||||
|
mainWindow->setWindowState(mainWindow->windowState() | Qt::WindowMaximized);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
mainWindow->chdir(fm_file_info_get_path(fi));
|
||||||
|
l = l->next;
|
||||||
|
for(; l; l = l->next) {
|
||||||
|
fi = FM_FILE_INFO(l->data);
|
||||||
|
mainWindow->addTab(fm_file_info_get_path(fi));
|
||||||
|
}
|
||||||
|
mainWindow->show();
|
||||||
|
mainWindow->raise();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
} //namespace PCManFM
|
44
pcmanfm/launcher.h
Normal file
44
pcmanfm/launcher.h
Normal file
@ -0,0 +1,44 @@
|
|||||||
|
/*
|
||||||
|
* <one line to give the library's name and an idea of what it does.>
|
||||||
|
* Copyright (C) 2014 <copyright holder> <email>
|
||||||
|
*
|
||||||
|
* This library is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU Lesser General Public
|
||||||
|
* License as published by the Free Software Foundation; either
|
||||||
|
* version 2.1 of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This library is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public
|
||||||
|
* License along with this library; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef PCMANFM_LAUNCHER_H
|
||||||
|
#define PCMANFM_LAUNCHER_H
|
||||||
|
|
||||||
|
#include <libfm-qt/filelauncher.h>
|
||||||
|
|
||||||
|
namespace PCManFM {
|
||||||
|
|
||||||
|
class MainWindow;
|
||||||
|
|
||||||
|
class Launcher : public Fm::FileLauncher {
|
||||||
|
public:
|
||||||
|
Launcher(MainWindow* mainWindow = NULL);
|
||||||
|
~Launcher();
|
||||||
|
|
||||||
|
protected:
|
||||||
|
virtual bool openFolder(GAppLaunchContext* ctx, GList* folder_infos, GError** err);
|
||||||
|
|
||||||
|
private:
|
||||||
|
MainWindow* mainWindow_;
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // PCMANFM_LAUNCHER_H
|
780
pcmanfm/main-win.ui
Normal file
780
pcmanfm/main-win.ui
Normal file
@ -0,0 +1,780 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<ui version="4.0">
|
||||||
|
<class>MainWindow</class>
|
||||||
|
<widget class="QMainWindow" name="MainWindow">
|
||||||
|
<property name="geometry">
|
||||||
|
<rect>
|
||||||
|
<x>0</x>
|
||||||
|
<y>0</y>
|
||||||
|
<width>460</width>
|
||||||
|
<height>369</height>
|
||||||
|
</rect>
|
||||||
|
</property>
|
||||||
|
<property name="windowTitle">
|
||||||
|
<string>File Manager</string>
|
||||||
|
</property>
|
||||||
|
<property name="windowIcon">
|
||||||
|
<iconset theme="folder">
|
||||||
|
<normaloff>.</normaloff>.</iconset>
|
||||||
|
</property>
|
||||||
|
<widget class="QWidget" name="centralwidget">
|
||||||
|
<layout class="QVBoxLayout" name="verticalLayout">
|
||||||
|
<property name="leftMargin">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<property name="topMargin">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<property name="rightMargin">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<property name="bottomMargin">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<item>
|
||||||
|
<widget class="PCManFM::TabBar" name="tabBar" native="true">
|
||||||
|
<property name="sizePolicy">
|
||||||
|
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
|
||||||
|
<horstretch>0</horstretch>
|
||||||
|
<verstretch>0</verstretch>
|
||||||
|
</sizepolicy>
|
||||||
|
</property>
|
||||||
|
<property name="acceptDrops">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QSplitter" name="splitter">
|
||||||
|
<property name="orientation">
|
||||||
|
<enum>Qt::Horizontal</enum>
|
||||||
|
</property>
|
||||||
|
<widget class="Fm::SidePane" name="sidePane" native="true">
|
||||||
|
<property name="sizePolicy">
|
||||||
|
<sizepolicy hsizetype="Preferred" vsizetype="Expanding">
|
||||||
|
<horstretch>0</horstretch>
|
||||||
|
<verstretch>0</verstretch>
|
||||||
|
</sizepolicy>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
<widget class="QFrame" name="frame">
|
||||||
|
<layout class="QVBoxLayout" name="verticalLayout_2">
|
||||||
|
<property name="spacing">
|
||||||
|
<number>2</number>
|
||||||
|
</property>
|
||||||
|
<property name="leftMargin">
|
||||||
|
<number>1</number>
|
||||||
|
</property>
|
||||||
|
<property name="topMargin">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<property name="rightMargin">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<property name="bottomMargin">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<item>
|
||||||
|
<widget class="QStackedWidget" name="stackedWidget">
|
||||||
|
<property name="sizePolicy">
|
||||||
|
<sizepolicy hsizetype="Expanding" vsizetype="Expanding">
|
||||||
|
<horstretch>0</horstretch>
|
||||||
|
<verstretch>0</verstretch>
|
||||||
|
</sizepolicy>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QLineEdit" name="filterBar">
|
||||||
|
<property name="placeholderText">
|
||||||
|
<string>Filter by string...</string>
|
||||||
|
</property>
|
||||||
|
<property name="clearButtonEnabled">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
<property name="toolTip">
|
||||||
|
<string>Focus with Ctrl+I</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
<widget class="QMenuBar" name="menubar">
|
||||||
|
<property name="geometry">
|
||||||
|
<rect>
|
||||||
|
<x>0</x>
|
||||||
|
<y>0</y>
|
||||||
|
<width>460</width>
|
||||||
|
<height>23</height>
|
||||||
|
</rect>
|
||||||
|
</property>
|
||||||
|
<widget class="QMenu" name="menu_File">
|
||||||
|
<property name="title">
|
||||||
|
<string>&File</string>
|
||||||
|
</property>
|
||||||
|
<widget class="QMenu" name="menuCreateNew">
|
||||||
|
<property name="title">
|
||||||
|
<string>C&reate New</string>
|
||||||
|
</property>
|
||||||
|
<addaction name="actionNewFolder"/>
|
||||||
|
<addaction name="actionNewBlankFile"/>
|
||||||
|
</widget>
|
||||||
|
<addaction name="actionNewTab"/>
|
||||||
|
<addaction name="actionNewWin"/>
|
||||||
|
<addaction name="separator"/>
|
||||||
|
<addaction name="menuCreateNew"/>
|
||||||
|
<addaction name="separator"/>
|
||||||
|
<addaction name="actionFileProperties"/>
|
||||||
|
<addaction name="actionFolderProperties"/>
|
||||||
|
<addaction name="separator"/>
|
||||||
|
<addaction name="actionCloseTab"/>
|
||||||
|
<addaction name="actionCloseWindow"/>
|
||||||
|
</widget>
|
||||||
|
<widget class="QMenu" name="menu_Help">
|
||||||
|
<property name="title">
|
||||||
|
<string>&Help</string>
|
||||||
|
</property>
|
||||||
|
<addaction name="actionAbout"/>
|
||||||
|
</widget>
|
||||||
|
<widget class="QMenu" name="menu_View">
|
||||||
|
<property name="title">
|
||||||
|
<string>&View</string>
|
||||||
|
</property>
|
||||||
|
<widget class="QMenu" name="menuSorting">
|
||||||
|
<property name="title">
|
||||||
|
<string>&Sorting</string>
|
||||||
|
</property>
|
||||||
|
<addaction name="actionByFileName"/>
|
||||||
|
<addaction name="actionByMTime"/>
|
||||||
|
<addaction name="actionByFileSize"/>
|
||||||
|
<addaction name="actionByFileType"/>
|
||||||
|
<addaction name="actionByOwner"/>
|
||||||
|
<addaction name="separator"/>
|
||||||
|
<addaction name="actionAscending"/>
|
||||||
|
<addaction name="actionDescending"/>
|
||||||
|
<addaction name="separator"/>
|
||||||
|
<addaction name="actionFolderFirst"/>
|
||||||
|
<addaction name="actionCaseSensitive"/>
|
||||||
|
</widget>
|
||||||
|
<addaction name="actionReload"/>
|
||||||
|
<addaction name="actionShowHidden"/>
|
||||||
|
<addaction name="separator"/>
|
||||||
|
<addaction name="actionIconView"/>
|
||||||
|
<addaction name="actionThumbnailView"/>
|
||||||
|
<addaction name="actionCompactView"/>
|
||||||
|
<addaction name="actionDetailedList"/>
|
||||||
|
<addaction name="separator"/>
|
||||||
|
<addaction name="menuSorting"/>
|
||||||
|
<addaction name="actionFilter"/>
|
||||||
|
<addaction name="actionMenu_bar"/>
|
||||||
|
</widget>
|
||||||
|
<widget class="QMenu" name="menu_Editw">
|
||||||
|
<property name="title">
|
||||||
|
<string>&Edit</string>
|
||||||
|
</property>
|
||||||
|
<addaction name="actionCut"/>
|
||||||
|
<addaction name="actionCopy"/>
|
||||||
|
<addaction name="actionPaste"/>
|
||||||
|
<addaction name="actionRename"/>
|
||||||
|
<addaction name="actionDelete"/>
|
||||||
|
<addaction name="separator"/>
|
||||||
|
<addaction name="actionSelectAll"/>
|
||||||
|
<addaction name="actionInvertSelection"/>
|
||||||
|
<addaction name="separator"/>
|
||||||
|
<addaction name="actionPreferences"/>
|
||||||
|
</widget>
|
||||||
|
<widget class="QMenu" name="menu_Bookmarks">
|
||||||
|
<property name="title">
|
||||||
|
<string>&Bookmarks</string>
|
||||||
|
</property>
|
||||||
|
<addaction name="actionAddToBookmarks"/>
|
||||||
|
<addaction name="actionEditBookmarks"/>
|
||||||
|
</widget>
|
||||||
|
<widget class="QMenu" name="menu_Go">
|
||||||
|
<property name="title">
|
||||||
|
<string>&Go</string>
|
||||||
|
</property>
|
||||||
|
<addaction name="actionHome"/>
|
||||||
|
<addaction name="actionDesktop"/>
|
||||||
|
<addaction name="actionComputer"/>
|
||||||
|
<addaction name="actionTrash"/>
|
||||||
|
<addaction name="actionNetwork"/>
|
||||||
|
<addaction name="actionApplications"/>
|
||||||
|
<addaction name="separator"/>
|
||||||
|
<addaction name="actionGoBack"/>
|
||||||
|
<addaction name="actionGoForward"/>
|
||||||
|
<addaction name="actionGoUp"/>
|
||||||
|
</widget>
|
||||||
|
<widget class="QMenu" name="menu_Tool">
|
||||||
|
<property name="title">
|
||||||
|
<string>&Tool</string>
|
||||||
|
</property>
|
||||||
|
<addaction name="actionOpenTerminal"/>
|
||||||
|
<addaction name="actionOpenAsRoot"/>
|
||||||
|
<addaction name="actionFindFiles"/>
|
||||||
|
</widget>
|
||||||
|
<addaction name="menu_File"/>
|
||||||
|
<addaction name="menu_Editw"/>
|
||||||
|
<addaction name="menu_View"/>
|
||||||
|
<addaction name="menu_Go"/>
|
||||||
|
<addaction name="menu_Bookmarks"/>
|
||||||
|
<addaction name="menu_Tool"/>
|
||||||
|
<addaction name="menu_Help"/>
|
||||||
|
</widget>
|
||||||
|
<widget class="QStatusBar" name="statusbar"/>
|
||||||
|
<widget class="QToolBar" name="toolBar">
|
||||||
|
<property name="windowTitle">
|
||||||
|
<string>Main Toolbar</string>
|
||||||
|
</property>
|
||||||
|
<property name="movable">
|
||||||
|
<bool>false</bool>
|
||||||
|
</property>
|
||||||
|
<property name="floatable">
|
||||||
|
<bool>false</bool>
|
||||||
|
</property>
|
||||||
|
<attribute name="toolBarArea">
|
||||||
|
<enum>TopToolBarArea</enum>
|
||||||
|
</attribute>
|
||||||
|
<attribute name="toolBarBreak">
|
||||||
|
<bool>false</bool>
|
||||||
|
</attribute>
|
||||||
|
<addaction name="actionNewTab"/>
|
||||||
|
<addaction name="actionGoBack"/>
|
||||||
|
<addaction name="actionGoForward"/>
|
||||||
|
<addaction name="actionGoUp"/>
|
||||||
|
<addaction name="actionReload"/>
|
||||||
|
<addaction name="actionGo"/>
|
||||||
|
<addaction name="separator"/>
|
||||||
|
<addaction name="actionMenu"/>
|
||||||
|
</widget>
|
||||||
|
<action name="actionGoUp">
|
||||||
|
<property name="icon">
|
||||||
|
<iconset theme="go-up">
|
||||||
|
<normaloff>.</normaloff>.</iconset>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>Go &Up</string>
|
||||||
|
</property>
|
||||||
|
<property name="toolTip">
|
||||||
|
<string>Go Up</string>
|
||||||
|
</property>
|
||||||
|
<property name="shortcut">
|
||||||
|
<string>Alt+Up</string>
|
||||||
|
</property>
|
||||||
|
</action>
|
||||||
|
<action name="actionHome">
|
||||||
|
<property name="icon">
|
||||||
|
<iconset theme="user-home">
|
||||||
|
<normaloff>.</normaloff>.</iconset>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>&Home</string>
|
||||||
|
</property>
|
||||||
|
<property name="shortcut">
|
||||||
|
<string>Alt+Home</string>
|
||||||
|
</property>
|
||||||
|
</action>
|
||||||
|
<action name="actionReload">
|
||||||
|
<property name="icon">
|
||||||
|
<iconset theme="view-refresh">
|
||||||
|
<normaloff>.</normaloff>.</iconset>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>&Reload</string>
|
||||||
|
</property>
|
||||||
|
<property name="shortcut">
|
||||||
|
<string>F5</string>
|
||||||
|
</property>
|
||||||
|
</action>
|
||||||
|
<action name="actionGo">
|
||||||
|
<property name="icon">
|
||||||
|
<iconset theme="go-jump">
|
||||||
|
<normaloff>.</normaloff>.</iconset>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>Go</string>
|
||||||
|
</property>
|
||||||
|
</action>
|
||||||
|
<action name="actionQuit">
|
||||||
|
<property name="icon">
|
||||||
|
<iconset theme="application-exit">
|
||||||
|
<normaloff>.</normaloff>.</iconset>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>Quit</string>
|
||||||
|
</property>
|
||||||
|
</action>
|
||||||
|
<action name="actionAbout">
|
||||||
|
<property name="icon">
|
||||||
|
<iconset theme="help-about">
|
||||||
|
<normaloff>.</normaloff>.</iconset>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>&About</string>
|
||||||
|
</property>
|
||||||
|
</action>
|
||||||
|
<action name="actionNewWin">
|
||||||
|
<property name="icon">
|
||||||
|
<iconset theme="window-new">
|
||||||
|
<normaloff>.</normaloff>.</iconset>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>&New Window</string>
|
||||||
|
</property>
|
||||||
|
<property name="toolTip">
|
||||||
|
<string>New Window</string>
|
||||||
|
</property>
|
||||||
|
<property name="shortcut">
|
||||||
|
<string>Ctrl+N</string>
|
||||||
|
</property>
|
||||||
|
</action>
|
||||||
|
<action name="actionShowHidden">
|
||||||
|
<property name="checkable">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>Show &Hidden</string>
|
||||||
|
</property>
|
||||||
|
<property name="shortcut">
|
||||||
|
<string>Ctrl+H</string>
|
||||||
|
</property>
|
||||||
|
</action>
|
||||||
|
<action name="actionComputer">
|
||||||
|
<property name="icon">
|
||||||
|
<iconset theme="computer">
|
||||||
|
<normaloff>.</normaloff>.</iconset>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>&Computer</string>
|
||||||
|
</property>
|
||||||
|
</action>
|
||||||
|
<action name="actionTrash">
|
||||||
|
<property name="icon">
|
||||||
|
<iconset theme="user-trash">
|
||||||
|
<normaloff>.</normaloff>.</iconset>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>&Trash</string>
|
||||||
|
</property>
|
||||||
|
</action>
|
||||||
|
<action name="actionNetwork">
|
||||||
|
<property name="text">
|
||||||
|
<string>&Network</string>
|
||||||
|
</property>
|
||||||
|
</action>
|
||||||
|
<action name="actionDesktop">
|
||||||
|
<property name="icon">
|
||||||
|
<iconset theme="user-desktop">
|
||||||
|
<normaloff>.</normaloff>.</iconset>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>&Desktop</string>
|
||||||
|
</property>
|
||||||
|
</action>
|
||||||
|
<action name="actionAddToBookmarks">
|
||||||
|
<property name="icon">
|
||||||
|
<iconset theme="list-add">
|
||||||
|
<normaloff>.</normaloff>.</iconset>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>&Add to Bookmarks</string>
|
||||||
|
</property>
|
||||||
|
</action>
|
||||||
|
<action name="actionApplications">
|
||||||
|
<property name="text">
|
||||||
|
<string>&Applications</string>
|
||||||
|
</property>
|
||||||
|
</action>
|
||||||
|
<action name="actionReload_2">
|
||||||
|
<property name="text">
|
||||||
|
<string>Reload</string>
|
||||||
|
</property>
|
||||||
|
</action>
|
||||||
|
<action name="actionIconView">
|
||||||
|
<property name="checkable">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>&Icon View</string>
|
||||||
|
</property>
|
||||||
|
</action>
|
||||||
|
<action name="actionCompactView">
|
||||||
|
<property name="checkable">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>&Compact View</string>
|
||||||
|
</property>
|
||||||
|
</action>
|
||||||
|
<action name="actionDetailedList">
|
||||||
|
<property name="checkable">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>&Detailed List</string>
|
||||||
|
</property>
|
||||||
|
</action>
|
||||||
|
<action name="actionThumbnailView">
|
||||||
|
<property name="checkable">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>&Thumbnail View</string>
|
||||||
|
</property>
|
||||||
|
</action>
|
||||||
|
<action name="actionCut">
|
||||||
|
<property name="icon">
|
||||||
|
<iconset theme="edit-cut">
|
||||||
|
<normaloff>.</normaloff>.</iconset>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>Cu&t</string>
|
||||||
|
</property>
|
||||||
|
<property name="shortcut">
|
||||||
|
<string>Ctrl+X</string>
|
||||||
|
</property>
|
||||||
|
</action>
|
||||||
|
<action name="actionCopy">
|
||||||
|
<property name="icon">
|
||||||
|
<iconset theme="edit-copy">
|
||||||
|
<normaloff>.</normaloff>.</iconset>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>&Copy</string>
|
||||||
|
</property>
|
||||||
|
<property name="shortcut">
|
||||||
|
<string>Ctrl+C</string>
|
||||||
|
</property>
|
||||||
|
</action>
|
||||||
|
<action name="actionPaste">
|
||||||
|
<property name="icon">
|
||||||
|
<iconset theme="edit-paste">
|
||||||
|
<normaloff>.</normaloff>.</iconset>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>&Paste</string>
|
||||||
|
</property>
|
||||||
|
<property name="shortcut">
|
||||||
|
<string>Ctrl+V</string>
|
||||||
|
</property>
|
||||||
|
</action>
|
||||||
|
<action name="actionSelectAll">
|
||||||
|
<property name="text">
|
||||||
|
<string>Select &All</string>
|
||||||
|
</property>
|
||||||
|
<property name="shortcut">
|
||||||
|
<string>Ctrl+A</string>
|
||||||
|
</property>
|
||||||
|
</action>
|
||||||
|
<action name="actionPreferences">
|
||||||
|
<property name="text">
|
||||||
|
<string>Pr&eferences</string>
|
||||||
|
</property>
|
||||||
|
</action>
|
||||||
|
<action name="actionAscending">
|
||||||
|
<property name="checkable">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>&Ascending</string>
|
||||||
|
</property>
|
||||||
|
</action>
|
||||||
|
<action name="actionDescending">
|
||||||
|
<property name="checkable">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>&Descending</string>
|
||||||
|
</property>
|
||||||
|
</action>
|
||||||
|
<action name="actionByFileName">
|
||||||
|
<property name="checkable">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>&By File Name</string>
|
||||||
|
</property>
|
||||||
|
</action>
|
||||||
|
<action name="actionByMTime">
|
||||||
|
<property name="checkable">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>By &Modification Time</string>
|
||||||
|
</property>
|
||||||
|
</action>
|
||||||
|
<action name="actionByFileType">
|
||||||
|
<property name="checkable">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>By File &Type</string>
|
||||||
|
</property>
|
||||||
|
</action>
|
||||||
|
<action name="actionByOwner">
|
||||||
|
<property name="checkable">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>By &Owner</string>
|
||||||
|
</property>
|
||||||
|
</action>
|
||||||
|
<action name="actionFolderFirst">
|
||||||
|
<property name="checkable">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>&Folder First</string>
|
||||||
|
</property>
|
||||||
|
</action>
|
||||||
|
<action name="actionNewTab">
|
||||||
|
<property name="icon">
|
||||||
|
<iconset theme="window-new">
|
||||||
|
<normaloff>.</normaloff>.</iconset>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>New &Tab</string>
|
||||||
|
</property>
|
||||||
|
<property name="toolTip">
|
||||||
|
<string>New Tab</string>
|
||||||
|
</property>
|
||||||
|
<property name="shortcut">
|
||||||
|
<string>Ctrl+T</string>
|
||||||
|
</property>
|
||||||
|
</action>
|
||||||
|
<action name="actionGoBack">
|
||||||
|
<property name="icon">
|
||||||
|
<iconset theme="go-previous">
|
||||||
|
<normaloff>.</normaloff>.</iconset>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>Go &Back</string>
|
||||||
|
</property>
|
||||||
|
<property name="toolTip">
|
||||||
|
<string>Go Back</string>
|
||||||
|
</property>
|
||||||
|
<property name="shortcut">
|
||||||
|
<string>Alt+Left</string>
|
||||||
|
</property>
|
||||||
|
</action>
|
||||||
|
<action name="actionGoForward">
|
||||||
|
<property name="icon">
|
||||||
|
<iconset theme="go-next">
|
||||||
|
<normaloff>.</normaloff>.</iconset>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>Go &Forward</string>
|
||||||
|
</property>
|
||||||
|
<property name="toolTip">
|
||||||
|
<string>Go Forward</string>
|
||||||
|
</property>
|
||||||
|
<property name="shortcut">
|
||||||
|
<string>Alt+Right</string>
|
||||||
|
</property>
|
||||||
|
</action>
|
||||||
|
<action name="actionInvertSelection">
|
||||||
|
<property name="text">
|
||||||
|
<string>&Invert Selection</string>
|
||||||
|
</property>
|
||||||
|
</action>
|
||||||
|
<action name="actionDelete">
|
||||||
|
<property name="icon">
|
||||||
|
<iconset theme="edit-delete">
|
||||||
|
<normaloff>.</normaloff>.</iconset>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>&Delete</string>
|
||||||
|
</property>
|
||||||
|
<property name="shortcut">
|
||||||
|
<string>Del</string>
|
||||||
|
</property>
|
||||||
|
</action>
|
||||||
|
<action name="actionRename">
|
||||||
|
<property name="text">
|
||||||
|
<string>&Rename</string>
|
||||||
|
</property>
|
||||||
|
<property name="shortcut">
|
||||||
|
<string>F2</string>
|
||||||
|
</property>
|
||||||
|
</action>
|
||||||
|
<action name="actionCloseTab">
|
||||||
|
<property name="text">
|
||||||
|
<string>C&lose Tab</string>
|
||||||
|
</property>
|
||||||
|
<property name="shortcut">
|
||||||
|
<string>Ctrl+W</string>
|
||||||
|
</property>
|
||||||
|
</action>
|
||||||
|
<action name="actionFileProperties">
|
||||||
|
<property name="text">
|
||||||
|
<string>File &Properties</string>
|
||||||
|
</property>
|
||||||
|
<property name="shortcut">
|
||||||
|
<string>Alt+Return</string>
|
||||||
|
</property>
|
||||||
|
</action>
|
||||||
|
<action name="actionFolderProperties">
|
||||||
|
<property name="text">
|
||||||
|
<string>&Folder Properties</string>
|
||||||
|
</property>
|
||||||
|
</action>
|
||||||
|
<action name="actionCaseSensitive">
|
||||||
|
<property name="checkable">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>&Case Sensitive</string>
|
||||||
|
</property>
|
||||||
|
</action>
|
||||||
|
<action name="actionByFileSize">
|
||||||
|
<property name="checkable">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>By File &Size</string>
|
||||||
|
</property>
|
||||||
|
</action>
|
||||||
|
<action name="actionCloseWindow">
|
||||||
|
<property name="text">
|
||||||
|
<string>&Close Window</string>
|
||||||
|
</property>
|
||||||
|
<property name="shortcut">
|
||||||
|
<string>Ctrl+Q</string>
|
||||||
|
</property>
|
||||||
|
</action>
|
||||||
|
<action name="actionEdit_Bookmarks">
|
||||||
|
<property name="text">
|
||||||
|
<string>Edit Bookmarks</string>
|
||||||
|
</property>
|
||||||
|
</action>
|
||||||
|
<action name="actionOpenTerminal">
|
||||||
|
<property name="text">
|
||||||
|
<string>Open &Terminal</string>
|
||||||
|
</property>
|
||||||
|
<property name="shortcut">
|
||||||
|
<string>F4</string>
|
||||||
|
</property>
|
||||||
|
</action>
|
||||||
|
<action name="actionOpenAsRoot">
|
||||||
|
<property name="text">
|
||||||
|
<string>Open as &Root</string>
|
||||||
|
</property>
|
||||||
|
</action>
|
||||||
|
<action name="actionEditBookmarks">
|
||||||
|
<property name="text">
|
||||||
|
<string>&Edit Bookmarks</string>
|
||||||
|
</property>
|
||||||
|
</action>
|
||||||
|
<action name="actionNewFolder">
|
||||||
|
<property name="icon">
|
||||||
|
<iconset theme="folder-new">
|
||||||
|
<normaloff>.</normaloff>.</iconset>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>&Folder</string>
|
||||||
|
</property>
|
||||||
|
<property name="shortcut">
|
||||||
|
<string>Ctrl+Shift+N</string>
|
||||||
|
</property>
|
||||||
|
</action>
|
||||||
|
<action name="actionNewBlankFile">
|
||||||
|
<property name="icon">
|
||||||
|
<iconset theme="document-new">
|
||||||
|
<normaloff>.</normaloff>.</iconset>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>&Blank File</string>
|
||||||
|
</property>
|
||||||
|
<property name="shortcut">
|
||||||
|
<string>Ctrl+Alt+N</string>
|
||||||
|
</property>
|
||||||
|
</action>
|
||||||
|
<action name="actionFindFiles">
|
||||||
|
<property name="text">
|
||||||
|
<string>&Find Files</string>
|
||||||
|
</property>
|
||||||
|
<property name="shortcut">
|
||||||
|
<string>F3</string>
|
||||||
|
</property>
|
||||||
|
</action>
|
||||||
|
<action name="actionFilter">
|
||||||
|
<property name="checkable">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>&Filter</string>
|
||||||
|
</property>
|
||||||
|
<property name="shortcut">
|
||||||
|
<string>Ctrl+B</string>
|
||||||
|
</property>
|
||||||
|
</action>
|
||||||
|
<action name="actionCloseLeft">
|
||||||
|
<property name="icon">
|
||||||
|
<iconset theme="go-previous">
|
||||||
|
<normaloff>.</normaloff>.</iconset>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>Close &left tabs</string>
|
||||||
|
</property>
|
||||||
|
</action>
|
||||||
|
<action name="actionCloseRight">
|
||||||
|
<property name="icon">
|
||||||
|
<iconset theme="go-next">
|
||||||
|
<normaloff>.</normaloff>.</iconset>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>Close &right tabs</string>
|
||||||
|
</property>
|
||||||
|
</action>
|
||||||
|
<action name="actionCloseOther">
|
||||||
|
<property name="text">
|
||||||
|
<string>Close &other tabs</string>
|
||||||
|
</property>
|
||||||
|
</action>
|
||||||
|
<action name="actionMenu_bar">
|
||||||
|
<property name="checkable">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>Menu bar</string>
|
||||||
|
</property>
|
||||||
|
<property name="toolTip">
|
||||||
|
<string>Menu bar</string>
|
||||||
|
</property>
|
||||||
|
<property name="shortcut">
|
||||||
|
<string>Ctrl+M</string>
|
||||||
|
</property>
|
||||||
|
</action>
|
||||||
|
<action name="actionMenu">
|
||||||
|
<property name="icon">
|
||||||
|
<iconset theme="application-menu"/>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>Menu</string>
|
||||||
|
</property>
|
||||||
|
<property name="toolTip">
|
||||||
|
<string>Menu</string>
|
||||||
|
</property>
|
||||||
|
</action>
|
||||||
|
</widget>
|
||||||
|
<customwidgets>
|
||||||
|
<customwidget>
|
||||||
|
<class>PCManFM::TabBar</class>
|
||||||
|
<extends>QWidget</extends>
|
||||||
|
<header>tabbar.h</header>
|
||||||
|
<container>1</container>
|
||||||
|
</customwidget>
|
||||||
|
<customwidget>
|
||||||
|
<class>Fm::SidePane</class>
|
||||||
|
<extends>QWidget</extends>
|
||||||
|
<header location="global">libfm-qt/sidepane.h</header>
|
||||||
|
<container>1</container>
|
||||||
|
</customwidget>
|
||||||
|
</customwidgets>
|
||||||
|
<resources/>
|
||||||
|
<connections/>
|
||||||
|
</ui>
|
1216
pcmanfm/mainwindow.cpp
Normal file
1216
pcmanfm/mainwindow.cpp
Normal file
File diff suppressed because it is too large
Load Diff
182
pcmanfm/mainwindow.h
Normal file
182
pcmanfm/mainwindow.h
Normal file
@ -0,0 +1,182 @@
|
|||||||
|
/*
|
||||||
|
|
||||||
|
Copyright (C) 2013 Hong Jen Yee (PCMan) <pcman.tw@gmail.com>
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation; either version 2 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License along
|
||||||
|
with this program; if not, write to the Free Software Foundation, Inc.,
|
||||||
|
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef FM_MAIN_WINDOW_H
|
||||||
|
#define FM_MAIN_WINDOW_H
|
||||||
|
|
||||||
|
#include "ui_main-win.h"
|
||||||
|
#include <QMainWindow>
|
||||||
|
#include <QListView>
|
||||||
|
#include <QSortFilterProxyModel>
|
||||||
|
#include <QLineEdit>
|
||||||
|
#include <QTabWidget>
|
||||||
|
#include <libfm/fm.h>
|
||||||
|
#include <QMessageBox>
|
||||||
|
#include <QTabBar>
|
||||||
|
#include <QStackedWidget>
|
||||||
|
#include <QSplitter>
|
||||||
|
#include "launcher.h"
|
||||||
|
|
||||||
|
namespace PCManFM {
|
||||||
|
|
||||||
|
class TabPage;
|
||||||
|
class Settings;
|
||||||
|
|
||||||
|
class MainWindow : public QMainWindow {
|
||||||
|
Q_OBJECT
|
||||||
|
public:
|
||||||
|
MainWindow(FmPath* path = NULL);
|
||||||
|
virtual ~MainWindow();
|
||||||
|
|
||||||
|
void chdir(FmPath* path);
|
||||||
|
int addTab(FmPath* path);
|
||||||
|
|
||||||
|
TabPage* currentPage() {
|
||||||
|
return reinterpret_cast<TabPage*>(ui.stackedWidget->currentWidget());
|
||||||
|
}
|
||||||
|
|
||||||
|
void updateFromSettings(Settings& settings);
|
||||||
|
|
||||||
|
protected Q_SLOTS:
|
||||||
|
|
||||||
|
void onPathEntryReturnPressed();
|
||||||
|
|
||||||
|
void on_actionNewTab_triggered();
|
||||||
|
void on_actionNewWin_triggered();
|
||||||
|
void on_actionNewFolder_triggered();
|
||||||
|
void on_actionNewBlankFile_triggered();
|
||||||
|
void on_actionCloseTab_triggered();
|
||||||
|
void on_actionCloseWindow_triggered();
|
||||||
|
void on_actionFileProperties_triggered();
|
||||||
|
void on_actionFolderProperties_triggered();
|
||||||
|
|
||||||
|
void on_actionCut_triggered();
|
||||||
|
void on_actionCopy_triggered();
|
||||||
|
void on_actionPaste_triggered();
|
||||||
|
void on_actionDelete_triggered();
|
||||||
|
void on_actionRename_triggered();
|
||||||
|
void on_actionSelectAll_triggered();
|
||||||
|
void on_actionInvertSelection_triggered();
|
||||||
|
void on_actionPreferences_triggered();
|
||||||
|
|
||||||
|
void on_actionGoBack_triggered();
|
||||||
|
void on_actionGoForward_triggered();
|
||||||
|
void on_actionGoUp_triggered();
|
||||||
|
void on_actionHome_triggered();
|
||||||
|
void on_actionReload_triggered();
|
||||||
|
|
||||||
|
void on_actionIconView_triggered();
|
||||||
|
void on_actionCompactView_triggered();
|
||||||
|
void on_actionDetailedList_triggered();
|
||||||
|
void on_actionThumbnailView_triggered();
|
||||||
|
|
||||||
|
void on_actionGo_triggered();
|
||||||
|
void on_actionShowHidden_triggered(bool check);
|
||||||
|
|
||||||
|
void on_actionByFileName_triggered(bool checked);
|
||||||
|
void on_actionByMTime_triggered(bool checked);
|
||||||
|
void on_actionByOwner_triggered(bool checked);
|
||||||
|
void on_actionByFileType_triggered(bool checked);
|
||||||
|
void on_actionByFileSize_triggered(bool checked);
|
||||||
|
void on_actionAscending_triggered(bool checked);
|
||||||
|
void on_actionDescending_triggered(bool checked);
|
||||||
|
void on_actionFolderFirst_triggered(bool checked);
|
||||||
|
void on_actionCaseSensitive_triggered(bool checked);
|
||||||
|
void on_actionFilter_triggered(bool checked);
|
||||||
|
|
||||||
|
void on_actionApplications_triggered();
|
||||||
|
void on_actionComputer_triggered();
|
||||||
|
void on_actionTrash_triggered();
|
||||||
|
void on_actionNetwork_triggered();
|
||||||
|
void on_actionDesktop_triggered();
|
||||||
|
void on_actionAddToBookmarks_triggered();
|
||||||
|
void on_actionEditBookmarks_triggered();
|
||||||
|
|
||||||
|
void on_actionOpenTerminal_triggered();
|
||||||
|
void on_actionOpenAsRoot_triggered();
|
||||||
|
void on_actionFindFiles_triggered();
|
||||||
|
|
||||||
|
void on_actionAbout_triggered();
|
||||||
|
|
||||||
|
void onBookmarkActionTriggered();
|
||||||
|
|
||||||
|
void onTabBarCloseRequested(int index);
|
||||||
|
void onTabBarCurrentChanged(int index);
|
||||||
|
void onTabBarTabMoved(int from, int to);
|
||||||
|
|
||||||
|
void focusFilterBar();
|
||||||
|
void onFilterStringChanged(QString str);
|
||||||
|
|
||||||
|
void onShortcutPrevTab();
|
||||||
|
void onShortcutNextTab();
|
||||||
|
void onShortcutJumpToTab();
|
||||||
|
|
||||||
|
void onStackedWidgetWidgetRemoved(int index);
|
||||||
|
|
||||||
|
void onTabPageTitleChanged(QString title);
|
||||||
|
void onTabPageStatusChanged(int type, QString statusText);
|
||||||
|
void onTabPageOpenDirRequested(FmPath* path, int target);
|
||||||
|
void onTabPageSortFilterChanged();
|
||||||
|
|
||||||
|
void onSidePaneChdirRequested(int type, FmPath* path);
|
||||||
|
void onSidePaneOpenFolderInNewWindowRequested(FmPath* path);
|
||||||
|
void onSidePaneOpenFolderInNewTabRequested(FmPath* path);
|
||||||
|
void onSidePaneOpenFolderInTerminalRequested(FmPath* path);
|
||||||
|
void onSidePaneCreateNewFolderRequested(FmPath* path);
|
||||||
|
void onSidePaneModeChanged(Fm::SidePane::Mode mode);
|
||||||
|
void onSplitterMoved(int pos, int index);
|
||||||
|
void onResetFocus();
|
||||||
|
|
||||||
|
void onBackForwardContextMenu(QPoint pos);
|
||||||
|
|
||||||
|
void tabContextMenu(const QPoint& pos);
|
||||||
|
void closeLeftTabs();
|
||||||
|
void closeRightTabs();
|
||||||
|
void closeOtherTabs() {
|
||||||
|
closeLeftTabs();
|
||||||
|
closeRightTabs();
|
||||||
|
}
|
||||||
|
void focusPathEntry();
|
||||||
|
void toggleMenuBar(bool checked);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
// void changeEvent( QEvent * event);
|
||||||
|
void closeTab(int index);
|
||||||
|
virtual void resizeEvent(QResizeEvent *event);
|
||||||
|
virtual void closeEvent(QCloseEvent *event);
|
||||||
|
|
||||||
|
private:
|
||||||
|
static void onBookmarksChanged(FmBookmarks* bookmarks, MainWindow* pThis);
|
||||||
|
void loadBookmarksMenu();
|
||||||
|
void updateUIForCurrentPage();
|
||||||
|
void updateViewMenuForCurrentPage();
|
||||||
|
void updateStatusBarForCurrentPage();
|
||||||
|
|
||||||
|
private:
|
||||||
|
Ui::MainWindow ui;
|
||||||
|
QLineEdit* pathEntry;
|
||||||
|
QLabel* fsInfoLabel;
|
||||||
|
FmBookmarks* bookmarks;
|
||||||
|
Launcher fileLauncher_;
|
||||||
|
int rightClickIndex;
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // FM_MAIN_WINDOW_H
|
29
pcmanfm/org.pcmanfm.Application.xml
Normal file
29
pcmanfm/org.pcmanfm.Application.xml
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
<!DOCTYPE node PUBLIC "-//freedesktop//DTD D-BUS Object Introspection 1.0//EN" "http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd">
|
||||||
|
<node>
|
||||||
|
<interface name="org.pcmanfm.Application">
|
||||||
|
<method name="preferences">
|
||||||
|
<arg type="s" direction="in"/>
|
||||||
|
</method>
|
||||||
|
<method name="desktopPrefrences">
|
||||||
|
<arg type="s" direction="in"/>
|
||||||
|
</method>
|
||||||
|
<method name="desktopManager">
|
||||||
|
<arg type="b" direction="in"/>
|
||||||
|
</method>
|
||||||
|
<method name="launchFiles">
|
||||||
|
<arg type="s" direction="in"/>
|
||||||
|
<arg type="as" direction="in"/>
|
||||||
|
<arg type="b" direction="in"/>
|
||||||
|
</method>
|
||||||
|
<method name="quit">
|
||||||
|
</method>
|
||||||
|
<method name="setWallpaper">
|
||||||
|
<arg type="s" direction="in"/>
|
||||||
|
<arg type="s" direction="in"/>
|
||||||
|
</method>
|
||||||
|
<method name="findFiles">
|
||||||
|
<arg type="as" direction="in"/>
|
||||||
|
</method>
|
||||||
|
<property name="desktopManagerEnabled" type="b" access="read"/>
|
||||||
|
</interface>
|
||||||
|
</node>
|
9
pcmanfm/pcmanfm-qt-desktop-pref.desktop.in
Normal file
9
pcmanfm/pcmanfm-qt-desktop-pref.desktop.in
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
[Desktop Entry]
|
||||||
|
Type=Application
|
||||||
|
Name=Desktop
|
||||||
|
GenericName=Desktop Settings
|
||||||
|
Comment=Change wallpapers and behavior of desktop manager
|
||||||
|
Exec=pcmanfm-qt --desktop-pref=general
|
||||||
|
Icon=user-desktop
|
||||||
|
Categories=Settings;Qt;DesktopSettings;
|
||||||
|
StartupNotify=true
|
10
pcmanfm/pcmanfm-qt.desktop.in
Normal file
10
pcmanfm/pcmanfm-qt.desktop.in
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
[Desktop Entry]
|
||||||
|
Type=Application
|
||||||
|
Name=PCManFM File Manager
|
||||||
|
GenericName=File Manager
|
||||||
|
Comment=Browse the file system and manage the files
|
||||||
|
Exec=pcmanfm-qt %U
|
||||||
|
MimeType=inode/directory;
|
||||||
|
Icon=system-file-manager
|
||||||
|
Categories=FileManager;Utility;Core;Qt;
|
||||||
|
StartupNotify=true
|
13
pcmanfm/pcmanfm.cpp
Normal file
13
pcmanfm/pcmanfm.cpp
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
#include <libfm/fm.h>
|
||||||
|
#include "application.h"
|
||||||
|
#include <libfm-qt/libfmqt.h>
|
||||||
|
|
||||||
|
int main(int argc, char** argv) {
|
||||||
|
// ensure that glib integration of Qt is not turned off
|
||||||
|
// This fixes #168: https://github.com/lxde/pcmanfm-qt/issues/168
|
||||||
|
qunsetenv("QT_NO_GLIB");
|
||||||
|
|
||||||
|
PCManFM::Application app(argc, argv);
|
||||||
|
app.init();
|
||||||
|
return app.exec();
|
||||||
|
}
|
1034
pcmanfm/preferences.ui
Normal file
1034
pcmanfm/preferences.ui
Normal file
File diff suppressed because it is too large
Load Diff
386
pcmanfm/preferencesdialog.cpp
Normal file
386
pcmanfm/preferencesdialog.cpp
Normal file
@ -0,0 +1,386 @@
|
|||||||
|
/*
|
||||||
|
|
||||||
|
Copyright (C) 2013 Hong Jen Yee (PCMan) <pcman.tw@gmail.com>
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation; either version 2 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License along
|
||||||
|
with this program; if not, write to the Free Software Foundation, Inc.,
|
||||||
|
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#include "preferencesdialog.h"
|
||||||
|
#include "application.h"
|
||||||
|
#include "settings.h"
|
||||||
|
#include <QDir>
|
||||||
|
#include <QHash>
|
||||||
|
#include <QStringBuilder>
|
||||||
|
#include <QSettings>
|
||||||
|
|
||||||
|
#include <libfm-qt/folderview.h>
|
||||||
|
|
||||||
|
namespace PCManFM {
|
||||||
|
|
||||||
|
static int bigIconSizes[] = {96, 72, 64, 48, 36, 32, 24, 20};
|
||||||
|
static int smallIconSizes[] = {48, 36, 32, 24, 20, 16, 12};
|
||||||
|
static int thumbnailIconSizes[] = {256, 224, 192, 160, 128, 96, 64};
|
||||||
|
|
||||||
|
PreferencesDialog::PreferencesDialog (QString activePage, QWidget* parent):
|
||||||
|
QDialog (parent) {
|
||||||
|
ui.setupUi(this);
|
||||||
|
setAttribute(Qt::WA_DeleteOnClose);
|
||||||
|
|
||||||
|
// resize the list widget according to the width of its content.
|
||||||
|
ui.listWidget->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Expanding);
|
||||||
|
ui.listWidget->setMaximumWidth(ui.listWidget->sizeHintForColumn(0) + ui.listWidget->frameWidth() * 2 + 4);
|
||||||
|
|
||||||
|
initFromSettings();
|
||||||
|
|
||||||
|
selectPage(activePage);
|
||||||
|
adjustSize();
|
||||||
|
}
|
||||||
|
|
||||||
|
PreferencesDialog::~PreferencesDialog() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
static void findIconThemesInDir(QHash<QString, QString>& iconThemes, QString dirName) {
|
||||||
|
QDir dir(dirName);
|
||||||
|
QStringList subDirs = dir.entryList(QDir::AllDirs);
|
||||||
|
GKeyFile* kf = g_key_file_new();
|
||||||
|
Q_FOREACH(QString subDir, subDirs) {
|
||||||
|
QString indexFile = dirName % '/' % subDir % "/index.theme";
|
||||||
|
if(g_key_file_load_from_file(kf, indexFile.toLocal8Bit().constData(), GKeyFileFlags(0), NULL)) {
|
||||||
|
// FIXME: skip hidden ones
|
||||||
|
// icon theme must have this key, so it has icons if it has this key
|
||||||
|
// otherwise, it might be a cursor theme or any other kind of theme.
|
||||||
|
if(g_key_file_has_key(kf, "Icon Theme", "Directories", NULL)) {
|
||||||
|
char* dispName = g_key_file_get_locale_string(kf, "Icon Theme", "Name", NULL, NULL);
|
||||||
|
// char* comment = g_key_file_get_locale_string(kf, "Icon Theme", "Comment", NULL, NULL);
|
||||||
|
iconThemes[subDir] = dispName;
|
||||||
|
g_free(dispName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
g_key_file_free(kf);
|
||||||
|
}
|
||||||
|
|
||||||
|
void PreferencesDialog::initIconThemes(Settings& settings) {
|
||||||
|
// check if auto-detection is done (for example, from xsettings)
|
||||||
|
if(settings.useFallbackIconTheme()) { // auto-detection failed
|
||||||
|
// load xdg icon themes and select the current one
|
||||||
|
QHash<QString, QString> iconThemes;
|
||||||
|
// user customed icon themes
|
||||||
|
findIconThemesInDir(iconThemes, QString(g_get_home_dir()) % "/.icons");
|
||||||
|
|
||||||
|
// search for icons in system data dir
|
||||||
|
const char* const* dataDirs = g_get_system_data_dirs();
|
||||||
|
for(const char* const* dataDir = dataDirs; *dataDir; ++dataDir) {
|
||||||
|
findIconThemesInDir(iconThemes, QString(*dataDir) % "/icons");
|
||||||
|
}
|
||||||
|
|
||||||
|
iconThemes.remove("hicolor"); // remove hicolor, which is only a fallback
|
||||||
|
QHash<QString, QString>::const_iterator it;
|
||||||
|
for(it = iconThemes.begin(); it != iconThemes.end(); ++it) {
|
||||||
|
ui.iconTheme->addItem(it.value(), it.key());
|
||||||
|
}
|
||||||
|
ui.iconTheme->model()->sort(0); // sort the list of icon theme names
|
||||||
|
|
||||||
|
// select current theme name
|
||||||
|
int n = ui.iconTheme->count();
|
||||||
|
int i;
|
||||||
|
for(i = 0; i < n; ++i) {
|
||||||
|
QVariant itemData = ui.iconTheme->itemData(i);
|
||||||
|
if(itemData == settings.fallbackIconThemeName()) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(i >= n)
|
||||||
|
i = 0;
|
||||||
|
ui.iconTheme->setCurrentIndex(i);
|
||||||
|
}
|
||||||
|
else { // auto-detection of icon theme works, hide the fallback icon theme combo box.
|
||||||
|
ui.iconThemeLabel->hide();
|
||||||
|
ui.iconTheme->hide();
|
||||||
|
}
|
||||||
|
|
||||||
|
ui.hMargin->setValue(settings.folderViewCellMargins().width());
|
||||||
|
ui.vMargin->setValue(settings.folderViewCellMargins().height());
|
||||||
|
connect(ui.lockMargins, &QAbstractButton::clicked, this, &PreferencesDialog::lockMargins);
|
||||||
|
}
|
||||||
|
|
||||||
|
void PreferencesDialog::initArchivers(Settings& settings) {
|
||||||
|
const GList* allArchivers = fm_archiver_get_all();
|
||||||
|
int i = 0;
|
||||||
|
for(const GList* l = allArchivers; l; l = l->next, ++i) {
|
||||||
|
FmArchiver* archiver = reinterpret_cast<FmArchiver*>(l->data);
|
||||||
|
ui.archiver->addItem(archiver->program, QString(archiver->program));
|
||||||
|
if(archiver->program == settings.archiver())
|
||||||
|
ui.archiver->setCurrentIndex(i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void PreferencesDialog::initDisplayPage(Settings& settings) {
|
||||||
|
initIconThemes(settings);
|
||||||
|
// icon sizes
|
||||||
|
int i;
|
||||||
|
for(i = 0; i < G_N_ELEMENTS(bigIconSizes); ++i) {
|
||||||
|
int size = bigIconSizes[i];
|
||||||
|
ui.bigIconSize->addItem(QString("%1 x %1").arg(size), size);
|
||||||
|
if(settings.bigIconSize() == size)
|
||||||
|
ui.bigIconSize->setCurrentIndex(i);
|
||||||
|
}
|
||||||
|
for(i = 0; i < G_N_ELEMENTS(smallIconSizes); ++i) {
|
||||||
|
int size = smallIconSizes[i];
|
||||||
|
QString text = QString("%1 x %1").arg(size);
|
||||||
|
ui.smallIconSize->addItem(text, size);
|
||||||
|
if(settings.smallIconSize() == size)
|
||||||
|
ui.smallIconSize->setCurrentIndex(i);
|
||||||
|
|
||||||
|
ui.sidePaneIconSize->addItem(text, size);
|
||||||
|
if(settings.sidePaneIconSize() == size)
|
||||||
|
ui.sidePaneIconSize->setCurrentIndex(i);
|
||||||
|
}
|
||||||
|
for(i = 0; i < G_N_ELEMENTS(thumbnailIconSizes); ++i) {
|
||||||
|
int size = thumbnailIconSizes[i];
|
||||||
|
ui.thumbnailIconSize->addItem(QString("%1 x %1").arg(size), size);
|
||||||
|
if(settings.thumbnailIconSize() == size)
|
||||||
|
ui.thumbnailIconSize->setCurrentIndex(i);
|
||||||
|
}
|
||||||
|
|
||||||
|
ui.siUnit->setChecked(settings.siUnit());
|
||||||
|
ui.backupAsHidden->setChecked(settings.backupAsHidden());
|
||||||
|
|
||||||
|
ui.showFullNames->setChecked(settings.showFullNames());
|
||||||
|
ui.shadowHidden->setChecked(settings.shadowHidden());
|
||||||
|
|
||||||
|
// FIXME: Hide options that we don't support yet.
|
||||||
|
ui.showFullNames->hide();
|
||||||
|
ui.shadowHidden->hide();
|
||||||
|
}
|
||||||
|
|
||||||
|
void PreferencesDialog::initUiPage(Settings& settings) {
|
||||||
|
ui.alwaysShowTabs->setChecked(settings.alwaysShowTabs());
|
||||||
|
ui.fullWidthTabbar->setChecked(settings.fullWidthTabBar());
|
||||||
|
ui.showTabClose->setChecked(settings.showTabClose());
|
||||||
|
ui.rememberWindowSize->setChecked(settings.rememberWindowSize());
|
||||||
|
ui.fixedWindowWidth->setValue(settings.fixedWindowWidth());
|
||||||
|
ui.fixedWindowHeight->setValue(settings.fixedWindowHeight());
|
||||||
|
|
||||||
|
// FIXME: Hide options that we don't support yet.
|
||||||
|
ui.showInPlaces->parentWidget()->hide();
|
||||||
|
}
|
||||||
|
|
||||||
|
void PreferencesDialog::initBehaviorPage(Settings& settings) {
|
||||||
|
ui.singleClick->setChecked(settings.singleClick());
|
||||||
|
ui.autoSelectionDelay->setValue(double(settings.autoSelectionDelay()) / 1000);
|
||||||
|
|
||||||
|
ui.bookmarkOpenMethod->setCurrentIndex(settings.bookmarkOpenMethod());
|
||||||
|
|
||||||
|
ui.viewMode->addItem(tr("Icon View"), (int)Fm::FolderView::IconMode);
|
||||||
|
ui.viewMode->addItem(tr("Compact Icon View"), (int)Fm::FolderView::CompactMode);
|
||||||
|
ui.viewMode->addItem(tr("Thumbnail View"), (int)Fm::FolderView::ThumbnailMode);
|
||||||
|
ui.viewMode->addItem(tr("Detailed List View"), (int)Fm::FolderView::DetailedListMode);
|
||||||
|
const Fm::FolderView::ViewMode modes[] = {
|
||||||
|
Fm::FolderView::IconMode,
|
||||||
|
Fm::FolderView::CompactMode,
|
||||||
|
Fm::FolderView::ThumbnailMode,
|
||||||
|
Fm::FolderView::DetailedListMode
|
||||||
|
};
|
||||||
|
for(int i = 0; i < G_N_ELEMENTS(modes); ++i) {
|
||||||
|
if(modes[i] == settings.viewMode()) {
|
||||||
|
ui.viewMode->setCurrentIndex(i);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ui.configmDelete->setChecked(settings.confirmDelete());
|
||||||
|
|
||||||
|
if(settings.supportTrash())
|
||||||
|
ui.useTrash->setChecked(settings.useTrash());
|
||||||
|
else {
|
||||||
|
ui.useTrash->hide();
|
||||||
|
}
|
||||||
|
|
||||||
|
ui.noUsbTrash->setChecked(settings.noUsbTrash());
|
||||||
|
ui.confirmTrash->setChecked(settings.confirmTrash());
|
||||||
|
ui.quickExec->setChecked(settings.quickExec());
|
||||||
|
}
|
||||||
|
|
||||||
|
void PreferencesDialog::initThumbnailPage(Settings& settings) {
|
||||||
|
ui.showThumbnails->setChecked(settings.showThumbnails());
|
||||||
|
ui.thumbnailLocal->setChecked(settings.thumbnailLocalFilesOnly());
|
||||||
|
ui.maxThumbnailFileSize->setValue(settings.maxThumbnailFileSize());
|
||||||
|
}
|
||||||
|
|
||||||
|
void PreferencesDialog::initVolumePage(Settings& settings) {
|
||||||
|
ui.mountOnStartup->setChecked(settings.mountOnStartup());
|
||||||
|
ui.mountRemovable->setChecked(settings.mountRemovable());
|
||||||
|
ui.autoRun->setChecked(settings.autoRun());
|
||||||
|
if(settings.closeOnUnmount())
|
||||||
|
ui.closeOnUnmount->setChecked(true);
|
||||||
|
else
|
||||||
|
ui.goHomeOnUnmount->setChecked(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
void PreferencesDialog::initTerminals(Settings& settings) {
|
||||||
|
// load the known terminal list from the terminal.list file of libfm
|
||||||
|
QSettings termlist(LIBFM_DATA_DIR "/terminals.list", QSettings::IniFormat);
|
||||||
|
ui.terminal->addItems(termlist.childGroups());
|
||||||
|
ui.terminal->setEditText(settings.terminal());
|
||||||
|
}
|
||||||
|
|
||||||
|
void PreferencesDialog::initAdvancedPage(Settings& settings) {
|
||||||
|
initArchivers(settings);
|
||||||
|
initTerminals(settings);
|
||||||
|
ui.suCommand->setText(settings.suCommand());
|
||||||
|
|
||||||
|
ui.onlyUserTemplates->setChecked(settings.onlyUserTemplates());
|
||||||
|
ui.templateTypeOnce->setChecked(settings.templateTypeOnce());
|
||||||
|
|
||||||
|
ui.templateRunApp->setChecked(settings.templateRunApp());
|
||||||
|
|
||||||
|
// FIXME: Hide options that we don't support yet.
|
||||||
|
ui.templateRunApp->hide();
|
||||||
|
}
|
||||||
|
|
||||||
|
void PreferencesDialog::initFromSettings() {
|
||||||
|
Settings& settings = static_cast<Application*>(qApp)->settings();
|
||||||
|
initDisplayPage(settings);
|
||||||
|
initUiPage(settings);
|
||||||
|
initBehaviorPage(settings);
|
||||||
|
initThumbnailPage(settings);
|
||||||
|
initVolumePage(settings);
|
||||||
|
initAdvancedPage(settings);
|
||||||
|
}
|
||||||
|
|
||||||
|
void PreferencesDialog::applyDisplayPage(Settings& settings) {
|
||||||
|
if(settings.useFallbackIconTheme()) {
|
||||||
|
// only apply the value if icon theme combo box is in use
|
||||||
|
// the combo box is hidden when auto-detection of icon theme from xsettings works.
|
||||||
|
QString newIconTheme = ui.iconTheme->itemData(ui.iconTheme->currentIndex()).toString();
|
||||||
|
if(newIconTheme != settings.fallbackIconThemeName()) {
|
||||||
|
settings.setFallbackIconThemeName(newIconTheme);
|
||||||
|
QIcon::setThemeName(settings.fallbackIconThemeName());
|
||||||
|
// update the UI by emitting a style change event
|
||||||
|
Q_FOREACH(QWidget *widget, QApplication::allWidgets()) {
|
||||||
|
QEvent event(QEvent::StyleChange);
|
||||||
|
QApplication::sendEvent(widget, &event);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
settings.setBigIconSize(ui.bigIconSize->itemData(ui.bigIconSize->currentIndex()).toInt());
|
||||||
|
settings.setSmallIconSize(ui.smallIconSize->itemData(ui.smallIconSize->currentIndex()).toInt());
|
||||||
|
settings.setThumbnailIconSize(ui.thumbnailIconSize->itemData(ui.thumbnailIconSize->currentIndex()).toInt());
|
||||||
|
settings.setSidePaneIconSize(ui.sidePaneIconSize->itemData(ui.sidePaneIconSize->currentIndex()).toInt());
|
||||||
|
|
||||||
|
settings.setSiUnit(ui.siUnit->isChecked());
|
||||||
|
settings.setBackupAsHidden(ui.backupAsHidden->isChecked());
|
||||||
|
settings.setShowFullNames(ui.showFullNames->isChecked());
|
||||||
|
settings.setShadowHidden(ui.shadowHidden->isChecked());
|
||||||
|
settings.setFolderViewCellMargins(QSize(ui.hMargin->value(), ui.vMargin->value()));
|
||||||
|
}
|
||||||
|
|
||||||
|
void PreferencesDialog::applyUiPage(Settings& settings) {
|
||||||
|
settings.setAlwaysShowTabs(ui.alwaysShowTabs->isChecked());
|
||||||
|
settings.setFullWidthTabBar(ui.fullWidthTabbar->isChecked());
|
||||||
|
settings.setShowTabClose(ui.showTabClose->isChecked());
|
||||||
|
settings.setRememberWindowSize(ui.rememberWindowSize->isChecked());
|
||||||
|
settings.setFixedWindowWidth(ui.fixedWindowWidth->value());
|
||||||
|
settings.setFixedWindowHeight(ui.fixedWindowHeight->value());
|
||||||
|
}
|
||||||
|
|
||||||
|
void PreferencesDialog::applyBehaviorPage(Settings& settings) {
|
||||||
|
settings.setSingleClick(ui.singleClick->isChecked());
|
||||||
|
settings.setAutoSelectionDelay(int(ui.autoSelectionDelay->value() * 1000));
|
||||||
|
|
||||||
|
settings.setBookmarkOpenMethod(OpenDirTargetType(ui.bookmarkOpenMethod->currentIndex()));
|
||||||
|
|
||||||
|
// FIXME: bug here?
|
||||||
|
Fm::FolderView::ViewMode mode = Fm::FolderView::ViewMode(ui.viewMode->itemData(ui.viewMode->currentIndex()).toInt());
|
||||||
|
settings.setViewMode(mode);
|
||||||
|
settings.setConfirmDelete(ui.configmDelete->isChecked());
|
||||||
|
|
||||||
|
if(settings.supportTrash())
|
||||||
|
settings.setUseTrash(ui.useTrash->isChecked());
|
||||||
|
|
||||||
|
settings.setNoUsbTrash(ui.noUsbTrash->isChecked());
|
||||||
|
settings.setConfirmTrash(ui.confirmTrash->isChecked());
|
||||||
|
settings.setQuickExec(ui.quickExec->isChecked());
|
||||||
|
}
|
||||||
|
|
||||||
|
void PreferencesDialog::applyThumbnailPage(Settings& settings) {
|
||||||
|
settings.setShowThumbnails(ui.showThumbnails->isChecked());
|
||||||
|
settings.setThumbnailLocalFilesOnly(ui.thumbnailLocal->isChecked());
|
||||||
|
settings.setMaxThumbnailFileSize(ui.maxThumbnailFileSize->value());
|
||||||
|
}
|
||||||
|
|
||||||
|
void PreferencesDialog::applyVolumePage(Settings& settings) {
|
||||||
|
settings.setAutoRun(ui.autoRun->isChecked());
|
||||||
|
settings.setMountOnStartup(ui.mountOnStartup->isChecked());
|
||||||
|
settings.setMountRemovable(ui.mountRemovable->isChecked());
|
||||||
|
settings.setCloseOnUnmount(ui.closeOnUnmount->isChecked());
|
||||||
|
}
|
||||||
|
|
||||||
|
void PreferencesDialog::applyAdvancedPage(Settings& settings) {
|
||||||
|
settings.setTerminal(ui.terminal->currentText());
|
||||||
|
settings.setSuCommand(ui.suCommand->text());
|
||||||
|
settings.setArchiver(ui.archiver->itemData(ui.archiver->currentIndex()).toString());
|
||||||
|
|
||||||
|
settings.setOnlyUserTemplates(ui.onlyUserTemplates->isChecked());
|
||||||
|
settings.setTemplateTypeOnce(ui.templateTypeOnce->isChecked());
|
||||||
|
settings.setTemplateRunApp(ui.templateRunApp->isChecked());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void PreferencesDialog::applySettings() {
|
||||||
|
Settings& settings = static_cast<Application*>(qApp)->settings();
|
||||||
|
applyDisplayPage(settings);
|
||||||
|
applyUiPage(settings);
|
||||||
|
applyBehaviorPage(settings);
|
||||||
|
applyThumbnailPage(settings);
|
||||||
|
applyVolumePage(settings);
|
||||||
|
applyAdvancedPage(settings);
|
||||||
|
|
||||||
|
settings.save();
|
||||||
|
|
||||||
|
Application* app = static_cast<Application*>(qApp);
|
||||||
|
app->updateFromSettings();
|
||||||
|
}
|
||||||
|
|
||||||
|
void PreferencesDialog::accept() {
|
||||||
|
applySettings();
|
||||||
|
QDialog::accept();
|
||||||
|
}
|
||||||
|
|
||||||
|
void PreferencesDialog::selectPage(QString name) {
|
||||||
|
if(!name.isEmpty()) {
|
||||||
|
QWidget* page = findChild<QWidget*>(name + "Page");
|
||||||
|
if(page) {
|
||||||
|
int index = ui.stackedWidget->indexOf(page);
|
||||||
|
ui.listWidget->setCurrentRow(index);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void PreferencesDialog::lockMargins(bool lock) {
|
||||||
|
ui.vMargin->setDisabled(lock);
|
||||||
|
if(lock) {
|
||||||
|
ui.vMargin->setValue(ui.hMargin->value());
|
||||||
|
connect(ui.hMargin, static_cast<void (QSpinBox::*)(int)>(&QSpinBox::valueChanged), ui.vMargin, &QSpinBox::setValue);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
disconnect(ui.hMargin, static_cast<void (QSpinBox::*)(int)>(&QSpinBox::valueChanged), ui.vMargin, &QSpinBox::setValue);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace PCManFM
|
75
pcmanfm/preferencesdialog.h
Normal file
75
pcmanfm/preferencesdialog.h
Normal file
@ -0,0 +1,75 @@
|
|||||||
|
/*
|
||||||
|
|
||||||
|
Copyright (C) 2013 Hong Jen Yee (PCMan) <pcman.tw@gmail.com>
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation; either version 2 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License along
|
||||||
|
with this program; if not, write to the Free Software Foundation, Inc.,
|
||||||
|
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef PCMANFM_PREFERENCESDIALOG_H
|
||||||
|
#define PCMANFM_PREFERENCESDIALOG_H
|
||||||
|
|
||||||
|
#include <QDialog>
|
||||||
|
#include "ui_preferences.h"
|
||||||
|
#include <QString>
|
||||||
|
|
||||||
|
namespace PCManFM
|
||||||
|
{
|
||||||
|
|
||||||
|
class Settings;
|
||||||
|
|
||||||
|
class PreferencesDialog : public QDialog {
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
// activePage is the name of page to select (general, display, advanced...)
|
||||||
|
explicit PreferencesDialog(QString activePage = QString(), QWidget* parent = 0);
|
||||||
|
virtual ~PreferencesDialog();
|
||||||
|
|
||||||
|
virtual void accept();
|
||||||
|
|
||||||
|
void selectPage(QString name);
|
||||||
|
|
||||||
|
protected Q_SLOTS:
|
||||||
|
void lockMargins(bool lock);
|
||||||
|
|
||||||
|
private:
|
||||||
|
void initIconThemes(Settings& settings);
|
||||||
|
void initArchivers(Settings& settings);
|
||||||
|
void initDisplayPage(Settings& settings);
|
||||||
|
void initUiPage(Settings& settings);
|
||||||
|
void initBehaviorPage(Settings& settings);
|
||||||
|
void initThumbnailPage(Settings& settings);
|
||||||
|
void initVolumePage(Settings& settings);
|
||||||
|
void initAdvancedPage(Settings& settings);
|
||||||
|
void initTerminals(Settings& settings);
|
||||||
|
|
||||||
|
void applyUiPage(Settings& settings);
|
||||||
|
void applyDisplayPage(Settings& settings);
|
||||||
|
void applyBehaviorPage(Settings& settings);
|
||||||
|
void applyThumbnailPage(Settings& settings);
|
||||||
|
void applyVolumePage(Settings& settings);
|
||||||
|
void applyAdvancedPage(Settings& settings);
|
||||||
|
|
||||||
|
void initFromSettings();
|
||||||
|
void applySettings();
|
||||||
|
|
||||||
|
private:
|
||||||
|
Ui::PreferencesDialog ui;
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // PCMANFM_PREFERENCESDIALOG_H
|
565
pcmanfm/settings.cpp
Normal file
565
pcmanfm/settings.cpp
Normal file
@ -0,0 +1,565 @@
|
|||||||
|
/*
|
||||||
|
|
||||||
|
Copyright (C) 2013 Hong Jen Yee (PCMan) <pcman.tw@gmail.com>
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation; either version 2 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License along
|
||||||
|
with this program; if not, write to the Free Software Foundation, Inc.,
|
||||||
|
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#include "settings.h"
|
||||||
|
#include <QDir>
|
||||||
|
#include <QFile>
|
||||||
|
#include <QStringBuilder>
|
||||||
|
#include <QSettings>
|
||||||
|
#include <QApplication>
|
||||||
|
#include "desktopwindow.h"
|
||||||
|
#include <libfm-qt/utilities.h>
|
||||||
|
// #include <QDesktopServices>
|
||||||
|
|
||||||
|
namespace PCManFM {
|
||||||
|
|
||||||
|
inline static const char* bookmarkOpenMethodToString(OpenDirTargetType value);
|
||||||
|
inline static OpenDirTargetType bookmarkOpenMethodFromString(const QString str);
|
||||||
|
|
||||||
|
inline static const char* wallpaperModeToString(int value);
|
||||||
|
inline static int wallpaperModeFromString(const QString str);
|
||||||
|
|
||||||
|
inline static const char* viewModeToString(Fm::FolderView::ViewMode value);
|
||||||
|
inline static Fm::FolderView::ViewMode viewModeFromString(const QString str);
|
||||||
|
|
||||||
|
inline static const char* sidePaneModeToString(Fm::SidePane::Mode value);
|
||||||
|
inline static Fm::SidePane::Mode sidePaneModeFromString(const QString& str);
|
||||||
|
|
||||||
|
inline static const char* sortOrderToString(Qt::SortOrder order);
|
||||||
|
inline static Qt::SortOrder sortOrderFromString(const QString str);
|
||||||
|
|
||||||
|
inline static const char* sortColumnToString(Fm::FolderModel::ColumnId value);
|
||||||
|
inline static Fm::FolderModel::ColumnId sortColumnFromString(const QString str);
|
||||||
|
|
||||||
|
Settings::Settings():
|
||||||
|
QObject(),
|
||||||
|
supportTrash_(Fm::uriExists("trash:///")), // check if trash:/// is supported
|
||||||
|
fallbackIconThemeName_(),
|
||||||
|
useFallbackIconTheme_(QIcon::themeName().isEmpty() || QIcon::themeName() == "hicolor"),
|
||||||
|
bookmarkOpenMethod_(OpenInCurrentTab),
|
||||||
|
suCommand_(),
|
||||||
|
terminal_(),
|
||||||
|
mountOnStartup_(true),
|
||||||
|
mountRemovable_(true),
|
||||||
|
autoRun_(true),
|
||||||
|
closeOnUnmount_(false),
|
||||||
|
wallpaperMode_(0),
|
||||||
|
wallpaper_(),
|
||||||
|
desktopBgColor_(),
|
||||||
|
desktopFgColor_(),
|
||||||
|
desktopShadowColor_(),
|
||||||
|
showWmMenu_(false),
|
||||||
|
desktopShowHidden_(false),
|
||||||
|
desktopSortOrder_(Qt::AscendingOrder),
|
||||||
|
desktopSortColumn_(Fm::FolderModel::ColumnFileName),
|
||||||
|
alwaysShowTabs_(true),
|
||||||
|
showTabClose_(true),
|
||||||
|
rememberWindowSize_(true),
|
||||||
|
fixedWindowWidth_(640),
|
||||||
|
fixedWindowHeight_(480),
|
||||||
|
lastWindowWidth_(640),
|
||||||
|
lastWindowHeight_(480),
|
||||||
|
lastWindowMaximized_(false),
|
||||||
|
splitterPos_(120),
|
||||||
|
sidePaneMode_(Fm::SidePane::ModePlaces),
|
||||||
|
showMenuBar_(true),
|
||||||
|
fullWidthTabBar_(true),
|
||||||
|
viewMode_(Fm::FolderView::IconMode),
|
||||||
|
showHidden_(false),
|
||||||
|
sortOrder_(Qt::AscendingOrder),
|
||||||
|
sortColumn_(Fm::FolderModel::ColumnFileName),
|
||||||
|
sortFolderFirst_(true),
|
||||||
|
showFilter_(false),
|
||||||
|
// settings for use with libfm
|
||||||
|
singleClick_(false),
|
||||||
|
autoSelectionDelay_(600),
|
||||||
|
useTrash_(true),
|
||||||
|
confirmDelete_(true),
|
||||||
|
noUsbTrash_(false),
|
||||||
|
confirmTrash_(false),
|
||||||
|
quickExec_(false),
|
||||||
|
showThumbnails_(true),
|
||||||
|
archiver_(),
|
||||||
|
siUnit_(false),
|
||||||
|
placesHome_(true),
|
||||||
|
placesDesktop_(true),
|
||||||
|
placesApplications_(true),
|
||||||
|
placesTrash_(true),
|
||||||
|
placesRoot_(true),
|
||||||
|
placesComputer_(true),
|
||||||
|
placesNetwork_(true),
|
||||||
|
bigIconSize_(48),
|
||||||
|
smallIconSize_(24),
|
||||||
|
sidePaneIconSize_(24),
|
||||||
|
thumbnailIconSize_(128),
|
||||||
|
folderViewCellMargins_(QSize(3, 3)),
|
||||||
|
desktopCellMargins_(QSize(3, 1)) {
|
||||||
|
}
|
||||||
|
|
||||||
|
Settings::~Settings() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
QString Settings::profileDir(QString profile, bool useFallback) {
|
||||||
|
// NOTE: it's a shame that QDesktopServices does not handle XDG_CONFIG_HOME
|
||||||
|
// try user-specific config file first
|
||||||
|
QString dirName;
|
||||||
|
// WARNING: Don't use XDG_CONFIG_HOME with root because it might
|
||||||
|
// give the user config directory if gksu-properties is set to su.
|
||||||
|
if(geteuid())
|
||||||
|
dirName = QLatin1String(qgetenv("XDG_CONFIG_HOME"));
|
||||||
|
if (dirName.isEmpty())
|
||||||
|
dirName = QDir::homePath() % QLatin1String("/.config");
|
||||||
|
dirName = dirName % "/pcmanfm-qt/" % profile;
|
||||||
|
QDir dir(dirName);
|
||||||
|
|
||||||
|
// if user config dir does not exist, try system-wide config dirs instead
|
||||||
|
if(!dir.exists() && useFallback) {
|
||||||
|
QString fallbackDir;
|
||||||
|
for(const char* const* configDir = g_get_system_config_dirs(); *configDir; ++configDir) {
|
||||||
|
fallbackDir = QString(*configDir) % "/pcmanfm-qt/" % profile;
|
||||||
|
dir.setPath(fallbackDir);
|
||||||
|
if(dir.exists()) {
|
||||||
|
dirName = fallbackDir;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return dirName;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Settings::load(QString profile) {
|
||||||
|
profileName_ = profile;
|
||||||
|
QString fileName = profileDir(profile, true) % "/settings.conf";
|
||||||
|
return loadFile(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Settings::save(QString profile) {
|
||||||
|
QString fileName = profileDir(profile.isEmpty() ? profileName_ : profile) % "/settings.conf";
|
||||||
|
return saveFile(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Settings::loadFile(QString filePath) {
|
||||||
|
QSettings settings(filePath, QSettings::IniFormat);
|
||||||
|
settings.beginGroup("System");
|
||||||
|
fallbackIconThemeName_ = settings.value("FallbackIconThemeName").toString();
|
||||||
|
if(fallbackIconThemeName_.isEmpty()) {
|
||||||
|
// FIXME: we should choose one from installed icon themes or get
|
||||||
|
// the value from XSETTINGS instead of hard code a fallback value.
|
||||||
|
fallbackIconThemeName_ = "elementary"; // fallback icon theme name
|
||||||
|
}
|
||||||
|
suCommand_ = settings.value("SuCommand", "lxqt-sudo %s").toString();
|
||||||
|
setTerminal(settings.value("Terminal", "xterm").toString());
|
||||||
|
setArchiver(settings.value("Archiver", "file-roller").toString());
|
||||||
|
setSiUnit(settings.value("SIUnit", false).toBool());
|
||||||
|
|
||||||
|
setOnlyUserTemplates(settings.value("OnlyUserTemplates", false).toBool());
|
||||||
|
setTemplateTypeOnce(settings.value("TemplateTypeOnce", false).toBool());
|
||||||
|
setTemplateRunApp(settings.value("TemplateRunApp", false).toBool());
|
||||||
|
|
||||||
|
settings.endGroup();
|
||||||
|
|
||||||
|
settings.beginGroup("Behavior");
|
||||||
|
bookmarkOpenMethod_ = bookmarkOpenMethodFromString(settings.value("BookmarkOpenMethod").toString());
|
||||||
|
// settings for use with libfm
|
||||||
|
useTrash_ = settings.value("UseTrash", true).toBool();
|
||||||
|
singleClick_ = settings.value("SingleClick", false).toBool();
|
||||||
|
autoSelectionDelay_ = settings.value("AutoSelectionDelay", 600).toInt();
|
||||||
|
confirmDelete_ = settings.value("ConfirmDelete", true).toBool();
|
||||||
|
setNoUsbTrash(settings.value("NoUsbTrash", false).toBool());
|
||||||
|
confirmTrash_ = settings.value("ConfirmTrash", false).toBool();
|
||||||
|
setQuickExec(settings.value("QuickExec", false).toBool());
|
||||||
|
// bool thumbnailLocal_;
|
||||||
|
// bool thumbnailMax;
|
||||||
|
settings.endGroup();
|
||||||
|
|
||||||
|
settings.beginGroup("Desktop");
|
||||||
|
wallpaperMode_ = wallpaperModeFromString(settings.value("WallpaperMode").toString());
|
||||||
|
wallpaper_ = settings.value("Wallpaper").toString();
|
||||||
|
desktopBgColor_.setNamedColor(settings.value("BgColor", "#000000").toString());
|
||||||
|
desktopFgColor_.setNamedColor(settings.value("FgColor", "#ffffff").toString());
|
||||||
|
desktopShadowColor_.setNamedColor(settings.value("ShadowColor", "#000000").toString());
|
||||||
|
if(settings.contains("Font"))
|
||||||
|
desktopFont_.fromString(settings.value("Font").toString());
|
||||||
|
else
|
||||||
|
desktopFont_ = QApplication::font();
|
||||||
|
showWmMenu_ = settings.value("ShowWmMenu", false).toBool();
|
||||||
|
desktopShowHidden_ = settings.value("ShowHidden", false).toBool();
|
||||||
|
|
||||||
|
desktopSortOrder_ = sortOrderFromString(settings.value("SortOrder").toString());
|
||||||
|
desktopSortColumn_ = sortColumnFromString(settings.value("SortColumn").toString());
|
||||||
|
|
||||||
|
desktopCellMargins_ = (settings.value("DesktopCellMargins", QSize(3, 1)).toSize()
|
||||||
|
.expandedTo(QSize(0, 0))).boundedTo(QSize(48, 48));
|
||||||
|
settings.endGroup();
|
||||||
|
|
||||||
|
settings.beginGroup("Volume");
|
||||||
|
mountOnStartup_ = settings.value("MountOnStartup", true).toBool();
|
||||||
|
mountRemovable_ = settings.value("MountRemovable", true).toBool();
|
||||||
|
autoRun_ = settings.value("AutoRun", true).toBool();
|
||||||
|
closeOnUnmount_ = settings.value("CloseOnUnmount", true).toBool();
|
||||||
|
settings.endGroup();
|
||||||
|
|
||||||
|
settings.beginGroup("Thumbnail");
|
||||||
|
showThumbnails_ = settings.value("ShowThumbnails", true).toBool();
|
||||||
|
setMaxThumbnailFileSize(settings.value("MaxThumbnailFileSize", 4096).toInt());
|
||||||
|
setThumbnailLocalFilesOnly(settings.value("ThumbnailLocalFilesOnly", true).toBool());
|
||||||
|
settings.endGroup();
|
||||||
|
|
||||||
|
settings.beginGroup("FolderView");
|
||||||
|
viewMode_ = viewModeFromString(settings.value("Mode", Fm::FolderView::IconMode).toString());
|
||||||
|
showHidden_ = settings.value("ShowHidden", false).toBool();
|
||||||
|
sortOrder_ = sortOrderFromString(settings.value("SortOrder").toString());
|
||||||
|
sortColumn_ = sortColumnFromString(settings.value("SortColumn").toString());
|
||||||
|
sortFolderFirst_ = settings.value("SortFolderFirst", true).toBool();
|
||||||
|
showFilter_ = settings.value("ShowFilter", false).toBool();
|
||||||
|
|
||||||
|
setBackupAsHidden(settings.value("BackupAsHidden", false).toBool());
|
||||||
|
showFullNames_ = settings.value("ShowFullNames", false).toBool();
|
||||||
|
shadowHidden_ = settings.value("ShadowHidden", false).toBool();
|
||||||
|
|
||||||
|
// override config in libfm's FmConfig
|
||||||
|
bigIconSize_ = settings.value("BigIconSize", 48).toInt();
|
||||||
|
smallIconSize_ = settings.value("SmallIconSize", 24).toInt();
|
||||||
|
sidePaneIconSize_ = settings.value("SidePaneIconSize", 24).toInt();
|
||||||
|
thumbnailIconSize_ = settings.value("ThumbnailIconSize", 128).toInt();
|
||||||
|
|
||||||
|
folderViewCellMargins_ = (settings.value("FolderViewCellMargins", QSize(3, 3)).toSize()
|
||||||
|
.expandedTo(QSize(0, 0))).boundedTo(QSize(48, 48));
|
||||||
|
settings.endGroup();
|
||||||
|
|
||||||
|
settings.beginGroup("Places");
|
||||||
|
placesHome_ = settings.value("PlacesHome", true).toBool();
|
||||||
|
placesDesktop_ = settings.value("PlacesDesktop", true).toBool();
|
||||||
|
placesApplications_ = settings.value("PlacesApplications", true).toBool();
|
||||||
|
placesTrash_ = settings.value("PlacesTrash", true).toBool();
|
||||||
|
placesRoot_ = settings.value("PlacesRoot", true).toBool();
|
||||||
|
placesComputer_ = settings.value("PlacesComputer", true).toBool();
|
||||||
|
placesNetwork_ = settings.value("PlacesNetwork", true).toBool();
|
||||||
|
settings.endGroup();
|
||||||
|
|
||||||
|
settings.beginGroup("Window");
|
||||||
|
fixedWindowWidth_ = settings.value("FixedWidth", 640).toInt();
|
||||||
|
fixedWindowHeight_ = settings.value("FixedHeight", 480).toInt();
|
||||||
|
lastWindowWidth_ = settings.value("LastWindowWidth", 640).toInt();
|
||||||
|
lastWindowHeight_ = settings.value("LastWindowHeight", 480).toInt();
|
||||||
|
lastWindowMaximized_ = settings.value("LastWindowMaximized", false).toBool();
|
||||||
|
rememberWindowSize_ = settings.value("RememberWindowSize", true).toBool();
|
||||||
|
alwaysShowTabs_ = settings.value("AlwaysShowTabs", true).toBool();
|
||||||
|
showTabClose_ = settings.value("ShowTabClose", true).toBool();
|
||||||
|
splitterPos_ = settings.value("SplitterPos", 150).toInt();
|
||||||
|
sidePaneMode_ = sidePaneModeFromString(settings.value("SidePaneMode").toString());
|
||||||
|
showMenuBar_ = settings.value("ShowMenuBar", true).toBool();
|
||||||
|
fullWidthTabBar_ = settings.value("FullWidthTabBar", true).toBool();
|
||||||
|
settings.endGroup();
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Settings::saveFile(QString filePath) {
|
||||||
|
QSettings settings(filePath, QSettings::IniFormat);
|
||||||
|
|
||||||
|
settings.beginGroup("System");
|
||||||
|
settings.setValue("FallbackIconThemeName", fallbackIconThemeName_);
|
||||||
|
settings.setValue("SuCommand", suCommand_);
|
||||||
|
settings.setValue("Terminal", terminal_);
|
||||||
|
settings.setValue("Archiver", archiver_);
|
||||||
|
settings.setValue("SIUnit", siUnit_);
|
||||||
|
|
||||||
|
settings.setValue("OnlyUserTemplates", onlyUserTemplates_);
|
||||||
|
settings.setValue("TemplateTypeOnce", templateTypeOnce_);
|
||||||
|
settings.setValue("TemplateRunApp", templateRunApp_);
|
||||||
|
|
||||||
|
settings.endGroup();
|
||||||
|
|
||||||
|
settings.beginGroup("Behavior");
|
||||||
|
settings.setValue("BookmarkOpenMethod", bookmarkOpenMethodToString(bookmarkOpenMethod_));
|
||||||
|
// settings for use with libfm
|
||||||
|
settings.setValue("UseTrash", useTrash_);
|
||||||
|
settings.setValue("SingleClick", singleClick_);
|
||||||
|
settings.setValue("AutoSelectionDelay", autoSelectionDelay_);
|
||||||
|
settings.setValue("ConfirmDelete", confirmDelete_);
|
||||||
|
settings.setValue("NoUsbTrash", noUsbTrash_);
|
||||||
|
settings.setValue("ConfirmTrash", confirmTrash_);
|
||||||
|
settings.setValue("QuickExec", quickExec_);
|
||||||
|
// bool thumbnailLocal_;
|
||||||
|
// bool thumbnailMax;
|
||||||
|
settings.endGroup();
|
||||||
|
|
||||||
|
settings.beginGroup("Desktop");
|
||||||
|
settings.setValue("WallpaperMode", wallpaperModeToString(wallpaperMode_));
|
||||||
|
settings.setValue("Wallpaper", wallpaper_);
|
||||||
|
settings.setValue("BgColor", desktopBgColor_.name());
|
||||||
|
settings.setValue("FgColor", desktopFgColor_.name());
|
||||||
|
settings.setValue("ShadowColor", desktopShadowColor_.name());
|
||||||
|
settings.setValue("Font", desktopFont_.toString());
|
||||||
|
settings.setValue("ShowWmMenu", showWmMenu_);
|
||||||
|
settings.setValue("ShowHidden", desktopShowHidden_);
|
||||||
|
settings.setValue("SortOrder", sortOrderToString(desktopSortOrder_));
|
||||||
|
settings.setValue("SortColumn", sortColumnToString(desktopSortColumn_));
|
||||||
|
settings.setValue("DesktopCellMargins", desktopCellMargins_);
|
||||||
|
settings.endGroup();
|
||||||
|
|
||||||
|
settings.beginGroup("Volume");
|
||||||
|
settings.setValue("MountOnStartup", mountOnStartup_);
|
||||||
|
settings.setValue("MountRemovable", mountRemovable_);
|
||||||
|
settings.setValue("AutoRun", autoRun_);
|
||||||
|
settings.setValue("CloseOnUnmount", closeOnUnmount_);
|
||||||
|
settings.endGroup();
|
||||||
|
|
||||||
|
settings.beginGroup("Thumbnail");
|
||||||
|
settings.setValue("ShowThumbnails", showThumbnails_);
|
||||||
|
settings.setValue("MaxThumbnailFileSize", maxThumbnailFileSize());
|
||||||
|
settings.setValue("ThumbnailLocalFilesOnly", thumbnailLocalFilesOnly());
|
||||||
|
settings.endGroup();
|
||||||
|
|
||||||
|
settings.beginGroup("FolderView");
|
||||||
|
settings.setValue("Mode", viewModeToString(viewMode_));
|
||||||
|
settings.setValue("ShowHidden", showHidden_);
|
||||||
|
settings.setValue("SortOrder", sortOrderToString(sortOrder_));
|
||||||
|
settings.setValue("SortColumn", sortColumnToString(sortColumn_));
|
||||||
|
settings.setValue("SortFolderFirst", sortFolderFirst_);
|
||||||
|
settings.setValue("ShowFilter", showFilter_);
|
||||||
|
|
||||||
|
settings.setValue("BackupAsHidden", backupAsHidden_);
|
||||||
|
settings.setValue("ShowFullNames", showFullNames_);
|
||||||
|
settings.setValue("ShadowHidden", shadowHidden_);
|
||||||
|
|
||||||
|
// override config in libfm's FmConfig
|
||||||
|
settings.setValue("BigIconSize", bigIconSize_);
|
||||||
|
settings.setValue("SmallIconSize", smallIconSize_);
|
||||||
|
settings.setValue("SidePaneIconSize", sidePaneIconSize_);
|
||||||
|
settings.setValue("ThumbnailIconSize", thumbnailIconSize_);
|
||||||
|
|
||||||
|
settings.setValue("FolderViewCellMargins", folderViewCellMargins_);
|
||||||
|
settings.endGroup();
|
||||||
|
|
||||||
|
settings.beginGroup("Places");
|
||||||
|
settings.setValue("PlacesHome", placesHome_);
|
||||||
|
settings.setValue("PlacesDesktop", placesDesktop_);
|
||||||
|
settings.setValue("PlacesApplications", placesApplications_);
|
||||||
|
settings.setValue("PlacesTrash", placesTrash_);
|
||||||
|
settings.setValue("PlacesRoot", placesRoot_);
|
||||||
|
settings.setValue("PlacesComputer", placesComputer_);
|
||||||
|
settings.setValue("PlacesNetwork", placesNetwork_);
|
||||||
|
settings.endGroup();
|
||||||
|
|
||||||
|
settings.beginGroup("Window");
|
||||||
|
settings.setValue("FixedWidth", fixedWindowWidth_);
|
||||||
|
settings.setValue("FixedHeight", fixedWindowHeight_);
|
||||||
|
settings.setValue("LastWindowWidth", lastWindowWidth_);
|
||||||
|
settings.setValue("LastWindowHeight", lastWindowHeight_);
|
||||||
|
settings.setValue("LastWindowMaximized", lastWindowMaximized_);
|
||||||
|
settings.setValue("RememberWindowSize", rememberWindowSize_);
|
||||||
|
settings.setValue("AlwaysShowTabs", alwaysShowTabs_);
|
||||||
|
settings.setValue("ShowTabClose", showTabClose_);
|
||||||
|
settings.setValue("SplitterPos", splitterPos_);
|
||||||
|
settings.setValue("SidePaneMode", sidePaneModeToString(sidePaneMode_));
|
||||||
|
settings.setValue("ShowMenuBar", showMenuBar_);
|
||||||
|
settings.setValue("FullWidthTabBar", fullWidthTabBar_);
|
||||||
|
settings.endGroup();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
static const char* bookmarkOpenMethodToString(OpenDirTargetType value) {
|
||||||
|
switch(value) {
|
||||||
|
case OpenInCurrentTab:
|
||||||
|
default:
|
||||||
|
return "current_tab";
|
||||||
|
case OpenInNewTab:
|
||||||
|
return "new_tab";
|
||||||
|
case OpenInNewWindow:
|
||||||
|
return "new_window";
|
||||||
|
case OpenInLastActiveWindow:
|
||||||
|
return "last_window";
|
||||||
|
}
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
static OpenDirTargetType bookmarkOpenMethodFromString(const QString str) {
|
||||||
|
|
||||||
|
if(str == QStringLiteral("new_tab"))
|
||||||
|
return OpenInNewTab;
|
||||||
|
else if(str == QStringLiteral("new_window"))
|
||||||
|
return OpenInNewWindow;
|
||||||
|
else if(str == QStringLiteral("last_window"))
|
||||||
|
return OpenInLastActiveWindow;
|
||||||
|
return OpenInCurrentTab;
|
||||||
|
}
|
||||||
|
|
||||||
|
static const char* viewModeToString(Fm::FolderView::ViewMode value) {
|
||||||
|
const char* ret;
|
||||||
|
switch(value) {
|
||||||
|
case Fm::FolderView::IconMode:
|
||||||
|
default:
|
||||||
|
ret = "icon";
|
||||||
|
break;
|
||||||
|
case Fm::FolderView::CompactMode:
|
||||||
|
ret = "compact";
|
||||||
|
break;
|
||||||
|
case Fm::FolderView::DetailedListMode:
|
||||||
|
ret = "detailed";
|
||||||
|
break;
|
||||||
|
case Fm::FolderView::ThumbnailMode:
|
||||||
|
ret = "thumbnail";
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
Fm::FolderView::ViewMode viewModeFromString(const QString str) {
|
||||||
|
Fm::FolderView::ViewMode ret;
|
||||||
|
if(str == "icon")
|
||||||
|
ret = Fm::FolderView::IconMode;
|
||||||
|
else if(str == "compact")
|
||||||
|
ret = Fm::FolderView::CompactMode;
|
||||||
|
else if(str == "detailed")
|
||||||
|
ret = Fm::FolderView::DetailedListMode;
|
||||||
|
else if(str == "thumbnail")
|
||||||
|
ret = Fm::FolderView::ThumbnailMode;
|
||||||
|
else
|
||||||
|
ret = Fm::FolderView::IconMode;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
static const char* sortOrderToString(Qt::SortOrder order) {
|
||||||
|
return (order == Qt::DescendingOrder ? "descending" : "ascending");
|
||||||
|
}
|
||||||
|
|
||||||
|
static Qt::SortOrder sortOrderFromString(const QString str) {
|
||||||
|
return (str == "descending" ? Qt::DescendingOrder : Qt::AscendingOrder);
|
||||||
|
}
|
||||||
|
|
||||||
|
static const char* sortColumnToString(Fm::FolderModel::ColumnId value) {
|
||||||
|
const char* ret;
|
||||||
|
switch(value) {
|
||||||
|
case Fm::FolderModel::ColumnFileName:
|
||||||
|
default:
|
||||||
|
ret = "name";
|
||||||
|
break;
|
||||||
|
case Fm::FolderModel::ColumnFileType:
|
||||||
|
ret = "type";
|
||||||
|
break;
|
||||||
|
case Fm::FolderModel::ColumnFileSize:
|
||||||
|
ret = "size";
|
||||||
|
break;
|
||||||
|
case Fm::FolderModel::ColumnFileMTime:
|
||||||
|
ret = "mtime";
|
||||||
|
break;
|
||||||
|
case Fm::FolderModel::ColumnFileOwner:
|
||||||
|
ret = "owner";
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
static Fm::FolderModel::ColumnId sortColumnFromString(const QString str) {
|
||||||
|
Fm::FolderModel::ColumnId ret;
|
||||||
|
if(str == "name")
|
||||||
|
ret = Fm::FolderModel::ColumnFileName;
|
||||||
|
else if(str == "type")
|
||||||
|
ret = Fm::FolderModel::ColumnFileType;
|
||||||
|
else if(str == "size")
|
||||||
|
ret = Fm::FolderModel::ColumnFileSize;
|
||||||
|
else if(str == "mtime")
|
||||||
|
ret = Fm::FolderModel::ColumnFileMTime;
|
||||||
|
else if(str == "owner")
|
||||||
|
ret = Fm::FolderModel::ColumnFileOwner;
|
||||||
|
else
|
||||||
|
ret = Fm::FolderModel::ColumnFileName;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
static const char* wallpaperModeToString(int value) {
|
||||||
|
const char* ret;
|
||||||
|
switch(value) {
|
||||||
|
case DesktopWindow::WallpaperNone:
|
||||||
|
default:
|
||||||
|
ret = "none";
|
||||||
|
break;
|
||||||
|
case DesktopWindow::WallpaperStretch:
|
||||||
|
ret = "stretch";
|
||||||
|
break;
|
||||||
|
case DesktopWindow::WallpaperFit:
|
||||||
|
ret = "fit";
|
||||||
|
break;
|
||||||
|
case DesktopWindow::WallpaperCenter:
|
||||||
|
ret = "center";
|
||||||
|
break;
|
||||||
|
case DesktopWindow::WallpaperTile:
|
||||||
|
ret = "tile";
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int wallpaperModeFromString(const QString str) {
|
||||||
|
int ret;
|
||||||
|
if(str == "stretch")
|
||||||
|
ret = DesktopWindow::WallpaperStretch;
|
||||||
|
else if(str == "fit")
|
||||||
|
ret = DesktopWindow::WallpaperFit;
|
||||||
|
else if(str == "center")
|
||||||
|
ret = DesktopWindow::WallpaperCenter;
|
||||||
|
else if(str == "tile")
|
||||||
|
ret = DesktopWindow::WallpaperTile;
|
||||||
|
else
|
||||||
|
ret = DesktopWindow::WallpaperNone;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
static const char* sidePaneModeToString(Fm::SidePane::Mode value) {
|
||||||
|
const char* ret;
|
||||||
|
switch(value) {
|
||||||
|
case Fm::SidePane::ModePlaces:
|
||||||
|
default:
|
||||||
|
ret = "places";
|
||||||
|
break;
|
||||||
|
case Fm::SidePane::ModeDirTree:
|
||||||
|
ret = "dirtree";
|
||||||
|
break;
|
||||||
|
case Fm::SidePane::ModeNone:
|
||||||
|
ret = "none";
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
static Fm::SidePane::Mode sidePaneModeFromString(const QString& str) {
|
||||||
|
Fm::SidePane::Mode ret;
|
||||||
|
if(str == "none")
|
||||||
|
ret = Fm::SidePane::ModeNone;
|
||||||
|
else if(str == "dirtree")
|
||||||
|
ret = Fm::SidePane::ModeDirTree;
|
||||||
|
else
|
||||||
|
ret = Fm::SidePane::ModePlaces;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Settings::setTerminal(QString terminalCommand) {
|
||||||
|
terminal_ = terminalCommand;
|
||||||
|
// override the settings in libfm FmConfig.
|
||||||
|
g_free(fm_config->terminal);
|
||||||
|
fm_config->terminal = g_strdup(terminal_.toLocal8Bit().constData());
|
||||||
|
g_signal_emit_by_name(fm_config, "changed::terminal");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
} // namespace PCManFM
|
718
pcmanfm/settings.h
Normal file
718
pcmanfm/settings.h
Normal file
@ -0,0 +1,718 @@
|
|||||||
|
/*
|
||||||
|
|
||||||
|
Copyright (C) 2013 Hong Jen Yee (PCMan) <pcman.tw@gmail.com>
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation; either version 2 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License along
|
||||||
|
with this program; if not, write to the Free Software Foundation, Inc.,
|
||||||
|
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef PCMANFM_SETTINGS_H
|
||||||
|
#define PCMANFM_SETTINGS_H
|
||||||
|
|
||||||
|
#include <QObject>
|
||||||
|
#include <libfm/fm.h>
|
||||||
|
#include <libfm-qt/folderview.h>
|
||||||
|
#include <libfm-qt/foldermodel.h>
|
||||||
|
#include "desktopwindow.h"
|
||||||
|
#include <libfm-qt/sidepane.h>
|
||||||
|
#include <libfm-qt/thumbnailloader.h>
|
||||||
|
|
||||||
|
namespace PCManFM {
|
||||||
|
|
||||||
|
enum OpenDirTargetType {
|
||||||
|
OpenInCurrentTab,
|
||||||
|
OpenInNewTab,
|
||||||
|
OpenInNewWindow,
|
||||||
|
OpenInLastActiveWindow
|
||||||
|
};
|
||||||
|
|
||||||
|
class Settings : public QObject {
|
||||||
|
Q_OBJECT
|
||||||
|
public:
|
||||||
|
Settings();
|
||||||
|
virtual ~Settings();
|
||||||
|
|
||||||
|
bool load(QString profile = "default");
|
||||||
|
bool save(QString profile = QString());
|
||||||
|
|
||||||
|
bool loadFile(QString filePath);
|
||||||
|
bool saveFile(QString filePath);
|
||||||
|
|
||||||
|
QString profileDir(QString profile, bool useFallback = false);
|
||||||
|
|
||||||
|
// setter/getter functions
|
||||||
|
QString profileName() const {
|
||||||
|
return profileName_;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool supportTrash() const {
|
||||||
|
return supportTrash_;
|
||||||
|
}
|
||||||
|
|
||||||
|
QString fallbackIconThemeName() const {
|
||||||
|
return fallbackIconThemeName_;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool useFallbackIconTheme() const {
|
||||||
|
return useFallbackIconTheme_;
|
||||||
|
}
|
||||||
|
|
||||||
|
void setFallbackIconThemeName(QString iconThemeName) {
|
||||||
|
fallbackIconThemeName_ = iconThemeName;
|
||||||
|
}
|
||||||
|
|
||||||
|
OpenDirTargetType bookmarkOpenMethod() {
|
||||||
|
return bookmarkOpenMethod_;
|
||||||
|
}
|
||||||
|
|
||||||
|
void setBookmarkOpenMethod(OpenDirTargetType bookmarkOpenMethod) {
|
||||||
|
bookmarkOpenMethod_ = bookmarkOpenMethod;
|
||||||
|
}
|
||||||
|
|
||||||
|
QString suCommand() const {
|
||||||
|
return suCommand_;
|
||||||
|
}
|
||||||
|
|
||||||
|
void setSuCommand(QString suCommand) {
|
||||||
|
suCommand_ = suCommand;
|
||||||
|
}
|
||||||
|
|
||||||
|
QString terminal() {
|
||||||
|
return terminal_;
|
||||||
|
}
|
||||||
|
void setTerminal(QString terminalCommand);
|
||||||
|
|
||||||
|
QString archiver() const {
|
||||||
|
return archiver_;
|
||||||
|
}
|
||||||
|
|
||||||
|
void setArchiver(QString archiver) {
|
||||||
|
archiver_ = archiver;
|
||||||
|
// override libfm FmConfig
|
||||||
|
g_free(fm_config->archiver);
|
||||||
|
fm_config->archiver = g_strdup(archiver_.toLocal8Bit().constData());
|
||||||
|
}
|
||||||
|
|
||||||
|
bool mountOnStartup() const {
|
||||||
|
return mountOnStartup_;
|
||||||
|
}
|
||||||
|
|
||||||
|
void setMountOnStartup(bool mountOnStartup) {
|
||||||
|
mountOnStartup_ = mountOnStartup;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool mountRemovable() {
|
||||||
|
return mountRemovable_;
|
||||||
|
}
|
||||||
|
|
||||||
|
void setMountRemovable(bool mountRemovable) {
|
||||||
|
mountRemovable_ = mountRemovable;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool autoRun() const {
|
||||||
|
return autoRun_;
|
||||||
|
}
|
||||||
|
|
||||||
|
void setAutoRun(bool autoRun) {
|
||||||
|
autoRun_ = autoRun;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool closeOnUnmount() const {
|
||||||
|
return closeOnUnmount_;
|
||||||
|
}
|
||||||
|
|
||||||
|
void setCloseOnUnmount(bool value) {
|
||||||
|
closeOnUnmount_ = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
DesktopWindow::WallpaperMode wallpaperMode() const {
|
||||||
|
return DesktopWindow::WallpaperMode(wallpaperMode_);
|
||||||
|
}
|
||||||
|
|
||||||
|
void setWallpaperMode(int wallpaperMode) {
|
||||||
|
wallpaperMode_ = wallpaperMode;
|
||||||
|
}
|
||||||
|
|
||||||
|
QString wallpaper() const {
|
||||||
|
return wallpaper_;
|
||||||
|
}
|
||||||
|
|
||||||
|
void setWallpaper(QString wallpaper) {
|
||||||
|
wallpaper_ = wallpaper;
|
||||||
|
}
|
||||||
|
|
||||||
|
const QColor& desktopBgColor() const {
|
||||||
|
return desktopBgColor_;
|
||||||
|
}
|
||||||
|
|
||||||
|
void setDesktopBgColor(QColor desktopBgColor) {
|
||||||
|
desktopBgColor_ = desktopBgColor;
|
||||||
|
}
|
||||||
|
|
||||||
|
const QColor& desktopFgColor() const {
|
||||||
|
return desktopFgColor_;
|
||||||
|
}
|
||||||
|
|
||||||
|
void setDesktopFgColor(QColor desktopFgColor) {
|
||||||
|
desktopFgColor_ = desktopFgColor;
|
||||||
|
}
|
||||||
|
|
||||||
|
const QColor& desktopShadowColor() const {
|
||||||
|
return desktopShadowColor_;
|
||||||
|
}
|
||||||
|
|
||||||
|
void setDesktopShadowColor(QColor desktopShadowColor) {
|
||||||
|
desktopShadowColor_ = desktopShadowColor;
|
||||||
|
}
|
||||||
|
|
||||||
|
QFont desktopFont() const {
|
||||||
|
return desktopFont_;
|
||||||
|
}
|
||||||
|
|
||||||
|
void setDesktopFont(QFont font) {
|
||||||
|
desktopFont_ = font;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool showWmMenu() const {
|
||||||
|
return showWmMenu_;
|
||||||
|
}
|
||||||
|
|
||||||
|
void setShowWmMenu(bool value) {
|
||||||
|
showWmMenu_ = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool desktopShowHidden() const {
|
||||||
|
return desktopShowHidden_;
|
||||||
|
}
|
||||||
|
|
||||||
|
void setDesktopShowHidden(bool desktopShowHidden) {
|
||||||
|
desktopShowHidden_ = desktopShowHidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
Qt::SortOrder desktopSortOrder() const {
|
||||||
|
return desktopSortOrder_;
|
||||||
|
}
|
||||||
|
|
||||||
|
void setDesktopSortOrder(Qt::SortOrder desktopSortOrder) {
|
||||||
|
desktopSortOrder_ = desktopSortOrder;
|
||||||
|
}
|
||||||
|
|
||||||
|
Fm::FolderModel::ColumnId desktopSortColumn() const {
|
||||||
|
return desktopSortColumn_;
|
||||||
|
}
|
||||||
|
|
||||||
|
void setDesktopSortColumn(Fm::FolderModel::ColumnId desktopSortColumn) {
|
||||||
|
desktopSortColumn_ = desktopSortColumn;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool alwaysShowTabs() const {
|
||||||
|
return alwaysShowTabs_;
|
||||||
|
}
|
||||||
|
|
||||||
|
void setAlwaysShowTabs(bool alwaysShowTabs) {
|
||||||
|
alwaysShowTabs_ = alwaysShowTabs;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool showTabClose() const {
|
||||||
|
return showTabClose_;
|
||||||
|
}
|
||||||
|
|
||||||
|
void setShowTabClose(bool showTabClose) {
|
||||||
|
showTabClose_ = showTabClose;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool rememberWindowSize() const {
|
||||||
|
return rememberWindowSize_;
|
||||||
|
}
|
||||||
|
|
||||||
|
void setRememberWindowSize(bool rememberWindowSize) {
|
||||||
|
rememberWindowSize_ = rememberWindowSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
int windowWidth() const {
|
||||||
|
if(rememberWindowSize_)
|
||||||
|
return lastWindowWidth_;
|
||||||
|
else
|
||||||
|
return fixedWindowWidth_;
|
||||||
|
}
|
||||||
|
|
||||||
|
int windowHeight() const {
|
||||||
|
if(rememberWindowSize_)
|
||||||
|
return lastWindowHeight_;
|
||||||
|
else
|
||||||
|
return fixedWindowHeight_;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool windowMaximized() const {
|
||||||
|
if(rememberWindowSize_)
|
||||||
|
return lastWindowMaximized_;
|
||||||
|
else
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
int fixedWindowWidth() const {
|
||||||
|
return fixedWindowWidth_;
|
||||||
|
}
|
||||||
|
|
||||||
|
void setFixedWindowWidth(int fixedWindowWidth) {
|
||||||
|
fixedWindowWidth_ = fixedWindowWidth;
|
||||||
|
}
|
||||||
|
|
||||||
|
int fixedWindowHeight() const {
|
||||||
|
return fixedWindowHeight_;
|
||||||
|
}
|
||||||
|
|
||||||
|
void setFixedWindowHeight(int fixedWindowHeight) {
|
||||||
|
fixedWindowHeight_ = fixedWindowHeight;
|
||||||
|
}
|
||||||
|
|
||||||
|
void setLastWindowWidth(int lastWindowWidth) {
|
||||||
|
lastWindowWidth_ = lastWindowWidth;
|
||||||
|
}
|
||||||
|
|
||||||
|
void setLastWindowHeight(int lastWindowHeight) {
|
||||||
|
lastWindowHeight_ = lastWindowHeight;
|
||||||
|
}
|
||||||
|
|
||||||
|
void setLastWindowMaximized(bool lastWindowMaximized) {
|
||||||
|
lastWindowMaximized_ = lastWindowMaximized;
|
||||||
|
}
|
||||||
|
|
||||||
|
int splitterPos() const {
|
||||||
|
return splitterPos_;
|
||||||
|
}
|
||||||
|
|
||||||
|
void setSplitterPos(int splitterPos) {
|
||||||
|
splitterPos_ = splitterPos;
|
||||||
|
}
|
||||||
|
|
||||||
|
Fm::SidePane::Mode sidePaneMode() const {
|
||||||
|
return sidePaneMode_;
|
||||||
|
}
|
||||||
|
|
||||||
|
void setSidePaneMode(Fm::SidePane::Mode sidePaneMode) {
|
||||||
|
sidePaneMode_ = sidePaneMode;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool showMenuBar() const {
|
||||||
|
return showMenuBar_;
|
||||||
|
}
|
||||||
|
|
||||||
|
void setShowMenuBar(bool showMenuBar) {
|
||||||
|
showMenuBar_ = showMenuBar;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool fullWidthTabBar() const {
|
||||||
|
return fullWidthTabBar_;
|
||||||
|
}
|
||||||
|
|
||||||
|
void setFullWidthTabBar(bool fullWith) {
|
||||||
|
fullWidthTabBar_ = fullWith;
|
||||||
|
}
|
||||||
|
|
||||||
|
Fm::FolderView::ViewMode viewMode() const {
|
||||||
|
return viewMode_;
|
||||||
|
}
|
||||||
|
|
||||||
|
void setViewMode(Fm::FolderView::ViewMode viewMode) {
|
||||||
|
viewMode_ = viewMode;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool showHidden() const {
|
||||||
|
return showHidden_;
|
||||||
|
}
|
||||||
|
|
||||||
|
void setShowHidden(bool showHidden) {
|
||||||
|
showHidden_ = showHidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool placesHome() const {
|
||||||
|
return placesHome_;
|
||||||
|
}
|
||||||
|
|
||||||
|
void setPlacesHome(bool placesHome) {
|
||||||
|
placesHome_ = placesHome;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool placesDesktop() const {
|
||||||
|
return placesDesktop_;
|
||||||
|
}
|
||||||
|
|
||||||
|
void setPlacesDesktop(bool placesDesktop) {
|
||||||
|
placesDesktop_ = placesDesktop;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool placesApplications() const {
|
||||||
|
return placesApplications_;
|
||||||
|
}
|
||||||
|
|
||||||
|
void setPlacesApplications(bool placesApplications) {
|
||||||
|
placesApplications_ = placesApplications;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool placesTrash() const {
|
||||||
|
return placesTrash_;
|
||||||
|
}
|
||||||
|
|
||||||
|
void setPlacesTrash(bool placesTrash) {
|
||||||
|
placesTrash_ = placesTrash;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool placesRoot() const {
|
||||||
|
return placesRoot_;
|
||||||
|
}
|
||||||
|
|
||||||
|
void setPlacesRoot(bool placesRoot) {
|
||||||
|
placesRoot_ = placesRoot;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool placesComputer() const {
|
||||||
|
return placesComputer_;
|
||||||
|
}
|
||||||
|
|
||||||
|
void setPlacesComputer(bool placesComputer) {
|
||||||
|
placesComputer_ = placesComputer;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool placesNetwork() const {
|
||||||
|
return placesNetwork_;
|
||||||
|
}
|
||||||
|
|
||||||
|
void setPlacesNetwork(bool placesNetwork) {
|
||||||
|
placesNetwork_ = placesNetwork;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Qt::SortOrder sortOrder() const {
|
||||||
|
return sortOrder_;
|
||||||
|
}
|
||||||
|
|
||||||
|
void setSortOrder(Qt::SortOrder sortOrder) {
|
||||||
|
sortOrder_ = sortOrder;
|
||||||
|
}
|
||||||
|
|
||||||
|
Fm::FolderModel::ColumnId sortColumn() const {
|
||||||
|
return sortColumn_;
|
||||||
|
}
|
||||||
|
|
||||||
|
void setSortColumn(Fm::FolderModel::ColumnId sortColumn) {
|
||||||
|
sortColumn_ = sortColumn;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool sortFolderFirst() const {
|
||||||
|
return sortFolderFirst_;
|
||||||
|
}
|
||||||
|
|
||||||
|
void setSortFolderFirst(bool folderFirst) {
|
||||||
|
sortFolderFirst_ = folderFirst;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool showFilter() const {
|
||||||
|
return showFilter_;
|
||||||
|
}
|
||||||
|
|
||||||
|
void setShowFilter(bool value) {
|
||||||
|
showFilter_ = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
// settings for use with libfm
|
||||||
|
bool singleClick() const {
|
||||||
|
return singleClick_;
|
||||||
|
}
|
||||||
|
|
||||||
|
void setSingleClick(bool singleClick) {
|
||||||
|
singleClick_ = singleClick;
|
||||||
|
}
|
||||||
|
|
||||||
|
int autoSelectionDelay() const {
|
||||||
|
return autoSelectionDelay_;
|
||||||
|
}
|
||||||
|
|
||||||
|
void setAutoSelectionDelay(int value) {
|
||||||
|
autoSelectionDelay_ = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool useTrash() const {
|
||||||
|
if(!supportTrash_)
|
||||||
|
return false;
|
||||||
|
return useTrash_;
|
||||||
|
}
|
||||||
|
|
||||||
|
void setUseTrash(bool useTrash) {
|
||||||
|
useTrash_ = useTrash;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool confirmDelete() const {
|
||||||
|
return confirmDelete_;
|
||||||
|
}
|
||||||
|
|
||||||
|
void setConfirmDelete(bool confirmDelete) {
|
||||||
|
confirmDelete_ = confirmDelete;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool noUsbTrash() const {
|
||||||
|
return noUsbTrash_;
|
||||||
|
}
|
||||||
|
|
||||||
|
void setNoUsbTrash(bool noUsbTrash) {
|
||||||
|
noUsbTrash_ = noUsbTrash;
|
||||||
|
fm_config->no_usb_trash = noUsbTrash_; // also set this to libfm since FmFileOpsJob reads this config value before trashing files.
|
||||||
|
}
|
||||||
|
|
||||||
|
bool confirmTrash() const {
|
||||||
|
return confirmTrash_;
|
||||||
|
}
|
||||||
|
|
||||||
|
void setConfirmTrash(bool value) {
|
||||||
|
confirmTrash_ = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool quickExec() const {
|
||||||
|
return quickExec_;
|
||||||
|
}
|
||||||
|
|
||||||
|
void setQuickExec(bool value) {
|
||||||
|
quickExec_ = value;
|
||||||
|
fm_config->quick_exec = quickExec_;
|
||||||
|
}
|
||||||
|
|
||||||
|
// bool thumbnailLocal_;
|
||||||
|
// bool thumbnailMax;
|
||||||
|
|
||||||
|
int bigIconSize() const {
|
||||||
|
return bigIconSize_;
|
||||||
|
}
|
||||||
|
|
||||||
|
void setBigIconSize(int bigIconSize) {
|
||||||
|
bigIconSize_ = bigIconSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
int smallIconSize() const {
|
||||||
|
return smallIconSize_;
|
||||||
|
}
|
||||||
|
|
||||||
|
void setSmallIconSize(int smallIconSize) {
|
||||||
|
smallIconSize_ = smallIconSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
int sidePaneIconSize() const {
|
||||||
|
return sidePaneIconSize_;
|
||||||
|
}
|
||||||
|
|
||||||
|
void setSidePaneIconSize(int sidePaneIconSize) {
|
||||||
|
sidePaneIconSize_ = sidePaneIconSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
int thumbnailIconSize() const {
|
||||||
|
return thumbnailIconSize_;
|
||||||
|
}
|
||||||
|
|
||||||
|
QSize folderViewCellMargins() const {
|
||||||
|
return folderViewCellMargins_;
|
||||||
|
}
|
||||||
|
|
||||||
|
void setFolderViewCellMargins(QSize size) {
|
||||||
|
folderViewCellMargins_ = size;
|
||||||
|
}
|
||||||
|
|
||||||
|
QSize desktopCellMargins() const {
|
||||||
|
return desktopCellMargins_;
|
||||||
|
}
|
||||||
|
|
||||||
|
void setDesktopCellMargins(QSize size) {
|
||||||
|
desktopCellMargins_ = size;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool showThumbnails() {
|
||||||
|
return showThumbnails_;
|
||||||
|
}
|
||||||
|
|
||||||
|
void setShowThumbnails(bool show) {
|
||||||
|
showThumbnails_ = show;
|
||||||
|
}
|
||||||
|
|
||||||
|
void setThumbnailLocalFilesOnly(bool value) {
|
||||||
|
Fm::ThumbnailLoader::setLocalFilesOnly(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool thumbnailLocalFilesOnly() {
|
||||||
|
return Fm::ThumbnailLoader::localFilesOnly();
|
||||||
|
}
|
||||||
|
|
||||||
|
int maxThumbnailFileSize() {
|
||||||
|
return Fm::ThumbnailLoader::maxThumbnailFileSize();
|
||||||
|
}
|
||||||
|
|
||||||
|
void setMaxThumbnailFileSize(int size) {
|
||||||
|
Fm::ThumbnailLoader::setMaxThumbnailFileSize(size);
|
||||||
|
}
|
||||||
|
|
||||||
|
void setThumbnailIconSize(int thumbnailIconSize) {
|
||||||
|
thumbnailIconSize_ = thumbnailIconSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool siUnit() {
|
||||||
|
return siUnit_;
|
||||||
|
}
|
||||||
|
|
||||||
|
void setSiUnit(bool siUnit) {
|
||||||
|
siUnit_ = siUnit;
|
||||||
|
// override libfm FmConfig settings. FIXME: should we do this?
|
||||||
|
fm_config->si_unit = (gboolean)siUnit_;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool backupAsHidden() const {
|
||||||
|
return backupAsHidden_;
|
||||||
|
}
|
||||||
|
|
||||||
|
void setBackupAsHidden(bool value) {
|
||||||
|
backupAsHidden_ = value;
|
||||||
|
fm_config->backup_as_hidden = backupAsHidden_; // also set this to libfm since fm_file_info_is_hidden() reads this value internally.
|
||||||
|
}
|
||||||
|
|
||||||
|
bool showFullNames() const {
|
||||||
|
return showFullNames_;
|
||||||
|
}
|
||||||
|
|
||||||
|
void setShowFullNames(bool value) {
|
||||||
|
showFullNames_ = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool shadowHidden() const {
|
||||||
|
return shadowHidden_;
|
||||||
|
}
|
||||||
|
|
||||||
|
void setShadowHidden(bool value) {
|
||||||
|
shadowHidden_ = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool onlyUserTemplates() const {
|
||||||
|
return onlyUserTemplates_;
|
||||||
|
}
|
||||||
|
|
||||||
|
void setOnlyUserTemplates(bool value) {
|
||||||
|
onlyUserTemplates_ = value;
|
||||||
|
fm_config->only_user_templates = onlyUserTemplates_;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool templateTypeOnce() const {
|
||||||
|
return templateTypeOnce_;
|
||||||
|
}
|
||||||
|
|
||||||
|
void setTemplateTypeOnce(bool value) {
|
||||||
|
templateTypeOnce_ = value;
|
||||||
|
fm_config->template_type_once = templateTypeOnce_;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool templateRunApp() const {
|
||||||
|
return templateRunApp_;
|
||||||
|
}
|
||||||
|
|
||||||
|
void setTemplateRunApp(bool value) {
|
||||||
|
templateRunApp_ = value;
|
||||||
|
fm_config->template_run_app = templateRunApp_;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private:
|
||||||
|
QString profileName_;
|
||||||
|
bool supportTrash_;
|
||||||
|
|
||||||
|
// PCManFM specific
|
||||||
|
QString fallbackIconThemeName_;
|
||||||
|
bool useFallbackIconTheme_;
|
||||||
|
|
||||||
|
OpenDirTargetType bookmarkOpenMethod_;
|
||||||
|
QString suCommand_;
|
||||||
|
QString terminal_;
|
||||||
|
bool mountOnStartup_;
|
||||||
|
bool mountRemovable_;
|
||||||
|
bool autoRun_;
|
||||||
|
bool closeOnUnmount_;
|
||||||
|
|
||||||
|
int wallpaperMode_;
|
||||||
|
QString wallpaper_;
|
||||||
|
QColor desktopBgColor_;
|
||||||
|
QColor desktopFgColor_;
|
||||||
|
QColor desktopShadowColor_;
|
||||||
|
QFont desktopFont_;
|
||||||
|
bool showWmMenu_;
|
||||||
|
|
||||||
|
bool desktopShowHidden_;
|
||||||
|
Qt::SortOrder desktopSortOrder_;
|
||||||
|
Fm::FolderModel::ColumnId desktopSortColumn_;
|
||||||
|
|
||||||
|
bool alwaysShowTabs_;
|
||||||
|
bool showTabClose_;
|
||||||
|
bool rememberWindowSize_;
|
||||||
|
int fixedWindowWidth_;
|
||||||
|
int fixedWindowHeight_;
|
||||||
|
int lastWindowWidth_;
|
||||||
|
int lastWindowHeight_;
|
||||||
|
bool lastWindowMaximized_;
|
||||||
|
int splitterPos_;
|
||||||
|
Fm::SidePane::Mode sidePaneMode_;
|
||||||
|
bool showMenuBar_;
|
||||||
|
bool fullWidthTabBar_;
|
||||||
|
|
||||||
|
Fm::FolderView::ViewMode viewMode_;
|
||||||
|
bool showHidden_;
|
||||||
|
Qt::SortOrder sortOrder_;
|
||||||
|
Fm::FolderModel::ColumnId sortColumn_;
|
||||||
|
bool sortFolderFirst_;
|
||||||
|
bool showFilter_;
|
||||||
|
|
||||||
|
// settings for use with libfm
|
||||||
|
bool singleClick_;
|
||||||
|
int autoSelectionDelay_;
|
||||||
|
bool useTrash_;
|
||||||
|
bool confirmDelete_;
|
||||||
|
bool noUsbTrash_; // do not trash files on usb removable devices
|
||||||
|
bool confirmTrash_; // Confirm before moving files into "trash can"
|
||||||
|
bool quickExec_; // Don't ask options on launch executable file
|
||||||
|
|
||||||
|
bool showThumbnails_;
|
||||||
|
|
||||||
|
QString archiver_;
|
||||||
|
bool siUnit_;
|
||||||
|
bool backupAsHidden_;
|
||||||
|
bool showFullNames_;
|
||||||
|
bool shadowHidden_;
|
||||||
|
|
||||||
|
bool placesHome_;
|
||||||
|
bool placesDesktop_;
|
||||||
|
bool placesApplications_;
|
||||||
|
bool placesTrash_;
|
||||||
|
bool placesRoot_;
|
||||||
|
bool placesComputer_;
|
||||||
|
bool placesNetwork_;
|
||||||
|
|
||||||
|
int bigIconSize_;
|
||||||
|
int smallIconSize_;
|
||||||
|
int sidePaneIconSize_;
|
||||||
|
int thumbnailIconSize_;
|
||||||
|
|
||||||
|
bool onlyUserTemplates_;
|
||||||
|
bool templateTypeOnce_;
|
||||||
|
bool templateRunApp_;
|
||||||
|
|
||||||
|
QSize folderViewCellMargins_;
|
||||||
|
QSize desktopCellMargins_;
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // PCMANFM_SETTINGS_H
|
41
pcmanfm/tabbar.cpp
Normal file
41
pcmanfm/tabbar.cpp
Normal file
@ -0,0 +1,41 @@
|
|||||||
|
/*
|
||||||
|
|
||||||
|
Copyright (C) 2014 Kuzma Shapran <kuzma.shapran@gmail.com>
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation; either version 2 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License along
|
||||||
|
with this program; if not, write to the Free Software Foundation, Inc.,
|
||||||
|
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#include "tabbar.h"
|
||||||
|
#include <QMouseEvent>
|
||||||
|
|
||||||
|
namespace PCManFM {
|
||||||
|
|
||||||
|
TabBar::TabBar(QWidget *parent):
|
||||||
|
QTabBar(parent)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void TabBar::mouseReleaseEvent(QMouseEvent *event) {
|
||||||
|
if (event->button() == Qt::MiddleButton) {
|
||||||
|
int index = tabAt(event->pos());
|
||||||
|
if (index != -1) {
|
||||||
|
Q_EMIT tabCloseRequested(index);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
QTabBar::mouseReleaseEvent(event);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
42
pcmanfm/tabbar.h
Normal file
42
pcmanfm/tabbar.h
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
/*
|
||||||
|
|
||||||
|
Copyright (C) 2014 Kuzma Shapran <kuzma.shapran@gmail.com>
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation; either version 2 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License along
|
||||||
|
with this program; if not, write to the Free Software Foundation, Inc.,
|
||||||
|
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef FM_TABBAR_H
|
||||||
|
#define FM_TABBAR_H
|
||||||
|
|
||||||
|
#include <QTabBar>
|
||||||
|
|
||||||
|
class QMouseEvent;
|
||||||
|
|
||||||
|
namespace PCManFM {
|
||||||
|
|
||||||
|
class TabBar : public QTabBar {
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
explicit TabBar(QWidget *parent = 0);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
void mouseReleaseEvent(QMouseEvent *event);
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // FM_TABBAR_H
|
539
pcmanfm/tabpage.cpp
Normal file
539
pcmanfm/tabpage.cpp
Normal file
@ -0,0 +1,539 @@
|
|||||||
|
/*
|
||||||
|
|
||||||
|
Copyright (C) 2013 Hong Jen Yee (PCMan) <pcman.tw@gmail.com>
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation; either version 2 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License along
|
||||||
|
with this program; if not, write to the Free Software Foundation, Inc.,
|
||||||
|
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#include "tabpage.h"
|
||||||
|
#include "launcher.h"
|
||||||
|
#include <libfm-qt/filemenu.h>
|
||||||
|
#include <libfm-qt/mountoperation.h>
|
||||||
|
#include <QApplication>
|
||||||
|
#include <QCursor>
|
||||||
|
#include <QMessageBox>
|
||||||
|
#include <QScrollBar>
|
||||||
|
#include <libfm-qt/proxyfoldermodel.h>
|
||||||
|
#include "settings.h"
|
||||||
|
#include "application.h"
|
||||||
|
#include <libfm-qt/cachedfoldermodel.h>
|
||||||
|
#include <QTimer>
|
||||||
|
#include <QTextStream>
|
||||||
|
|
||||||
|
using namespace Fm;
|
||||||
|
|
||||||
|
namespace PCManFM {
|
||||||
|
|
||||||
|
bool ProxyFilter::filterAcceptsRow(const Fm::ProxyFolderModel* model, FmFileInfo* info) const {
|
||||||
|
if(!model || !info)
|
||||||
|
return true;
|
||||||
|
QString baseName(fm_file_info_get_name(info));
|
||||||
|
if(!virtHiddenList_.isEmpty() && !model->showHidden() && virtHiddenList_.contains(baseName))
|
||||||
|
return false;
|
||||||
|
if(!filterStr_.isEmpty() && !baseName.contains(filterStr_, Qt::CaseInsensitive))
|
||||||
|
return false;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ProxyFilter::setVirtHidden(FmFolder* folder) {
|
||||||
|
virtHiddenList_ = QStringList(); // reset the list
|
||||||
|
if(!folder) return;
|
||||||
|
if(FmPath* path = fm_folder_get_path(folder)) {
|
||||||
|
char* pathStr = fm_path_to_str(path);
|
||||||
|
if(pathStr) {
|
||||||
|
QString dotHidden = QString(pathStr) + QString("/.hidden");
|
||||||
|
g_free(pathStr);
|
||||||
|
QFile file(dotHidden);
|
||||||
|
if(file.open(QIODevice::ReadOnly | QIODevice::Text)) {
|
||||||
|
QTextStream in(&file);
|
||||||
|
while(!in.atEnd())
|
||||||
|
virtHiddenList_.append(in.readLine());
|
||||||
|
file.close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
TabPage::TabPage(FmPath* path, QWidget* parent):
|
||||||
|
QWidget(parent),
|
||||||
|
folder_(NULL),
|
||||||
|
folderModel_(NULL),
|
||||||
|
overrideCursor_(false) {
|
||||||
|
|
||||||
|
Settings& settings = static_cast<Application*>(qApp)->settings();
|
||||||
|
|
||||||
|
// create proxy folder model to do item filtering
|
||||||
|
proxyModel_ = new ProxyFolderModel();
|
||||||
|
proxyModel_->setShowHidden(settings.showHidden());
|
||||||
|
proxyModel_->setShowThumbnails(settings.showThumbnails());
|
||||||
|
connect(proxyModel_, &ProxyFolderModel::sortFilterChanged, this, &TabPage::onModelSortFilterChanged);
|
||||||
|
|
||||||
|
verticalLayout = new QVBoxLayout(this);
|
||||||
|
verticalLayout->setContentsMargins(0, 0, 0, 0);
|
||||||
|
|
||||||
|
folderView_ = new View(settings.viewMode(), this);
|
||||||
|
folderView_->setMargins(settings.folderViewCellMargins());
|
||||||
|
// newView->setColumnWidth(Fm::FolderModel::ColumnName, 200);
|
||||||
|
connect(folderView_, &View::openDirRequested, this, &TabPage::onOpenDirRequested);
|
||||||
|
connect(folderView_, &View::selChanged, this, &TabPage::onSelChanged);
|
||||||
|
connect(folderView_, &View::clickedBack, this, &TabPage::backwardRequested);
|
||||||
|
connect(folderView_, &View::clickedForward, this, &TabPage::forwardRequested);
|
||||||
|
|
||||||
|
proxyFilter_ = new ProxyFilter();
|
||||||
|
proxyModel_->addFilter(proxyFilter_);
|
||||||
|
|
||||||
|
// FIXME: this is very dirty
|
||||||
|
folderView_->setModel(proxyModel_);
|
||||||
|
verticalLayout->addWidget(folderView_);
|
||||||
|
|
||||||
|
chdir(path, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
TabPage::~TabPage() {
|
||||||
|
freeFolder();
|
||||||
|
if(proxyFilter_)
|
||||||
|
delete proxyFilter_;
|
||||||
|
if(proxyModel_)
|
||||||
|
delete proxyModel_;
|
||||||
|
if(folderModel_)
|
||||||
|
folderModel_->unref();
|
||||||
|
|
||||||
|
if(overrideCursor_) {
|
||||||
|
QApplication::restoreOverrideCursor(); // remove busy cursor
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void TabPage::freeFolder() {
|
||||||
|
if(folder_) {
|
||||||
|
g_signal_handlers_disconnect_by_func(folder_, (gpointer)onFolderStartLoading, this);
|
||||||
|
g_signal_handlers_disconnect_by_func(folder_, (gpointer)onFolderFinishLoading, this);
|
||||||
|
g_signal_handlers_disconnect_by_func(folder_, (gpointer)onFolderError, this);
|
||||||
|
g_signal_handlers_disconnect_by_func(folder_, (gpointer)onFolderFsInfo, this);
|
||||||
|
g_signal_handlers_disconnect_by_func(folder_, (gpointer)onFolderRemoved, this);
|
||||||
|
g_signal_handlers_disconnect_by_func(folder_, (gpointer)onFolderUnmount, this);
|
||||||
|
g_signal_handlers_disconnect_by_func(folder_, (gpointer)onFolderContentChanged, this);
|
||||||
|
g_object_unref(folder_);
|
||||||
|
folder_ = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*static*/ void TabPage::onFolderStartLoading(FmFolder* _folder, TabPage* pThis) {
|
||||||
|
if(!pThis->overrideCursor_) {
|
||||||
|
// FIXME: sometimes FmFolder of libfm generates unpaired "start-loading" and
|
||||||
|
// "finish-loading" signals of uncertain reasons. This should be a bug in libfm.
|
||||||
|
// Until it's fixed in libfm, we need to workaround the problem here, not to
|
||||||
|
// override the cursor twice.
|
||||||
|
QApplication::setOverrideCursor(QCursor(Qt::WaitCursor));
|
||||||
|
pThis->overrideCursor_ = true;
|
||||||
|
}
|
||||||
|
#if 0
|
||||||
|
#if FM_CHECK_VERSION(1, 0, 2) && 0 // disabled
|
||||||
|
if(fm_folder_is_incremental(_folder)) {
|
||||||
|
/* create a model for the folder and set it to the view
|
||||||
|
it is delayed for non-incremental folders since adding rows into
|
||||||
|
model is much faster without handlers connected to its signals */
|
||||||
|
FmFolderModel* model = fm_folder_model_new(folder, FALSE);
|
||||||
|
fm_folder_view_set_model(fv, model);
|
||||||
|
fm_folder_model_set_sort(model, app_config->sort_by,
|
||||||
|
(app_config->sort_type == GTK_SORT_ASCENDING) ?
|
||||||
|
FM_SORT_ASCENDING : FM_SORT_DESCENDING);
|
||||||
|
g_object_unref(model);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
#endif
|
||||||
|
fm_folder_view_set_model(fv, NULL);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
// slot
|
||||||
|
void TabPage::restoreScrollPos() {
|
||||||
|
// scroll to recorded position
|
||||||
|
folderView_->childView()->verticalScrollBar()->setValue(browseHistory().currentScrollPos());
|
||||||
|
|
||||||
|
// if the current folder is the parent folder of the last browsed folder,
|
||||||
|
// select the folder item in current view.
|
||||||
|
if(lastFolderPath_.parent() == path()) {
|
||||||
|
QModelIndex index = folderView_->indexFromFolderPath(lastFolderPath_.data());
|
||||||
|
if(index.isValid()) {
|
||||||
|
folderView_->childView()->scrollTo(index, QAbstractItemView::EnsureVisible);
|
||||||
|
folderView_->childView()->setCurrentIndex(index);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*static*/ void TabPage::onFolderFinishLoading(FmFolder* _folder, TabPage* pThis) {
|
||||||
|
// FIXME: is this needed?
|
||||||
|
FmFileInfo* fi = fm_folder_get_info(_folder);
|
||||||
|
if(fi) { // if loading of the folder fails, it's possible that we don't have FmFileInfo.
|
||||||
|
pThis->title_ = QString::fromUtf8(fm_file_info_get_disp_name(fi));
|
||||||
|
Q_EMIT pThis->titleChanged(pThis->title_);
|
||||||
|
}
|
||||||
|
|
||||||
|
fm_folder_query_filesystem_info(_folder); // FIXME: is this needed?
|
||||||
|
#if 0
|
||||||
|
FmFolderView* fv = folder_view;
|
||||||
|
const FmNavHistoryItem* item;
|
||||||
|
GtkScrolledWindow* scroll = GTK_SCROLLED_WINDOW(fv);
|
||||||
|
|
||||||
|
/* Note: most of the time, we delay the creation of the
|
||||||
|
* folder model and do it after the whole folder is loaded.
|
||||||
|
* That is because adding rows into model is much faster when no handlers
|
||||||
|
* are connected to its signals. So we detach the model from folder view
|
||||||
|
* and create the model again when it's fully loaded.
|
||||||
|
* This optimization, however, is not used for FmFolder objects
|
||||||
|
* with incremental loading (search://) */
|
||||||
|
if(fm_folder_view_get_model(fv) == NULL) {
|
||||||
|
/* create a model for the folder and set it to the view */
|
||||||
|
FmFolderModel* model = fm_folder_model_new(folder, app_config->show_hidden);
|
||||||
|
fm_folder_view_set_model(fv, model);
|
||||||
|
#if FM_CHECK_VERSION(1, 0, 2)
|
||||||
|
/* since 1.0.2 sorting should be applied on model instead of view */
|
||||||
|
fm_folder_model_set_sort(model, app_config->sort_by,
|
||||||
|
(app_config->sort_type == GTK_SORT_ASCENDING) ?
|
||||||
|
FM_SORT_ASCENDING : FM_SORT_DESCENDING);
|
||||||
|
#endif
|
||||||
|
g_object_unref(model);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// update status text
|
||||||
|
QString& text = pThis->statusText_[StatusTextNormal];
|
||||||
|
text = pThis->formatStatusText();
|
||||||
|
Q_EMIT pThis->statusChanged(StatusTextNormal, text);
|
||||||
|
|
||||||
|
if(pThis->overrideCursor_) {
|
||||||
|
QApplication::restoreOverrideCursor(); // remove busy cursor
|
||||||
|
pThis->overrideCursor_ = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// After finishing loading the folder, the model is updated, but Qt delays the UI update
|
||||||
|
// for performance reasons. Therefore at this point the UI is not up to date.
|
||||||
|
// Of course, the scrollbar ranges are not updated yet. We solve this by installing an Qt timeout handler.
|
||||||
|
QTimer::singleShot(10, pThis, SLOT(restoreScrollPos()));
|
||||||
|
}
|
||||||
|
|
||||||
|
/*static*/ FmJobErrorAction TabPage::onFolderError(FmFolder* _folder, GError* err, FmJobErrorSeverity severity, TabPage* pThis) {
|
||||||
|
if(err->domain == G_IO_ERROR) {
|
||||||
|
if(err->code == G_IO_ERROR_NOT_MOUNTED && severity < FM_JOB_ERROR_CRITICAL) {
|
||||||
|
FmPath* path = fm_folder_get_path(_folder);
|
||||||
|
MountOperation* op = new MountOperation(pThis);
|
||||||
|
op->mount(path);
|
||||||
|
if(op->wait()) { // blocking event loop, wait for mount operation to finish.
|
||||||
|
// This will reload the folder, which generates a new "start-loading"
|
||||||
|
// signal, so we get more "start-loading" signals than "finish-loading"
|
||||||
|
// signals. FIXME: This is a bug of libfm.
|
||||||
|
// Because the two signals are not correctly paired, we need to
|
||||||
|
// remove busy cursor here since "finish-loading" is not emitted.
|
||||||
|
QApplication::restoreOverrideCursor(); // remove busy cursor
|
||||||
|
pThis->overrideCursor_ = false;
|
||||||
|
return FM_JOB_RETRY;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(severity >= FM_JOB_ERROR_MODERATE) {
|
||||||
|
/* Only show more severe errors to the users and
|
||||||
|
* ignore milder errors. Otherwise too many error
|
||||||
|
* message boxes can be annoying.
|
||||||
|
* This fixes bug #3411298- Show "Permission denied" when switching to super user mode.
|
||||||
|
* https://sourceforge.net/tracker/?func=detail&aid=3411298&group_id=156956&atid=801864
|
||||||
|
* */
|
||||||
|
|
||||||
|
// FIXME: consider replacing this modal dialog with an info bar to improve usability
|
||||||
|
QMessageBox::critical(pThis, tr("Error"), QString::fromUtf8(err->message));
|
||||||
|
}
|
||||||
|
return FM_JOB_CONTINUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*static*/ void TabPage::onFolderFsInfo(FmFolder* _folder, TabPage* pThis) {
|
||||||
|
guint64 free, total;
|
||||||
|
QString& msg = pThis->statusText_[StatusTextFSInfo];
|
||||||
|
if(fm_folder_get_filesystem_info(_folder, &total, &free)) {
|
||||||
|
char total_str[64];
|
||||||
|
char free_str[64];
|
||||||
|
fm_file_size_to_str(free_str, sizeof(free_str), free, fm_config->si_unit);
|
||||||
|
fm_file_size_to_str(total_str, sizeof(total_str), total, fm_config->si_unit);
|
||||||
|
msg = tr("Free space: %1 (Total: %2)")
|
||||||
|
.arg(QString::fromUtf8(free_str))
|
||||||
|
.arg(QString::fromUtf8(total_str));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
msg.clear();
|
||||||
|
Q_EMIT pThis->statusChanged(StatusTextFSInfo, msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
QString TabPage::formatStatusText() {
|
||||||
|
if(proxyModel_ && folder_) {
|
||||||
|
FmFileInfoList* files = fm_folder_get_files(folder_);
|
||||||
|
int total_files = fm_file_info_list_get_length(files);
|
||||||
|
int shown_files = proxyModel_->rowCount();
|
||||||
|
int hidden_files = total_files - shown_files;
|
||||||
|
QString text = tr("%n item(s)", "", shown_files);
|
||||||
|
if(hidden_files > 0)
|
||||||
|
text += tr(" (%n hidden)", "", hidden_files);
|
||||||
|
return text;
|
||||||
|
}
|
||||||
|
return QString();
|
||||||
|
}
|
||||||
|
|
||||||
|
/*static*/ void TabPage::onFolderRemoved(FmFolder* _folder, TabPage* pThis) {
|
||||||
|
// the folder we're showing is removed, destroy the widget
|
||||||
|
qDebug("folder removed");
|
||||||
|
Settings& settings = static_cast<Application*>(qApp)->settings();
|
||||||
|
// NOTE: call pThis->deleteLater() directly from this GObject signal handler
|
||||||
|
// does not work but I don't know why.
|
||||||
|
// Maybe it's the problem of glib mainloop integration?
|
||||||
|
// Call it when idle works, though.
|
||||||
|
if(settings.closeOnUnmount())
|
||||||
|
QTimer::singleShot(0, pThis, SLOT(deleteLater()));
|
||||||
|
else
|
||||||
|
pThis->chdir(fm_path_get_home());
|
||||||
|
}
|
||||||
|
|
||||||
|
/*static*/ void TabPage::onFolderUnmount(FmFolder* _folder, TabPage* pThis) {
|
||||||
|
// the folder we're showing is unmounted, destroy the widget
|
||||||
|
qDebug("folder unmount");
|
||||||
|
// NOTE: call pThis->deleteLater() directly from this GObject signal handler
|
||||||
|
// does not work but I don't know why.
|
||||||
|
// Maybe it's the problem of glib mainloop integration?
|
||||||
|
// Call it when idle works, though.
|
||||||
|
Settings& settings = static_cast<Application*>(qApp)->settings();
|
||||||
|
// NOTE: call pThis->deleteLater() directly from this GObject signal handler
|
||||||
|
// does not work but I don't know why.
|
||||||
|
// Maybe it's the problem of glib mainloop integration?
|
||||||
|
// Call it when idle works, though.
|
||||||
|
if(settings.closeOnUnmount())
|
||||||
|
QTimer::singleShot(0, pThis, SLOT(deleteLater()));
|
||||||
|
else
|
||||||
|
pThis->chdir(fm_path_get_home());
|
||||||
|
}
|
||||||
|
|
||||||
|
/*static */ void TabPage::onFolderContentChanged(FmFolder* _folder, TabPage* pThis) {
|
||||||
|
/* update status text */
|
||||||
|
pThis->statusText_[StatusTextNormal] = pThis->formatStatusText();
|
||||||
|
Q_EMIT pThis->statusChanged(StatusTextNormal, pThis->statusText_[StatusTextNormal]);
|
||||||
|
}
|
||||||
|
|
||||||
|
QString TabPage::pathName() {
|
||||||
|
char* disp_path = fm_path_display_name(path(), TRUE);
|
||||||
|
QString ret = QString::fromUtf8(disp_path);
|
||||||
|
g_free(disp_path);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
void TabPage::chdir(FmPath* newPath, bool addHistory) {
|
||||||
|
if(folder_) {
|
||||||
|
// we're already in the specified dir
|
||||||
|
if(fm_path_equal(newPath, fm_folder_get_path(folder_)))
|
||||||
|
return;
|
||||||
|
|
||||||
|
// remember the previous folder path that we have browsed.
|
||||||
|
lastFolderPath_ = fm_folder_get_path(folder_);
|
||||||
|
|
||||||
|
if(addHistory) {
|
||||||
|
// store current scroll pos in the browse history
|
||||||
|
BrowseHistoryItem& item = history_.currentItem();
|
||||||
|
QAbstractItemView* childView = folderView_->childView();
|
||||||
|
item.setScrollPos(childView->verticalScrollBar()->value());
|
||||||
|
}
|
||||||
|
|
||||||
|
// free the previous model
|
||||||
|
if(folderModel_) {
|
||||||
|
proxyModel_->setSourceModel(NULL);
|
||||||
|
folderModel_->unref(); // unref the cached model
|
||||||
|
folderModel_ = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
freeFolder();
|
||||||
|
}
|
||||||
|
|
||||||
|
char* disp_name = fm_path_display_basename(newPath);
|
||||||
|
title_ = QString::fromUtf8(disp_name);
|
||||||
|
Q_EMIT titleChanged(title_);
|
||||||
|
g_free(disp_name);
|
||||||
|
|
||||||
|
folder_ = fm_folder_from_path(newPath);
|
||||||
|
proxyFilter_->setVirtHidden(folder_);
|
||||||
|
if(addHistory) {
|
||||||
|
// add current path to browse history
|
||||||
|
history_.add(path());
|
||||||
|
}
|
||||||
|
g_signal_connect(folder_, "start-loading", G_CALLBACK(onFolderStartLoading), this);
|
||||||
|
g_signal_connect(folder_, "finish-loading", G_CALLBACK(onFolderFinishLoading), this);
|
||||||
|
g_signal_connect(folder_, "error", G_CALLBACK(onFolderError), this);
|
||||||
|
g_signal_connect(folder_, "fs-info", G_CALLBACK(onFolderFsInfo), this);
|
||||||
|
/* destroy the page when the folder is unmounted or deleted. */
|
||||||
|
g_signal_connect(folder_, "removed", G_CALLBACK(onFolderRemoved), this);
|
||||||
|
g_signal_connect(folder_, "unmount", G_CALLBACK(onFolderUnmount), this);
|
||||||
|
g_signal_connect(folder_, "content-changed", G_CALLBACK(onFolderContentChanged), this);
|
||||||
|
|
||||||
|
folderModel_ = CachedFolderModel::modelFromFolder(folder_);
|
||||||
|
proxyModel_->setSourceModel(folderModel_);
|
||||||
|
proxyModel_->sort(proxyModel_->sortColumn(), proxyModel_->sortOrder());
|
||||||
|
Settings& settings = static_cast<Application*>(qApp)->settings();
|
||||||
|
proxyModel_->setFolderFirst(settings.sortFolderFirst());
|
||||||
|
proxyModel_->sort(settings.sortColumn(), settings.sortOrder());
|
||||||
|
|
||||||
|
if(fm_folder_is_loaded(folder_)) {
|
||||||
|
onFolderStartLoading(folder_, this);
|
||||||
|
onFolderFinishLoading(folder_, this);
|
||||||
|
onFolderFsInfo(folder_, this);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
onFolderStartLoading(folder_, this);
|
||||||
|
}
|
||||||
|
|
||||||
|
void TabPage::selectAll() {
|
||||||
|
folderView_->selectAll();
|
||||||
|
}
|
||||||
|
|
||||||
|
void TabPage::invertSelection() {
|
||||||
|
folderView_->invertSelection();
|
||||||
|
}
|
||||||
|
|
||||||
|
void TabPage::onOpenDirRequested(FmPath* path, int target) {
|
||||||
|
Q_EMIT openDirRequested(path, target);
|
||||||
|
}
|
||||||
|
|
||||||
|
// when the current selection in the folder view is changed
|
||||||
|
void TabPage::onSelChanged(int numSel) {
|
||||||
|
QString msg;
|
||||||
|
if(numSel > 0) {
|
||||||
|
/* FIXME: display total size of all selected files. */
|
||||||
|
if(numSel == 1) { /* only one file is selected */
|
||||||
|
FmFileInfoList* files = folderView_->selectedFiles();
|
||||||
|
FmFileInfo* fi = fm_file_info_list_peek_head(files);
|
||||||
|
const char* size_str = fm_file_info_get_disp_size(fi);
|
||||||
|
if(size_str) {
|
||||||
|
msg = QString("\"%1\" (%2) %3")
|
||||||
|
.arg(QString::fromUtf8(fm_file_info_get_disp_name(fi)))
|
||||||
|
.arg(QString::fromUtf8(size_str ? size_str : ""))
|
||||||
|
.arg(QString::fromUtf8(fm_file_info_get_desc(fi)));
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
msg = QString("\"%1\" %2")
|
||||||
|
.arg(QString::fromUtf8(fm_file_info_get_disp_name(fi)))
|
||||||
|
.arg(QString::fromUtf8(fm_file_info_get_desc(fi)));
|
||||||
|
}
|
||||||
|
/* FIXME: should we support statusbar plugins as in the gtk+ version? */
|
||||||
|
fm_file_info_list_unref(files);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
goffset sum;
|
||||||
|
GList* l;
|
||||||
|
msg = tr("%1 item(s) selected", NULL, numSel).arg(numSel);
|
||||||
|
/* don't count if too many files are selected, that isn't lightweight */
|
||||||
|
if(numSel < 1000) {
|
||||||
|
sum = 0;
|
||||||
|
FmFileInfoList* files = folderView_->selectedFiles();
|
||||||
|
for(l = fm_file_info_list_peek_head_link(files); l; l = l->next) {
|
||||||
|
if(fm_file_info_is_dir(FM_FILE_INFO(l->data))) {
|
||||||
|
/* if we got a directory then we cannot tell it's size
|
||||||
|
unless we do deep count but we cannot afford it */
|
||||||
|
sum = -1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
sum += fm_file_info_get_size(FM_FILE_INFO(l->data));
|
||||||
|
}
|
||||||
|
if(sum >= 0) {
|
||||||
|
char size_str[128];
|
||||||
|
fm_file_size_to_str(size_str, sizeof(size_str), sum,
|
||||||
|
fm_config->si_unit);
|
||||||
|
msg += QString(" (%1)").arg(QString::fromUtf8(size_str));
|
||||||
|
}
|
||||||
|
/* FIXME: should we support statusbar plugins as in the gtk+ version? */
|
||||||
|
fm_file_info_list_unref(files);
|
||||||
|
}
|
||||||
|
/* FIXME: can we show some more info on selection?
|
||||||
|
that isn't lightweight if a lot of files are selected */
|
||||||
|
}
|
||||||
|
}
|
||||||
|
statusText_[StatusTextSelectedFiles] = msg;
|
||||||
|
Q_EMIT statusChanged(StatusTextSelectedFiles, msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void TabPage::backward() {
|
||||||
|
// remember current scroll position
|
||||||
|
BrowseHistoryItem& item = history_.currentItem();
|
||||||
|
QAbstractItemView* childView = folderView_->childView();
|
||||||
|
item.setScrollPos(childView->verticalScrollBar()->value());
|
||||||
|
|
||||||
|
history_.backward();
|
||||||
|
chdir(history_.currentPath(), false);
|
||||||
|
}
|
||||||
|
|
||||||
|
void TabPage::forward() {
|
||||||
|
// remember current scroll position
|
||||||
|
BrowseHistoryItem& item = history_.currentItem();
|
||||||
|
QAbstractItemView* childView = folderView_->childView();
|
||||||
|
item.setScrollPos(childView->verticalScrollBar()->value());
|
||||||
|
|
||||||
|
history_.forward();
|
||||||
|
chdir(history_.currentPath(), false);
|
||||||
|
}
|
||||||
|
|
||||||
|
void TabPage::jumpToHistory(int index)
|
||||||
|
{
|
||||||
|
if(index >=0 && index < history_.size()) {
|
||||||
|
// remember current scroll position
|
||||||
|
BrowseHistoryItem& item = history_.currentItem();
|
||||||
|
QAbstractItemView* childView = folderView_->childView();
|
||||||
|
item.setScrollPos(childView->verticalScrollBar()->value());
|
||||||
|
|
||||||
|
history_.setCurrentIndex(index);
|
||||||
|
chdir(history_.currentPath(), false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool TabPage::canUp() {
|
||||||
|
return (path() != NULL && fm_path_get_parent(path()) != NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
void TabPage::up() {
|
||||||
|
FmPath* _path = path();
|
||||||
|
if(_path) {
|
||||||
|
FmPath* parent = fm_path_get_parent(_path);
|
||||||
|
if(parent) {
|
||||||
|
chdir(parent, true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void TabPage::onModelSortFilterChanged() {
|
||||||
|
Q_EMIT sortFilterChanged();
|
||||||
|
}
|
||||||
|
|
||||||
|
void TabPage::updateFromSettings(Settings& settings) {
|
||||||
|
folderView_->updateFromSettings(settings);
|
||||||
|
}
|
||||||
|
|
||||||
|
void TabPage::setShowHidden(bool showHidden) {
|
||||||
|
if(!proxyModel_ || showHidden == proxyModel_->showHidden())
|
||||||
|
return;
|
||||||
|
proxyModel_->setShowHidden(showHidden);
|
||||||
|
statusText_[StatusTextNormal] = formatStatusText();
|
||||||
|
Q_EMIT statusChanged(StatusTextNormal, statusText_[StatusTextNormal]);
|
||||||
|
}
|
||||||
|
|
||||||
|
void TabPage:: applyFilter() {
|
||||||
|
if(!proxyModel_) return;
|
||||||
|
proxyModel_->updateFilters();
|
||||||
|
statusText_[StatusTextNormal] = formatStatusText();
|
||||||
|
Q_EMIT statusChanged(StatusTextNormal, statusText_[StatusTextNormal]);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace PCManFM
|
252
pcmanfm/tabpage.h
Normal file
252
pcmanfm/tabpage.h
Normal file
@ -0,0 +1,252 @@
|
|||||||
|
/*
|
||||||
|
|
||||||
|
Copyright (C) 2013 Hong Jen Yee (PCMan) <pcman.tw@gmail.com>
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation; either version 2 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License along
|
||||||
|
with this program; if not, write to the Free Software Foundation, Inc.,
|
||||||
|
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef FM_TABPAGE_H
|
||||||
|
#define FM_TABPAGE_H
|
||||||
|
|
||||||
|
#include <QWidget>
|
||||||
|
#include <QVBoxLayout>
|
||||||
|
#include <libfm/fm.h>
|
||||||
|
#include <libfm-qt/browsehistory.h>
|
||||||
|
#include "view.h"
|
||||||
|
#include <libfm-qt/path.h>
|
||||||
|
|
||||||
|
namespace Fm {
|
||||||
|
class FileLauncher;
|
||||||
|
class FolderModel;
|
||||||
|
class ProxyFolderModel;
|
||||||
|
class CachedFolderModel;
|
||||||
|
};
|
||||||
|
|
||||||
|
namespace PCManFM {
|
||||||
|
|
||||||
|
class Settings;
|
||||||
|
class Launcher;
|
||||||
|
|
||||||
|
class ProxyFilter : public Fm::ProxyFolderModelFilter {
|
||||||
|
public:
|
||||||
|
bool filterAcceptsRow(const Fm::ProxyFolderModel* model, FmFileInfo* info) const;
|
||||||
|
virtual ~ProxyFilter() {}
|
||||||
|
void setVirtHidden(FmFolder* folder);
|
||||||
|
QString getFilterStr() {
|
||||||
|
return filterStr_;
|
||||||
|
}
|
||||||
|
void setFilterStr(QString str) {
|
||||||
|
filterStr_ = str;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
QString filterStr_;
|
||||||
|
QStringList virtHiddenList_;
|
||||||
|
};
|
||||||
|
|
||||||
|
class TabPage : public QWidget {
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
enum StatusTextType {
|
||||||
|
StatusTextNormal,
|
||||||
|
StatusTextSelectedFiles,
|
||||||
|
StatusTextFSInfo,
|
||||||
|
StatusTextNum
|
||||||
|
};
|
||||||
|
|
||||||
|
public:
|
||||||
|
explicit TabPage(FmPath* path, QWidget* parent = nullptr);
|
||||||
|
virtual ~TabPage();
|
||||||
|
|
||||||
|
void chdir(FmPath* newPath, bool addHistory = true);
|
||||||
|
|
||||||
|
Fm::FolderView::ViewMode viewMode() {
|
||||||
|
return folderView_->viewMode();
|
||||||
|
}
|
||||||
|
|
||||||
|
void setViewMode(Fm::FolderView::ViewMode mode) {
|
||||||
|
folderView_->setViewMode(mode);
|
||||||
|
}
|
||||||
|
|
||||||
|
void sort(int col, Qt::SortOrder order = Qt::AscendingOrder) {
|
||||||
|
// if(folderModel_)
|
||||||
|
// folderModel_->sort(col, order);
|
||||||
|
if(proxyModel_)
|
||||||
|
proxyModel_->sort(col, order);
|
||||||
|
}
|
||||||
|
|
||||||
|
int sortColumn() {
|
||||||
|
return proxyModel_->sortColumn();
|
||||||
|
}
|
||||||
|
|
||||||
|
Qt::SortOrder sortOrder() {
|
||||||
|
return proxyModel_->sortOrder();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool sortFolderFirst() {
|
||||||
|
return proxyModel_->folderFirst();
|
||||||
|
}
|
||||||
|
void setSortFolderFirst(bool value) {
|
||||||
|
proxyModel_->setFolderFirst(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool sortCaseSensitive() {
|
||||||
|
return proxyModel_->sortCaseSensitivity();
|
||||||
|
}
|
||||||
|
void setSortCaseSensitive(bool value) {
|
||||||
|
proxyModel_->setSortCaseSensitivity(value ? Qt::CaseSensitive : Qt::CaseInsensitive);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool showHidden() {
|
||||||
|
return proxyModel_->showHidden();
|
||||||
|
}
|
||||||
|
|
||||||
|
void setShowHidden(bool showHidden);
|
||||||
|
|
||||||
|
FmPath* path() {
|
||||||
|
return folder_ ? fm_folder_get_path(folder_) : nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
QString pathName();
|
||||||
|
|
||||||
|
FmFolder* folder() {
|
||||||
|
return folder_;
|
||||||
|
}
|
||||||
|
|
||||||
|
Fm::FolderModel* folderModel() {
|
||||||
|
return reinterpret_cast<Fm::FolderModel*>(folderModel_);
|
||||||
|
}
|
||||||
|
|
||||||
|
View* folderView() {
|
||||||
|
return folderView_;
|
||||||
|
}
|
||||||
|
|
||||||
|
Fm::BrowseHistory& browseHistory() {
|
||||||
|
return history_;
|
||||||
|
}
|
||||||
|
|
||||||
|
FmFileInfoList* selectedFiles() {
|
||||||
|
return folderView_->selectedFiles();
|
||||||
|
}
|
||||||
|
|
||||||
|
FmPathList* selectedFilePaths() {
|
||||||
|
return folderView_->selectedFilePaths();
|
||||||
|
}
|
||||||
|
|
||||||
|
void selectAll();
|
||||||
|
|
||||||
|
void invertSelection();
|
||||||
|
|
||||||
|
void reload() {
|
||||||
|
if(folder_) {
|
||||||
|
proxyFilter_->setVirtHidden(folder_); // reread ".hidden"
|
||||||
|
fm_folder_reload(folder_);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
QString title() const {
|
||||||
|
return title_;
|
||||||
|
}
|
||||||
|
|
||||||
|
QString statusText(StatusTextType type = StatusTextNormal) const {
|
||||||
|
return statusText_[type];
|
||||||
|
}
|
||||||
|
|
||||||
|
bool canBackward() {
|
||||||
|
return history_.canBackward();
|
||||||
|
}
|
||||||
|
|
||||||
|
void backward();
|
||||||
|
|
||||||
|
bool canForward() {
|
||||||
|
return history_.canForward();
|
||||||
|
}
|
||||||
|
|
||||||
|
void forward();
|
||||||
|
|
||||||
|
void jumpToHistory(int index);
|
||||||
|
|
||||||
|
bool canUp();
|
||||||
|
|
||||||
|
void up();
|
||||||
|
|
||||||
|
void updateFromSettings(Settings& settings);
|
||||||
|
|
||||||
|
void setFileLauncher(Fm::FileLauncher* launcher) {
|
||||||
|
folderView_->setFileLauncher(launcher);
|
||||||
|
}
|
||||||
|
|
||||||
|
Fm::FileLauncher* fileLauncher() {
|
||||||
|
return folderView_->fileLauncher();
|
||||||
|
}
|
||||||
|
|
||||||
|
QString getFilterStr() {
|
||||||
|
if(proxyFilter_)
|
||||||
|
return proxyFilter_->getFilterStr();
|
||||||
|
return QString();
|
||||||
|
}
|
||||||
|
|
||||||
|
void setFilterStr(QString str) {
|
||||||
|
if(proxyFilter_)
|
||||||
|
proxyFilter_->setFilterStr(str);
|
||||||
|
}
|
||||||
|
|
||||||
|
void applyFilter();
|
||||||
|
|
||||||
|
Q_SIGNALS:
|
||||||
|
void statusChanged(int type, QString statusText);
|
||||||
|
void titleChanged(QString title);
|
||||||
|
void openDirRequested(FmPath* path, int target);
|
||||||
|
void sortFilterChanged();
|
||||||
|
void forwardRequested();
|
||||||
|
void backwardRequested();
|
||||||
|
|
||||||
|
protected Q_SLOTS:
|
||||||
|
void onOpenDirRequested(FmPath* path, int target);
|
||||||
|
void onModelSortFilterChanged();
|
||||||
|
void onSelChanged(int numSel);
|
||||||
|
void restoreScrollPos();
|
||||||
|
|
||||||
|
private:
|
||||||
|
void freeFolder();
|
||||||
|
QString formatStatusText();
|
||||||
|
|
||||||
|
static void onFolderStartLoading(FmFolder* _folder, TabPage* pThis);
|
||||||
|
static void onFolderFinishLoading(FmFolder* _folder, TabPage* pThis);
|
||||||
|
static FmJobErrorAction onFolderError(FmFolder* _folder, GError* err, FmJobErrorSeverity severity, TabPage* pThis);
|
||||||
|
static void onFolderFsInfo(FmFolder* _folder, TabPage* pThis);
|
||||||
|
static void onFolderRemoved(FmFolder* _folder, TabPage* pThis);
|
||||||
|
static void onFolderUnmount(FmFolder* _folder, TabPage* pThis);
|
||||||
|
static void onFolderContentChanged(FmFolder* _folder, TabPage* pThis);
|
||||||
|
|
||||||
|
private:
|
||||||
|
View* folderView_;
|
||||||
|
Fm::CachedFolderModel* folderModel_;
|
||||||
|
Fm::ProxyFolderModel* proxyModel_;
|
||||||
|
ProxyFilter* proxyFilter_;
|
||||||
|
QVBoxLayout* verticalLayout;
|
||||||
|
FmFolder* folder_;
|
||||||
|
QString title_;
|
||||||
|
QString statusText_[StatusTextNum];
|
||||||
|
Fm::BrowseHistory history_; // browsing history
|
||||||
|
Fm::Path lastFolderPath_; // last browsed folder
|
||||||
|
bool overrideCursor_;
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // FM_TABPAGE_H
|
4
pcmanfm/translations/pcmanfm-qt-desktop-pref_de.desktop
Normal file
4
pcmanfm/translations/pcmanfm-qt-desktop-pref_de.desktop
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
#Translations
|
||||||
|
Name[de]=Schreibtisch
|
||||||
|
GenericName[de]=Schreibtischeinstellungen
|
||||||
|
Comment[de]=Einstellungen wie Hintergrundbild oder verwendete Menüs
|
3
pcmanfm/translations/pcmanfm-qt-desktop-pref_el.desktop
Normal file
3
pcmanfm/translations/pcmanfm-qt-desktop-pref_el.desktop
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
Name[el]=Επιφάνεια εργασίας
|
||||||
|
GenericName[el]=Ρυθμίσεις της επιφάνειας εργασίας
|
||||||
|
Comment[el]=Αλλαγή της ταπετσαρίας και της συμπεριφοράς του διαχειριστή της επιφάνειας εργασίας
|
4
pcmanfm/translations/pcmanfm-qt-desktop-pref_hu.desktop
Normal file
4
pcmanfm/translations/pcmanfm-qt-desktop-pref_hu.desktop
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
#Translations
|
||||||
|
Name[hu]=Asztal
|
||||||
|
GenericName[hu]=Asztalbeállítás
|
||||||
|
Comment[hu]=Asztal kinézet és viselkedés beállítása
|
4
pcmanfm/translations/pcmanfm-qt-desktop-pref_it.desktop
Normal file
4
pcmanfm/translations/pcmanfm-qt-desktop-pref_it.desktop
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
#Translations
|
||||||
|
Name[it]=Scrivania
|
||||||
|
GenericName[it]=Preferenze della scrivania
|
||||||
|
Comment[it]=Configura percorso e aspetto della scrivania
|
4
pcmanfm/translations/pcmanfm-qt-desktop-pref_pl.desktop
Normal file
4
pcmanfm/translations/pcmanfm-qt-desktop-pref_pl.desktop
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
#Translations
|
||||||
|
Name[pl]=Pulpit
|
||||||
|
GenericName[pl]=Ustawienia pulpitu
|
||||||
|
Comment[pl]=Zmiana tapety oraz zachowania pulpitu
|
4
pcmanfm/translations/pcmanfm-qt-desktop-pref_pt.desktop
Normal file
4
pcmanfm/translations/pcmanfm-qt-desktop-pref_pt.desktop
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
#Translations
|
||||||
|
Name[pt]=Área de trabalho
|
||||||
|
GenericName[pt]=Definições da área de trabalho
|
||||||
|
Comment[pt]=Mudar o papel de parede e o comportamento da área de trabalho
|
4
pcmanfm/translations/pcmanfm-qt-desktop-pref_ru.desktop
Normal file
4
pcmanfm/translations/pcmanfm-qt-desktop-pref_ru.desktop
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
#Translations
|
||||||
|
Name[ru]=Рабочий стол
|
||||||
|
GenericName[ru]=Настройки рабочего стола
|
||||||
|
Comment[ru]=Изменить обои и поведение менеджера рабочего стола
|
4
pcmanfm/translations/pcmanfm-qt-desktop-pref_tr.desktop
Normal file
4
pcmanfm/translations/pcmanfm-qt-desktop-pref_tr.desktop
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
#Translations / translated by tulliana <tulliana@yandex.com>
|
||||||
|
Name[tr]=Dosya Yöneticisi (pcmanfm-qt)
|
||||||
|
GenericName[tr]=Dosya ve masaüstü yönetim uygulaması
|
||||||
|
Comment[tr]=Dosya Yöneticisi ve Masaüstü Ayarları (duvarkağıtları, menüler vs..)
|
1258
pcmanfm/translations/pcmanfm-qt.ts
Normal file
1258
pcmanfm/translations/pcmanfm-qt.ts
Normal file
File diff suppressed because it is too large
Load Diff
1268
pcmanfm/translations/pcmanfm-qt_ar.ts
Normal file
1268
pcmanfm/translations/pcmanfm-qt_ar.ts
Normal file
File diff suppressed because it is too large
Load Diff
1307
pcmanfm/translations/pcmanfm-qt_cs_CZ.ts
Normal file
1307
pcmanfm/translations/pcmanfm-qt_cs_CZ.ts
Normal file
File diff suppressed because it is too large
Load Diff
4
pcmanfm/translations/pcmanfm-qt_de.desktop
Normal file
4
pcmanfm/translations/pcmanfm-qt_de.desktop
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
#Translations
|
||||||
|
Name[de]=PCManFM-Qt
|
||||||
|
GenericName[de]=Dateimanager
|
||||||
|
Comment[de]=Dateimanager der Desktop-Umgebung LXQt
|
1462
pcmanfm/translations/pcmanfm-qt_de.ts
Normal file
1462
pcmanfm/translations/pcmanfm-qt_de.ts
Normal file
File diff suppressed because it is too large
Load Diff
4
pcmanfm/translations/pcmanfm-qt_el.desktop
Normal file
4
pcmanfm/translations/pcmanfm-qt_el.desktop
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
Name[el]=Διαχειριστής αρχείων PCManFM
|
||||||
|
GenericName[el]=Διαχειριστής αρχείων
|
||||||
|
Comment[el]=Περιήγηση του συστήματος αρχείων και διαχείριση των αρχείων
|
||||||
|
|
1456
pcmanfm/translations/pcmanfm-qt_el.ts
Normal file
1456
pcmanfm/translations/pcmanfm-qt_el.ts
Normal file
File diff suppressed because it is too large
Load Diff
1450
pcmanfm/translations/pcmanfm-qt_es.ts
Normal file
1450
pcmanfm/translations/pcmanfm-qt_es.ts
Normal file
File diff suppressed because it is too large
Load Diff
1359
pcmanfm/translations/pcmanfm-qt_fr.ts
Normal file
1359
pcmanfm/translations/pcmanfm-qt_fr.ts
Normal file
File diff suppressed because it is too large
Load Diff
1372
pcmanfm/translations/pcmanfm-qt_gl.ts
Normal file
1372
pcmanfm/translations/pcmanfm-qt_gl.ts
Normal file
File diff suppressed because it is too large
Load Diff
4
pcmanfm/translations/pcmanfm-qt_hu.desktop
Normal file
4
pcmanfm/translations/pcmanfm-qt_hu.desktop
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
#Translations
|
||||||
|
Name[hu]=PCManFM-Qt fájlkezelő
|
||||||
|
GenericName[hu]=Fájlkezelő
|
||||||
|
Comment[hu]=Fájlok böngészése és karbantartása
|
1276
pcmanfm/translations/pcmanfm-qt_hu.ts
Normal file
1276
pcmanfm/translations/pcmanfm-qt_hu.ts
Normal file
File diff suppressed because it is too large
Load Diff
4
pcmanfm/translations/pcmanfm-qt_it.desktop
Normal file
4
pcmanfm/translations/pcmanfm-qt_it.desktop
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
#Translations
|
||||||
|
Name[it]=Gestore file PCmanFM
|
||||||
|
GenericName[it]=Gestore file
|
||||||
|
Comment[it]=Esplora e organizza file e cartelle
|
1348
pcmanfm/translations/pcmanfm-qt_it.ts
Normal file
1348
pcmanfm/translations/pcmanfm-qt_it.ts
Normal file
File diff suppressed because it is too large
Load Diff
1403
pcmanfm/translations/pcmanfm-qt_ja.ts
Normal file
1403
pcmanfm/translations/pcmanfm-qt_ja.ts
Normal file
File diff suppressed because it is too large
Load Diff
1361
pcmanfm/translations/pcmanfm-qt_lt_LT.ts
Normal file
1361
pcmanfm/translations/pcmanfm-qt_lt_LT.ts
Normal file
File diff suppressed because it is too large
Load Diff
4
pcmanfm/translations/pcmanfm-qt_pl.desktop
Normal file
4
pcmanfm/translations/pcmanfm-qt_pl.desktop
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
#Translations
|
||||||
|
Name[pl]=Menedżer plików PCManFM
|
||||||
|
GenericName[pl]=Menedżer plików
|
||||||
|
Comment[pl]=Przegląd systemu plików i zarządzanie plikami
|
1456
pcmanfm/translations/pcmanfm-qt_pl.ts
Normal file
1456
pcmanfm/translations/pcmanfm-qt_pl.ts
Normal file
File diff suppressed because it is too large
Load Diff
4
pcmanfm/translations/pcmanfm-qt_pt.desktop
Normal file
4
pcmanfm/translations/pcmanfm-qt_pt.desktop
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
#Translations
|
||||||
|
Name[pt]=Gestor de ficheiros PCManFM
|
||||||
|
GenericName[pt]=Gestor de ficheiros
|
||||||
|
Comment[pt]=Explorar o sistema de ficheiros e gerir os seus ficheiros e pastas
|
1408
pcmanfm/translations/pcmanfm-qt_pt.ts
Normal file
1408
pcmanfm/translations/pcmanfm-qt_pt.ts
Normal file
File diff suppressed because it is too large
Load Diff
4
pcmanfm/translations/pcmanfm-qt_ru.desktop
Normal file
4
pcmanfm/translations/pcmanfm-qt_ru.desktop
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
#Translations
|
||||||
|
Name[ru]=Диспетчер файлов PCManFM
|
||||||
|
GenericName[ru]=Диспетчер файлов
|
||||||
|
Comment[ru]=Просматривайте файловую систему и управляйте файлами
|
1439
pcmanfm/translations/pcmanfm-qt_ru.ts
Normal file
1439
pcmanfm/translations/pcmanfm-qt_ru.ts
Normal file
File diff suppressed because it is too large
Load Diff
4
pcmanfm/translations/pcmanfm-qt_tr.desktop
Normal file
4
pcmanfm/translations/pcmanfm-qt_tr.desktop
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
#Translations / translated by tulliana <tulliana@yandex.com>
|
||||||
|
Name[tr]=PCManFM-Qt
|
||||||
|
GenericName[tr]=Dosya Yönetici
|
||||||
|
Comment[tr]=Lxqt dosya ve masaüstü yöneticisi
|
1277
pcmanfm/translations/pcmanfm-qt_tr_TR.ts
Normal file
1277
pcmanfm/translations/pcmanfm-qt_tr_TR.ts
Normal file
File diff suppressed because it is too large
Load Diff
1383
pcmanfm/translations/pcmanfm-qt_zh_TW.ts
Normal file
1383
pcmanfm/translations/pcmanfm-qt_zh_TW.ts
Normal file
File diff suppressed because it is too large
Load Diff
148
pcmanfm/view.cpp
Normal file
148
pcmanfm/view.cpp
Normal file
@ -0,0 +1,148 @@
|
|||||||
|
/*
|
||||||
|
|
||||||
|
Copyright (C) 2013 Hong Jen Yee (PCMan) <pcman.tw@gmail.com>
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation; either version 2 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License along
|
||||||
|
with this program; if not, write to the Free Software Foundation, Inc.,
|
||||||
|
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#include "view.h"
|
||||||
|
#include <libfm-qt/filemenu.h>
|
||||||
|
#include <libfm-qt/foldermenu.h>
|
||||||
|
#include "application.h"
|
||||||
|
#include "settings.h"
|
||||||
|
#include "application.h"
|
||||||
|
#include "mainwindow.h"
|
||||||
|
#include "launcher.h"
|
||||||
|
#include <QAction>
|
||||||
|
|
||||||
|
namespace PCManFM {
|
||||||
|
|
||||||
|
View::View(Fm::FolderView::ViewMode _mode, QWidget* parent):
|
||||||
|
Fm::FolderView(_mode, parent) {
|
||||||
|
|
||||||
|
Settings& settings = static_cast<Application*>(qApp)->settings();
|
||||||
|
updateFromSettings(settings);
|
||||||
|
}
|
||||||
|
|
||||||
|
View::~View() {
|
||||||
|
}
|
||||||
|
|
||||||
|
void View::onFileClicked(int type, FmFileInfo* fileInfo) {
|
||||||
|
if(type == MiddleClick) {
|
||||||
|
if(fm_file_info_is_dir(fileInfo)) {
|
||||||
|
Q_EMIT openDirRequested(fm_file_info_get_path(fileInfo), OpenInNewTab);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
Fm::FolderView::onFileClicked(type, fileInfo);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void View::onNewWindow() {
|
||||||
|
Fm::FileMenu* menu = static_cast<Fm::FileMenu*>(sender()->parent());
|
||||||
|
// FIXME: open the files in a new window
|
||||||
|
Application* app = static_cast<Application*>(qApp);
|
||||||
|
app->openFolders(menu->files());
|
||||||
|
}
|
||||||
|
|
||||||
|
void View::onNewTab() {
|
||||||
|
Fm::FileMenu* menu = static_cast<Fm::FileMenu*>(sender()->parent());
|
||||||
|
for(GList* l = fm_file_info_list_peek_head_link(menu->files()); l; l = l->next) {
|
||||||
|
FmFileInfo* file = FM_FILE_INFO(l->data);
|
||||||
|
Q_EMIT openDirRequested(fm_file_info_get_path(file), OpenInNewTab);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void View::onOpenInTerminal() {
|
||||||
|
Application* app = static_cast<Application*>(qApp);
|
||||||
|
Fm::FileMenu* menu = static_cast<Fm::FileMenu*>(sender()->parent());
|
||||||
|
for(GList* l = fm_file_info_list_peek_head_link(menu->files()); l; l = l->next) {
|
||||||
|
FmFileInfo* file = FM_FILE_INFO(l->data);
|
||||||
|
app->openFolderInTerminal(fm_file_info_get_path(file));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void View::onSearch() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void View::prepareFileMenu(Fm::FileMenu* menu) {
|
||||||
|
Application* app = static_cast<Application*>(qApp);
|
||||||
|
menu->setConfirmDelete(app->settings().confirmDelete());
|
||||||
|
menu->setConfirmTrash(app->settings().confirmTrash());
|
||||||
|
menu->setUseTrash(app->settings().useTrash());
|
||||||
|
|
||||||
|
// add some more menu items for dirs
|
||||||
|
bool all_native = true;
|
||||||
|
bool all_directory = true;
|
||||||
|
FmFileInfoList* files = menu->files();
|
||||||
|
for(GList* l = fm_file_info_list_peek_head_link(files); l; l = l->next) {
|
||||||
|
FmFileInfo* fi = FM_FILE_INFO(l->data);
|
||||||
|
if(!fm_file_info_is_dir(fi))
|
||||||
|
all_directory = false;
|
||||||
|
else if(fm_file_info_is_dir(fi) && !fm_file_info_is_native(fi))
|
||||||
|
all_native = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (all_directory)
|
||||||
|
{
|
||||||
|
QAction* action = new QAction(QIcon::fromTheme("window-new"), tr("Open in New T&ab"), menu);
|
||||||
|
connect(action, &QAction::triggered, this, &View::onNewTab);
|
||||||
|
menu->insertAction(menu->separator1(), action);
|
||||||
|
|
||||||
|
action = new QAction(QIcon::fromTheme("window-new"), tr("Open in New Win&dow"), menu);
|
||||||
|
connect(action, &QAction::triggered, this, &View::onNewWindow);
|
||||||
|
menu->insertAction(menu->separator1(), action);
|
||||||
|
|
||||||
|
// TODO: add search
|
||||||
|
// action = menu->addAction(_("Search"));
|
||||||
|
|
||||||
|
if(all_native)
|
||||||
|
{
|
||||||
|
action = new QAction(QIcon::fromTheme("utilities-terminal"), tr("Open in Termina&l"), menu);
|
||||||
|
connect(action, &QAction::triggered, this, &View::onOpenInTerminal);
|
||||||
|
menu->insertAction(menu->separator1(), action);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if(menu->pasteAction()) // NULL for trash
|
||||||
|
menu->pasteAction()->setVisible(false);
|
||||||
|
if(menu->createAction())
|
||||||
|
menu->createAction()->setVisible(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void View::prepareFolderMenu(Fm::FolderMenu* menu) {
|
||||||
|
}
|
||||||
|
|
||||||
|
void View::updateFromSettings(Settings& settings) {
|
||||||
|
|
||||||
|
setIconSize(Fm::FolderView::IconMode, QSize(settings.bigIconSize(), settings.bigIconSize()));
|
||||||
|
setIconSize(Fm::FolderView::CompactMode, QSize(settings.smallIconSize(), settings.smallIconSize()));
|
||||||
|
setIconSize(Fm::FolderView::ThumbnailMode, QSize(settings.thumbnailIconSize(), settings.thumbnailIconSize()));
|
||||||
|
setIconSize(Fm::FolderView::DetailedListMode, QSize(settings.smallIconSize(), settings.smallIconSize()));
|
||||||
|
|
||||||
|
setMargins(settings.folderViewCellMargins());
|
||||||
|
|
||||||
|
setAutoSelectionDelay(settings.autoSelectionDelay());
|
||||||
|
|
||||||
|
Fm::ProxyFolderModel* proxyModel = model();
|
||||||
|
if(proxyModel) {
|
||||||
|
proxyModel->setShowThumbnails(settings.showThumbnails());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace PCManFM
|
70
pcmanfm/view.h
Normal file
70
pcmanfm/view.h
Normal file
@ -0,0 +1,70 @@
|
|||||||
|
/*
|
||||||
|
|
||||||
|
Copyright (C) 2013 Hong Jen Yee (PCMan) <pcman.tw@gmail.com>
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation; either version 2 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License along
|
||||||
|
with this program; if not, write to the Free Software Foundation, Inc.,
|
||||||
|
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef PCMANFM_FOLDERVIEW_H
|
||||||
|
#define PCMANFM_FOLDERVIEW_H
|
||||||
|
|
||||||
|
#include <libfm-qt/folderview.h>
|
||||||
|
|
||||||
|
namespace Fm {
|
||||||
|
class FileMenu;
|
||||||
|
class FolderMenu;
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace PCManFM {
|
||||||
|
|
||||||
|
class Settings;
|
||||||
|
|
||||||
|
class View : public Fm::FolderView {
|
||||||
|
Q_OBJECT
|
||||||
|
public:
|
||||||
|
|
||||||
|
explicit View(Fm::FolderView::ViewMode _mode = IconMode, QWidget* parent = 0);
|
||||||
|
virtual ~View();
|
||||||
|
|
||||||
|
void updateFromSettings(Settings& settings);
|
||||||
|
|
||||||
|
QSize getMargins() const {
|
||||||
|
return Fm::FolderView::getMargins();
|
||||||
|
}
|
||||||
|
void setMargins(QSize size) {
|
||||||
|
Fm::FolderView::setMargins(size);
|
||||||
|
}
|
||||||
|
|
||||||
|
Q_SIGNALS:
|
||||||
|
void openDirRequested(FmPath* path, int target);
|
||||||
|
|
||||||
|
protected Q_SLOTS:
|
||||||
|
void onNewWindow();
|
||||||
|
void onNewTab();
|
||||||
|
void onOpenInTerminal();
|
||||||
|
void onSearch();
|
||||||
|
|
||||||
|
protected:
|
||||||
|
virtual void onFileClicked(int type, FmFileInfo* fileInfo);
|
||||||
|
virtual void prepareFileMenu(Fm::FileMenu* menu);
|
||||||
|
virtual void prepareFolderMenu(Fm::FolderMenu* menu);
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
};
|
||||||
|
#endif // PCMANFM_FOLDERVIEW_H
|
72
pcmanfm/xdgdir.cpp
Normal file
72
pcmanfm/xdgdir.cpp
Normal file
@ -0,0 +1,72 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2013 Hong Jen Yee (PCMan) <pcman.tw@gmail.com>
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License along
|
||||||
|
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||||
|
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "xdgdir.h"
|
||||||
|
#include <QStandardPaths>
|
||||||
|
#include <QFile>
|
||||||
|
#include <QDir>
|
||||||
|
#include <QSaveFile>
|
||||||
|
|
||||||
|
QString XdgDir::readUserDirsFile() {
|
||||||
|
QFile file(QStandardPaths::writableLocation(QStandardPaths::ConfigLocation) + QStringLiteral("/user-dirs.dirs"));
|
||||||
|
if(file.open(QIODevice::ReadOnly | QIODevice::Text)) {
|
||||||
|
QByteArray data = file.readAll();
|
||||||
|
file.close();
|
||||||
|
return QString::fromLocal8Bit(data);
|
||||||
|
}
|
||||||
|
return QString();
|
||||||
|
}
|
||||||
|
|
||||||
|
QString XdgDir::readDesktopDir() {
|
||||||
|
QString str = readUserDirsFile();
|
||||||
|
if(str.isEmpty())
|
||||||
|
return QStandardPaths::writableLocation(QStandardPaths::HomeLocation) + QStringLiteral("/Desktop");
|
||||||
|
QRegExp reg(QStringLiteral("XDG_DESKTOP_DIR=\"([^\n]*)\""));
|
||||||
|
if(reg.lastIndexIn(str) != -1) {
|
||||||
|
str = reg.cap(1);
|
||||||
|
if(str.startsWith(QStringLiteral("$HOME")))
|
||||||
|
str = QStandardPaths::writableLocation(QStandardPaths::HomeLocation) + str.mid(5);
|
||||||
|
return str;
|
||||||
|
}
|
||||||
|
return QString();
|
||||||
|
}
|
||||||
|
|
||||||
|
void XdgDir::setDesktopDir(QString path) {
|
||||||
|
QString home = QStandardPaths::writableLocation(QStandardPaths::HomeLocation);
|
||||||
|
if(path.startsWith(home))
|
||||||
|
path = QStringLiteral("$HOME") + path.mid(home.length());
|
||||||
|
QString str = readUserDirsFile();
|
||||||
|
QRegExp reg(QStringLiteral("XDG_DESKTOP_DIR=\"([^\n]*)\""));
|
||||||
|
QString line = QStringLiteral("XDG_DESKTOP_DIR=\"") + path + '\"';
|
||||||
|
if(reg.indexIn(str) != -1)
|
||||||
|
str.replace(reg, line);
|
||||||
|
else {
|
||||||
|
if(!str.endsWith('\n'))
|
||||||
|
str += '\n';
|
||||||
|
str += line + '\n';
|
||||||
|
}
|
||||||
|
QString dir = QStandardPaths::writableLocation(QStandardPaths::ConfigLocation);
|
||||||
|
if(QDir().mkpath(dir)) { // write the file
|
||||||
|
QSaveFile file(dir + QStringLiteral("/user-dirs.dirs"));
|
||||||
|
if(file.open(QIODevice::WriteOnly | QIODevice::Text)) {
|
||||||
|
file.write(str.toLocal8Bit());
|
||||||
|
file.commit();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
33
pcmanfm/xdgdir.h
Normal file
33
pcmanfm/xdgdir.h
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2013 Hong Jen Yee (PCMan) <pcman.tw@gmail.com>
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License along
|
||||||
|
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||||
|
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <QObject>
|
||||||
|
#include <QString>
|
||||||
|
|
||||||
|
class XdgDir : public QObject
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
static QString readDesktopDir();
|
||||||
|
|
||||||
|
static void setDesktopDir(QString path);
|
||||||
|
|
||||||
|
private:
|
||||||
|
static QString readUserDirsFile();
|
||||||
|
};
|
Loading…
x
Reference in New Issue
Block a user