Lubuntuify the package.

ubuntu/disco
Simon Quigley 5 years ago
parent 9ae1574941
commit 8a17a95390

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

@ -1,787 +0,0 @@
pcmanfm-qt-0.14.1 / 2019-02-24
==============================
* Corrected the logic of sorting. When a tab page's sorting is changed in
whatever way, remember it.
* Use user name for home desktop shortcut
* Give window parents to some app-modal dialogs
* Save/restore custom columns of detailed view
* Allow double-clicking an item on the autorun dialog to do that action
* Fix crash on sorting by group
* Updated translations
* Note for packagers: pcmanfm-qt now depends on liblxqt >= 0.14.1 and
libfm-qt >= 0.14.1
pcmanfm-qt-0.14.0 / 2019-01-25
==============================
* Removed the use of libfm C APIs.
* An option for showing full names (instead of display names).
* Prefer theme icons for view actions.
* Shadow hidden icons optionally.
* Fixed DND and drop indicator on desktop.
* Fixed closing tab on ejecting/unmounting.
* Fixed a rare crash on unmounting.
* Fixed filtering for detailed list mode.
* Fixed status-bar message when some selected files were filtered out.
* Restart warning bar for Preferences.
* A (warning) bar for the root instance.
* Transient filter-bar by default.
* Added split view.
* Delete trashed files with Delete key.
* Select the first row of Preferences by default.
* Optional Desktop shortcuts (Trash, Home, Computer, and Network). The Trash shortcut is interactive.
* A Tool menu item (and shortcut) to copy the full path of the selected file.
* Really use the terminal emulator chosen by user when launching desktop files.
* Preserve relative positions of Desktop items with DND.
* Dropped QDesktopWidget, and used QScreen instead.
pcmanfm-qt-0.13.0 / 2018-05-21
==============================
* Check minimum version of libfm-qt
* Bumped minor version to 13
* Spanish translation update
* Avoid using the old FmPath struct in libfm and use libfm-qt Fm::FilePath instead.
* Just changed a label in Preferences
* Replace the deprecated Fm::MountOperation::mount() with Fm::MountOperation::mountEnclosingVolume().
* Cleanup
* Migrate to the new libfm-qt Fm::FileLauncher API.
* CMake: Prevent in-source builds
* Use new libfm-qt Fm::Archiver API. (#660)
* Fixed tab close button setting
* Optionally select newly created files
* fixes http -> https
* Fixed some lxde mentions
* Drop usage of Fm::IconTheme
* Add symlink target info to statusbar
* Add Simplified Chinese desktop entries (#640)
* Follow GLib to know if a file is hidden
* Remember hidden Places items between sessions
* Drop Qt foreach
* Use QString Use multi-arg
* Prevent a possible c++11 range-loop detach container (QList)
* Don't call QList::first() on temporary
* Warnings (#625)
* move config to /usr/share/pcmanfm-qt/lxqt
* Fixed the setting for "backup as hidden"" (#614)
* Sweep a desktop mess under the carpet
* cmake: Don't set CMP0063
* cmake: Handle CMP0071 - Mark DBus files with SKIP_AUTOGEN
* cmake: Handle CMP0071 related to UI files.
* Refer to PCManFM-Qt in desktop entries
* Add Spanish desktop entries
* Use QChars
* Simplify if statements
* Const it
* Fix typos, move encloseWithBidiMarks to private and fix its behaviour
* Fix direction of statusbar message
* Give context to singleShot()
* Added a short comment
* Wait for events to be processed before chdir
* Rename progress dialog
* Basic bulk rename
* Really cancel multiple renaming on cancelling
* Initialize dragStarted_ in constructor
* Compact disconnection format
* Tab DND
* View tool-buttons
pcmanfm-qt-0.12.0 / 2017-10-21
==============================
* Release 0.12.0: Update changelog
* Set Version
* removed dangeling symlink to debian dir
* Text eliding, long texts and newline
* Update status message appropriately
* fixup...use static const
* Fix icon sizes
* Just fixed my typo in search settings (#574)
* Lithuanian translation
* Lithuanian translation
* Disable menubar actions that cannot be used
* Save and restore search settings
* Don't export github templates
* Wallpaper Slide Show
* Inline renaming with F2 for detailed list view (#554)
* Inline renaming with F2
* Fix showing/hiding hidden files (#535)
* Don't select or scroll to child folder on reloading (#536)
* Replace customized DesktopItemDelegate hacks with the standard Fm::FolderItemDelegate provided by libfm-qt. (#529)
* liblxqt version make no sense here
* Copied issue template
* Fix Ctrl+A on desktop (#526)
* Update statusbar size info when needed
* Drops Qt5Core_VERSION_STRING
* set Qt::AA_UseHighDpiPixmaps to true
* Fix jerky desktop items
* Place dropped item at drop position (#504)
* Make custom pos checkbox work for multiple items (#499)
* Fix crash on removing desktop items with custom position (#496)
* Fix cursor on hovering desktop items
* Fix pressing RETURN in location bar
* Remove the old tilde replacement
* Included LXQTConfigVars
* Fixed config/CMakeLists.txt - removed not needed things
* Added merged autostart and config to CMakeLists.txt
* Updated *_da.desktop files and removed *_da_DK.desktop files
* Update desktop entries and Replace fr_FR by fr
* lxqt-rc.xml: Change default config install path
* PCManFM-Qt: Update default wallpaper (#49)
* Merge pull request #48 from lxde/pcmanfm-qt-sort-order
* Settings Openbox updated.
* Default key shortcuts added to lxqt-globalkeysd.
* Use lxqt-sudo in pcmanfm-qt config file by default.
* Update Greek translation (el) Remove country variant from language code
* CMake: Adds Runtime and Devel install COMPONENTs
* Coding style changes
* Adds double quotes to everything that may break
* Updates the build system to use the Targets infrastructure
* adjust default wallpaper to default theme
* Drops hardcoded /etc/xdg paths
* Updated german translation, replaced Qt4 by Qt in all xsession/translations
* Updates translations infrastructure
* Update the required minimum cmake version
* remove dead template lines switch OnlyShowIn from Razor -> LXQt stringchanges LxQt -> LXQt
* Add session.conf and windowmanagers.conf.
* Support lxqt-session and add necessary xdg autostart desktop entry files.
* Rename dirs and replace razor with lxqt. Install lxqt.conf to /etc/xdg/lxqt and provide theme config.
* Properly set default wallpaper for pcmanfm-qt. Comment out openbox config handling in startlxde-qt since it's not needed.
* Remove custom openbox config file in desktop.conf temporarily until lxsession is fixed.
* Fix file paths, replacing razor with lxqt. * Remove Alt+F2 and Ctrl+Esc from openbox config file to avoid conflicts with lxqt-panel & lxqt-globalkeys.
* Add default configuration files for lxde-qt session.
* Use const iterators (Fix a FTBFS in debug mode) (#483)
* Fixed desktop items movement
* Fixes some pedantic bugs
* Correct alignment of small icons on desktop
* Rename namespace Fm2 to Fm.
* Remove unused header includes.
* Fix a bug in correct tab page dir path which causes problems of file searching.
* Fix incorrect URI of application menu.
* Fix the broken folder reload.
* Fix incorrect title update of tabs.
* Add basic error handling when folder loading is failed.
* Port status message handling to the new libfm C++ API.
* Use Fm2::Path::homePath() API.
* Use the new libfm C++ terminal emulator APIs.
* Adopt to changes of libfm C++ APIs.
* Deprecate the use of Fm::Thumbnailer.
* Replace all NULL with C++ 11 nullptr.
* Initial port to the new C++ libfm API.
* DesktopWindow: Render tilled wallpaper manually
* Use const iterators
* Checks bookmarks iterators validity (#444)
pcmanfm-qt-0.11.3 / 2017-01-14
==============================
* Release 0.11.3: Update changelog
* remove 0.11.3 changelog entries
* Bump patch version
* Release 0.11.3: Update changelog
* Add a workaround for the Qt5 bug which causes broken wallpaper background.
* Update AUTHORS
pcmanfm-qt-0.11.2 / 2016-12-21
==============================
* Release 0.11.2: Update changelog
* Use static_cast instead of the C style cast
* Fix sign-compare warnings
* Prevent wrong clearing of filter-bar with path buttons (#432)
* bump patch version (#429)
* Add *da.desktop files
* Re-layout on Changing Display Name. (#355)
* Add Pathbar Separator
* New tab on middle clicking a path button
* Make dialogue "About" point out it's the Qt version of PCManFM. (#421)
* CMake: Drop finding XCB
* Avoid code duplication.
* Added a wallpaper zooming option
* Implement a "Connect to server" dialog for easily mounting remote filesystems. Add new API PCManFM::MainWindow::lastActive() to get last active window.
* Use the new button-style path bar by default. Properly handle the editing of button-style path bar.
* Add missing ui file.
* Move the pcmanfm-qt_pt_BR.ts file to lxqt-l10n repo.
* Remove context menu from toolbar and menubar
* Support button-style path bar and adjust the layout of the view menu slightly.
* Create pcmanfm-qt_fr.desktop
* Create pcmanfm-qt-desktop-pref_fr.desktop
* Adds Build PROJECT_NAME with Qt version message
* Moved LIBFM_DATA_DIR compile definition from libfm-qt
* Use target_compile_definitions().
* Use the new lxqt-build-tools package
* Added very basic .gitattributes
* remove "building with cpack" from CMakeLists.txt - not used anymore
* Add Catalan translations
* Added Brazilian Portuguese Translation (pt_BR)
pcmanfm-qt-0.11.1 / 2016-09-24
==============================
* Release 0.11.1: Add changelog
* Bump version to 0.11.1 (#399)
* Extend README.md
* Ensure the existence of libfm dir.
* Fix the bug that breaks sort folder first option.
* Preserve per-folder view settings. * Code refactor and cleanup. * Use Fm::FolderConfig internally for storing the per-folder settings.
* Per-folder saving of sorting and view mode
* Use libfm-qt C++ wrappers instead of the original libfm C API whenever possible.
* Replace tilde with home path (#371)
* Fix -Wswitch warning
* Use LXQtCompilerSettings cmake module
* Replaces deprecated QStyleOptionViewItemV4
* Fixes two typos (#381)
* Add Arabic Translations for Desktop Files
* I18N: Fix plural string (#374)
* Fix some icons for RTL (#366)
* Use a wide spread icon theme as fallback for the time beeing (#359)
* build: Use external translations
* ts-files removal (#352)
* Fix memory leak in main window tool bar (#350)
* Change "compact icon view" in "icon view" (#349)
* Merge pull request #341 from lxde/desktop_sort_settings
* Add some tooltips to Pref dialog
* Add setting for Desktop con size
* Fix a few compiler warnings
pcmanfm-qt-0.11.0 / 2016-03-13
==============================
* Switch automatically to newly opened tabs
* Fixes libfm-qt dependency contradiction on README.md
* Optional fullwidth tabbar By default, the tabbar is stretched over the left pane too. This commit makes that optional with a check button in the UI page of the Preferences dialog. It's checked by default but if unchecked, the tabbar will be positioned right above the folder-view.
* A toolbar button appearing on hiding menubar It has a dropdown menu containing all menubar items, is added to the end of toolbar, after a separator, when menubar is hidden and is removed (hidden) with its separator when menubar is shown.
* fix new grep 2.23 behaviour for the time beeing
* Bump year
* Bump version number to 0.11.0, preparing for a new release.
* Add hide menu bar menu entry
* Add menubar actions to the main window
* Return focus to the folder view when hitting escape
* Added options for min. item margins. Also included a fix (or workaround) for text shadow resetting.
* Added shortcut(s) for filterbar. Also added Ctrl+F, in addition to F3, for the search utility and cleared filter string for all tabs when closing the filterbar.
* Make it possible to hide the menu bar
* Set quit shortcut from the ui file
* Update the tab bar visibility when the settings change
* Add quit shortcut
* Always draw the text shadow on desktop. Also fixed the selected text color.
* Update czech translation (by Petr Balíček <pbalicek@seznam.cz>)
* Improve french translation
* Move the XdndWorkaround to libfm-qt internal instead.
* Fixed a crash on right clicking trashed files.
* Select all of the text in the path entry when focusing it using shortcut keys Alt+D and Ctrl+L.
* Use lxqt-sudo as the default su tool instead of gksu.
* Add some ``beautiful'' workarounds that bypass Qt bug #49947 and 47981. This should fix the bug lxqt/#688 temporarily.
* Prevent large gaps at desktop bottom
* Update pcmanfm-qt_it.ts
* Let the style engine draw the text selection rect on desktop.
* options: Make options of wallpaper-mode switch untranslatable
* turkiash translate files added
* Fix --wallpaper-mode description in translations
* Polish translation updated
* Polish translation updated
* Fix --show-pref option not switching to next name
* Add config values for customizing "places" (not implemented yet).
* Updated Russian translation Removed ru_RU files
pcmanfm-qt-0.10.1 / 2015-12-05
==============================
* hide 'Create New...' menu for files
* Russian translation update
* Deal with CMAKE POLICY 0063
* Use CMAKE_CXX_VISIBILITY_PRESET and CMAKE_VISIBILITY_INLINES_HIDDEN
* Adds Clang support to symbols visibility
* Fix typo in setting key
* hide 'Paste' in file context menu
* restore 'Open with...' for directories in left panel
* Fix referencing generated headers in translations
* CMake: Drop qt5_use_modules()
* CMake: Use the new libfm-qt Targets
* Move libfm-qt to its own repository.
split-libfm-qt / 2015-11-24
===========================
* Fix typos in man page
* Update French translation
* Tab context menu for closing other tabs
* Italian translation updates
* Add bindings to Ctrl+PgUp/Ctrl+PgDn.
* Update French translation of GPL license
* Fix a random crash related to editing the bookmarks by disconnecting from GObject signals properly.
* Fix a crash triggered when unmounting a volume from the side pane.
* Avoid duplicated volumes and mounts in the side panel. (This fixes the mtp:// problem.)
* Select the item of the previously folder in current folder view if it's a direct child of the current folder.
* Fix missing null pointer check in Fm::Path::parent() and use nullptr instead of NULL in path.h.
* Code cleanup, «using» directive only if necessary
* Upgrade of pcmanfm-qt to C++11
* Fix setting a SIGTERM handler with undefined flags
* Fix two typos in README
* Force the root config dir on the root instance
* Fix --version option not displaying version
* hu translations updated
* Fixed several problems with item selection and alignment
* Fix CMake LICENSE path
* Fix compiling with Qt < 5.4
* Move LICENSE file
* Check for null pointers.
* Changed the static wentUp to the private variable wentUp_.
* Select the folder from where we have gone up.
0.10.0 / 2015-11-02
===================
* Release 0.10.0
* Remove unnecessary qDebug traces
* Update zh_TW translations.
* Update translations.
* Provide an option in the view menu to turn off the filter bar (turned off by default).
* The signal QAbstractItemView::iconSizeChanged is only available after Qt 5.5. Add workarounds for older Qt versions.
* Add more null pointer checks in the thumbnail loader to avoid crashes caused by older versions of libfm.
* Fix CPack README path
* Update translations
* Use markdown for README
* Bump minimum CMake to 3.0.2
* Reduce margin and spacing of the central widget
* Avoid the column resizing tricks for the detailed list view when the view contains no columns.
* Improve the column width computation for the detailed view
* Some code cleanup.
* desktop: Makes the Desktop Folder Edit functionality optional
* desktop: Renames Advanced page config layout manager
* PlacesView: activate on click on the second column
* SidePane: reduce size of button's column width
* Remove ugly board of main window's central widget
* Added a filterbar + Handle virtually hidden files
* Russian translation update
* Prevent the desktop window from being closed accidentally. This fixes #194.
* mouse fix
* Update cs_CZ translation with the strings provided by petrbal in pull request #218.
* Add apply button to desktop preferences dialog
* Removed pcmanfm-qt.kdev4 and fixed .gitignore
* desktop: Makes the preferences dialog General page tighter
* Add a shortcut key "F3" for launching the file searching utility. * Small UI layout adjistment.
* Allow adding or removing paths in the file search dialog. Fix bugs in searching for documents.
* Try to implement file searching by using the new Fm::FileSearchDialog class.
* Fix a incorrecy free() in fm_search_free() API.
* Add Fm::Path::take() API to take the ownership of a raw FmPath pointer.
* Add class Fm::FileSearchDialog used to show a dialog for searching files.
* Add FmSearch API which is used to build a search:// URI. (implemented in C and might become part of libfm later).
* Fix #197 by using a different method to forward the XCB mouse events to the root window.
* Fix #195 - Crash when rightclick on item in trash.
* Add a null check for FmFileInfo in Fm::ProxyFolderModel::lessThan(). This closes #205.
* Fix (workaround) for right-click crash in placesview.
* Russian translation: update
* Italian translation: add desktop entry files, adjust TS files
* placesview: middle-click correct item to activate (fix of segfault)
* Paste into folder from its context menu.
* libfm-qt: updated german translation
* libfm-qt: lupdated translation files
* Add Greek (el) translation
* added support for mouse back/forward buttons
* Add few missing Polish translations and modify few existing.
* xdg main category added
* Update German translation
* fixed paths in .ts files + lupdate
* Update German translation
* Update Russian translation
* CMake: Remove unused INSTALL variables
* Support opening items in the bookmarks menu in new tabs or new windows.
* Add new signal prepareFileMenu() to Fm::SidePane and Fm::DirTree so there's a chance to customize the file menu before its shown.
* Port some missing config options from the gtk+ version of pcmanfm.
* Also show hidden dirs in the directory tree when the "Show Hidden" option in the menu is turned on.
* Fix #190 - Column layout is not always updated.
* Fix relative paths in command line arguments. Close lxde/pcmanfm-qt#170 - relative paths stated by xdg-open not considered.
* Create New menu actions, context menu in tree side pane, #163.
* Install SIGTERM handler to save settings when logging out, #157.
* Store side pane mode setting, #157.
* Adds UPDATE_TRANSLATIONS option to the top CMakeLists
* Fixes an translation regression
* Updates translations
* Handles .desktop files translations
* Uses LXQt lxqt_translate_ts() to handle translations
* Add German translation of pcmanfm-qt.desktop
* Fix lxde/lxqt#447 - missing actions in Places' context menus
* Remove trailing whitespaces
* polishing German translation
* Add menu items and shortcuts for new folder and blank file, fixes #163.
*_hu desktops added
* Display folders first when active and sort order descending, fixes #179.
* Avoid space wasted by incorrect decoration in detailed view columns, fixes #177.
* Avoid flickering column header while resizing manually, fixes #176.
* Update pcmanfm-qt_it.ts
* Fix loading new desktop dir
* Hungarian translation
* Fix #627 - long startup time. (This blocking is caused by checking the availability of "network:///".)
* Enable text selection in file properties dialog
* Fixes #168 - qunsetenv("QT_NO_GLIB"); required before constructing the application.
* Fix some memory leaks reported by valgrind.
* Fix warnings reported by cppcheck.
* Fix warnings reported by scan-build.
* Sort indicators in detailed view, store column and order in settings, fixes #109.
* Fix lxde/lxqt#512 - pcmanfm-qt: cannot delete to trash.
* Fix lxde/lxqt#512 - "pcmanfm-qt: cannot delete to trash" by using a safer way to check trash:/// support.
* Polish translations added
* Bumps version
* Rearrange tab order (tabstops)
* Use 'user-trash' icon for 'Move to Trash'
* The "Custom" option in the application chooser combo box inside file properties dialog is broken. Fix by preventing recursive signal handler invocation.
* The file property dialog does not show correct default applications. Fix a bug in AppChooserComboBox::setMimeType() that does incorrect app comparison.
* When converting an UID or GID to its name, show the number as string when the user or group does not exists.
0.9.0 / 2015-02-05
==================
* Add more null checks.
* Fix #130 - Remember width of side panel.
* Portuguese update
* Add very basic "remaining time" display to the progress dialog. Fix lxde/lxqt#463 - Progress dialog of pcmanfm-qt does not show remaining time.
* Fix lxde/pcmanfm-qt#120 - Foucs "Rename" button when file name changed.
* remember maximized state
* Remove unnecessary '\n' charactor from the translated strings.
* Fix translations (the newly added string comes from the translation of libfm).
* Improve trash can handling: provide an option to delete the files if moving to trashcan fails.
* Fix broken filenames of translation files.
* Support NoUsbTrash option and fix #125 - "Move to trash " on mounted devices.
* Bump version numbers, preparing for a new release.
* Completely remove dependency on libqtxdg.
* More migration to Qt5 new signal/slot syntax for better type safety & speed.
* Migrade to new Qt5 signal/slot syntax for better type safety and speed.
* Fix the broken sorting option.
* Fix lxde/lxqt#448 - PCmanFM-QT renaming place bookmarks does nothing.
* Fix broken rememberWindowSize settings.
* Portuguese update
* Support linguistic sorting of file names. This fixes #105.
* Avoid using Qt 5.4 API if compiled with older Qt versions. Fix #121.
* Update the folder model & view after files are changed.
* Open folders in new tabs by middle clicking on items in the side pane.
* Support reordering of tabs using drag and drop.
* Portuguese update
* Fix a crash of the context menu of places view caused by change of items.
* Save the result of "Edit bookmarks" to gtk+3 bookmarks file instead of the deprecated ~/.gtkbookmarks file. This fixes bug #112 partially.
* Fix #396: pcmanfm-qt back and/or up does not remember position.
* Add spanish translations
* Adds GUI to change desktop dir in Desktop preferences. Uses libqtxdg.
* Add .gitignore
* Update Japanese translation
* Add German translation
* add Japanese translation
* Implement "UnTrash" for files in trash:/// and close lxde/lxqt#136.
* Handle command line URIs correctly and fix bug lxde/lxqt#414.
* Handle command line arguments with QCommandLineParser instead of using glib. Requires Qt >= 5.2.
* Add Russian translation
* Drop Qt4 support in code
* Clean up CMakeLists.txt and drop Qt4 support
* New files added from LXDE Pootle server based on templates
0.8.0 / 2014-09-28
==================
* Commit from LXDE Pootle server by user Julius22.: 1007 of 1008 strings translated (2 need review).
* Commit from LXDE Pootle server by user Julius22.: 709 of 1008 strings translated (2 need review).
* Commit from LXDE Pootle server by user mbouzada.: 1008 of 1008 strings translated (0 need review).
* Commit from LXDE Pootle server by user mbouzada.: 891 of 1008 strings translated (0 need review).
* Commit from LXDE Pootle server by user mbouzada.: 615 of 1008 strings translated (0 need review).
* Commit from LXDE Pootle server by user mbouzada.: 364 of 364 strings translated (0 need review).
* New files added from LXDE Pootle server based on templates
* Keep CMAKE_CXX_FLAGS value
* Update ts files.
* Add manpage for pcmanfm-qt
* Add cs_CZ translation for libfm-qt.
* Commit from LXDE Pootle server by user dforsi.: 520 of 644 strings translated (0 need review).
* Commit from LXDE Pootle server by user dforsi.: 364 of 364 strings translated (0 need review).
* Commit from LXDE Pootle server by user dforsi.: 358 of 364 strings translated (0 need review).
* Change version number to 0.8 and update the info in the about dialog.
* Ensure that Qt 5.1 and above is used when built with Qt5 support.
* Bump package version number and library soversion to prepare for 0.2 release.
* queue relayout of desktop items when the desktop window is resized.
* Add cs_CZ translation for pcmanfm-qt.
* Fix broken Qt4 build.
* Fix bugs in multihead support and also add workaround for Qt5 bug #40681. * Handle switches between virtual desktop mode and non-virtual mode correctly. * Disable desktop wallpaper cache for non-primary screens.
* Correctly reposition desktop items when the icon size, font, or Qt style is changed.
* Slight improvement of the preference dialog for the newly added "remember window size" option.
* Fix #85 - Scrolling doesn't work in compact view.
* Hide UI elements that are not usable and disable trash can when gvfs is not available. * Add new API Fm::isUriSchemeSupported().
* Avoid showing the popup menu when moving desktop items.
* Improve handling of file selection and fixing FolderView::selectAll(), which is reported in #45. Delay the handling of selectionChanged() signal to avoid too frequent UI updates.
* Little adjustment for the grid of the folder view to decrease unnecessary margins.
* Use a new way to optimize the size of filename display based on current view mode and font size. This also fixes lxde/lxde-qt #198 - PCmanFM-qt incorrectly displays 256x256 Thumbnails.
* Replace the very broken QDesktopWidget with QScreen in Qt 5 when handling multihead support.
* Fully support single click activation and auto-selection with associated options added to the preference dialog.
* Add single click and auto-selection on hover support to Fm::FolderView.
* Re-layout desktop icons properly on QEvent::StyleChange and QEvent::FontChange.
* Try to support multihead setup in virtual screen mode (used by XRandR).
* Handle QEvent::WinIdChange event and reset X11 window properties correctly.
* New files added from LXDE Pootle server based on templates
* New files added from LXDE Pootle server based on templates
* Support forced deletion of files which bypasses the trash can with "Shift+Delete" shortcut key. * Simplify shortcut setup code a little.
* Add proper keyboard shortcuts to the desktop window. This closes bug #67.
* Add an option to go to home directory when the currently shown folder is deleted or unmounted.
* Improve update of translations to avoid unnecessary regeneration of ts files.
* Improve handling of fallback icons. This closes bug #57.
* Fix the mark for current history item in the popup menu of forward and backward buttons.
* Translations are lost accidentally in a previous commit. Restore them all.
* Add a workaround for Qt bug 32567 which causes bug #251 of lxde/lxde-qt. Now the desktop window should monitor the change of work area correctly.
* Avoid ambiguity when including path.h from libfm-qt.
* Fix a crash in Fm::PlacesModel when gvfs is not available. This closes bug #35 - Ctrl+W closes all windows.
* Fix a memory leak and free the file info list properly when renaming files.
* Do not detect filename extension and select the whole filename by default while renaming directories. This closes bug #71 - Don't try to detect extensions on directories. * API changed: Fm::renameFile() now accepect FmFileInfo as its first parameter.
* Show browse history in the context menu of back and forward tool buttons.
* Remove an unnecessary slot.
* Backspace to go up
* Fix bug #80 - make execute in context menu doesn't do change permissions.
* Remove unnecessary matrix set on the background brush.
* Avoid unnecessary writes to the desktop icon config file.
* Revert "fixed selection issue #45" This patch breaks copying files by DND in icon view mode and moving desktop icons.
* Avoid unnecessary relayout.
* Fix lxde/lxde-qt #184 - cannot move icons on desktop.
* Support showing the desktop menu provided by the window manager.
* Use qss instead of QPalette to set the background color of ColorButton. This fixed bug #192 of lxde-qt.
* Adds option to remember last window size
* Replace hard-coded version number 0x050000 with QT_VERSION_CHECK(5, 0, 0) for better readability.
* Rename the library from libfm-qt to libfm-qt5 when built with Qt5.
* fixed selection issue #45
* Make settings of size of icons be properly loaded
* Makes the "Show Hidden" option be saved in settings file and properly loaded. I don't understand why it was not done yet, bu here it is.
* Close tabs by middle click
* Fix middle click position calculation in detailed view mode
* Fix crash when context menu is requested but selection is empty
* Activate view items only if clicked with left mouse button
* Do not emit activated signal when keyboard modifiers are on.
* Splits the checks for needed libraries
* Removes duplicated include_directories() entry
* Replaces ${CMAKE_SOURCE_DIR} by ${PROJECT_SOURCE_DIR}
* Fix LICENSE. It's GPL2. Oops.
* Make sure clang compiler does not complain
* Clean up desktop files
* Install pkgconfig file of libfm-qt to correct location in FreeBSD
* Fix missing return values in several methods.
0.7.0 / 2014-05-07
==================
* Update README
* Avoid endless popups of error dialogs when there are errors launching files.
* Fix encoding handling of filenames passed via command line arguments.
* Save thumbnails as png files correctly.
0.6.99 / 2014-04-29
===================
* Update AUTHORS and COPYING
* Cached the scaled version of the wallpaper as needed to speed up program startup.
* Correctly relayout items when the work area is changed
* Adjust size of the preference dialog
* Remember custom positions for desktop icons and fix #29.
* Use new FmTerminal APIs provided by libfm. Also fix #31.
* Add template support to the folder context menus and fix #39.
* Show "owner" in the detailed list view mode. * Fix a crash when switching to detailed list mode in qt5.
* Use xcb to set EWMH window type hint to the desktop window in Qt5. * Some more cleanup for the CMakeList.txt files
* Add initial support for Qt5.
* Try to fix #36 again.
* Fix a seg fault caused by the widget being deleted during glib signal handling.
* Code cleanup, removing unnecessary header inclusion to speed up compilation.
* Avoid further handling of MountOperation in the gio finished callback if the object is deleted.
* Last fix for #36 is incorrect. Fix it again.
* Delete the tab if the folder currently being shown is deleted or unmounted.
* Use modeless dialogs for app chooser and error reporting in Fm::FileLauncher and Fm::FileMenu.
* Add an small emblem for symlinks (using icon name "emblem-symbolic-link"). Fix bug #27.
* Add missing file to git.
* Move internal implementation details to private headers which are not installed to the system.
* Add Doxygen support for API doc generation.
* Fix a regression bug, hiding "Open with..." sub menu of Fm::FileMenu for selected folders.
* Implement Fm::AppChooserDialog and Fm::AppMenuView classes. * Add <Open with...>/<Other Applications> menu item to Fm::FileMenu. * Add custom app to Fm::AppChooserComboBox.
* Add Fm::AppChooserComboBox and use it in Fm::FilePropsDialog.
* Redesign Fm::FileLauncher APIs to make it more usable. * Add Fm::FileMenu::setFileLauncher() and Fm::FolderView::setFileLauncher() APIs. * Move PCManFM::View::onFileClick() and other popup menu handling to Fm::FolderView.
* Improve Fm::FileLaucher to make it easy to derive subclasses. * Implement a special dialog for opening executable files (Fix bug #13 - it does not launch executables)
* Fix bug #28 - Tash can icon does not refresh when the trash can changes its empty/full status
* Load autocompletion list for Fm::PathEdit only when the widget has the keyboard focus to avoid unnecessary I/O.
* Add proper popup menu items for selected folders and fix #20 and #19. * Some code refactors, adding openFolders() and openFolderInTerminal() to Application class.
* Fix #25 - Amount of items in the folder is not refreshed when the folder content changes. * Update status bar text properly on switching tab pages, selection changes, and folder content changes.
* Fix the broken compiler definitions caused by previous commit.
* Fix bug #22 - Do not select file extension by default on file rename. * Avoid installing private headers (*_p.h files)
* Setup pcmanfm-qt to support optional Custom Actions Menubar detects if libfm was built with vala or not if so a fm-actions.h will exist and support will be compiled in if not, will still compile with no actions menu
* Don't append library suffix to library install path, but use it by default
* Allow installation path configuration with standard CMake X_INSTALL_DIR
* Support reordering bookmark items in the places view with DND.
* Support adding bookmarks to the places view using drag and drop
* Preparing for implementing dnd for places view.
* Improve the usability of icon view mode, fixing github bug #24.
* Fix crashes caused by invalid pointer access.
* Switch current dir of the folder view correctly with dir tree view in the side pane.
* Finish chdir operation for Fm::DirTreeView.
* Support hiding hidden folders from DirTreeModel.
* Move some methods from DirTreeModel to DirTreeModelItem and fix some row updating problems.
* Implement dynamic folder loading/unloading when expanding or collapsing dir tree nodes. * Enable horizontal scrollbar of dir tree view.
* Move some code from Fm::DirTreeModel to Fm::DirTreeModelItem.
* Partially implement Fm::DirTreeView and Fm::DirTreeModel. (not finished yet)
* Fix an invalid pointer
* Implment different modes for Fm::SidePane, matching libfm-qtk design. * Add basic skeleton for dir tree view/model.
* Fix the cosmetic defect introduced by the eject buttons in the places view.
* Add eject buttons to mounted volumes in the places side pane.
* Fix #18 New windows should always show up in front.
* Fix #18 New windows should always show up in front.
* Remove x-directory/normal, close github bug #6 and #17.
* Add a wrapper class Fm::Path for FmPath C struct.
* Do not emit StyleChange events if the icon theme is not really changed.
* Initialize icon_ member of PlacesModelItem correctly.
* Fix fallback icon when a platform plugin is abscent. * Make Fm::IconTheme::checkUpdate() a static function.
* Remove xsettings support. Use a cleaner way to detect config changes by monitor StyleChange events. * Add Fm::IconTheme::changed() signal which is emitted when the icon theme name is changed. * Replace nested Fm::PlacesModel::Item and related classes with their own separate toplevel classes.
* Fix the icon for files of unknown mime types, again.
* Fix the icon for files of unknown mime types.
* Add DES-EMA custom actions to the popup menus.
* Make it safe to create multiple Fm::LibFmQt objects and only initialize libfm once.
* Fix incorrect export symbols and use GNUInstallDirs for installation destination
* Correctly save new wallpaper config.
* Support changing wallpaper from command line & dbus.
* Read fallback default settings from /etc/xdg/pcmanfm-qt.
* Use the latest libfm thumbnailer APIs.
* Fix #3614873 - Thumbnails in icon view shown upside down for some jpegs.
* Adopt recent changes of libfm. FmIcon is essentially identical to GIcon now.
* Add a UI file for application chooser dialog.
* Correctly handle display names of folders in path entry auto-completion.
* Add a global header and add proper definition for LIBFM_QT_API macro.
* Put cmake_minimum_required(VERSION 2.8.6) at the right place.
* Add "Empty trash" and fix a memory leak.
* Fix persistent busy cursor when loading menu://applications/
* Fix memory leaks for bookmarks. Fix the broken "Network" item in places.
* Select correct folder view mode in the preference dialog.
* Reduce memory usage: Paint the folder items with our own code instead of using a dirty hacks duplicating pixmaps.
* Reduce of size of QPixmapCache in the hope of decreasing memory usage.
* Add fallback icons for places item "applications" and "network".
* Paint the background of the whole desktop window with wallpaper, including the reserved spaces.
* Set workare with QSS does not work properly. Revert the change.
* Add class Fm::CachedFolderModel, a convinient way to share Fm::FolderModel objects and reduce memory usage.
* Resize the columns of detailed list view when items are inserted or removed.
* Optimize column widths in detailed list mode when the view is resized.
* Resize the left list widget in the preference dialog according to its content.
* Detect icon theme name automatically using Xsettings or other desktop-specific way. * Rename "IconThemeName" key in the config file to "FallbackIconThemeName". * Hide the icon theme selection combo box if an icon theme name is detected automatically.
* Only show thumbnails for the first column in detailed list mode.
* Use new "automoc" feature of cmake 2.8.6 and remove cumbersome #include "*.moc" code.
* Fix work area problems of desktop window.
* Trivial fix.
* Add additional custom filter support to ProxyFolderModel.
* Add some keyboard shortcuts to the main window
* Fix some memory leaks.
* Fix some compiler errors and update translations.
* Support the latest libfm trunk. Remove -fpermissive compiler flag and fix compiler errors/warnings.
* Adopt new libfm thumbnail APIs.
* Enable thumbnail related settings.
* Adopt the latest thumbnail API in libfm (thumbnail branch) to speed up loading.
* Workardound incorrect thumbnail painting caused by bug of QStyledItemDelegate. :-(
* Fix a crash caused by accessing data for invalid model index.
* Add basic thumbnail support (need the latest thumbnail branch of libfm).
0.1 / 2013-03-26
================
* Add soname 0.0.0 for libfm-qt, preparing for 0.1 release.
* Fix crashes caused by incorrect deletion of dialog objects.
* Update zh_TW translations and translation templates.
* Add Portuguese translation (pt).
* Add Lithuanian translation (lt_LT).
* Fix a crash caused by accessing data for invalid model index.
* Add a Qt designer ui file for "Find Files" utility (not yet implemented).
* Add archiver integration for file context menus.
* Add archiver integration to file context menus.
* Add mnemonics for menu items. Make confirm dialog before delete and trash can optional.
* Update side pane according to current dir. Little fix.
* Implement "Open in Terminal" and "Open as Root".
* Enable auto-run related options in preferences dialog.
* Implement "Auto Run" for newly inserted removable devices.
* Add "Edit Bookmarks" dialog.
* Implement "Invert Selection". Little fix of UI, add a Tool menu to main window.
* Implement "Create New" menu in the folder popup menu.
* Modify make rules for translations. Avoid deleting generated ts files when "make clean". Fix a small error in zh_TW translation.
* Add auto-completion to path entry bar.
* Rename Fm::Application to Fm::LibFmQt to decrease confusion. Set required Qt version to 4.6.
* Load translation files correctly for pcmanfm-qt and libfm-qt.
* Add basic skeleton for i18n (using Qt QTranslator & Qt Linguist).
* Add separate CMakeLists.txt files for pcmanfm and libfm-qt. Hide more implementation details from libfm-qt headers.
* Fix copyright notice in all source files.
* Install desktop entry files for pcmanfm-qt & its desktop preferences dialog.
* Install a pkgconfig file for libfm-qt for use in other projects.
* Fix typos causing crashes.
* Fix a memory error caused by incorrect array size. Fix incorrect spacing of icons.
* Finish chown and chmod supports.
* Try to add file opermission settings UI.
* Implement very basic drag and drop support.
* Supress the incorrect default dnd handling of QListView.
* Try to implement Dnd.
* Make desktop preferences accessible from popup menu of desktop window.
* Convert enum values to/from strings for saving/loading config files.
* Finish desktop preferences.
* Improve desktop preferences and apply settings (partially done).
* Add desktop preferences dialog.
* Apply side pane icon size correctly. Add basic skeleton for archiver integration.
* Set shortcuts for frequently used menu options. Implement "rename file" support. Hide tabs when there is only one tab left (optional).
* Delete windows properly when they're closed with setAttribute(Qt::WA_DeleteOnClose); Apply settings to windows after clicking OK in the preference dialog.
* Improve preferences dialog. Improve loading/saving of config file.
* Improve preferences dialog. Change base class of SidePane to QWidget.
* Add basic skeleton of preferences dialog options.
* Add -fno-exceptions to compiler flags.
* Fix a crash during updating View menu.
* Sync the state of folder popup menu and main menu bar.
* Implement sort options for main window.
* Fix file sorting options for Fm::FolderMenu.
* Correctly implement browse history and fix crashes.
* Add very simple browse history (back/forward) handling.
* Apply gcc visiblility attributes to export less symbols.
* Correctly handle file rename/overwrite during file operations.
* Exclude unnecessary files from CPack.
* Add COPYING, AUTHORS, and README and add basic CPack support.
* Build libfm-qt as a separate shared library and install haeder files.
* Little fix for desktop item text shadow.
* Add DesktopItemDelegate to draw better desktop icons.
* Add code used to draw desktop wallpapers.
* Improve folder popup menu.
* Add folder popup menu. Some UI polishing.
* Fix a little crash.
* Fix crashes when turning off desktop manager.
* Show popup menu for blank area of folders.
* Do some refactor to make Fm::FolderView cleaner. Add PCManFM::View to do file manager-specific operations.
* Add desktopManagerEnabled dbus property. Little fix for command line descriptions.
* Little fix.
* Little fix for translatable strings.
* Improve desktop management support (wallpaper & icons).
* Replace QCommandLine with glib GOptionContext for command line parsing. * Improve IPC.
* Add command line parsing and basic IPC via dbus.
* Try to use QCommandLine for command line parsing.
* Move application initialization code to PCManFM::Applicaion class.
* Move files for libfm-qt and pcmanfm-qt to separate subdirs.
* Implement cut and copy files to clipboard.
* Add a item delegate to overriding the incredibly small width of text label. Special thanks to razor-qt developers for the hint!
* Make Settings class more complete, add getters and setters.
* Trivial fix.
* Add PCManFM::Settings class for config file loading/saving. Enable dragging of items in Fm::Folderview (Dnd does not fully work yet).
* Add missing files again.
* Add missing files.
* Add the basic skeleton of "ask for rename or overwrite" dialog.
* Polishing file operation dialogs.
* Add a very primitive desktop icons window implementation.
* Add basic skeleton for preferences dialog.
* Put PCManFM specific classes under new namespace PCManFM.
* Implement very primitive and basic file operations and partial clipboard support.
* Fix bugs in Fm::FileLauncher (should not free string returned by DisplayString()).
* Add a combobox to file properties dialog to select default application.
* Implement context menu for places view to remove bookmarks and unmount volumes. Little fixes for mount operation.
* Fully implement GUI for GMountOperation.
* Implement Qt-based GUI for GMountOperation.
* Improve icon theme handling.
* Implement bookmarks menu.
* Update PlacesModel when volumes/mounts/bookmarks change.
* Improve volume mounting APIs.
* Improve internal implementation of Fm::PlacesModel. Add skelaton of file operation progress dialog.
* Handle file selection correctly.
* Improve the file properties dialog.
* Add primitive implementation of properties dialog. * Some UI polishing.
* Use Fm::ProxyFolderModel to do filter and sorting. * Little fix for Fm::IconTheme and Fm::PlacesView/Model.
* Rework Fm::IconTheme, replacing QPixmap with QIcon. Improve Fm::ProxyFolderModel and use it to implement showHidden().
* Add a more professional about dialog.
* Little fix to ensure glib/GObject and libfm are correctly initialized.
* Use QTabBar + QStackedWidget to replace QTabWidget so we can share the same side pane among all tab pages.
* Slightly improve places view/model.
* Rename to pcmanfm-qt. * Implement tabbed-browsing. * Implement basic skeleton of GMountOperation. * Implement basic skeleton of Fm::PlacesView.
* Handle "returnPressed()" of the path entry.
* Use both of QListView and QTreeView to implement Fm::FolderView.
* Initial import, an attempt to create qt4 support for libfm.

@ -1,74 +0,0 @@
cmake_minimum_required(VERSION 3.1.0 FATAL_ERROR)
# CMP0000: Call the cmake_minimum_required() command at the beginning of the top-level
# CMakeLists.txt file even before calling the project() command.
# The cmake_minimum_required(VERSION) command implicitly invokes the cmake_policy(VERSION)
# command to specify that the current project code is written for the given range of CMake
# versions.
project(pcmanfm-qt)
# PcmanFm-Qt Version
set(PCMANFM_QT_VERSION_MAJOR 0)
set(PCMANFM_QT_VERSION_MINOR 14)
set(PCMANFM_QT_VERSION_PATCH 1)
set(PCMANFM_QT_VERSION ${PCMANFM_QT_VERSION_MAJOR}.${PCMANFM_QT_VERSION_MINOR}.${PCMANFM_QT_VERSION_PATCH})
# Minimum versions
set(LIBFMQT_MINIMUM_VERSION "0.14.1")
set(LXQTBT_MINIMUM_VERSION "0.6.0")
set(QT_MINIMUM_VERSION "5.7.1")
list(APPEND CMAKE_MODULE_PATH "${PROJECT_SOURCE_DIR}/cmake")
find_package(Qt5DBus ${QT_MINIMUM_VERSION} REQUIRED)
find_package(Qt5LinguistTools ${QT_MINIMUM_VERSION} REQUIRED)
find_package(Qt5Widgets ${QT_MINIMUM_VERSION} REQUIRED)
find_package(Qt5X11Extras ${QT_MINIMUM_VERSION} REQUIRED)
find_package(fm-qt ${LIBFMQT_MINIMUM_VERSION} REQUIRED)
find_package(lxqt-build-tools ${LXQTBT_MINIMUM_VERSION} REQUIRED)
message(STATUS "Building ${PROJECT_NAME} with Qt ${Qt5Core_VERSION}")
option(UPDATE_TRANSLATIONS "Update source translation translations/*.ts files" OFF)
include(GNUInstallDirs)
include(LXQtPreventInSourceBuilds)
include(LXQtConfigVars)
include(LXQtTranslateTs)
include(LXQtTranslateDesktop)
include(LXQtCompilerSettings NO_POLICY_SCOPE)
set(CMAKE_AUTOMOC TRUE)
set(CMAKE_AUTOUIC ON)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
add_subdirectory(pcmanfm)
# 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()
add_subdirectory(autostart)
add_subdirectory(config)

File diff suppressed because it is too large Load Diff

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

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

@ -1,15 +0,0 @@
file(GLOB DESKTOP_FILES_IN *.desktop.in)
# Translations **********************************
lxqt_translate_desktop(DESKTOP_FILES
SOURCES
${DESKTOP_FILES_IN}
)
add_custom_target(autostart_desktop_files ALL DEPENDS ${DESKTOP_FILES})
#************************************************
install(FILES
${DESKTOP_FILES}
DESTINATION "${LXQT_ETC_XDG_DIR}/autostart"
COMPONENT Runtime
)

@ -1,9 +0,0 @@
[Desktop Entry]
Type=Application
Name=Desktop
Exec=pcmanfm-qt --desktop --profile=lxqt
TryExec=pcmanfm-qt
OnlyShowIn=LXQt;
X-LXQt-Module=true
#TRANSLATIONS_DIR=translations

@ -1,2 +0,0 @@
# Translations
Name[ar]=سطح المكتب

@ -1,2 +0,0 @@
# Translations
Name[cs]=Plocha

@ -1,2 +0,0 @@
# Translations
Name[da]=Skrivebord

@ -1,2 +0,0 @@
# Translations
Name[de]=Arbeitsfläche

@ -1,2 +0,0 @@
# Translations
Name[el]=Επιφάνεια εργασίας

@ -1,2 +0,0 @@
# Translations
Name[eo]=Labortablo

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

@ -1,2 +0,0 @@
# Translations
Name[eu]=Mahaigaina

@ -1,2 +0,0 @@
# Translations
Name[fi]=Työpöytä

@ -1,2 +0,0 @@
# Translations
Name[fr]=Bureau

@ -1,2 +0,0 @@
# Translations
Name[hu]=Asztal

@ -1,2 +0,0 @@
# Translations
Name[ia]=Scriptorio

@ -1,2 +0,0 @@
# Translations
Name[it_IT]=Desktop

@ -1,2 +0,0 @@
# Translations
Name[ja]=デスクトップ

@ -1,2 +0,0 @@
# Translations
Name[lt]=Darbalaukis

@ -1,2 +0,0 @@
# Translations
Name[nl]=Bureaublad

@ -1,2 +0,0 @@
# Translations
Name[pl_PL]=Pulpit

@ -1,2 +0,0 @@
# Translations
Name[pt]=Área de trabalho

@ -1,2 +0,0 @@
# Translations
Name[pt_BR]=Área de trabalho

@ -1,2 +0,0 @@
# Translations
Name[ro_RO]=Desktop

@ -1,2 +0,0 @@
# Translations
Name[ru]=Pабочий стол

@ -1,2 +0,0 @@
# Translations
Name[ru_RU]=Рабочий стол

@ -1,2 +0,0 @@
# Translations
Name[sl]=Namizje

@ -1,2 +0,0 @@
# Translations
Name[th_TH]=เดสก์ท็อป

@ -1,2 +0,0 @@
# Translations
Name[tr]=Masaüstü

@ -1,2 +0,0 @@
# Translations
Name[uk]=Стільниця

@ -1,2 +0,0 @@
# Translations
Name[zh_CN]=桌面

@ -1,2 +0,0 @@
# Translations
Name[zh_TW]=桌面

@ -1,8 +0,0 @@
# install default config files to /etc/xdg
configure_file(pcmanfm-qt/lxqt/settings.conf.in pcmanfm-qt/lxqt/settings.conf @ONLY)
install(FILES
"${CMAKE_CURRENT_BINARY_DIR}/pcmanfm-qt/lxqt/settings.conf"
DESTINATION "${CMAKE_INSTALL_DATADIR}/pcmanfm-qt/lxqt"
COMPONENT Runtime
)

@ -1,53 +0,0 @@
[System]
IconThemeName=elementary
SuCommand=lxqt-sudo %s
TerminalCommand=
Archiver=file-roller
SIUnit=false
TerminalDirCommand=xterm
TerminalExecCommand=xterm -e %s
[Behavior]
BookmarkOpenMethod=0
UseTrash=true
SingleClick=false
ConfirmDelete=true
[Desktop]
WallpaperMode=stretch
Wallpaper=@LXQT_SHARE_DIR@/themes/frost/lxqt-origami-light.png
BgColor=#000000
FgColor=#ffffff
ShadowColor=#000000
ShowHidden=false
SortOrder=ascending
SortColumn=name
Font="Sans Serif,10,-1,5,50,0,0,0,0,0"
[Volume]
MountOnStartup=true
MountRemovable=true
AutoRun=true
[FolderView]
Mode=icon
ShowHidden=false
SortOrder=ascending
SortColumn=name
BigIconSize=48
SmallIconSize=24
SidePaneIconSize=24
ThumbnailIconSize=128
[Window]
Width=640
Height=480
AlwaysShowTabs=false
ShowTabClose=true
SplitterPos=150
SidePaneMode=0
[Thumbnail]
ShowThumbnails=true
MaxThumbnailFileSize=4096
ThumbnailLocalFilesOnly=true

394
debian/changelog vendored

@ -1,390 +1,100 @@
pcmanfm-qt (0.14.1-1) unstable; urgency=medium
pavucontrol-qt (0.14.1-1ubuntu1) disco; urgency=medium
* Cherry-picking upstream release 0.14.1.
* Bumped minimum version libfm-qt-dev (>= 0.14.1~)
* Depend now on libfm-qt6 (>= 0.14.1~)
* Improved the description of the language package
* Lubuntuify the package.
-- Alf Gaida <agaida@siduction.org> Sun, 24 Feb 2019 23:23:24 +0100
-- Simon Quigley <tsimonq2@ubuntu.com> Sat, 09 Mar 2019 12:29:43 -0600
pcmanfm-qt (0.14.0-1) unstable; urgency=medium
pavucontrol-qt (0.14.1-1) unstable; urgency=medium
* Cherry-picking upstream release 0.14.0.
* 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 libfm-qt-dev (>= 0.14.0~)
* Bumped minimum version lxqt-build-tools (>= 0.6.0~)
* Depend now on libfm-qt6 (>= 0.14.0~)
* Removed obsolete PULL_TRANSLATIONS= OFF from dh_auto_configure
* Added Build-Depends-Package field to symbols
* Added l10n-package, moved from lxqt-l10n
* Added d/upstream/metadata
-- Alf Gaida <agaida@siduction.org> Sun, 27 Jan 2019 19:40:51 +0100
pcmanfm-qt (0.13.0-2) unstable; urgency=medium
* Switch to unstable
* Bumped build dependency libfm-qt-dev to >= 0.13.1~
* Bumped Standards to 4.1.5, no changes needed
-- Alf Gaida <agaida@siduction.org> Sun, 27 Jan 2019 15:25:30 +0100
-- Alf Gaida <agaida@siduction.org> Sat, 07 Jul 2018 14:37:15 +0200
pavucontrol-qt (0.4.0-1) unstable; urgency=medium
pcmanfm-qt (0.13.0-1) experimental; 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
* Cherry-picking upstream release 0.13.0.
* Bumped build dependency libfm-qt-dev to >= 0.13.0~
* Bumped build dependency lxqt-build-tools to >= 0.5.0~
* Added papirus-icon-theme as default alternative for icon-themes
* Bumped year in copyright
* Removed ported back upstream patches.
* Moved debian/.gitignore -> ./.gitignore
-- Alf Gaida <agaida@siduction.org> Wed, 23 May 2018 20:29:30 +0200
-- Alf Gaida <agaida@siduction.org> Sat, 26 May 2018 02:25:19 +0200
pcmanfm-qt (0.12.0-6) unstable; urgency=medium
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
* Fixed a glitch in VCS fields
* Changed VCS fields for salsa
* Changed Homepage, Source and watch to lxqt
* Bumped year in copyright
-- Alf Gaida <agaida@siduction.org> Sat, 28 Apr 2018 18:43:40 +0200
pcmanfm-qt (0.12.0-5) unstable; urgency=medium
* Moved git to salsa, changed the VCS fields that way
* Bumped Standards to 4.1.3, no changes needed
* Added gfvs-fuse to recommends, thanks robert <maxl1234@gmx.at>
(Closes: #886166)
-- Alf Gaida <agaida@siduction.org> Fri, 05 Jan 2018 19:12:49 +0100
pcmanfm-qt (0.12.0-4) unstable; urgency=medium
* Really bumped Standards.
* Bumped years in copyright
* Removed trailing whitespaces in changelog
-- Alf Gaida <agaida@siduction.org> Sat, 16 Dec 2017 03:48:34 +0100
-- Alf Gaida <agaida@siduction.org> Sat, 28 Apr 2018 18:21:55 +0200
pcmanfm-qt (0.12.0-3) unstable; urgency=medium
pavucontrol-qt (0.3.0-3) unstable; urgency=medium
* Bumped Standards to 4.1.2, no changes needed
* Move config to /usr/share/pcmanfm-qt/lxqt
* Removed branch from VCS fields
* Removed debian/gbp.conf
-- Alf Gaida <agaida@siduction.org> Fri, 15 Dec 2017 00:49:17 +0100
-- Alf Gaida <agaida@siduction.org> Thu, 14 Dec 2017 23:51:12 +0100
pcmanfm-qt (0.12.0-2) unstable; urgency=medium
pavucontrol-qt (0.3.0-2) unstable; urgency=medium
* Transition to unstable
-- Alf Gaida <agaida@siduction.org> Tue, 05 Dec 2017 01:51:44 +0100
-- Alf Gaida <agaida@siduction.org> Mon, 04 Dec 2017 20:00:17 +0100
pcmanfm-qt (0.12.0-1) experimental; urgency=medium
pavucontrol-qt (0.3.0-1) experimental; urgency=medium
* Cherry-picking upstream release 0.12.0.
* Bumped Standards to 4.1.1
* Bumped build-tools >= 0.4.0
* Bumped libfm-qt-dev >= 0.12.0
* 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
* Added build dependency libexif-dev
* Added Breaks and Replaces for lxqt-common << 0.12.0
-- Alf Gaida <agaida@siduction.org> Tue, 24 Oct 2017 21:53:39 +0200
pcmanfm-qt (0.11.3-4) unstable; urgency=medium
* Depend on desktop-file-utils (Closes: #866900)
* Recommend ffmpegthumbnailer (Closes: #867460)
* Removed the alternative dependency gksu. Reason: #867236
-- Alf Gaida <agaida@siduction.org> Thu, 06 Jul 2017 19:58:03 +0200
pcmanfm-qt (0.11.3-3) unstable; urgency=medium
-- Alf Gaida <agaida@siduction.org> Sun, 24 Sep 2017 15:19:13 +0200
* Bumped Standards to 4.0.0
* Depend on lxqt-sudo | gksu we need at least one UI for sudo
* Added Recommends: lximage-qt, lxqt-policykit, lxqt-qtplugin
(Closes: #866347)
* pcmanfm-qt allow multiple file selections with mouse, the implementation is
horrible in some places, but it works. (Closes: #853201)
pavucontrol-qt (0.2.0-1) unstable; urgency=medium
-- Alf Gaida <agaida@siduction.org> Sun, 02 Jul 2017 18:05:08 +0200
pcmanfm-qt (0.11.3-2) unstable; urgency=medium
* set oxygen-icon-theme as default alternative recommendation
(Closes: #851411)
-- Alf Gaida <agaida@siduction.org> Sun, 15 Jan 2017 01:35:46 +0100
pcmanfm-qt (0.11.3-1) unstable; urgency=medium
* Cherry-picking upstream release 0.11.3.
-- Alf Gaida <agaida@siduction.org> Sat, 14 Jan 2017 03:54:54 +0100
pcmanfm-qt (0.11.2-1) unstable; urgency=medium
* Cherry-picking upstream release 0.11.2.
* Removed build dependencies:
- libfm-dev
* Cherry-picking upstream release 0.2.0.
* Removed some no longer needed build dependencies:
- cmake
- liblxqt0-dev
* Bumped minimum versions
- libfm-qt-dev (>= 0.11.2)
- lxqt-build-tools (>= 0.3.0)
- libfm-qt3 (>= 0.11.2)
* Suggests: cdtool -> cdtool [linux-any]
-- Alf Gaida <agaida@siduction.org> Thu, 22 Dec 2016 02:02:37 +0100
pcmanfm-qt (0.11.1-3) unstable; urgency=medium
* Added versioned dependency libfm-qt3 (>= 0.11.1), dh detect only
a minimum version of 0.11.0 - false because some symbols are added
which are needed for pcmanfm-qt (>= 0.11.1) (Closes: #842080)
* Removed build dependencies
- libqt5xdg-dev
- pkg-config,
- qttools5-dev,
- libqt5xdgiconloader-dev
- pkg-config
- qttools5-dev
- qttools5-dev-tools
* Added build dependency lxqt-build-tools
-- Alf Gaida <agaida@siduction.org> Sat, 05 Nov 2016 02:06:06 +0100
pcmanfm-qt (0.11.1-2) unstable; urgency=medium
* Cherry-picking upstream release 0.11.1.
* Synced debian foo with experimental
* Removed --parallel from rules, standard compat 10
* New dep. default-dbus-session-bus | dbus-session-bus | dbus-x11
(Closes: #836284)
* Fixed Crashes while copying (Closes: #823753)
* Bumped minimum version libfm-qt-dev (>= 0.11.1)
* Bumped minimum version libqt5xdg-dev (>= 2.0.0)
* Added build dependency libkf5windowsystem-dev
* Added build dependency libqt5svg5-dev
* Added build dependency liblxqt0-dev (>= 0.11.0)
* Added Recommends pcmanfm-qt-l10n
* Fixed VCS fields, using plain /git/
* Fixed copyright Format field, using https
* Dropped patches, applied upstream
* Added translation controls
* Set CMAKE_BUILD_TYPE=RelWithDebInfo
-- Alf Gaida <agaida@siduction.org> Tue, 18 Oct 2016 22:59:30 +0200
pcmanfm-qt (0.11.0-10) unstable; urgency=medium
* Fixed typo in Recommends: oyxgen-icon-theme -> oxygen-icon-theme
-- Alf Gaida <agaida@siduction.org> Mon, 19 Sep 2016 21:50:10 +0200
pcmanfm-qt (0.11.0-9) unstable; urgency=medium
* Bumped compat to 10
* Bumped build dependency debhelper (>=10)
* Fixed typo in Recommends: faenza--icon-theme > faenza-icon-theme
-- Alf Gaida <agaida@siduction.org> Mon, 19 Sep 2016 04:23:26 +0200
pcmanfm-qt (0.11.0-8) unstable; urgency=medium
* Replace dep. dbus-x11 with default-dbus-session-bus | dbus-session-bus
(Closes: #836284)
* Set CMAKE_BUILD_TYPE=RelWithDebInfo
-- Alf Gaida <agaida@siduction.org> Thu, 01 Sep 2016 22:56:35 +0200
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
* Added build dependency lxqt-build-tools (>= 0.3.0)
* Added dependency pulseaudio (Closes: #847373)
* Fixed Recommends: obconf-qt-l10n -> pavucontrol-qt-l10n
* New upstream release.
* Remove libfm-qt as upstream moved it into another source repository.
* Remove dbg package in favor of dbgsym.
* Update Vcs-Browser.
-- Alf Gaida <agaida@siduction.org> Mon, 12 Dec 2016 18:56:14 +0100
-- ChangZhuo Chen (陳昌倬) <czchen@debian.org> Sun, 07 Feb 2016 16:13:27 +0800
pavucontrol-qt (0.1.0-2) unstable; urgency=medium
pcmanfm-qt (0.10.0-2) unstable; urgency=medium
* Moved to unstable
* Fixed signing-key, thanks Rohan Garg <rohan@kde.org>
* Merge from experimental.
* New upstream release.
* Update minimum version of liblxqt.
* Update symbols.
* Remove menu file, see CTTE #741573.
-- Alf Gaida <agaida@siduction.org> Tue, 18 Oct 2016 20:34:41 +0200
-- ChangZhuo Chen (陳昌倬) <czchen@debian.org> Sun, 15 Nov 2015 21:14:41 +0800
pavucontrol-qt (0.1.0-1) experimental; urgency=medium
pcmanfm-qt (0.9.0+20150908-2) unstable; urgency=medium
* Initial release (Closes: #838724)
* Menufile deleted
* debian/rules --fail-missing included --list-missig, so
--list-missing deleted
-- Alf Gaida <agaida@siduction.org> Fri, 13 Nov 2015 02:37:53 +0100
pcmanfm-qt (0.9.0+20150908-1) unstable; urgency=medium
[ Alf Gaida ]
* Cherry-picked upstream version 0.9.0+20150908.
* Tar-ignore .gitignore
* Fixed control with cme fix
* Added upstream signing-key and use it in watch file
* Removed automoc build dependency - not needed with Qt5
* Fixed symbols for i386 and amd64
[ ChangZhuo Chen (陳昌倬) ]
* Use arch-bits to fix 32 bit architecture symbols.
* Add Shih-Yuan Lee (FourDollars) as Uploaders.
-- ChangZhuo Chen (陳昌倬) <czchen@debian.org> Tue, 15 Sep 2015 23:30:13 +0800
pcmanfm-qt (0.9.0+20150816-1) unstable; urgency=medium
[ ChangZhuo Chen (陳昌倬) ]
* Import debian directory from Wen.Liao.
* Initial release (Closes: #747605)
* Merge debian directory.
* Backup *.ts.
* Fix package-contains-empty-directory.
* Don't use variable for command.
* Add libfm-qt1 and libfm-qt-dev.
* Update copyright.
* Add Pre-Depends: ${misc:Pre-Depends} to libfm-qt1.
* Create manpage for pcmanfm-qt.
* add libfm-qt1.symbols.
* Revert "Create manpage for pcmanfm-qt".
* Add pcmanfm-qt.manpages.
* Fix manpage.
* Install include to libfm-qt-dev.
* Update package description.
* Use patch to install manpage.
* Migrate to QT5.
* Update d/copyright.
* Fix copyright typo.
* Revert accidiently ts changed.
[ Alf Gaida ]
* gitignore added.
* new upstream translation files.
* some cleanup in debian rules.
* two missed symbols added.
* they need a little bit of beautyfing.
* we should not save translations in debian/bak. if there is a real
problem with the translations this should be fixed upstream.
* add two symbols @czchen - would you be so kind and clean them up.
* catch up with upstream Patch descriptions changed.
* Imported Upstream version 0.8.0
* Min Qt version 5.3.2.
* bump standards to 3.9.6.
* removed all patches, integrated in upstream.
* fix symbols (two symbols added).
* fix prefs desktop file.
* fix arch for dbg packages.
* Imported Upstream version 0.8.0.
* Min Qt version 5.3.2.
* bump standards to 3.9.6.
* removed all patches, integrated in upstream.
* fix symbols (two symbols added).
* fix prefs desktop file.
* fix arch for dbg packages.
* patch added released.
* fixing arch dependent symbols.
* recommend gfvs-backends.
* Some cleanup in debian $foo.
* some changes in debian $foo.
* drop transitional packages.
[ ChangZhuo Chen (陳昌倬) ]
* Unapply Debian patch.
* Add debian/source/local-options.
* Backup / Restore translations.
* Fix override_dh_clean.
* Use override_dh_auto_clean to restore translations.
* Update symbol control file.
* Quote in symbol control file.
* Restore upstream file.
* Imported Upstream version 0.9.0+20150816.
* Add (c++) to symbol control file.
* Update changelog.
* Update symbol control file.
* Fix symbol control file.
* Fix Architecture.
* Add Multi-Arch: same.
[ Shih-Yuan Lee (FourDollars) ]
* Polish debian/control by 'cme fix dpkg-control'.
* Update package description.
[ Andrew Lee (李健秋) ]
* Added myself as Uploader.
* Removing whitespaces at EOL and EOF.
* Refine descriptions.
* Don't need to backup/restore translation files, this fixed upstream.
* Warpped lines in copyright.
-- Andrew Lee (李健秋) <ajqlee@debian.org> Mon, 17 Aug 2015 21:04:54 +0800
-- Alf Gaida <agaida@siduction.org> Sat, 24 Sep 2016 16:18:14 +0200

76
debian/control vendored

@ -1,61 +1,41 @@
Source: pcmanfm-qt
Maintainer: LXQt Packaging Team <pkg-lxqt-devel@lists.alioth.debian.org>
Uploaders: Alf Gaida <agaida@siduction.org>,
ChangZhuo Chen (陳昌倬) <czchen@debian.org>,
Andrew Lee (李健秋) <ajqlee@debian.org>,
Shih-Yuan Lee (FourDollars) <fourdollars@gmail.com>,
Yuan CHAO <yuanchao@gmail.com>
Section: x11
Source: pavucontrol-qt
Maintainer: Lubuntu Developers <lubuntu-devel@lists.ubuntu.com>
XSBC-Original-Maintainer: LXQt Packaging Team <pkg-lxqt-devel@lists.alioth.debian.org>
Uploaders: Simon Quigley <tsimonq2@ubuntu.com>
Section: utils
Priority: optional
Build-Depends: debhelper-compat (= 12),
libexif-dev,
libfm-qt-dev (>= 0.14.1~),
libkf5windowsystem-dev,
libmenu-cache-dev,
libpulse-dev,
libqt5svg5-dev,
libqt5x11extras5-dev,
libx11-dev,
lxqt-build-tools (>= 0.6.0~)
lxqt-build-tools (>= 0.6.0~),
xdg-user-dirs
Standards-Version: 4.3.0
Vcs-Browser: https://salsa.debian.org/lxqt-team/pcmanfm-qt
Vcs-Git: https://salsa.debian.org/lxqt-team/pcmanfm-qt.git
Homepage: https://github.com/lxqt/pcmanfm-qt
Vcs-Browser: https://phab.lubuntu.me/source/pavucontrol-qt/
Vcs-Git: https://phab.lubuntu.me/source/pavucontrol-qt.git
XS-Debian-Vcs-Browser: https://salsa.debian.org/lxqt-team/pavucontrol-qt
XS-Debian-Vcs-Git: https://salsa.debian.org/lxqt-team/pavucontrol-qt.git
Homepage: https://github.com/lxqt/pavucontrol-qt
Package: pcmanfm-qt
Package: pavucontrol-qt
Architecture: any
Depends: ${misc:Depends},
${shlibs:Depends},
default-dbus-session-bus | dbus-session-bus | dbus-x11,
desktop-file-utils,
libfm-qt6 (>= 0.14.1~),
lxqt-sudo
Recommends: eject,
ffmpegthumbnailer,
gvfs-backends,
gvfs-fuse,
lximage-qt,
lxqt-policykit,
lxqt-qtplugin,
papirus-icon-theme | breeze-icon-theme | faenza-icon-theme | oxygen-icon-theme,
pcmanfm-qt-l10n
Suggests: cdtool [linux-any]
Breaks: lxqt-common (<< 0.12.0)
Replaces: lxqt-common (<< 0.12.0)
Description: extremely fast and lightweight file and desktop icon manager
PCManFM-Qt is the Qt port of the LXDE file manager PCManFM.
Depends: pulseaudio, ${misc:Depends}, ${shlibs:Depends}
Recommends: pavucontrol-qt-l10n
Description: Qt port of volume control pavucontrol
Qt port of volume control pavucontrol of sound server PulseAudio. As such it
can be used to adjust all controls provided by PulseAudio as well as some
additional settings.
.
Libfm-Qt is a companion library providing components to build desktop file
managers.
The software belongs to the LXQt project but its usage isn't limited to this
desktop environment.
.
This package contain the application files.
Package: pcmanfm-qt-l10n
Package: pavucontrol-qt-l10n
Architecture: all
Multi-Arch: foreign
Section: localization
Depends: ${misc:Depends},
qttranslations5-l10n
Breaks: pcmanfm-qt (<< 0.11.1)
Replaces: pcmanfm-qt (<< 0.11.1)
Description: Language package for pcmanfm-qt
PCManFM-Qt is the Qt port of the LXDE file manager PCManFM.
.
This package contains the l10n files needed by the pcmanfm-qt.
Depends: qttranslations5-l10n, ${misc:Depends}
Description: Language package for pavucontrol-qt
This package contains the l10n files needed by the pavucontrol-qt.

57
debian/copyright vendored

@ -1,32 +1,59 @@
Format: https://www.debian.org/doc/packaging-manuals/copyright-format/1.0/
Upstream-Name: pcmanfm-qt
Source: https://github.com/lxqt/pcmanfm-qt
Upstream-Name: pavucontrol-qt
Source: https://github.com/lxqt/pavucontrol-qt
Files: *
Copyright: 2013-2019 LXQt team
2013-2018 Hong Jen Yee (PCMan) <pcman.tw@gmail.com>
2012-2013 Andriy Grytsenko (LStranger) <andrej@rep.kiev.ua>
2014 Kuzma Shapran <kuzma.shapran@gmail.com>
Copyright: 2016-2019 LXQt team
2016-2017 Hong Jen Yee (PCMan) <pcman.tw@gmail.com>
2016-2017 Palo Kisa <palo.kisa@gmail.com>
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/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: 2006-2008 Lennart Poettering
2009 Colin Guthrie
License: GPL-2.0+
Files: src/pavucontrol.cc
src/pavucontrol.h
Copyright: 2006-2008 Lennart Poettering
2008 Sjoerd Simons <sjoerd@luon.net>
License: GPL-2.0+
Files: debian/*
Copyright: 2014-2015 Wen Liao <wen.cf83@gmail.com>
2014-2016 ChangZhuo Chen (陳昌倬) <czchen@debian.org>
2013-2019 Alf Gaida <agaida@siduction.org>
2015 Andrew Lee (李健秋) <ajqlee@debian.org>
Copyright: 2016-2019 Alf Gaida <agaida@siduction.org>
License: GPL-2.0+
License: GPL-2.0+
This package is free software; you can redistribute it and/or modify
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 package is distributed in the hope that it will be useful,
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
.
On Debian systems, the complete text of the GNU General
Public License version 2 can be found in
"/usr/share/common-licenses/GPL-2".
On Debian systems, the complete text of the GNU General Public License
version 2 can be found in "/usr/share/common-licenses/GPL-2".

@ -0,0 +1,4 @@
# yes, we know
pavucontrol-qt: binary-without-manpage usr/bin/pavucontrol-qt
pavucontrol-qt: desktop-entry-lacks-keywords-entry usr/share/applications/pavucontrol-qt.desktop

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

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

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

@ -1,7 +1,7 @@
Name: pcmanfm-qt
Bug-Database: https://github.com/lxqt/pcmanfm-qt/issues
Bug-Submit: https://github.com/lxqt/pcmanfm-qt/issues/new
Changelog: https://github.com/lxqt/pcmanfm-qt/blob/master/CHANGELOG
Repository: https://github.com/lxqt/pcmanfm-qt
Repository-Browser: https://github.com/lxqt/pcmanfm-qt
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-Browser: https://github.com/lxqt/pavucontrol-qt

2
debian/watch vendored

@ -1,3 +1,3 @@
version=4
opts="pgpsigurlmangle=s/$/.asc/" \
https://github.com/lxqt/pcmanfm-qt/releases .*/pcmanfm-qt-([\d\.]+).tar.xz
https://github.com/lxqt/pavucontrol-qt/releases .*/pavucontrol-qt-([\d\.]+).tar.xz

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

@ -1,92 +0,0 @@
set(pcmanfm_SRCS
application.cpp
pcmanfm.cpp
mainwindow.cpp
tabpage.cpp
tabbar.cpp
statusbar.cpp
view.cpp
launcher.cpp
preferencesdialog.cpp
xdgdir.cpp
desktoppreferencesdialog.cpp
desktopwindow.cpp
autorundialog.cpp
connectserverdialog.cpp
settings.cpp
bulkrename.cpp
)
qt5_add_dbus_adaptor(pcmanfm_DBUS_SRCS
org.pcmanfm.Application.xml
application.h
PCManFM::Application
applicationadaptor
ApplicationAdaptor
)
# qt5_add_dbus_adaptor() already generated the moc files. It also marked the
# files with SKIP_AUTOMOC but we still need to mark them witk SKIP_AUTOGEN.
# TODO: Check if this behaviour is a CMake bug.
set_source_files_properties(${pcmanfm_DBUS_SRCS} PROPERTIES SKIP_AUTOGEN ON)
set(pcmanfm_UIS
main-win.ui
about.ui
preferences.ui
desktop-preferences.ui
desktop-folder.ui
autorun.ui
connect.ui
bulk-rename.ui
)
# add translation for pcmanfm-qt
lxqt_translate_ts(QM_FILES
UPDATE_TRANSLATIONS ${UPDATE_TRANSLATIONS}
SOURCES ${pcmanfm_SRCS} ${pcmanfm_UIS}
INSTALL_DIR "${CMAKE_INSTALL_DATADIR}/${PROJECT_NAME}/translations"
)
# 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_DBUS_SRCS}
${pcmanfm_UIS}
${QM_FILES}
${DESKTOP_FILES}
)
target_compile_definitions(pcmanfm-qt
PRIVATE
PCMANFM_DATA_DIR="${CMAKE_INSTALL_PREFIX}/share/pcmanfm-qt"
PCMANFM_QT_VERSION="${PCMANFM_QT_VERSION}"
LIBFM_DATA_DIR="${PKG_FM_PREFIX}/share/libfm"
)
target_include_directories(pcmanfm-qt
PRIVATE
"${Qt5Gui_PRIVATE_INCLUDE_DIRS}"
)
target_link_libraries(pcmanfm-qt
Qt5::X11Extras
Qt5::Widgets
Qt5::DBus
fm-qt
)
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"
)
# prevent the generated files from being deleted during make clean
set_directory_properties(PROPERTIES CLEAN_NO_CUSTOM true)

@ -1,180 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>AboutDialog</class>
<widget class="QDialog" name="AboutDialog">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>430</width>
<height>325</height>
</rect>
</property>
<property name="windowTitle">
<string>About</string>
</property>
<property name="windowIcon">
<iconset theme="help-about">
<normaloff/>
</iconset>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<widget class="QLabel" name="label">
<property name="text">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;&lt;span style=&quot; font-size:16pt; font-weight:600;&quot;&gt;PCManFM-Qt&lt;/span&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="textFormat">
<enum>Qt::RichText</enum>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="version">
<property name="text">
<string/>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="label_2">
<property name="text">
<string>Lightweight file manager</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="label_3">
<property name="text">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;&lt;a href=&quot;https://lxqt.org/&quot;&gt;&lt;span style=&quot; text-decoration: underline; color:#0000ff;&quot;&gt;https://lxqt.org/&lt;/span&gt;&lt;/a&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="textFormat">
<enum>Qt::RichText</enum>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
<item>
<widget class="QTabWidget" name="tabWidget">
<property name="currentIndex">
<number>0</number>
</property>
<property name="tabsClosable">
<bool>false</bool>
</property>
<widget class="QWidget" name="tab">
<attribute name="title">
<string>Authors</string>
</attribute>
<layout class="QVBoxLayout" name="verticalLayout_4">
<item>
<widget class="QPlainTextEdit" name="plainTextEdit_2">
<property name="readOnly">
<bool>true</bool>
</property>
<property name="plainText">
<string>Programming:
* Hong Jen Yee (PCMan) &lt;pcman.tw@gmail.com&gt;
</string>
</property>
<property name="backgroundVisible">
<bool>false</bool>
</property>
</widget>
</item>
</layout>
</widget>
<widget class="QWidget" name="tab_2">
<attribute name="title">
<string>License</string>
</attribute>
<layout class="QVBoxLayout" name="verticalLayout_3">
<item>
<widget class="QPlainTextEdit" name="plainTextEdit">
<property name="readOnly">
<bool>true</bool>
</property>
<property name="plainText">
<string>PCManFM-Qt 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>

@ -1,897 +0,0 @@
/*
Copyright (C) 2013 Hong Jen Yee (PCMan) <pcman.tw@gmail.com>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#include "application.h"
#include "mainwindow.h"
#include "desktopwindow.h"
#include <QDBusConnection>
#include <QDBusInterface>
#include <QDir>
#include <QVector>
#include <QLocale>
#include <QLibraryInfo>
#include <QPixmapCache>
#include <QFile>
#include <QMessageBox>
#include <QCommandLineParser>
#include <QSocketNotifier>
#include <QScreen>
#include <QWindow>
#include <QFileSystemWatcher>
#include <gio/gio.h>
#include <sys/socket.h>
#include <libfm-qt/mountoperation.h>
#include <libfm-qt/filesearchdialog.h>
#include <libfm-qt/core/terminal.h>
#include <libfm-qt/core/bookmarks.h>
#include <libfm-qt/core/folderconfig.h>
#include "applicationadaptor.h"
#include "preferencesdialog.h"
#include "desktoppreferencesdialog.h"
#include "autorundialog.h"
#include "launcher.h"
#include "xdgdir.h"
#include "connectserverdialog.h"
#include <X11/Xlib.h>
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),
enableDesktopManager_(false),
desktopWindows_(),
preferencesDialog_(),
editBookmarksialog_(),
volumeMonitor_(nullptr),
userDirsWatcher_(nullptr),
lxqtRunning_(false) {
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();
// 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|zoom"), 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 app config
settings_.load(profileName_);
// init per-folder config
QString perFolderConfigFile = settings_.profileDir(profileName_) + "/dir-settings.conf";
Fm::FolderConfig::init(perFolderConfigFile.toLocal8Bit().constData());
// decrease the cache size to reduce memory usage
QPixmapCache::setCacheLimit(2048);
if(settings_.useFallbackIconTheme()) {
QIcon::setThemeName(settings_.fallbackIconThemeName());
}
// 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()) {
if(event->type() == QEvent::StyleChange ||
event->type() == 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);
if(enabled) {
if(!enableDesktopManager_) {
// installNativeEventFilter(this);
const auto allScreens = screens();
for(QScreen* screen : allScreens) {
connect(screen, &QScreen::virtualGeometryChanged, this, &Application::onVirtualGeometryChanged);
connect(screen, &QScreen::availableGeometryChanged, this, &Application::onAvailableGeometryChanged);
connect(screen, &QObject::destroyed, this, &Application::onScreenDestroyed);
}
connect(this, &QApplication::screenAdded, this, &Application::onScreenAdded);
connect(this, &QApplication::screenRemoved, this, &Application::onScreenRemoved);
// 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(primaryScreen() && primaryScreen()->virtualSiblings().size() > 1) {
DesktopWindow* window = createDesktopWindow(-1);
desktopWindows_.push_back(window);
}
else {
int n = qMax(allScreens.size(), 1);
desktopWindows_.reserve(n);
for(int i = 0; i < n; ++i) {
DesktopWindow* window = createDesktopWindow(i);
desktopWindows_.push_back(window);
}
}
}
}
else {
if(enableDesktopManager_) {
int n = desktopWindows_.size();
for(int i = 0; i < n; ++i) {
DesktopWindow* window = desktopWindows_.at(i);
delete window;
}
desktopWindows_.clear();
const auto allScreens = screens();
for(QScreen* screen : allScreens) {
disconnect(screen, &QScreen::virtualGeometryChanged, this, &Application::onVirtualGeometryChanged);
disconnect(screen, &QScreen::availableGeometryChanged, this, &Application::onAvailableGeometryChanged);
disconnect(screen, &QObject::destroyed, this, &Application::onScreenDestroyed);
}
disconnect(this, &QApplication::screenAdded, this, &Application::onScreenAdded);
disconnect(this, &QApplication::screenRemoved, this, &Application::onScreenRemoved);
// 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());
// get search settings
settings_.setSearchNameCaseInsensitive(dlg->nameCaseInsensitive());
settings_.setsearchContentCaseInsensitive(dlg->contentCaseInsensitive());
settings_.setSearchNameRegexp(dlg->nameRegexp());
settings_.setSearchContentRegexp(dlg->contentRegexp());
settings_.setSearchRecursive(dlg->recursive());
settings_.setSearchhHidden(dlg->searchhHidden());
Fm::FilePathList paths;
paths.emplace_back(dlg->searchUri());
MainWindow* window = MainWindow::lastActive();
Launcher(window).launchPaths(nullptr, paths);
}
void Application::onConnectToServerAccepted() {
ConnectServerDialog* dlg = static_cast<ConnectServerDialog*>(sender());
QString uri = dlg->uriText();
Fm::FilePathList paths;
paths.push_back(Fm::FilePath::fromUri(uri.toUtf8().constData()));
MainWindow* window = MainWindow::lastActive();
Launcher(window).launchPaths(nullptr, 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);
// set search settings
dlg->setNameCaseInsensitive(settings_.searchNameCaseInsensitive());
dlg->setContentCaseInsensitive(settings_.searchContentCaseInsensitive());
dlg->setNameRegexp(settings_.searchNameRegexp());
dlg->setContentRegexp(settings_.searchContentRegexp());
dlg->setRecursive(settings_.searchRecursive());
dlg->setSearchhHidden(settings_.searchhHidden());
dlg->show();
}
void Application::connectToServer() {
ConnectServerDialog* dlg = new ConnectServerDialog();
connect(dlg, &QDialog::accepted, this, &Application::onConnectToServerAccepted);
dlg->setAttribute(Qt::WA_DeleteOnClose);
dlg->show();
}
void Application::launchFiles(QString cwd, QStringList paths, bool /*inNewWindow*/) {
Fm::FilePathList pathList;
Fm::FilePath cwd_path;
QStringList::iterator it;
for(const QString& it : qAsConst(paths)) {
QByteArray pathName = it.toLocal8Bit();
Fm::FilePath path;
if(pathName == "~") { // special case for home dir
path = Fm::FilePath::homeDir();
}
if(pathName[0] == '/') { // absolute path
path = Fm::FilePath::fromLocalPath(pathName.constData());
}
else if(pathName.contains(":/")) { // URI
path = Fm::FilePath::fromUri(pathName.constData());
}
else { // basename
if(Q_UNLIKELY(!cwd_path)) {
cwd_path = Fm::FilePath::fromLocalPath(cwd.toLocal8Bit().constData());
}
path = cwd_path.relativePath(pathName.constData());
}
pathList.push_back(std::move(path));
}
Launcher(nullptr).launchPaths(nullptr, pathList);
}
void Application::openFolders(Fm::FileInfoList files) {
Launcher(nullptr).launchFiles(nullptr, std::move(files));
}
void Application::openFolderInTerminal(Fm::FilePath path) {
if(!settings_.terminal().isEmpty()) {
Fm::GErrorPtr err;
auto terminalName = settings_.terminal().toUtf8();
if(!Fm::launchTerminal(terminalName.constData(), path, err)) {
QMessageBox::critical(nullptr, tr("Error"), err.message());
}
}
else {
// show an error message and ask the user to set the command
QMessageBox::critical(nullptr, 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(std::size_t i = 0; i < G_N_ELEMENTS(valid_wallpaper_modes); ++i) {
if(modeString == valid_wallpaper_modes[i]) {
// We don't take safety checks because valid_wallpaper_modes[] is
// defined in this function and we can clearly see that it does not
// overflow.
mode = static_cast<DesktopWindow::WallpaperMode>(i);
if(mode != settings_.wallpaperMode()) {
changed = true;
}
break;
}
}
// FIXME: support different wallpapers on different screen.
// update wallpaper
if(changed) {
if(enableDesktopManager_) {
for(DesktopWindow* desktopWin : qAsConst(desktopWindows_)) {
if(!path.isEmpty()) {
desktopWin->setWallpaperFile(path);
}
if(mode != settings_.wallpaperMode()) {
desktopWin->setWallpaperMode(mode);
}
desktopWin->updateWallpaper();
}
settings_.save(); // save the settings to the config file
}
}
}
DesktopWindow* Application::createDesktopWindow(int screenNum) {
DesktopWindow* window = new DesktopWindow(screenNum);
if(screenNum == -1) { // one large virtual desktop only
QRect rect = primaryScreen()->virtualGeometry();
window->setGeometry(rect);
}
else {
QRect rect;
const auto allScreens = screens();
if(auto screen = window->getDesktopScreen()) {
rect = screen->geometry();
}
window->setGeometry(rect);
}
window->updateFromSettings(settings_);
window->show();
return window;
}
// 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(bool changeSlide) {
QVector<DesktopWindow*>::iterator it;
for(it = desktopWindows_.begin(); it != desktopWindows_.end(); ++it) {
DesktopWindow* desktopWin = static_cast<DesktopWindow*>(*it);
desktopWin->updateFromSettings(settings_, changeSlide);
}
}
void Application::editBookmarks() {
if(!editBookmarksialog_) {
editBookmarksialog_ = new Fm::EditBookmarksDialog(Fm::Bookmarks::globalInstance());
}
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, &QScreen::availableGeometryChanged, this, &Application::onAvailableGeometryChanged);
connect(newScreen, &QObject::destroyed, this, &Application::onScreenDestroyed);
const auto siblings = primaryScreen()->virtualSiblings();
if(siblings.contains(newScreen)) { // the primary screen is changed
if(desktopWindows_.size() == 1) {
desktopWindows_.at(0)->setGeometry(newScreen->virtualGeometry());
if(siblings.size() > 1) { // a virtual desktop is created
desktopWindows_.at(0)->setScreenNum(-1);
}
}
else if(desktopWindows_.isEmpty()) { // for the sake of certainty
DesktopWindow* window = createDesktopWindow(desktopWindows_.size());
desktopWindows_.push_back(window);
}
}
else { // a separate screen is added
DesktopWindow* window = createDesktopWindow(desktopWindows_.size());
desktopWindows_.push_back(window);
}
}
}
void Application::onScreenRemoved(QScreen* oldScreen) {
if(enableDesktopManager_){
disconnect(oldScreen, &QScreen::virtualGeometryChanged, this, &Application::onVirtualGeometryChanged);
disconnect(oldScreen, &QScreen::availableGeometryChanged, this, &Application::onAvailableGeometryChanged);
disconnect(oldScreen, &QObject::destroyed, this, &Application::onScreenDestroyed);
if(desktopWindows_.isEmpty()) {
return;
}
if(desktopWindows_.size() == 1) { // a single desktop is changed
if(primaryScreen() != nullptr) {
desktopWindows_.at(0)->setGeometry(primaryScreen()->virtualGeometry());
if(primaryScreen()->virtualSiblings().size() == 1) {
desktopWindows_.at(0)->setScreenNum(0); // there is no virtual desktop anymore
}
}
else if (screens().isEmpty()) { // for the sake of certainty
desktopWindows_.at(0)->setScreenNum(0);
}
}
else { // a separate desktop is removed
int n = desktopWindows_.size();
for(int i = 0; i < n; ++i) {
DesktopWindow* window = desktopWindows_.at(i);
if(window->getDesktopScreen() == oldScreen) {
desktopWindows_.remove(i);
delete window;
break;
}
}
}
}
}
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 lxqt/lxqt bug #204, #205, and #206.
// Qt 5 has two new regression bugs which breaks lxqt-panel in a multihead environment.
// #40681: Regression bug: QWidget::winId() returns old value and QEvent::WinIdChange event is not emitted sometimes. (multihead setup)
// #40791: Regression: QPlatformWindow, QWindow, and QWidget::winId() are out of sync.
// 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.
for(DesktopWindow* desktopWin : qAsConst(desktopWindows_)) {
if(desktopWin->windowHandle()->screen() == screenObj) {
desktopWin->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.
for(DesktopWindow* desktopWin : qAsConst(desktopWindows_)) {
if(!desktopWin->windowHandle()) {
desktopWin->create(); // re-create the underlying native window
desktopWin->queueRelayout();
desktopWin->show();
}
}
}
}
void Application::onVirtualGeometryChanged(const QRect& /*rect*/) {
// update desktop geometries
if(enableDesktopManager_) {
for(DesktopWindow* desktopWin : qAsConst(desktopWindows_)) {
auto desktopScreen = desktopWin->getDesktopScreen();
if(desktopScreen) {
desktopWin->setGeometry(desktopScreen->virtualGeometry());
}
}
}
}
void Application::onAvailableGeometryChanged(const QRect& /*rect*/) {
// update desktop layouts
if(enableDesktopManager_) {
for(DesktopWindow* desktopWin : qAsConst(desktopWindows_)) {
desktopWin->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

@ -1,157 +0,0 @@
/*
Copyright (C) 2013 Hong Jen Yee (PCMan) <pcman.tw@gmail.com>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#ifndef PCMANFM_APPLICATION_H
#define PCMANFM_APPLICATION_H
#include <QApplication>
#include "settings.h"
#include <libfm-qt/libfmqt.h>
#include <libfm-qt/editbookmarksdialog.h>
#include <QVector>
#include <QPointer>
#include <QProxyStyle>
#include <QTranslator>
#include <gio/gio.h>
#include <libfm-qt/core/filepath.h>
#include <libfm-qt/core/fileinfo.h>
class QScreen;
class QFileSystemWatcher;
namespace PCManFM {
class MainWindow;
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());
void connectToServer();
bool desktopManagerEnabled() {
return enableDesktopManager_;
}
void updateFromSettings();
void updateDesktopsFromSettings(bool changeSlide = true);
void openFolderInTerminal(Fm::FilePath path);
void openFolders(Fm::FileInfoList files);
QString profileName() {
return profileName_;
}
protected Q_SLOTS:
void onAboutToQuit();
void onSigtermNotified();
void onLastWindowClosed();
void onSaveStateRequest(QSessionManager& manager);
void initVolumeManager();
void onVirtualGeometryChanged(const QRect& rect);
void onAvailableGeometryChanged(const QRect& rect);
void onScreenDestroyed(QObject* screenObj);
void onScreenAdded(QScreen* newScreen);
void onScreenRemoved(QScreen* oldScreen);
void reloadDesktopsAsNeeded();
void onFindFileAccepted();
void onConnectToServerAccepted();
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

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

@ -1,144 +0,0 @@
/*
Copyright (C) 2013 Hong Jen Yee (PCMan) <pcman.tw@gmail.com>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#include "autorundialog.h"
#include <QListWidgetItem>
#include "application.h"
#include "mainwindow.h"
#include <libfm-qt/core/filepath.h>
#include <libfm-qt/core/iconinfo.h>
namespace PCManFM {
AutoRunDialog::AutoRunDialog(GVolume* volume, GMount* mount, QWidget* parent, Qt::WindowFlags f):
QDialog(parent, f),
cancellable(g_cancellable_new()),
applications(nullptr),
mount_(G_MOUNT(g_object_ref(mount))) {
setAttribute(Qt::WA_DeleteOnClose);
ui.setupUi(this);
GIcon* gicon = g_volume_get_icon(volume);
QIcon icon = Fm::IconInfo::fromGIcon(gicon)->qicon();
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);
connect(ui.listWidget, &QListWidget::itemDoubleClicked, this, &QDialog::accept);
}
AutoRunDialog::~AutoRunDialog() {
g_list_foreach(applications, (GFunc)g_object_unref, nullptr);
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(nullptr, gf);
g_app_info_launch(app, filelist, nullptr, nullptr);
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();
Fm::FilePath path{gf, true};
// 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);
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 = nullptr;
}
char** types = g_mount_guess_content_type_finish(mount, res, nullptr);
char* desc = nullptr;
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::IconInfo::fromGIcon(gicon)->qicon();
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

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

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

@ -1,103 +0,0 @@
/*
Copyright (C) 2017 Pedram Pourang (Tsu Jan) <tsujan2000@gmail.com>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#include "bulkrename.h"
#include <QTimer>
#include <QPushButton>
#include <QMessageBox>
#include <QProgressDialog>
#include <libfm-qt/utilities.h>
namespace PCManFM {
BulkRenameDialog::BulkRenameDialog(QWidget* parent, Qt::WindowFlags flags) :
QDialog(parent, flags) {
ui.setupUi(this);
ui.lineEdit->setFocus();
connect(ui.buttonBox->button(QDialogButtonBox::Ok), &QAbstractButton::clicked, this, &QDialog::accept);
connect(ui.buttonBox->button(QDialogButtonBox::Cancel), &QAbstractButton::clicked, this, &QDialog::reject);
resize(minimumSize());
setMaximumHeight(minimumHeight()); // no vertical resizing
}
void BulkRenameDialog::showEvent(QShowEvent* event) {
QDialog::showEvent(event);
if(ui.lineEdit->text().endsWith(QLatin1Char('#'))) { // select what's before "#"
QTimer::singleShot(0, [this]() {
ui.lineEdit->setSelection(0, ui.lineEdit->text().size() - 1);
});
}
}
BulkRenamer::BulkRenamer(const Fm::FileInfoList& files, QWidget* parent) {
if(files.size() <= 1) { // no bulk rename with just one file
return;
}
QString baseName;
int start = 0;
BulkRenameDialog dlg(parent);
switch(dlg.exec()) {
case QDialog::Accepted:
baseName = dlg.getBaseName();
start = dlg.getStart();
break;
default:
return;
}
if(!baseName.contains(QLatin1Char('#'))) {
// insert "#" before the last dot
int end = baseName.lastIndexOf(QLatin1Char('.'));
if(end == -1) {
end = baseName.size();
}
baseName.insert(end, QLatin1Char('#'));
}
QProgressDialog progress(QObject::tr("Renaming files..."), QObject::tr("Abort"), 0, files.size(), parent);
progress.setWindowModality(Qt::WindowModal);
int i = 0, failed = 0;
for(auto& file: files) {
progress.setValue(i);
if(progress.wasCanceled()) {
progress.close();
QMessageBox::warning(parent, QObject::tr("Warning"), QObject::tr("Renaming is aborted."));
return;
}
auto fileName = QString::fromStdString(file->name());
QString newName = baseName;
newName.replace(QLatin1Char('#'), QString::number(start + i));
if (newName == fileName || !Fm::changeFileName(file->path(), newName, nullptr, false)) {
++failed;
}
++i;
}
progress.setValue(i);
if(failed == i) {
QMessageBox::critical(parent, QObject::tr("Error"), QObject::tr("No file could be renamed."));
}
else if(failed > 0) {
QMessageBox::critical(parent, QObject::tr("Error"), QObject::tr("Some files could not be renamed."));
}
}
BulkRenamer::~BulkRenamer() {
}
} //namespace PCManFM

@ -1,57 +0,0 @@
/*
Copyright (C) 2017 Pedram Pourang (Tsu Jan) <tsujan2000@gmail.com>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#ifndef PCMANFM_BULKRENAME_H
#define PCMANFM_BULKRENAME_H
#include "ui_bulk-rename.h"
#include <QDialog>
#include <libfm-qt/core/fileinfo.h>
namespace PCManFM {
class BulkRenameDialog : public QDialog {
Q_OBJECT
public:
explicit BulkRenameDialog(QWidget* parent = nullptr, Qt::WindowFlags flags = 0);
QString getBaseName() const {
return ui.lineEdit->text();
}
int getStart() const {
return ui.spinBox->value();
}
protected:
virtual void showEvent(QShowEvent* event) override;
private:
Ui::BulkRenameDialog ui;
};
class BulkRenamer {
public:
BulkRenamer(const Fm::FileInfoList& files, QWidget* parent = nullptr);
~BulkRenamer();
};
}
#endif // PCMANFM_BULKRENAME_H

@ -1,173 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>ConnectServerDialog</class>
<widget class="QDialog" name="ConnectServerDialog">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>450</width>
<height>256</height>
</rect>
</property>
<property name="windowTitle">
<string>Connect to remote server</string>
</property>
<property name="windowIcon">
<iconset theme="folder-remote"/>
</property>
<layout class="QGridLayout" name="gridLayout">
<item row="5" column="0" colspan="4">
<widget class="QRadioButton" name="ananymousLogin">
<property name="text">
<string>Anonymous &amp;login</string>
</property>
<property name="checked">
<bool>true</bool>
</property>
</widget>
</item>
<item row="4" column="1" colspan="3">
<widget class="QLineEdit" name="path"/>
</item>
<item row="6" column="0">
<widget class="QRadioButton" name="loginAsUser">
<property name="text">
<string>Login as &amp;user:</string>
</property>
</widget>
</item>
<item row="6" column="1" colspan="3">
<widget class="QLineEdit" name="userName"/>
</item>
<item row="1" column="1" colspan="3">
<widget class="QComboBox" name="serverType"/>
</item>
<item row="8" column="0" colspan="4">
<widget class="QDialogButtonBox" name="buttonBox">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="standardButtons">
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
</property>
</widget>
</item>
<item row="0" column="0" colspan="4">
<widget class="QLabel" name="label">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>Specify remote folder to connect</string>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QLabel" name="label_2">
<property name="text">
<string>Type:</string>
</property>
</widget>
</item>
<item row="2" column="2">
<widget class="QLabel" name="label_4">
<property name="text">
<string>Port:</string>
</property>
</widget>
</item>
<item row="4" column="0">
<widget class="QLabel" name="label_5">
<property name="text">
<string>Path:</string>
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="QLineEdit" name="host"/>
</item>
<item row="2" column="0">
<widget class="QLabel" name="label_3">
<property name="text">
<string>Host:</string>
</property>
</widget>
</item>
<item row="2" column="3">
<widget class="QSpinBox" name="port">
<property name="maximum">
<number>65535</number>
</property>
</widget>
</item>
<item row="7" column="0">
<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>
<resources/>
<connections>
<connection>
<sender>buttonBox</sender>
<signal>accepted()</signal>
<receiver>ConnectServerDialog</receiver>
<slot>accept()</slot>
<hints>
<hint type="sourcelabel">
<x>254</x>
<y>249</y>
</hint>
<hint type="destinationlabel">
<x>157</x>
<y>274</y>
</hint>
</hints>
</connection>
<connection>
<sender>buttonBox</sender>
<signal>rejected()</signal>
<receiver>ConnectServerDialog</receiver>
<slot>reject()</slot>
<hints>
<hint type="sourcelabel">
<x>322</x>
<y>249</y>
</hint>
<hint type="destinationlabel">
<x>286</x>
<y>274</y>
</hint>
</hints>
</connection>
<connection>
<sender>loginAsUser</sender>
<signal>toggled(bool)</signal>
<receiver>userName</receiver>
<slot>setEnabled(bool)</slot>
<hints>
<hint type="sourcelabel">
<x>65</x>
<y>194</y>
</hint>
<hint type="destinationlabel">
<x>163</x>
<y>184</y>
</hint>
</hints>
</connection>
</connections>
</ui>

@ -1,88 +0,0 @@
#include "connectserverdialog.h"
#include <QMessageBox>
#include <QPushButton>
namespace PCManFM {
ConnectServerDialog::ConnectServerDialog(QWidget *parent): QDialog(parent) {
serverTypes = QList<ServerType>{
{tr("SSH"), "sftp", 22, false},
{tr("FTP"), "ftp", 21, true},
{tr("WebDav"), "dav", 80, true},
{tr("Secure WebDav"), "davs", 443, false},
{tr("HTTP"), "http", 80, true},
{tr("HTTPS"), "https", 443, true},
};
ui.setupUi(this);
connect(ui.serverType, static_cast<void(QComboBox::*)(int)>(&QComboBox::currentIndexChanged),
this, &ConnectServerDialog::onCurrentIndexChanged);
connect(ui.host, &QLineEdit::textChanged, this, &ConnectServerDialog::checkInput);
connect(ui.userName, &QLineEdit::textChanged, this, &ConnectServerDialog::checkInput);
for(const auto& serverType : const_cast<const QList<ServerType>&>(serverTypes)) {
ui.serverType->addItem(serverType.name);
}
ui.serverType->setCurrentIndex(0);
onCurrentIndexChanged(0);
}
ConnectServerDialog::~ConnectServerDialog() {
}
QString ConnectServerDialog::uriText() {
QString uri;
int serverTypeIdx = ui.serverType->currentIndex();
const auto& serverType = serverTypes[serverTypeIdx];
// make an URI from the data
uri = QString::fromLatin1(serverType.scheme);
uri += QStringLiteral("://");
if(ui.loginAsUser->isChecked()) {
uri += ui.userName->text();
uri += '@';
}
uri += ui.host->text();
int port = ui.port->value();
if(port != serverType.defaultPort) {
uri += ':';
uri += QString::number(port);
}
QString path = ui.path->text();
if(path.isEmpty() || path[0] != '/') {
uri += '/';
}
uri += path;
return uri;
}
void ConnectServerDialog::onCurrentIndexChanged(int /*index*/) {
int serverTypeIdx = ui.serverType->currentIndex();
const auto& serverType = serverTypes[serverTypeIdx];
ui.port->setValue(serverType.defaultPort);
ui.ananymousLogin->setEnabled(serverType.canAnonymous);
if(serverType.canAnonymous)
ui.ananymousLogin->setChecked(true);
else
ui.loginAsUser->setChecked(true);
ui.host->setFocus();
checkInput();
}
void ConnectServerDialog::checkInput() {
bool valid = true;
if(ui.host->text().isEmpty()) {
valid = false;
}
else if(ui.loginAsUser->isChecked() && ui.userName->text().isEmpty()) {
valid = false;
}
ui.buttonBox->button(QDialogButtonBox::Ok)->setEnabled(valid);
}
} // namespace PCManFM

@ -1,38 +0,0 @@
#ifndef CONNECTSERVERDIALOG_H
#define CONNECTSERVERDIALOG_H
#include <QDialog>
#include <QList>
#include "ui_connect.h"
namespace PCManFM {
class ConnectServerDialog : public QDialog {
Q_OBJECT
public:
ConnectServerDialog(QWidget* parent=nullptr);
virtual ~ConnectServerDialog();
QString uriText();
private:
struct ServerType {
QString name;
const char* scheme;
int defaultPort;
bool canAnonymous;
};
private Q_SLOTS:
void onCurrentIndexChanged(int index);
void checkInput();
private:
Ui::ConnectServerDialog ui;
QList<ServerType> serverTypes;
};
} // namespace PCManFM
#endif // CONNECTSERVERDIALOG_H

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

@ -1,601 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>DesktopPreferencesDialog</class>
<widget class="QDialog" name="DesktopPreferencesDialog">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>534</width>
<height>434</height>
</rect>
</property>
<property name="windowTitle">
<string>Desktop Preferences</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<widget class="QTabWidget" name="tabWidget">
<property name="currentIndex">
<number>0</number>
</property>
<widget class="QWidget" name="generalPage">
<attribute name="title">
<string>General</string>
</attribute>
<layout class="QVBoxLayout" name="verticalLayout_2">
<item>
<widget class="QGroupBox" name="groupBox_2">
<property name="title">
<string>Background</string>
</property>
<layout class="QGridLayout" name="gridLayout">
<item row="2" column="1" colspan="2">
<widget class="QComboBox" name="wallpaperMode">
<property name="sizePolicy">
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
</widget>
</item>
<item row="2" column="0">
<widget class="QLabel" name="label">
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>Wallpaper mode:</string>
</property>
</widget>
</item>
<item row="3" column="0">
<widget class="QLabel" name="label_6">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>Wallpaper image file:</string>
</property>
</widget>
</item>
<item row="5" column="1">
<widget class="Fm::ColorButton" name="backgroundColor">
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string/>
</property>
</widget>
</item>
<item row="5" column="0">
<widget class="QLabel" name="label_5">
<property name="text">
<string>Select background color:</string>
</property>
</widget>
</item>
<item row="4" column="0" colspan="3">
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<widget class="QLineEdit" name="imageFile">
<property name="toolTip">
<string>Image file</string>
</property>
<property name="statusTip">
<string/>
</property>
<property name="placeholderText">
<string>Image file path</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="browse">
<property name="text">
<string>&amp;Browse</string>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QGroupBox" name="groupBox_5">
<property name="title">
<string>Icons</string>
</property>
<layout class="QFormLayout" name="formLayout">
<item row="0" column="0">
<widget class="QLabel" name="label_9">
<property name="text">
<string>Icon size:</string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QComboBox" name="iconSize"/>
</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="bgPage">
<attribute name="title">
<string>Slide Show</string>
</attribute>
<layout class="QVBoxLayout" name="verticalLayout_3">
<item>
<widget class="QGroupBox" name="slideShow">
<property name="title">
<string>Enable Slide Show</string>
</property>
<property name="checkable">
<bool>true</bool>
</property>
<property name="checked">
<bool>false</bool>
</property>
<layout class="QGridLayout" name="gridLayout_4">
<item row="0" column="0" colspan="7">
<widget class="QLabel" name="label_10">
<property name="text">
<string>Wallpaper image folder:</string>
</property>
</widget>
</item>
<item row="1" column="6">
<widget class="QPushButton" name="folderBrowse">
<property name="text">
<string>Browse</string>
</property>
</widget>
</item>
<item row="2" column="2">
<widget class="QSpinBox" name="hours">
<property name="suffix">
<string> hour(s)</string>
</property>
<property name="maximum">
<number>24</number>
</property>
</widget>
</item>
<item row="2" column="3">
<widget class="QLabel" name="label_12">
<property name="text">
<string>and</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
<property name="margin">
<number>5</number>
</property>
</widget>
</item>
<item row="2" column="0">
<widget class="QLabel" name="label_11">
<property name="toolTip">
<string>Intervals less than 5min will be ignored</string>
</property>
<property name="text">
<string>Interval:</string>
</property>
</widget>
</item>
<item row="2" column="4">
<widget class="QSpinBox" name="minutes">
<property name="suffix">
<string> minute(s)</string>
</property>
<property name="maximum">
<number>55</number>
</property>
<property name="singleStep">
<number>5</number>
</property>
</widget>
</item>
<item row="2" column="5">
<spacer name="horizontalSpacer_2">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>10</width>
<height>5</height>
</size>
</property>
</spacer>
</item>
<item row="1" column="0" colspan="6">
<widget class="QLineEdit" name="imageFolder">
<property name="placeholderText">
<string>Wallpaper folder</string>
</property>
</widget>
</item>
<item row="2" column="1">
<spacer name="horizontalSpacer_3">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeType">
<enum>QSizePolicy::Minimum</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>5</width>
<height>5</height>
</size>
</property>
</spacer>
</item>
<item row="3" column="0" colspan="6">
<widget class="QCheckBox" name="randomize">
<property name="text">
<string>Randomize the slide show</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="advancedPage">
<attribute name="title">
<string>Advanced</string>
</attribute>
<layout class="QVBoxLayout" name="advancedPageLayout">
<item>
<widget class="QGroupBox" name="groupBox_6">
<property name="title">
<string>Visible Shortcuts</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout_4">
<item>
<widget class="QCheckBox" name="homeBox">
<property name="text">
<string>Home</string>
</property>
<property name="icon">
<iconset theme="user-home">
<normaloff>.</normaloff>.</iconset>
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="trashBox">
<property name="text">
<string>Trash</string>
</property>
<property name="icon">
<iconset theme="user-trash">
<normaloff>.</normaloff>.</iconset>
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="computerBox">
<property name="text">
<string>Computer</string>
</property>
<property name="icon">
<iconset theme="computer">
<normaloff>.</normaloff>.</iconset>
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="networkBox">
<property name="text">
<string>Network</string>
</property>
<property name="icon">
<iconset theme="folder-network">
<normaloff>.</normaloff>.</iconset>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<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>

@ -1,284 +0,0 @@
/*
Copyright (C) 2013 Hong Jen Yee (PCMan) <pcman.tw@gmail.com>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#include "desktoppreferencesdialog.h"
#include "desktopwindow.h"
#include "settings.h"
#include "application.h"
#include "xdgdir.h"
#include <QFileDialog>
#include <QImageReader>
#include <QFile>
#include <QDir>
#include <QSaveFile>
#include <QRegExp>
#include <QDebug>
#include <QStandardPaths>
namespace PCManFM {
static int iconSizes[] = {96, 72, 64, 48, 36, 32, 24, 20};
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);
ui.wallpaperMode->addItem(tr("Zoom the image to fill the entire screen"), DesktopWindow::WallpaperZoom);
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;
case DesktopWindow::WallpaperZoom:
i = 5;
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.slideShow->setChecked(settings.slideShowInterval() > 0);
ui.imageFolder->setText(settings.wallpaperDir());
int minutes = qMax(settings.slideShowInterval() / 60000, 5); // 5 min at least
ui.hours->setValue(minutes / 60);
ui.minutes->setValue(minutes % 60);
ui.randomize->setChecked(settings.wallpaperRandomize());
connect(ui.folderBrowse, &QPushButton::clicked, this, &DesktopPreferencesDialog::onFolderBrowseClicked);
for(std::size_t i = 0; i < G_N_ELEMENTS(iconSizes); ++i) {
int size = iconSizes[i];
ui.iconSize->addItem(QString("%1 x %1").arg(size), size);
if(settings.desktopIconSize() == size)
ui.iconSize->setCurrentIndex(i);
}
ui.font->setFont(settings.desktopFont());
ui.backgroundColor->setColor(settings.desktopBgColor());
ui.textColor->setColor(settings.desktopFgColor());
ui.shadowColor->setColor(settings.desktopShadowColor());
const QStringList ds = settings.desktopShortcuts();
ui.homeBox->setChecked(ds.contains(QLatin1String("Home")));
ui.trashBox->setChecked(ds.contains(QLatin1String("Trash")));
ui.computerBox->setChecked(ds.contains(QLatin1String("Computer")));
ui.networkBox->setChecked(ds.contains(QLatin1String("Network")));
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.setWallpaperDir(ui.imageFolder->text());
int interval = 0;
if(ui.slideShow->isChecked())
interval = (ui.minutes->value() + 60 * ui.hours->value()) * 60000;
settings.setSlideShowInterval(interval);
settings.setWallpaperRandomize(ui.randomize->isChecked());
settings.setDesktopIconSize(ui.iconSize->itemData(ui.iconSize->currentIndex()).toInt());
settings.setDesktopFont(ui.font->font());
settings.setDesktopBgColor(ui.backgroundColor->color());
settings.setDesktopFgColor(ui.textColor->color());
settings.setDesktopShadowColor(ui.shadowColor->color());
QStringList ds;
if(ui.homeBox->isChecked()) {
ds << QLatin1String("Home");
}
if(ui.trashBox->isChecked()) {
ds << QLatin1String("Trash");
}
if(ui.computerBox->isChecked()) {
ds << QLatin1String("Computer");
}
if(ui.networkBox->isChecked()) {
ds << QLatin1String("Network");
}
settings.setDesktopShortcuts(ds);
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(false); // don't change slide wallpaper on clicking OK
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 += " (";
const QList<QByteArray> formats = QImageReader::supportedImageFormats();
for(const 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().constFirst();
ui.imageFile->setText(filename);
}
}
void DesktopPreferencesDialog::onFolderBrowseClicked() {
QFileDialog dlg;
dlg.setAcceptMode(QFileDialog::AcceptOpen);
dlg.setFileMode(QFileDialog::Directory);
dlg.setOption(QFileDialog::ShowDirsOnly);
dlg.setDirectory(QDir::home().path());
if(dlg.exec() == QDialog::Accepted) {
QString foldername;
foldername = dlg.selectedFiles().constFirst();
ui.imageFolder->setText(foldername);
}
}
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().constFirst();
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

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

File diff suppressed because it is too large Load Diff

@ -1,195 +0,0 @@
/*
Copyright (C) 2013 Hong Jen Yee (PCMan) <pcman.tw@gmail.com>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#ifndef PCMANFM_DESKTOPWINDOW_H
#define PCMANFM_DESKTOPWINDOW_H
#include "view.h"
#include "launcher.h"
#include <unordered_map>
#include <string>
#include <QHash>
#include <QPoint>
#include <QByteArray>
#include <QScreen>
#include <xcb/xcb.h>
#include <libfm-qt/core/folder.h>
namespace Fm {
class CachedFolderModel;
class ProxyFolderModel;
class FolderViewListView;
}
namespace PCManFM {
class Settings;
class DesktopWindow : public View {
Q_OBJECT
public:
friend class Application;
enum WallpaperMode {
WallpaperNone,
WallpaperStretch,
WallpaperFit,
WallpaperCenter,
WallpaperTile,
WallpaperZoom
};
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 setLastSlide(QString filename);
void setWallpaperDir(QString dirname);
void setSlideShowInterval(int interval);
void setWallpaperRandomize(bool randomize);
// void setWallpaperAlpha(qreal alpha);
void updateWallpaper();
bool pickWallpaper();
void nextWallpaper();
void updateFromSettings(Settings& settings, bool changeSlide = true);
void queueRelayout(int delay = 0);
int screenNum() const {
return screenNum_;
}
void setScreenNum(int num);
QScreen* getDesktopScreen() const;
protected:
virtual void prepareFolderMenu(Fm::FolderMenu* menu) override;
virtual void prepareFileMenu(Fm::FileMenu* menu) override;
virtual void resizeEvent(QResizeEvent* event) override;
virtual void onFileClicked(int type, const std::shared_ptr<const Fm::FileInfo>& fileInfo) override;
void loadItemPositions();
void saveItemPositions();
QImage loadWallpaperFile(QSize requiredSize);
virtual bool event(QEvent* event) override;
virtual bool eventFilter(QObject* watched, QEvent* event) override;
virtual void childDragMoveEvent(QDragMoveEvent* e) override;
virtual void childDropEvent(QDropEvent* e) override;
virtual void closeEvent(QCloseEvent* event) override;
virtual void paintEvent(QPaintEvent* event) override;
protected Q_SLOTS:
void onOpenDirRequested(const Fm::FilePath& path, int target);
void onDesktopPreferences();
void selectAll();
void toggleDesktop();
void onRowsAboutToBeRemoved(const QModelIndex& parent, int start, int end);
void onRowsInserted(const QModelIndex& parent, int start, int end);
void onLayoutChanged();
void onModelSortFilterChanged();
void onDataChanged(const QModelIndex& topLeft, const QModelIndex& bottomRight);
void onFolderStartLoading();
void onFolderFinishLoading();
void onFilesAdded(const Fm::FileInfoList files);
void relayoutItems();
void onStickToCurrentPos(bool toggled);
// void updateWorkArea();
// file operations
void onCutActivated();
void onCopyActivated();
void onCopyFullPathActivated();
void onPasteActivated();
void onRenameActivated();
void onBulkRenameActivated();
void onDeleteActivated();
void onFilePropertiesActivated();
void updateTrashIcon();
private:
void removeBottomGap();
void addDesktopActions(QMenu* menu);
void paintBackground(QPaintEvent* event);
void paintDropIndicator();
bool stickToPosition(const std::string& file, QPoint& pos, const QRect& workArea, const QSize& grid, bool reachedLastCell = false);
static void alignToGrid(QPoint& pos, const QPoint& topLeft, const QSize& grid, const int spacing);
void updateShortcutsFromSettings(Settings& settings);
void createTrashShortcut(int items);
void createHomeShortcut();
void createComputerShortcut();
void createNetworkShortcut();
void createTrash();
static void onTrashChanged(GFileMonitor* monitor, GFile* gf, GFile* other, GFileMonitorEvent evt, DesktopWindow* pThis);
void trustOurDesktopShortcut(std::shared_ptr<const Fm::FileInfo> file);
bool isTrashCan(std::shared_ptr<const Fm::FileInfo> file);
private:
Fm::ProxyFolderModel* proxyModel_;
Fm::CachedFolderModel* model_;
std::shared_ptr<Fm::Folder> folder_;
Fm::FolderViewListView* listView_;
QColor fgColor_;
QColor bgColor_;
QColor shadowColor_;
QString wallpaperFile_;
WallpaperMode wallpaperMode_;
QString lastSlide_;
QString wallpaperDir_;
int slideShowInterval_;
QTimer* wallpaperTimer_;
bool wallpaperRandomize_;
QPixmap wallpaperPixmap_;
Launcher fileLauncher_;
bool showWmMenu_;
bool desktopHideItems_;
int screenNum_;
std::unordered_map<std::string, QPoint> customItemPos_;
QHash<QModelIndex, QString> displayNames_; // only for desktop entries and shortcuts
QTimer* relayoutTimer_;
QTimer* selectionTimer_;
QRect dropRect_;
QTimer* trashUpdateTimer_;
GFileMonitor* trashMonitor_;
};
}
#endif // PCMANFM_DESKTOPWINDOW_H

@ -1,67 +0,0 @@
/*
* <one line to give the library's name and an idea of what it does.>
* Copyright (C) 2014 <copyright holder> <email>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
*/
#include "launcher.h"
#include "mainwindow.h"
#include "application.h"
#include <libfm-qt/core/filepath.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*/, const Fm::FileInfoList& folderInfos, Fm::GErrorPtr& /*err*/) {
auto fi = folderInfos[0];
Application* app = static_cast<Application*>(qApp);
MainWindow* mainWindow = mainWindow_;
Fm::FilePath path = fi->path();
if(!mainWindow) {
mainWindow = new MainWindow(std::move(path));
mainWindow->resize(app->settings().windowWidth(), app->settings().windowHeight());
if(app->settings().windowMaximized()) {
mainWindow->setWindowState(mainWindow->windowState() | Qt::WindowMaximized);
}
}
else {
mainWindow->chdir(std::move(path));
}
for(size_t i = 1; i < folderInfos.size(); ++i) {
fi = folderInfos[i];
path = fi->path();
mainWindow->addTab(std::move(path));
}
mainWindow->show();
mainWindow->raise();
return true;
}
} //namespace PCManFM

@ -1,44 +0,0 @@
/*
* <one line to give the library's name and an idea of what it does.>
* Copyright (C) 2014 <copyright holder> <email>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
*/
#ifndef PCMANFM_LAUNCHER_H
#define PCMANFM_LAUNCHER_H
#include <libfm-qt/filelauncher.h>
namespace PCManFM {
class MainWindow;
class Launcher : public Fm::FileLauncher {
public:
Launcher(MainWindow* mainWindow = nullptr);
~Launcher();
protected:
bool openFolder(GAppLaunchContext* ctx, const Fm::FileInfoList& folderInfos, Fm::GErrorPtr& err) override;
private:
MainWindow* mainWindow_;
};
}
#endif // PCMANFM_LAUNCHER_H

@ -1,878 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>MainWindow</class>
<widget class="QMainWindow" name="MainWindow">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>460</width>
<height>369</height>
</rect>
</property>
<property name="windowTitle">
<string>File Manager</string>
</property>
<property name="windowIcon">
<iconset theme="folder">
<normaloff>.</normaloff>.</iconset>
</property>
<widget class="QWidget" name="centralwidget">
<layout class="QVBoxLayout" name="verticalLayout">
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item>
<widget class="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="QSplitter" name="viewSplitter">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
</widget>
</widget>
</item>
</layout>
</widget>
<widget class="QMenuBar" name="menubar">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>460</width>
<height>30</height>
</rect>
</property>
<property name="contextMenuPolicy">
<enum>Qt::PreventContextMenu</enum>
</property>
<widget class="QMenu" name="menu_File">
<property name="title">
<string>&amp;File</string>
</property>
<widget class="QMenu" name="menuCreateNew">
<property name="title">
<string>C&amp;reate New</string>
</property>
<addaction name="actionNewFolder"/>
<addaction name="actionNewBlankFile"/>
</widget>
<addaction name="actionNewTab"/>
<addaction name="actionNewWin"/>
<addaction name="separator"/>
<addaction name="menuCreateNew"/>
<addaction name="separator"/>
<addaction name="actionFileProperties"/>
<addaction name="actionFolderProperties"/>
<addaction name="separator"/>
<addaction name="actionCloseTab"/>
<addaction name="actionCloseWindow"/>
</widget>
<widget class="QMenu" name="menu_Help">
<property name="title">
<string>&amp;Help</string>
</property>
<addaction name="actionAbout"/>
</widget>
<widget class="QMenu" name="menu_View">
<property name="title">
<string>&amp;View</string>
</property>
<widget class="QMenu" name="menuSorting">
<property name="title">
<string>&amp;Sorting</string>
</property>
<addaction name="actionByFileName"/>
<addaction name="actionByMTime"/>
<addaction name="actionByFileSize"/>
<addaction name="actionByFileType"/>
<addaction name="actionByOwner"/>
<addaction name="actionByGroup"/>
<addaction name="separator"/>
<addaction name="actionAscending"/>
<addaction name="actionDescending"/>
<addaction name="separator"/>
<addaction name="actionFolderFirst"/>
<addaction name="actionCaseSensitive"/>
</widget>
<widget class="QMenu" name="menu_View_2">
<property name="title">
<string>&amp;View</string>
</property>
<addaction name="actionIconView"/>
<addaction name="actionThumbnailView"/>
<addaction name="actionCompactView"/>
<addaction name="actionDetailedList"/>
<addaction name="separator"/>
</widget>
<widget class="QMenu" name="menuToolbars">
<property name="title">
<string>&amp;Toolbars</string>
</property>
<addaction name="actionFilter"/>
<addaction name="actionMenu_bar"/>
</widget>
<widget class="QMenu" name="menuPathBarStyle">
<property name="title">
<string>Path &amp;Bar</string>
</property>
<addaction name="actionLocationBar"/>
<addaction name="actionPathButtons"/>
</widget>
<widget class="QMenu" name="menuFiltering">
<property name="title">
<string>&amp;Filtering</string>
</property>
<addaction name="actionShowFilter"/>
<addaction name="actionUnfilter"/>
</widget>
<addaction name="actionReload"/>
<addaction name="separator"/>
<addaction name="actionShowHidden"/>
<addaction name="actionSplitView"/>
<addaction name="menuSorting"/>
<addaction name="menu_View_2"/>
<addaction name="actionPreserveView"/>
<addaction name="separator"/>
<addaction name="menuToolbars"/>
<addaction name="menuPathBarStyle"/>
<addaction name="separator"/>
<addaction name="menuFiltering"/>
</widget>
<widget class="QMenu" name="menu_Edit">
<property name="title">
<string>&amp;Edit</string>
</property>
<addaction name="actionCut"/>
<addaction name="actionCopy"/>
<addaction name="actionPaste"/>
<addaction name="actionRename"/>
<addaction name="actionDelete"/>
<addaction name="separator"/>
<addaction name="actionSelectAll"/>
<addaction name="actionInvertSelection"/>
<addaction name="separator"/>
<addaction name="separator"/>
<addaction name="actionBulkRename"/>
<addaction name="separator"/>
<addaction name="actionPreferences"/>
</widget>
<widget class="QMenu" name="menu_Bookmarks">
<property name="title">
<string>&amp;Bookmarks</string>
</property>
<addaction name="actionAddToBookmarks"/>
<addaction name="actionEditBookmarks"/>
</widget>
<widget class="QMenu" name="menu_Go">
<property name="title">
<string>&amp;Go</string>
</property>
<addaction name="actionHome"/>
<addaction name="actionDesktop"/>
<addaction name="actionComputer"/>
<addaction name="actionTrash"/>
<addaction name="actionNetwork"/>
<addaction name="actionApplications"/>
<addaction name="separator"/>
<addaction name="actionGoBack"/>
<addaction name="actionGoForward"/>
<addaction name="actionGoUp"/>
<addaction name="separator"/>
<addaction name="actionConnectToServer"/>
</widget>
<widget class="QMenu" name="menu_Tool">
<property name="title">
<string>&amp;Tool</string>
</property>
<addaction name="actionOpenTerminal"/>
<addaction name="actionOpenAsRoot"/>
<addaction name="actionCopyFullPath"/>
<addaction name="actionFindFiles"/>
</widget>
<addaction name="menu_File"/>
<addaction name="menu_Edit"/>
<addaction name="menu_View"/>
<addaction name="menu_Go"/>
<addaction name="menu_Bookmarks"/>
<addaction name="menu_Tool"/>
<addaction name="menu_Help"/>
</widget>
<widget class="PCManFM::StatusBar" name="statusbar"/>
<widget class="QToolBar" name="toolBar">
<property name="contextMenuPolicy">
<enum>Qt::PreventContextMenu</enum>
</property>
<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="separator"/>
<addaction name="actionIconView"/>
<addaction name="actionThumbnailView"/>
<addaction name="actionCompactView"/>
<addaction name="actionDetailedList"/>
<addaction name="separator"/>
<addaction name="actionGo"/>
<addaction name="actionMenu"/>
</widget>
<action name="actionGoUp">
<property name="icon">
<iconset theme="go-up">
<normaloff>.</normaloff>.</iconset>
</property>
<property name="text">
<string>Go &amp;Up</string>
</property>
<property name="toolTip">
<string>Go Up</string>
</property>
<property name="shortcut">
<string>Alt+Up</string>
</property>
</action>
<action name="actionHome">
<property name="icon">
<iconset theme="user-home">
<normaloff>.</normaloff>.</iconset>
</property>
<property name="text">
<string>&amp;Home</string>
</property>
<property name="shortcut">
<string>Alt+Home</string>
</property>
</action>
<action name="actionReload">
<property name="icon">
<iconset theme="view-refresh">
<normaloff>.</normaloff>.</iconset>
</property>
<property name="text">
<string>&amp;Reload</string>
</property>
<property name="shortcut">
<string>F5</string>
</property>
</action>
<action name="actionGo">
<property name="icon">
<iconset theme="go-jump">
<normaloff>.</normaloff>.</iconset>
</property>
<property name="text">
<string>Go</string>
</property>
</action>
<action name="actionQuit">
<property name="icon">
<iconset theme="application-exit">
<normaloff>.</normaloff>.</iconset>
</property>
<property name="text">
<string>Quit</string>
</property>
</action>
<action name="actionAbout">
<property name="icon">
<iconset theme="help-about">
<normaloff>.</normaloff>.</iconset>
</property>
<property name="text">
<string>&amp;About</string>
</property>
</action>
<action name="actionNewWin">
<property name="icon">
<iconset theme="window-new">
<normaloff>.</normaloff>.</iconset>
</property>
<property name="text">
<string>&amp;New Window</string>
</property>
<property name="toolTip">
<string>New Window</string>
</property>
<property name="shortcut">
<string>Ctrl+N</string>
</property>
</action>
<action name="actionShowHidden">
<property name="checkable">
<bool>true</bool>
</property>
<property name="text">
<string>Show &amp;Hidden</string>
</property>
<property name="shortcut">
<string>Ctrl+H</string>
</property>
</action>
<action name="actionComputer">
<property name="icon">
<iconset theme="computer">
<normaloff>.</normaloff>.</iconset>
</property>
<property name="text">
<string>&amp;Computer</string>
</property>
</action>
<action name="actionTrash">
<property name="icon">
<iconset theme="user-trash">
<normaloff>.</normaloff>.</iconset>
</property>
<property name="text">
<string>&amp;Trash</string>
</property>
</action>
<action name="actionNetwork">
<property name="text">
<string>&amp;Network</string>
</property>
</action>
<action name="actionDesktop">
<property name="icon">
<iconset theme="user-desktop">
<normaloff>.</normaloff>.</iconset>
</property>
<property name="text">
<string>&amp;Desktop</string>
</property>
</action>
<action name="actionAddToBookmarks">
<property name="icon">
<iconset theme="list-add">
<normaloff>.</normaloff>.</iconset>
</property>
<property name="text">
<string>&amp;Add to Bookmarks</string>
</property>
</action>
<action name="actionApplications">
<property name="text">
<string>&amp;Applications</string>
</property>
</action>
<action name="actionReload_2">
<property name="text">
<string>Reload</string>
</property>
</action>
<action name="actionIconView">
<property name="checkable">
<bool>true</bool>
</property>
<property name="text">
<string>&amp;Icon View</string>
</property>
</action>
<action name="actionCompactView">
<property name="checkable">
<bool>true</bool>
</property>
<property name="text">
<string>&amp;Compact View</string>
</property>
</action>
<action name="actionDetailedList">
<property name="checkable">
<bool>true</bool>
</property>
<property name="text">
<string>&amp;Detailed List</string>
</property>
</action>
<action name="actionThumbnailView">
<property name="checkable">
<bool>true</bool>
</property>
<property name="text">
<string>&amp;Thumbnail View</string>
</property>
</action>
<action name="actionCut">
<property name="icon">
<iconset theme="edit-cut">
<normaloff>.</normaloff>.</iconset>
</property>
<property name="text">
<string>Cu&amp;t</string>
</property>
<property name="shortcut">
<string>Ctrl+X</string>
</property>
</action>
<action name="actionCopy">
<property name="icon">
<iconset theme="edit-copy">
<normaloff>.</normaloff>.</iconset>
</property>
<property name="text">
<string>&amp;Copy</string>
</property>
<property name="shortcut">
<string>Ctrl+C</string>
</property>
</action>
<action name="actionPaste">
<property name="icon">
<iconset theme="edit-paste">
<normaloff>.</normaloff>.</iconset>
</property>
<property name="text">
<string>&amp;Paste</string>
</property>
<property name="shortcut">
<string>Ctrl+V</string>
</property>
</action>
<action name="actionSelectAll">
<property name="text">
<string>Select &amp;All</string>
</property>
<property name="shortcut">
<string>Ctrl+A</string>
</property>
</action>
<action name="actionPreferences">
<property name="text">
<string>Pr&amp;eferences</string>
</property>
</action>
<action name="actionAscending">
<property name="checkable">
<bool>true</bool>
</property>
<property name="text">
<string>&amp;Ascending</string>
</property>
</action>
<action name="actionDescending">
<property name="checkable">
<bool>true</bool>
</property>
<property name="text">
<string>&amp;Descending</string>
</property>
</action>
<action name="actionByFileName">
<property name="checkable">
<bool>true</bool>
</property>
<property name="text">
<string>&amp;By File Name</string>
</property>
</action>
<action name="actionByMTime">
<property name="checkable">
<bool>true</bool>
</property>
<property name="text">
<string>By &amp;Modification Time</string>
</property>
</action>
<action name="actionByFileType">
<property name="checkable">
<bool>true</bool>
</property>
<property name="text">
<string>By File &amp;Type</string>
</property>
</action>
<action name="actionByOwner">
<property name="checkable">
<bool>true</bool>
</property>
<property name="text">
<string>By &amp;Owner</string>
</property>
</action>
<action name="actionByGroup">
<property name="checkable">
<bool>true</bool>
</property>
<property name="text">
<string>By &amp;Group</string>
</property>
</action>
<action name="actionFolderFirst">
<property name="checkable">
<bool>true</bool>
</property>
<property name="text">
<string>&amp;Folder First</string>
</property>
</action>
<action name="actionPreserveSorting">
<property name="checkable">
<bool>true</bool>
</property>
<property name="text">
<string>&amp;Preserve sorting for this folder</string>
</property>
</action>
<action name="actionNewTab">
<property name="icon">
<iconset theme="window-new">
<normaloff>.</normaloff>.</iconset>
</property>
<property name="text">
<string>New &amp;Tab</string>
</property>
<property name="toolTip">
<string>New Tab</string>
</property>
<property name="shortcut">
<string>Ctrl+T</string>
</property>
</action>
<action name="actionGoBack">
<property name="icon">
<iconset theme="go-previous">
<normaloff>.</normaloff>.</iconset>
</property>
<property name="text">
<string>Go &amp;Back</string>
</property>
<property name="toolTip">
<string>Go Back</string>
</property>
<property name="shortcut">
<string>Alt+Left</string>
</property>
</action>
<action name="actionGoForward">
<property name="icon">
<iconset theme="go-next">
<normaloff>.</normaloff>.</iconset>
</property>
<property name="text">
<string>Go &amp;Forward</string>
</property>
<property name="toolTip">
<string>Go Forward</string>
</property>
<property name="shortcut">
<string>Alt+Right</string>
</property>
</action>
<action name="actionInvertSelection">
<property name="text">
<string>&amp;Invert Selection</string>
</property>
</action>
<action name="actionDelete">
<property name="icon">
<iconset theme="edit-delete">
<normaloff>.</normaloff>.</iconset>
</property>
<property name="text">
<string>&amp;Delete</string>
</property>
<property name="shortcut">
<string>Del</string>
</property>
</action>
<action name="actionRename">
<property name="text">
<string>&amp;Rename</string>
</property>
<property name="shortcut">
<string>F2</string>
</property>
</action>
<action name="actionCloseTab">
<property name="text">
<string>C&amp;lose Tab</string>
</property>
<property name="shortcut">
<string>Ctrl+W</string>
</property>
</action>
<action name="actionFileProperties">
<property name="text">
<string>File &amp;Properties</string>
</property>
<property name="shortcut">
<string>Alt+Return</string>
</property>
</action>
<action name="actionFolderProperties">
<property name="text">
<string>&amp;Folder Properties</string>
</property>
</action>
<action name="actionCaseSensitive">
<property name="checkable">
<bool>true</bool>
</property>
<property name="text">
<string>&amp;Case Sensitive</string>
</property>
</action>
<action name="actionByFileSize">
<property name="checkable">
<bool>true</bool>
</property>
<property name="text">
<string>By File &amp;Size</string>
</property>
</action>
<action name="actionCloseWindow">
<property name="text">
<string>&amp;Close Window</string>
</property>
<property name="shortcut">
<string>Ctrl+Q</string>
</property>
</action>
<action name="actionEdit_Bookmarks">
<property name="text">
<string>Edit Bookmarks</string>
</property>
</action>
<action name="actionOpenTerminal">
<property name="text">
<string>Open &amp;Terminal</string>
</property>
<property name="shortcut">
<string>F4</string>
</property>
</action>
<action name="actionOpenAsRoot">
<property name="text">
<string>Open as &amp;Root</string>
</property>
</action>
<action name="actionEditBookmarks">
<property name="text">
<string>&amp;Edit Bookmarks</string>
</property>
</action>
<action name="actionNewFolder">
<property name="icon">
<iconset theme="folder-new">
<normaloff>.</normaloff>.</iconset>
</property>
<property name="text">
<string>&amp;Folder</string>
</property>
<property name="shortcut">
<string>Ctrl+Shift+N</string>
</property>
</action>
<action name="actionNewBlankFile">
<property name="icon">
<iconset theme="document-new">
<normaloff>.</normaloff>.</iconset>
</property>
<property name="text">
<string>&amp;Blank File</string>
</property>
<property name="shortcut">
<string>Ctrl+Alt+N</string>
</property>
</action>
<action name="actionFindFiles">
<property name="text">
<string>&amp;Find Files</string>
</property>
<property name="shortcut">
<string>F3</string>
</property>
</action>
<action name="actionFilter">
<property name="checkable">
<bool>true</bool>
</property>
<property name="text">
<string>Permanent &amp;filter bar</string>
</property>
<property name="shortcut">
<string>Ctrl+B</string>
</property>
</action>
<action name="actionUnfilter">
<property name="text">
<string>&amp;Clear All Filters</string>
</property>
<property name="shortcut">
<string>Ctrl+Shift+K</string>
</property>
</action>
<action name="actionCloseLeft">
<property name="icon">
<iconset theme="go-previous">
<normaloff>.</normaloff>.</iconset>
</property>
<property name="text">
<string>Close &amp;previous tabs</string>
</property>
</action>
<action name="actionCloseRight">
<property name="icon">
<iconset theme="go-next">
<normaloff>.</normaloff>.</iconset>
</property>
<property name="text">
<string>Close &amp;next tabs</string>
</property>
</action>
<action name="actionCloseOther">
<property name="text">
<string>Close &amp;other tabs</string>
</property>
</action>
<action name="actionMenu_bar">
<property name="checkable">
<bool>true</bool>
</property>
<property name="text">
<string>&amp;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">
<normaloff>.</normaloff>.</iconset>
</property>
<property name="text">
<string>Menu</string>
</property>
<property name="toolTip">
<string>Menu</string>
</property>
</action>
<action name="actionPreserveView">
<property name="checkable">
<bool>true</bool>
</property>
<property name="text">
<string>&amp;Preserve Settings for This Folder</string>
</property>
</action>
<action name="actionConnectToServer">
<property name="text">
<string>Connect to &amp;Server</string>
</property>
</action>
<action name="actionLocationBar">
<property name="checkable">
<bool>true</bool>
</property>
<property name="text">
<string>&amp;Location</string>
</property>
</action>
<action name="actionPathButtons">
<property name="checkable">
<bool>true</bool>
</property>
<property name="text">
<string>&amp;Path Buttons</string>
</property>
</action>
<action name="actionBulkRename">
<property name="text">
<string>&amp;Bulk Rename</string>
</property>
<property name="toolTip">
<string>Bulk Rename</string>
</property>
<property name="shortcut">
<string>Ctrl+F2</string>
</property>
</action>
<action name="actionShowFilter">
<property name="text">
<string>&amp;Show/Focus Filter Bar</string>
</property>
<property name="toolTip">
<string>Show Filter Bar</string>
</property>
<property name="shortcut">
<string>Ctrl+I</string>
</property>
</action>
<action name="actionSplitView">
<property name="checkable">
<bool>true</bool>
</property>
<property name="text">
<string>S&amp;plit View</string>
</property>
<property name="toolTip">
<string>Split View</string>
</property>
<property name="shortcut">
<string>F6</string>
</property>
</action>
<action name="actionCopyFullPath">
<property name="text">
<string>&amp;Copy Full Path</string>
</property>
<property name="shortcut">
<string>Ctrl+Shift+C</string>
</property>
</action>
</widget>
<customwidgets>
<customwidget>
<class>PCManFM::StatusBar</class>
<extends>QStatusBar</extends>
<header>statusbar.h</header>
<container>1</container>
</customwidget>
<customwidget>
<class>Fm::SidePane</class>
<extends>QWidget</extends>
<header location="global">libfm-qt/sidepane.h</header>
<container>1</container>
</customwidget>
</customwidgets>
<resources/>
<connections/>
</ui>

File diff suppressed because it is too large Load Diff

@ -1,272 +0,0 @@
/*
Copyright (C) 2013 Hong Jen Yee (PCMan) <pcman.tw@gmail.com>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#ifndef FM_MAIN_WINDOW_H
#define FM_MAIN_WINDOW_H
#include "ui_main-win.h"
#include <QMainWindow>
#include <QListView>
#include <QSortFilterProxyModel>
#include <QLineEdit>
#include <QTabWidget>
#include <QMessageBox>
#include <QTabBar>
#include <QStackedWidget>
#include <QSplitter>
#include "launcher.h"
#include "tabbar.h"
#include <libfm-qt/core/filepath.h>
#include <libfm-qt/core/bookmarks.h>
namespace Fm {
class PathEdit;
class PathBar;
}
namespace PCManFM {
class ViewFrame : public QFrame {
Q_OBJECT
public:
ViewFrame(QWidget* parent = nullptr);
~ViewFrame() {};
void createTopBar(bool usePathButtons);
void removeTopBar();
QWidget* getTopBar() const {
return topBar_;
}
TabBar* getTabBar() const {
return tabBar_;
}
QStackedWidget* getStackedWidget() const {
return stackedWidget_;
}
private:
QWidget* topBar_;
TabBar* tabBar_;
QStackedWidget* stackedWidget_;
};
//======================================================================
class TabPage;
class Settings;
class MainWindow : public QMainWindow {
Q_OBJECT
public:
MainWindow(Fm::FilePath path = Fm::FilePath());
virtual ~MainWindow();
void chdir(Fm::FilePath path, ViewFrame* viewFrame);
void chdir(Fm::FilePath path) {
chdir(path, activeViewFrame_);
}
int addTab(Fm::FilePath path, ViewFrame* viewFrame);
int addTab(Fm::FilePath path) {
return addTab(path, activeViewFrame_);
}
TabPage* currentPage(ViewFrame* viewFrame) {
return reinterpret_cast<TabPage*>(viewFrame->getStackedWidget()->currentWidget());
}
TabPage* currentPage() {
return currentPage(activeViewFrame_);
}
void updateFromSettings(Settings& settings);
static MainWindow* lastActive() {
return lastActive_;
}
protected Q_SLOTS:
void onPathEntryReturnPressed();
void onPathBarChdir(const Fm::FilePath& dirPath);
void onPathBarMiddleClickChdir(const Fm::FilePath &dirPath);
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_actionBulkRename_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_actionConnectToServer_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_actionSplitView_triggered(bool check);
void on_actionPreserveView_triggered(bool checked);
void on_actionByFileName_triggered(bool checked);
void on_actionByMTime_triggered(bool checked);
void on_actionByOwner_triggered(bool checked);
void on_actionByGroup_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_actionUnfilter_triggered();
void on_actionShowFilter_triggered();
void on_actionLocationBar_triggered(bool checked);
void on_actionPathButtons_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_actionCopyFullPath_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 onShortcutPrevTab();
void onShortcutNextTab();
void onShortcutJumpToTab();
void onStackedWidgetWidgetRemoved(int index);
void onTabPageTitleChanged(QString title);
void onTabPageStatusChanged(int type, QString statusText);
void onTabPageOpenDirRequested(const Fm::FilePath &path, int target);
void onTabPageSortFilterChanged();
void onSidePaneChdirRequested(int type, const Fm::FilePath &path);
void onSidePaneOpenFolderInNewWindowRequested(const Fm::FilePath &path);
void onSidePaneOpenFolderInNewTabRequested(const Fm::FilePath &path);
void onSidePaneOpenFolderInTerminalRequested(const Fm::FilePath &path);
void onSidePaneCreateNewFolderRequested(const Fm::FilePath &path);
void onSidePaneModeChanged(Fm::SidePane::Mode mode);
void onSplitterMoved(int pos, int index);
void onResetFocus();
void onBackForwardContextMenu(QPoint pos);
void onFolderUnmounted();
void tabContextMenu(const QPoint& pos);
void onTabBarClicked(int index);
void closeLeftTabs();
void closeRightTabs();
void closeOtherTabs() {
closeLeftTabs();
closeRightTabs();
}
void focusPathEntry();
void toggleMenuBar(bool checked);
void detachTab();
void onBookmarksChanged();
void onSettingHiddenPlace(const QString& str, bool hide);
protected:
bool event(QEvent* event) override;
void changeEvent(QEvent* event) override;
void closeTab(int index, ViewFrame* viewFrame);
void closeTab(int index) {
closeTab(index, activeViewFrame_);
}
virtual void resizeEvent(QResizeEvent* event) override;
virtual void closeEvent(QCloseEvent* event) override;
virtual void dragEnterEvent(QDragEnterEvent* event) override;
virtual void dropEvent(QDropEvent* event) override;
virtual bool eventFilter(QObject* watched, QEvent* event);
private:
void loadBookmarksMenu();
void updateUIForCurrentPage(bool setFocus = true);
void updateViewMenuForCurrentPage();
void updateEditSelectedActions();
void updateStatusBarForCurrentPage();
void setRTLIcons(bool isRTL);
void createPathBar(bool usePathButtons);
void addViewFrame(const Fm::FilePath& path);
ViewFrame* viewFrameForTabPage(TabPage* page);
int addTabWithPage(TabPage* page, ViewFrame* viewFrame, Fm::FilePath path = Fm::FilePath());
void dropTab();
private:
Ui::MainWindow ui;
Fm::PathEdit* pathEntry_;
Fm::PathBar* pathBar_;
QLabel* fsInfoLabel_;
std::shared_ptr<Fm::Bookmarks> bookmarks_;
Launcher fileLauncher_;
int rightClickIndex_;
bool updatingViewMenu_;
QAction* menuSep_;
QAction* menuSpacer_;
ViewFrame* activeViewFrame_;
// The split mode of this window is changed only from its settings,
// not from another window. So, we get the mode at the start and keep it.
bool splitView_;
static MainWindow* lastActive_;
};
}
#endif // FM_MAIN_WINDOW_H

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

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

@ -1,10 +0,0 @@
[Desktop Entry]
Type=Application
Name=PCManFM-Qt 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

@ -1,14 +0,0 @@
#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/lxqt/pcmanfm-qt/issues/168
qunsetenv("QT_NO_GLIB");
PCManFM::Application app(argc, argv);
app.setAttribute(Qt::AA_UseHighDpiPixmaps, true);
app.init();
return app.exec();
}

@ -1,983 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>PreferencesDialog</class>
<widget class="QDialog" name="PreferencesDialog">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>685</width>
<height>440</height>
</rect>
</property>
<property name="windowTitle">
<string>Preferences</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<layout class="QHBoxLayout" name="horizontalLayout" stretch="0,0">
<item>
<widget class="QListWidget" name="listWidget">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Expanding">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="horizontalScrollBarPolicy">
<enum>Qt::ScrollBarAlwaysOff</enum>
</property>
<property name="currentRow">
<number>0</number>
</property>
<item>
<property name="text">
<string>Behavior</string>
</property>
</item>
<item>
<property name="text">
<string>Display</string>
</property>
</item>
<item>
<property name="text">
<string>User Interface</string>
</property>
</item>
<item>
<property name="text">
<string>Thumbnail</string>
</property>
</item>
<item>
<property name="text">
<string>Volume</string>
</property>
</item>
<item>
<property name="text">
<string>Advanced</string>
</property>
</item>
</widget>
</item>
<item>
<widget class="QStackedWidget" name="stackedWidget">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="currentIndex">
<number>0</number>
</property>
<widget class="QWidget" name="behaviorPage">
<layout class="QVBoxLayout" name="verticalLayout_3" stretch="0,0,1">
<item>
<widget class="QGroupBox" name="groupBox_4">
<property name="title">
<string>Browsing</string>
</property>
<layout class="QFormLayout" name="formLayout_5">
<property name="fieldGrowthPolicy">
<enum>QFormLayout::AllNonFixedFieldsGrow</enum>
</property>
<item row="0" column="0" colspan="2">
<widget class="QCheckBox" name="singleClick">
<property name="text">
<string>Open files with single click</string>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QLabel" name="label">
<property name="enabled">
<bool>false</bool>
</property>
<property name="text">
<string>Delay of auto-selection in single click mode (0 to disable)</string>
</property>
</widget>
</item>
<item row="3" column="0">
<widget class="QLabel" name="label_11">
<property name="text">
<string>Default view mode:</string>
</property>
</widget>
</item>
<item row="3" column="1">
<widget class="QComboBox" name="viewMode"/>
</item>
<item row="1" column="1">
<widget class="QDoubleSpinBox" name="autoSelectionDelay">
<property name="enabled">
<bool>false</bool>
</property>
<property name="suffix">
<string> sec</string>
</property>
<property name="singleStep">
<double>0.100000000000000</double>
</property>
</widget>
</item>
<item row="2" column="0">
<widget class="QLabel" name="label_2">
<property name="text">
<string>Bookmarks:</string>
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="QComboBox" name="bookmarkOpenMethod">
<item>
<property name="text">
<string>Open in current tab</string>
</property>
</item>
<item>
<property name="text">
<string>Open in new tab</string>
</property>
</item>
<item>
<property name="text">
<string>Open in new window</string>
</property>
</item>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QGroupBox" name="groupBox_6">
<property name="title">
<string>File Operations</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout_9">
<item>
<widget class="QCheckBox" name="configmDelete">
<property name="text">
<string>Confirm before deleting files</string>
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="useTrash">
<property name="text">
<string>Move deleted files to &quot;trash bin&quot; instead of erasing from disk.</string>
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="noUsbTrash">
<property name="text">
<string>Erase files on removable media instead of &quot;trash can&quot; creation</string>
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="confirmTrash">
<property name="text">
<string>Confirm before moving files into &quot;trash can&quot;</string>
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="quickExec">
<property name="toolTip">
<string>Requires application restart to take effect completely</string>
</property>
<property name="text">
<string>Launch executable files without prompt</string>
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="selectNewFiles">
<property name="text">
<string>Select newly created files</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>0</width>
<height>0</height>
</size>
</property>
</spacer>
</item>
</layout>
</widget>
<widget class="QWidget" name="displayPage">
<layout class="QVBoxLayout" name="verticalLayout_7" stretch="0,0,1">
<item>
<widget class="QGroupBox" name="groupBox_2">
<property name="title">
<string>Icons</string>
</property>
<layout class="QFormLayout" name="formLayout_2">
<item row="0" column="0">
<widget class="QLabel" name="iconThemeLabel">
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>Icon theme:</string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QComboBox" name="iconTheme">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QLabel" name="label_6">
<property name="toolTip">
<string>Used by Icon View</string>
</property>
<property name="text">
<string>Size of big icons:</string>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QComboBox" name="bigIconSize">
<property name="toolTip">
<string>Used by Icon View</string>
</property>
</widget>
</item>
<item row="2" column="0">
<widget class="QLabel" name="label_7">
<property name="toolTip">
<string>Used by Compact View and Detailed List View</string>
</property>
<property name="text">
<string>Size of small icons:</string>
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="QComboBox" name="smallIconSize">
<property name="toolTip">
<string>Used by Compact View and Detailed List View</string>
</property>
</widget>
</item>
<item row="3" column="0">
<widget class="QLabel" name="label_8">
<property name="toolTip">
<string>Used by Thumbnail View</string>
</property>
<property name="text">
<string>Size of thumbnails:</string>
</property>
</widget>
</item>
<item row="3" column="1">
<widget class="QComboBox" name="thumbnailIconSize">
<property name="toolTip">
<string>Used by Thumbnail View</string>
</property>
</widget>
</item>
<item row="4" column="0">
<widget class="QLabel" name="label_9">
<property name="text">
<string>Size of side pane icons:</string>
</property>
</widget>
</item>
<item row="4" column="1">
<widget class="QComboBox" name="sidePaneIconSize"/>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QGroupBox" name="groupBox_9">
<property name="title">
<string>User interface</string>
</property>
<layout class="QGridLayout" name="gridLayout">
<item row="0" column="0" colspan="6">
<widget class="QCheckBox" name="siUnit">
<property name="text">
<string>Use SI decimal prefixes instead of IEC binary prefixes</string>
</property>
</widget>
</item>
<item row="1" column="0" colspan="6">
<widget class="QCheckBox" name="backupAsHidden">
<property name="text">
<string>Treat backup files as hidden</string>
</property>
</widget>
</item>
<item row="2" column="0" colspan="6">
<widget class="QCheckBox" name="showFullNames">
<property name="toolTip">
<string>Requires application restart to take effect completely</string>
</property>
<property name="text">
<string>Always show full file names</string>
</property>
</widget>
</item>
<item row="3" column="0" colspan="6">
<widget class="QCheckBox" name="shadowHidden">
<property name="toolTip">
<string>Requires application restart to take effect completely</string>
</property>
<property name="text">
<string>Show icons of hidden files shadowed</string>
</property>
</widget>
</item>
<item row="4" column="0">
<spacer name="verticalSpacer_7">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeType">
<enum>QSizePolicy::Fixed</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>5</height>
</size>
</property>
</spacer>
</item>
<item row="5" column="0">
<widget class="QLabel" name="label_15">
<property name="text">
<string>Minimum item margins in icon view:</string>
</property>
</widget>
</item>
<item row="5" 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="5" column="2">
<widget class="QLabel" name="label_16">
<property name="text">
<string>x</string>
</property>
</widget>
</item>
<item row="5" column="3">
<widget class="QSpinBox" name="vMargin">
<property name="toolTip">
<string>3 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>3</number>
</property>
</widget>
</item>
<item row="5" column="4">
<widget class="QCheckBox" name="lockMargins">
<property name="text">
<string>Lock</string>
</property>
</widget>
</item>
<item row="5" 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_5">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>0</width>
<height>0</height>
</size>
</property>
</spacer>
</item>
</layout>
</widget>
<widget class="QWidget" name="uiPage">
<layout class="QVBoxLayout" name="verticalLayout_5" stretch="0,0,1">
<item>
<widget class="QGroupBox" name="groupBox_5">
<property name="title">
<string>Window</string>
</property>
<layout class="QFormLayout" name="formLayout_7">
<property name="fieldGrowthPolicy">
<enum>QFormLayout::ExpandingFieldsGrow</enum>
</property>
<item row="0" column="0" colspan="2">
<widget class="QCheckBox" name="alwaysShowTabs">
<property name="toolTip">
<string>When unchecked, the tab bar will be shown
only if there are more than one tab.</string>
</property>
<property name="text">
<string>Always show the tab bar</string>
</property>
</widget>
</item>
<item row="1" column="0" colspan="2">
<widget class="QCheckBox" name="showTabClose">
<property name="text">
<string>Show 'Close' buttons on tabs </string>
</property>
</widget>
</item>
<item row="2" column="0" colspan="2">
<widget class="QCheckBox" name="rememberWindowSize">
<property name="text">
<string>Remember the size of the last closed window</string>
</property>
</widget>
</item>
<item row="3" column="0">
<widget class="QLabel" name="label_12">
<property name="text">
<string>Default width of new windows:</string>
</property>
</widget>
</item>
<item row="3" column="1">
<widget class="QSpinBox" name="fixedWindowWidth">
<property name="maximum">
<number>32768</number>
</property>
</widget>
</item>
<item row="4" column="0">
<widget class="QLabel" name="label_13">
<property name="text">
<string>Default height of new windows:</string>
</property>
</widget>
</item>
<item row="4" column="1">
<widget class="QSpinBox" name="fixedWindowHeight">
<property name="maximum">
<number>32768</number>
</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>0</width>
<height>0</height>
</size>
</property>
</spacer>
</item>
</layout>
</widget>
<widget class="QWidget" name="thumbnailPage">
<layout class="QVBoxLayout" name="verticalLayout_11">
<item>
<widget class="QGroupBox" name="groupBox_8">
<property name="title">
<string>Thumbnail</string>
</property>
<layout class="QFormLayout" name="formLayout_3">
<item row="2" column="0">
<widget class="QLabel" name="label_10">
<property name="text">
<string>Do not generate thumbnails for image files exceeding this size:</string>
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="QSpinBox" name="maxThumbnailFileSize">
<property name="suffix">
<string> KB</string>
</property>
<property name="maximum">
<number>1048576</number>
</property>
</widget>
</item>
<item row="1" column="0" colspan="2">
<widget class="QCheckBox" name="thumbnailLocal">
<property name="text">
<string>Only show thumbnails for local files</string>
</property>
</widget>
</item>
<item row="0" column="0" colspan="2">
<widget class="QCheckBox" name="showThumbnails">
<property name="toolTip">
<string>Needs ffmpegthumbnailer</string>
</property>
<property name="text">
<string>Show thumbnails of files</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<spacer name="verticalSpacer_6">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>0</width>
<height>225</height>
</size>
</property>
</spacer>
</item>
</layout>
</widget>
<widget class="QWidget" name="volumePage">
<layout class="QVBoxLayout" name="verticalLayout_4" stretch="0,0,1">
<item>
<widget class="QGroupBox" name="groupBox_3">
<property name="title">
<string>Auto Mount</string>
</property>
<layout class="QFormLayout" name="formLayout_4">
<item row="0" column="0">
<widget class="QCheckBox" name="mountOnStartup">
<property name="text">
<string>Mount mountable volumes automatically on program startup</string>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QCheckBox" name="mountRemovable">
<property name="text">
<string>Mount removable media automatically when they are inserted</string>
</property>
</widget>
</item>
<item row="2" column="0">
<widget class="QCheckBox" name="autoRun">
<property name="text">
<string>Show available options for removable media when they are inserted</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QGroupBox" name="groupBox_7">
<property name="title">
<string>When removable medium unmounted:</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout_6">
<item>
<widget class="QRadioButton" name="closeOnUnmount">
<property name="text">
<string>Close &amp;tab containing removable medium</string>
</property>
</widget>
</item>
<item>
<widget class="QRadioButton" name="goHomeOnUnmount">
<property name="text">
<string>Chan&amp;ge folder in the tab to home folder</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>0</width>
<height>0</height>
</size>
</property>
</spacer>
</item>
</layout>
</widget>
<widget class="QWidget" name="advancedPage">
<layout class="QVBoxLayout" name="verticalLayout_2" stretch="0,0,1">
<item>
<widget class="QGroupBox" name="groupBox">
<property name="title">
<string>Programs</string>
</property>
<layout class="QFormLayout" name="formLayout">
<property name="fieldGrowthPolicy">
<enum>QFormLayout::AllNonFixedFieldsGrow</enum>
</property>
<item row="0" column="0">
<widget class="QLabel" name="label_14">
<property name="text">
<string>Terminal emulator:</string>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QLabel" name="label_3">
<property name="text">
<string>Switch &amp;user command:</string>
</property>
<property name="buddy">
<cstring>suCommand</cstring>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QLineEdit" name="suCommand"/>
</item>
<item row="2" column="0" colspan="2">
<widget class="QLabel" name="label_4">
<property name="text">
<string>Examples: &quot;xterm -e %s&quot; for terminal or &quot;gksu %s&quot; for switching user.
%s = the command line you want to execute with terminal or su.</string>
</property>
<property name="textFormat">
<enum>Qt::PlainText</enum>
</property>
</widget>
</item>
<item row="3" column="0">
<widget class="QLabel" name="label_5">
<property name="text">
<string>Archiver in&amp;tegration:</string>
</property>
<property name="buddy">
<cstring>archiver</cstring>
</property>
</widget>
</item>
<item row="3" column="1">
<widget class="QComboBox" name="archiver"/>
</item>
<item row="0" column="1">
<widget class="QComboBox" name="terminal">
<property name="editable">
<bool>true</bool>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QGroupBox" name="groupBox_11">
<property name="title">
<string>Templates</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout_12">
<item>
<widget class="QCheckBox" name="onlyUserTemplates">
<property name="text">
<string>Show only user defined templates in menu</string>
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="templateTypeOnce">
<property name="text">
<string>Show only one template for each MIME type</string>
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="templateRunApp">
<property name="text">
<string>Run default application after creation from template</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>0</width>
<height>0</height>
</size>
</property>
</spacer>
</item>
</layout>
</widget>
</widget>
</item>
</layout>
</item>
<item>
<widget class="QLabel" name="warningLabel">
<property name="styleSheet">
<string notr="true">background-color:#7d0000; color:white; font-weight:bold; border-radius:3px; margin:2px; padding:5px;</string>
</property>
<property name="lineWidth">
<number>0</number>
</property>
<property name="text">
<string>Application restart is needed for changes to take effect.</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</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>
<tabstops>
<tabstop>listWidget</tabstop>
<tabstop>alwaysShowTabs</tabstop>
<tabstop>showTabClose</tabstop>
<tabstop>rememberWindowSize</tabstop>
<tabstop>fixedWindowWidth</tabstop>
<tabstop>fixedWindowHeight</tabstop>
<tabstop>singleClick</tabstop>
<tabstop>autoSelectionDelay</tabstop>
<tabstop>viewMode</tabstop>
<tabstop>configmDelete</tabstop>
<tabstop>useTrash</tabstop>
<tabstop>mountOnStartup</tabstop>
<tabstop>mountRemovable</tabstop>
<tabstop>autoRun</tabstop>
<tabstop>closeOnUnmount</tabstop>
<tabstop>goHomeOnUnmount</tabstop>
<tabstop>terminal</tabstop>
<tabstop>suCommand</tabstop>
<tabstop>archiver</tabstop>
</tabstops>
<resources/>
<connections>
<connection>
<sender>buttonBox</sender>
<signal>accepted()</signal>
<receiver>PreferencesDialog</receiver>
<slot>accept()</slot>
<hints>
<hint type="sourcelabel">
<x>261</x>
<y>487</y>
</hint>
<hint type="destinationlabel">
<x>157</x>
<y>274</y>
</hint>
</hints>
</connection>
<connection>
<sender>buttonBox</sender>
<signal>rejected()</signal>
<receiver>PreferencesDialog</receiver>
<slot>reject()</slot>
<hints>
<hint type="sourcelabel">
<x>329</x>
<y>487</y>
</hint>
<hint type="destinationlabel">
<x>286</x>
<y>274</y>
</hint>
</hints>
</connection>
<connection>
<sender>listWidget</sender>
<signal>currentRowChanged(int)</signal>
<receiver>stackedWidget</receiver>
<slot>setCurrentIndex(int)</slot>
<hints>
<hint type="sourcelabel">
<x>94</x>
<y>157</y>
</hint>
<hint type="destinationlabel">
<x>359</x>
<y>145</y>
</hint>
</hints>
</connection>
<connection>
<sender>singleClick</sender>
<signal>toggled(bool)</signal>
<receiver>label</receiver>
<slot>setEnabled(bool)</slot>
<hints>
<hint type="sourcelabel">
<x>237</x>
<y>39</y>
</hint>
<hint type="destinationlabel">
<x>237</x>
<y>39</y>
</hint>
</hints>
</connection>
<connection>
<sender>rememberWindowSize</sender>
<signal>toggled(bool)</signal>
<receiver>fixedWindowWidth</receiver>
<slot>setDisabled(bool)</slot>
<hints>
<hint type="sourcelabel">
<x>506</x>
<y>351</y>
</hint>
<hint type="destinationlabel">
<x>462</x>
<y>386</y>
</hint>
</hints>
</connection>
<connection>
<sender>singleClick</sender>
<signal>toggled(bool)</signal>
<receiver>autoSelectionDelay</receiver>
<slot>setEnabled(bool)</slot>
<hints>
<hint type="sourcelabel">
<x>237</x>
<y>39</y>
</hint>
<hint type="destinationlabel">
<x>237</x>
<y>39</y>
</hint>
</hints>
</connection>
<connection>
<sender>rememberWindowSize</sender>
<signal>toggled(bool)</signal>
<receiver>fixedWindowHeight</receiver>
<slot>setDisabled(bool)</slot>
<hints>
<hint type="sourcelabel">
<x>549</x>
<y>351</y>
</hint>
<hint type="destinationlabel">
<x>462</x>
<y>421</y>
</hint>
</hints>
</connection>
<connection>
<sender>rememberWindowSize</sender>
<signal>toggled(bool)</signal>
<receiver>label_12</receiver>
<slot>setDisabled(bool)</slot>
<hints>
<hint type="sourcelabel">
<x>211</x>
<y>342</y>
</hint>
<hint type="destinationlabel">
<x>211</x>
<y>374</y>
</hint>
</hints>
</connection>
<connection>
<sender>rememberWindowSize</sender>
<signal>toggled(bool)</signal>
<receiver>label_13</receiver>
<slot>setDisabled(bool)</slot>
<hints>
<hint type="sourcelabel">
<x>183</x>
<y>338</y>
</hint>
<hint type="destinationlabel">
<x>187</x>
<y>404</y>
</hint>
</hints>
</connection>
</connections>
</ui>

@ -1,416 +0,0 @@
/*
Copyright (C) 2013 Hong Jen Yee (PCMan) <pcman.tw@gmail.com>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#include "preferencesdialog.h"
#include "application.h"
#include "settings.h"
#include <QDir>
#include <QHash>
#include <QStringBuilder>
#include <QSettings>
#include <libfm-qt/folderview.h>
#include <libfm-qt/core/terminal.h>
#include <libfm-qt/core/archiver.h>
namespace PCManFM {
PreferencesDialog::PreferencesDialog(QString activePage, QWidget* parent):
QDialog(parent) {
ui.setupUi(this);
setAttribute(Qt::WA_DeleteOnClose);
warningCounter_ = 0;
ui.warningLabel->hide();
// 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);
const QStringList subDirs = dir.entryList(QDir::AllDirs);
GKeyFile* kf = g_key_file_new();
for(const QString& subDir : subDirs) {
QString indexFile = dirName % '/' % subDir % "/index.theme";
if(g_key_file_load_from_file(kf, indexFile.toLocal8Bit().constData(), GKeyFileFlags(0), nullptr)) {
// FIXME: skip hidden ones
// 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", nullptr)) {
char* dispName = g_key_file_get_locale_string(kf, "Icon Theme", "Name", nullptr, nullptr);
// char* comment = g_key_file_get_locale_string(kf, "Icon Theme", "Comment", nullptr, nullptr);
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.constBegin(); it != iconThemes.constEnd(); ++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) {
auto& allArchivers = Fm::Archiver::allArchivers();
for(int i = 0; i < int(allArchivers.size()); ++i) {
auto& archiver = allArchivers[i];
ui.archiver->addItem(archiver->program(), QString(archiver->program()));
if(archiver->program() == settings.archiver()) {
ui.archiver->setCurrentIndex(i);
}
}
}
void PreferencesDialog::initDisplayPage(Settings& settings) {
initIconThemes(settings);
// icon sizes
int i = 0;
for (const auto & size : Settings::iconSizes(Settings::Big)) {
ui.bigIconSize->addItem(QString("%1 x %1").arg(size), size);
if(settings.bigIconSize() == size) {
ui.bigIconSize->setCurrentIndex(i);
}
++i;
}
i = 0;
for (const auto & size : Settings::iconSizes(Settings::Small)) {
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);
}
++i;
}
i = 0;
for (const auto & size : Settings::iconSizes(Settings::Thumbnail)) {
ui.thumbnailIconSize->addItem(QString("%1 x %1").arg(size), size);
if(settings.thumbnailIconSize() == size) {
ui.thumbnailIconSize->setCurrentIndex(i);
}
++i;
}
ui.siUnit->setChecked(settings.siUnit());
ui.backupAsHidden->setChecked(settings.backupAsHidden());
ui.showFullNames->setChecked(settings.showFullNames());
ui.shadowHidden->setChecked(settings.shadowHidden());
// app restart warning
connect(ui.showFullNames, &QAbstractButton::toggled, [this, &settings] (bool checked) {
restartWarning(settings.showFullNames() != checked);
});
connect(ui.shadowHidden, &QAbstractButton::toggled, [this, &settings] (bool checked) {
restartWarning(settings.shadowHidden() != checked);
});
}
void PreferencesDialog::initUiPage(Settings& settings) {
ui.alwaysShowTabs->setChecked(settings.alwaysShowTabs());
ui.showTabClose->setChecked(settings.showTabClose());
ui.rememberWindowSize->setChecked(settings.rememberWindowSize());
ui.fixedWindowWidth->setValue(settings.fixedWindowWidth());
ui.fixedWindowHeight->setValue(settings.fixedWindowHeight());
}
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 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(std::size_t 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());
ui.selectNewFiles->setChecked(settings.selectNewFiles());
// app restart warning
connect(ui.quickExec, &QAbstractButton::toggled, [this, &settings] (bool checked) {
restartWarning(settings.quickExec() != checked);
});
}
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
for(auto& terminal: Fm::allKnownTerminals()) {
ui.terminal->addItem(terminal.get());
}
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
const auto widgets = QApplication::allWidgets();
for(QWidget* widget : widgets) {
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.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());
settings.setSelectNewFiles(ui.selectNewFiles->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);
}
}
void PreferencesDialog::restartWarning(bool warn) {
if(warn) {
++warningCounter_;
}
else {
--warningCounter_;
}
ui.warningLabel->setVisible(warningCounter_ > 0);
}
} // namespace PCManFM

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

@ -1,792 +0,0 @@
/*
Copyright (C) 2013 Hong Jen Yee (PCMan) <pcman.tw@gmail.com>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#include "settings.h"
#include <QDir>
#include <QFile>
#include <QStringBuilder>
#include <QSettings>
#include <QApplication>
#include "desktopwindow.h"
#include <libfm-qt/utilities.h>
#include <libfm-qt/core/folderconfig.h>
#include <libfm-qt/core/terminal.h>
#include <QStandardPaths>
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_(),
lastSlide_(),
wallpaperDir_(),
slideShowInterval_(0),
wallpaperRandomize_(false),
desktopBgColor_(),
desktopFgColor_(),
desktopShadowColor_(),
desktopIconSize_(48),
showWmMenu_(false),
desktopShowHidden_(false),
desktopHideItems_(false),
desktopSortOrder_(Qt::AscendingOrder),
desktopSortColumn_(Fm::FolderModel::ColumnFileMTime),
desktopSortFolderFirst_(true),
alwaysShowTabs_(true),
showTabClose_(true),
rememberWindowSize_(true),
fixedWindowWidth_(640),
fixedWindowHeight_(480),
lastWindowWidth_(640),
lastWindowHeight_(480),
lastWindowMaximized_(false),
splitterPos_(120),
sidePaneMode_(Fm::SidePane::ModePlaces),
showMenuBar_(true),
splitView_(false),
viewMode_(Fm::FolderView::IconMode),
showHidden_(false),
sortOrder_(Qt::AscendingOrder),
sortColumn_(Fm::FolderModel::ColumnFileName),
sortFolderFirst_(true),
sortCaseSensitive_(false),
showFilter_(false),
pathBarButtons_(true),
// settings for use with libfm
singleClick_(false),
autoSelectionDelay_(600),
useTrash_(true),
confirmDelete_(true),
noUsbTrash_(false),
confirmTrash_(false),
quickExec_(false),
selectNewFiles_(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)),
searchNameCaseInsensitive_(false),
searchContentCaseInsensitive_(false),
searchNameRegexp_(true),
searchContentRegexp_(true),
searchRecursive_(false),
searchhHidden_(false) {
}
Settings::~Settings() {
}
QString Settings::xdgUserConfigDir() {
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() != 0) { // non-root user
dirName = QStandardPaths::writableLocation(QStandardPaths::ConfigLocation);
}
if(dirName.isEmpty()) {
dirName = QDir::homePath() % QLatin1String("/.config");
}
return dirName;
}
QString Settings::profileDir(QString profile, bool useFallback) {
// try user-specific config file first
QString dirName = xdgUserConfigDir();
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_ = "oxygen"; // 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());
selectNewFiles_ = settings.value("SelectNewFiles", false).toBool();
// bool thumbnailLocal_;
// bool thumbnailMax;
settings.endGroup();
settings.beginGroup("Desktop");
wallpaperMode_ = wallpaperModeFromString(settings.value("WallpaperMode").toString());
wallpaper_ = settings.value("Wallpaper").toString();
lastSlide_ = settings.value("LastSlide").toString();
wallpaperDir_ = settings.value("WallpaperDirectory").toString();
slideShowInterval_ = settings.value("SlideShowInterval", 0).toInt();
wallpaperRandomize_ = settings.value("WallpaperRandomize").toBool();
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();
}
desktopIconSize_ = settings.value("DesktopIconSize", 48).toInt();
desktopShortcuts_ = settings.value("DesktopShortcuts").toStringList();
showWmMenu_ = settings.value("ShowWmMenu", false).toBool();
desktopShowHidden_ = settings.value("ShowHidden", false).toBool();
desktopHideItems_ = settings.value("HideItems", false).toBool();
desktopSortOrder_ = sortOrderFromString(settings.value("SortOrder").toString());
desktopSortColumn_ = sortColumnFromString(settings.value("SortColumn").toString());
desktopSortFolderFirst_ = settings.value("SortFolderFirst", true).toBool();
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();
sortCaseSensitive_ = settings.value("SortCaseSensitive", false).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_ = toIconSize(settings.value("BigIconSize", 48).toInt(), Big);
smallIconSize_ = toIconSize(settings.value("SmallIconSize", 24).toInt(), Small);
sidePaneIconSize_ = toIconSize(settings.value("SidePaneIconSize", 24).toInt(), Small);
thumbnailIconSize_ = toIconSize(settings.value("ThumbnailIconSize", 128).toInt(), Thumbnail);
folderViewCellMargins_ = (settings.value("FolderViewCellMargins", QSize(3, 3)).toSize()
.expandedTo(QSize(0, 0))).boundedTo(QSize(48, 48));
// detailed list columns
customColumnWidths_ = settings.value("CustomColumnWidths").toList();
hiddenColumns_ = settings.value("HiddenColumns").toList();
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();
hiddenPlaces_ = settings.value("HiddenPlaces").toStringList().toSet();
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();
splitView_ = settings.value("SplitView", false).toBool();
pathBarButtons_ = settings.value("PathBarButtons", true).toBool();
settings.endGroup();
settings.beginGroup("Search");
searchNameCaseInsensitive_ = settings.value("searchNameCaseInsensitive", false).toBool();
searchContentCaseInsensitive_ = settings.value("searchContentCaseInsensitive", false).toBool();
searchNameRegexp_ = settings.value("searchNameRegexp", true).toBool();
searchContentRegexp_ = settings.value("searchContentRegexp", true).toBool();
searchRecursive_ = settings.value("searchRecursive", false).toBool();
searchhHidden_ = settings.value("searchhHidden", false).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_);
settings.setValue("SelectNewFiles", selectNewFiles_);
// bool thumbnailLocal_;
// bool thumbnailMax;
settings.endGroup();
settings.beginGroup("Desktop");
settings.setValue("WallpaperMode", wallpaperModeToString(wallpaperMode_));
settings.setValue("Wallpaper", wallpaper_);
settings.setValue("LastSlide", lastSlide_);
settings.setValue("WallpaperDirectory", wallpaperDir_);
settings.setValue("SlideShowInterval", slideShowInterval_);
settings.setValue("WallpaperRandomize", wallpaperRandomize_);
settings.setValue("BgColor", desktopBgColor_.name());
settings.setValue("FgColor", desktopFgColor_.name());
settings.setValue("ShadowColor", desktopShadowColor_.name());
settings.setValue("Font", desktopFont_.toString());
settings.setValue("DesktopIconSize", desktopIconSize_);
settings.setValue("DesktopShortcuts", desktopShortcuts_);
settings.setValue("ShowWmMenu", showWmMenu_);
settings.setValue("ShowHidden", desktopShowHidden_);
settings.setValue("HideItems", desktopHideItems_);
settings.setValue("SortOrder", sortOrderToString(desktopSortOrder_));
settings.setValue("SortColumn", sortColumnToString(desktopSortColumn_));
settings.setValue("SortFolderFirst", desktopSortFolderFirst_);
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("SortCaseSensitive", sortCaseSensitive_);
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_);
// detailed list columns
settings.setValue("CustomColumnWidths", customColumnWidths_);
std::sort(hiddenColumns_.begin(), hiddenColumns_.end());
settings.setValue("HiddenColumns", hiddenColumns_);
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_);
if (hiddenPlaces_.isEmpty()) { // don't save "@Invalid()"
settings.remove("HiddenPlaces");
}
else {
QStringList hiddenPlaces = hiddenPlaces_.toList();
settings.setValue("HiddenPlaces", hiddenPlaces);
}
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("SplitView", splitView_);
settings.setValue("PathBarButtons", pathBarButtons_);
settings.endGroup();
// save per-folder settings
Fm::FolderConfig::saveCache();
settings.beginGroup("Search");
settings.setValue("searchNameCaseInsensitive", searchNameCaseInsensitive_);
settings.setValue("searchContentCaseInsensitive", searchContentCaseInsensitive_);
settings.setValue("searchNameRegexp", searchNameRegexp_);
settings.setValue("searchContentRegexp", searchContentRegexp_);
settings.setValue("searchRecursive", searchRecursive_);
settings.setValue("searchhHidden", searchhHidden_);
settings.endGroup();
return true;
}
const QList<int> & Settings::iconSizes(IconType type) {
static const QList<int> sizes_big = {96, 72, 64, 48, 32};
static const QList<int> sizes_thumbnail = {256, 224, 192, 160, 128, 96, 64};
static const QList<int> sizes_small = {48, 32, 24, 22, 16};
switch(type) {
case Big:
return sizes_big;
break;
case Thumbnail:
return sizes_thumbnail;
break;
case Small:
default:
return sizes_small;
break;
}
}
int Settings::toIconSize(int size, IconType type) const {
const QList<int> & sizes = iconSizes(type);
for (const auto & s : sizes) {
if(size >= s) {
return s;
}
}
return sizes.back();
}
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;
case Fm::FolderModel::ColumnFileGroup:
ret = "group";
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 if(str == "group") {
ret = Fm::FolderModel::ColumnFileGroup;
}
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;
case DesktopWindow::WallpaperZoom:
ret = "zoom";
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 if(str == "zoom") {
ret = DesktopWindow::WallpaperZoom;
}
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;
Fm::setDefaultTerminal(terminal_.toStdString());
}
// per-folder settings
FolderSettings Settings::loadFolderSettings(const Fm::FilePath& path) const {
FolderSettings settings;
Fm::FolderConfig cfg(path);
// set defaults
settings.setSortOrder(sortOrder());
settings.setSortColumn(sortColumn());
settings.setViewMode(viewMode());
settings.setShowHidden(showHidden());
settings.setSortFolderFirst(sortFolderFirst());
settings.setSortCaseSensitive(sortCaseSensitive());
// columns?
if(!cfg.isEmpty()) {
// load folder-specific settings
settings.setCustomized(true);
char* str;
// load sorting
str = cfg.getString("SortOrder");
if(str != nullptr) {
settings.setSortOrder(sortOrderFromString(str));
g_free(str);
}
str = cfg.getString("SortColumn");
if(str != nullptr) {
settings.setSortColumn(sortColumnFromString(str));
g_free(str);
}
str = cfg.getString("ViewMode");
if(str != nullptr) {
// set view mode
settings.setViewMode(viewModeFromString(str));
g_free(str);
}
bool show_hidden;
if(cfg.getBoolean("ShowHidden", &show_hidden)) {
settings.setShowHidden(show_hidden);
}
bool folder_first;
if(cfg.getBoolean("SortFolderFirst", &folder_first)) {
settings.setSortFolderFirst(folder_first);
}
bool case_sensitive;
if(cfg.getBoolean("SortCaseSensitive", &case_sensitive)) {
settings.setSortCaseSensitive(case_sensitive);
}
}
return settings;
}
void Settings::saveFolderSettings(const Fm::FilePath& path, const FolderSettings& settings) {
if(path) {
// ensure that we have the libfm dir
QString dirName = xdgUserConfigDir() % QStringLiteral("/libfm");
QDir().mkpath(dirName); // if libfm config dir does not exist, create it
Fm::FolderConfig cfg(path);
cfg.setString("SortOrder", sortOrderToString(settings.sortOrder()));
cfg.setString("SortColumn", sortColumnToString(settings.sortColumn()));
cfg.setString("ViewMode", viewModeToString(settings.viewMode()));
cfg.setBoolean("ShowHidden", settings.showHidden());
cfg.setBoolean("SortFolderFirst", settings.sortFolderFirst());
cfg.setBoolean("SortCaseSensitive", settings.sortCaseSensitive());
}
}
void Settings::clearFolderSettings(const Fm::FilePath& path) const {
if(path) {
Fm::FolderConfig cfg(path);
cfg.purge();
}
}
} // namespace PCManFM

File diff suppressed because it is too large Load Diff

@ -1,96 +0,0 @@
/*
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
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 "statusbar.h"
#include <QPainter>
#include <QStyleOption>
#define MESSAGE_DELAY 250
namespace PCManFM {
Label::Label(QWidget* parent, Qt::WindowFlags f):
QLabel(parent, f),
lastWidth_(0) {
setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred);
// set a min width to prevent the window from widening with long texts
setMinimumWidth(fontMetrics().averageCharWidth() * 10);
}
// A simplified version of QLabel::paintEvent()
// without pixmap or shortcut but with eliding.
void Label::paintEvent(QPaintEvent* /*event*/) {
QRect cr = contentsRect().adjusted(margin(), margin(), -margin(), -margin());
QString txt = text();
// if the text is changed or its rect is resized (due to window resizing),
// find whether it needs to be elided...
if (txt != lastText_ || cr.width() != lastWidth_) {
lastText_ = txt;
lastWidth_ = cr.width();
elidedText_ = fontMetrics().elidedText(txt, Qt::ElideMiddle, cr.width());
}
// ... then, draw the (elided) text
if(!elidedText_.isEmpty()) {
QPainter painter(this);
QStyleOption opt;
opt.initFrom(this);
style()->drawItemText(&painter, cr, alignment(), opt.palette, isEnabled(), elidedText_, foregroundRole());
}
}
StatusBar::StatusBar(QWidget *parent):
QStatusBar(parent),
lastTimeOut_(0) {
statusLabel_ = new Label();
statusLabel_->setFrameShape(QFrame::NoFrame);
// 4px space on both sides (not to be mixed with the permanent widget)
statusLabel_->setContentsMargins(4, 0, 4, 0);
addWidget(statusLabel_);
messageTimer_ = new QTimer (this);
messageTimer_->setSingleShot(true);
messageTimer_->setInterval(MESSAGE_DELAY);
connect(messageTimer_, &QTimer::timeout, this, &StatusBar::reallyShowMessage);
}
StatusBar::~StatusBar() {
if(messageTimer_) {
messageTimer_->stop();
delete messageTimer_;
}
}
void StatusBar::showMessage(const QString &message, int timeout) {
// don't show the message immediately
lastMessage_ = message;
lastTimeOut_ = timeout;
if(!messageTimer_->isActive()) {
messageTimer_->start();
}
}
void StatusBar::reallyShowMessage() {
if(lastTimeOut_ == 0) {
// set the text on the label to prevent its disappearance on focusing menubar items
// and also ensure that it contsains no newline (because file names may contain it)
statusLabel_->setText(lastMessage_.replace(QLatin1Char('\n'), QLatin1Char(' ')));
}
else {
QStatusBar::showMessage(lastMessage_, lastTimeOut_);
}
}
}

@ -1,63 +0,0 @@
/*
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
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_STATUSBAR_H
#define FM_STATUSBAR_H
#include <QStatusBar>
#include <QLabel>
#include <QTimer>
namespace PCManFM {
class Label : public QLabel {
Q_OBJECT
public:
explicit Label(QWidget *parent = 0, Qt::WindowFlags f = Qt::WindowFlags());
protected:
void paintEvent(QPaintEvent *event) override;
private:
QString elidedText_;
QString lastText_;
int lastWidth_;
};
class StatusBar : public QStatusBar {
Q_OBJECT
public:
explicit StatusBar(QWidget *parent = 0);
~StatusBar();
public Q_SLOTS:
void showMessage(const QString &message, int timeout = 0);
protected Q_SLOTS:
void reallyShowMessage();
private:
Label* statusLabel_; // for a stable (elided) text
QTimer* messageTimer_;
QString lastMessage_;
int lastTimeOut_;
};
}
#endif // FM_STATUSBAR_H

@ -1,118 +0,0 @@
/*
Copyright (C) 2014 Kuzma Shapran <kuzma.shapran@gmail.com>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#include "tabbar.h"
#include <QPointer>
#include <QMouseEvent>
#include <QApplication>
#include <QDrag>
#include <QMimeData>
namespace PCManFM {
TabBar::TabBar(QWidget *parent):
QTabBar(parent),
dragStarted_(false),
detachable_(true)
{
}
void TabBar::mousePressEvent(QMouseEvent *event) {
QTabBar::mousePressEvent (event);
if(detachable_){
if(event->button() == Qt::LeftButton
&& tabAt(event->pos()) > -1) {
dragStartPosition_ = event->pos();
}
dragStarted_ = false;
}
}
void TabBar::mouseMoveEvent(QMouseEvent *event)
{
if(!detachable_) {
QTabBar::mouseMoveEvent(event);
return;
}
if(!dragStartPosition_.isNull()
&& (event->pos() - dragStartPosition_).manhattanLength() >= QApplication::startDragDistance()) {
dragStarted_ = true;
}
if((event->buttons() & Qt::LeftButton)
&& dragStarted_
&& !window()->geometry().contains(event->globalPos())) {
if(currentIndex() == -1) {
return;
}
QPointer<QDrag> drag = new QDrag(this);
QMimeData *mimeData = new QMimeData;
mimeData->setData("application/pcmanfm-qt-tab", QByteArray());
drag->setMimeData(mimeData);
Qt::DropAction dragged = drag->exec();
if(dragged == Qt::IgnoreAction) { // a tab is dropped outside all windows
if(count() > 1) {
Q_EMIT tabDetached();
}
else {
finishMouseMoveEvent();
}
event->accept();
}
else if(dragged == Qt::MoveAction) { // a tab is dropped into another window
event->accept();
}
drag->deleteLater();
}
else {
QTabBar::mouseMoveEvent(event);
}
}
void TabBar::finishMouseMoveEvent() {
QMouseEvent finishingEvent(QEvent::MouseMove, QPoint(), Qt::NoButton, Qt::NoButton, Qt::NoModifier);
mouseMoveEvent(&finishingEvent);
}
void TabBar::releaseMouse() {
QMouseEvent releasingEvent(QEvent::MouseButtonRelease, QPoint(), Qt::LeftButton, Qt::NoButton, Qt::NoModifier);
mouseReleaseEvent(&releasingEvent);
}
void TabBar::mouseReleaseEvent(QMouseEvent *event) {
if (event->button() == Qt::MiddleButton) {
int index = tabAt(event->pos());
if (index != -1) {
Q_EMIT tabCloseRequested(index);
}
}
QTabBar::mouseReleaseEvent(event);
}
// Let the main window receive dragged tabs!
void TabBar::dragEnterEvent(QDragEnterEvent *event) {
if(detachable_ && event->mimeData()->hasFormat("application/pcmanfm-qt-tab")) {
event->ignore();
}
}
}

@ -1,60 +0,0 @@
/*
Copyright (C) 2014 Kuzma Shapran <kuzma.shapran@gmail.com>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#ifndef FM_TABBAR_H
#define FM_TABBAR_H
#include <QTabBar>
class QMouseEvent;
namespace PCManFM {
class TabBar : public QTabBar {
Q_OBJECT
public:
explicit TabBar(QWidget *parent = 0);
void finishMouseMoveEvent();
void releaseMouse();
void setDetachable(bool detachable) {
detachable_ = detachable;
}
Q_SIGNALS:
void tabDetached();
protected:
void mouseReleaseEvent(QMouseEvent *event);
// from qtabbar.cpp
virtual void mousePressEvent(QMouseEvent *event);
virtual void mouseMoveEvent(QMouseEvent *event);
virtual void dragEnterEvent(QDragEnterEvent *event);
private:
QPoint dragStartPosition_;
bool dragStarted_;
bool detachable_;
};
}
#endif // FM_TABBAR_H

@ -1,835 +0,0 @@
/*
Copyright (C) 2013 Hong Jen Yee (PCMan) <pcman.tw@gmail.com>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#include "tabpage.h"
#include "launcher.h"
#include <libfm-qt/filemenu.h>
#include <libfm-qt/mountoperation.h>
#include <libfm-qt/proxyfoldermodel.h>
#include <libfm-qt/cachedfoldermodel.h>
#include <libfm-qt/core/fileinfo.h>
#include <libfm-qt/utilities.h>
#include <QApplication>
#include <QCursor>
#include <QMessageBox>
#include <QScrollBar>
#include <QToolButton>
#include <QLabel>
#include <QDir>
#include "settings.h"
#include "application.h"
#include <QTimer>
#include <QTextStream>
#include <QDebug>
using namespace Fm;
namespace PCManFM {
bool ProxyFilter::filterAcceptsRow(const Fm::ProxyFolderModel* model, const std::shared_ptr<const Fm::FileInfo>& info) const {
if(!model || !info) {
return true;
}
QString baseName = QString::fromStdString(info->name());
if(!filterStr_.isEmpty() && !baseName.contains(filterStr_, Qt::CaseInsensitive)) {
return false;
}
return true;
}
//==================================================
FilterEdit::FilterEdit(QWidget* parent) : QLineEdit(parent) {
setClearButtonEnabled(true);
if(QToolButton *clearButton = findChild<QToolButton*>()) {
clearButton->setToolTip(tr("Clear text (Ctrl+K)"));
}
}
void FilterEdit::keyPressEvent(QKeyEvent* event) {
// since two views can be shown in the split mode, Ctrl+K can't be
// used as a QShortcut but can come here for clearing the text
if(event->modifiers() == Qt::ControlModifier && event->key() == Qt::Key_K) {
clear();
}
QLineEdit::keyPressEvent(event);
}
void FilterEdit::keyPressed(QKeyEvent* event) {
// NOTE: Movement and delete keys should be left to the view.
// Copy/paste shortcuts are taken by the view but they aren't needed here
// (Shift+Insert works for pasting but, since most users may not be familiar
// with it, an action is added to the main window for focusing an empty bar).
if(!hasFocus()
&& event->key() != Qt::Key_Left && event->key() != Qt::Key_Right
&& event->key() != Qt::Key_Home && event->key() != Qt::Key_End
&& event->key() != Qt::Key_Delete) {
keyPressEvent(event);
}
}
FilterBar::FilterBar(QWidget* parent) : QWidget(parent) {
QHBoxLayout* HLayout = new QHBoxLayout(this);
HLayout->setSpacing(5);
filterEdit_ = new FilterEdit();
QLabel *label = new QLabel(tr("Filter:"));
HLayout->addWidget(label);
HLayout->addWidget(filterEdit_);
connect(filterEdit_, &QLineEdit::textChanged, this, &FilterBar::textChanged);
connect(filterEdit_, &FilterEdit::lostFocus, this, &FilterBar::lostFocus);
}
//==================================================
TabPage::TabPage(QWidget* parent):
QWidget(parent),
folderView_{nullptr},
folderModel_{nullptr},
proxyModel_{nullptr},
proxyFilter_{nullptr},
verticalLayout{nullptr},
overrideCursor_(false),
selectionTimer_(nullptr),
filterBar_(nullptr) {
Settings& settings = static_cast<Application*>(qApp)->settings();
// create proxy folder model to do item filtering
proxyModel_ = new ProxyFolderModel();
proxyModel_->setShowHidden(settings.showHidden());
proxyModel_->setBackupAsHidden(settings.backupAsHidden());
proxyModel_->setShowThumbnails(settings.showThumbnails());
connect(proxyModel_, &ProxyFolderModel::sortFilterChanged, this, [this] {
saveFolderSorting();
Q_EMIT sortFilterChanged();
});
verticalLayout = new QVBoxLayout(this);
verticalLayout->setContentsMargins(0, 0, 0, 0);
folderView_ = new View(settings.viewMode(), this);
folderView_->setMargins(settings.folderViewCellMargins());
folderView_->setShadowHidden(settings.shadowHidden());
// newView->setColumnWidth(Fm::FolderModel::ColumnName, 200);
connect(folderView_, &View::openDirRequested, this, &TabPage::openDirRequested);
connect(folderView_, &View::selChanged, this, &TabPage::onSelChanged);
connect(folderView_, &View::clickedBack, this, &TabPage::backwardRequested);
connect(folderView_, &View::clickedForward, this, &TabPage::forwardRequested);
// customization of columns of detailed list view
folderView_->setCustomColumnWidths(settings.getCustomColumnWidths());
folderView_->setHiddenColumns(settings.getHiddenColumns());
connect(folderView_, &View::columnResizedByUser, this, [this, &settings]() {
settings.setCustomColumnWidths(folderView_->getCustomColumnWidths());
});
connect(folderView_, &View::columnHiddenByUser, this, [this, &settings]() {
settings.setHiddenColumns(folderView_->getHiddenColumns());
});
proxyFilter_ = new ProxyFilter();
proxyModel_->addFilter(proxyFilter_);
// FIXME: this is very dirty
folderView_->setModel(proxyModel_);
verticalLayout->addWidget(folderView_);
// filter-bar and its settings
filterBar_ = new FilterBar();
verticalLayout->addWidget(filterBar_);
if(!settings.showFilter()){
transientFilterBar(true);
}
connect(filterBar_, &FilterBar::textChanged, this, &TabPage::onFilterStringChanged);
}
TabPage::~TabPage() {
freeFolder();
if(proxyFilter_) {
delete proxyFilter_;
}
if(proxyModel_) {
delete proxyModel_;
}
if(folderModel_) {
disconnect(folderModel_, &Fm::FolderModel::fileSizeChanged, this, &TabPage::onFileSizeChanged);
disconnect(folderModel_, &Fm::FolderModel::filesAdded, this, &TabPage::onFilesAdded);
folderModel_->unref();
}
if(overrideCursor_) {
QApplication::restoreOverrideCursor(); // remove busy cursor
}
}
void TabPage::transientFilterBar(bool transient) {
if(filterBar_) {
filterBar_->clear();
if(transient) {
filterBar_->hide();
folderView_->childView()->removeEventFilter(this);
folderView_->childView()->installEventFilter(this);
connect(filterBar_, &FilterBar::lostFocus, this, &TabPage::onLosingFilterBarFocus);
}
else {
filterBar_->show();
folderView_->childView()->removeEventFilter(this);
disconnect(filterBar_, &FilterBar::lostFocus, this, &TabPage::onLosingFilterBarFocus);
}
}
}
void TabPage::onLosingFilterBarFocus() {
// hide the empty transient filter-bar when it loses focus
if(getFilterStr().isEmpty()) {
filterBar_->hide();
}
}
void TabPage::showFilterBar() {
if(filterBar_) {
filterBar_->show();
if(isVisibleTo(this)) { // the page itself may be in an inactive tab
filterBar_->focusBar();
}
}
}
bool TabPage::eventFilter(QObject* watched, QEvent* event) {
// when a text is typed inside the view, type it inside the filter-bar
if(filterBar_ && watched == folderView_->childView() && event->type() == QEvent::KeyPress) {
if(QKeyEvent* ke = static_cast<QKeyEvent*>(event)) {
filterBar_->keyPressed(ke);
}
}
return QWidget::eventFilter(watched, event);
}
void TabPage::backspacePressed() {
if(filterBar_ && filterBar_->isVisible()) {
QKeyEvent bs = QKeyEvent(QEvent::KeyPress, Qt::Key_Backspace, Qt::NoModifier);
filterBar_->keyPressed(&bs);
}
}
void TabPage::onFilterStringChanged(QString str) {
if(filterBar_ && str != getFilterStr()) {
setFilterStr(str);
applyFilter();
// show/hide the transient filter-bar appropriately
if(!static_cast<Application*>(qApp)->settings().showFilter()) {
if(filterBar_->isVisibleTo(this)) { // the page itself may be in an inactive tab
if(str.isEmpty()) {
// focus the view BEFORE hiding the filter-bar to avoid redundant "FocusIn" events;
// otherwise, another widget inside the main window might gain focus immediately
// after the filter-bar is hidden and only after that, the view will be focused.
folderView()->childView()->setFocus();
filterBar_->hide();
}
}
else if(!str.isEmpty()) {
filterBar_->show();
}
}
}
}
void TabPage::freeFolder() {
if(folder_) {
if(folderSettings_.isCustomized()) {
// save custom view settings for this folder
static_cast<Application*>(qApp)->settings().saveFolderSettings(folder_->path(), folderSettings_);
}
disconnect(folder_.get(), nullptr, this, nullptr); // disconnect from all signals
folder_ = nullptr;
}
}
void TabPage::onFolderStartLoading() {
if(folderModel_){
disconnect(folderModel_, &Fm::FolderModel::filesAdded, this, &TabPage::onFilesAdded);
}
if(!overrideCursor_) {
// FIXME: sometimes FmFolder of libfm generates unpaired "start-loading" and
// "finish-loading" signals of uncertain reasons. This should be a bug in libfm.
// Until it's fixed in libfm, we need to workaround the problem here, not to
// override the cursor twice.
QApplication::setOverrideCursor(QCursor(Qt::WaitCursor));
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, nullptr);
#endif
}
void TabPage::onUiUpdated() {
// 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_ && lastFolderPath_.parent() == path()) {
QModelIndex index = folderView_->indexFromFolderPath(lastFolderPath_);
if(index.isValid()) {
folderView_->childView()->scrollTo(index, QAbstractItemView::EnsureVisible);
folderView_->childView()->setCurrentIndex(index);
}
}
if(folderModel_) {
// update selection statusbar info when needed
connect(folderModel_, &Fm::FolderModel::fileSizeChanged, this, &TabPage::onFileSizeChanged);
// get ready to select files that may be added later
connect(folderModel_, &Fm::FolderModel::filesAdded, this, &TabPage::onFilesAdded);
}
}
void TabPage::onFileSizeChanged(const QModelIndex& index) {
if(folderView_->hasSelection()) {
QModelIndexList indexes = folderView_->selectionModel()->selectedIndexes();
if(indexes.contains(proxyModel_->mapFromSource(index))) {
onSelChanged();
}
}
}
// slot
void TabPage::onFilesAdded(Fm::FileInfoList files) {
if(static_cast<Application*>(qApp)->settings().selectNewFiles()) {
if(!selectionTimer_) {
folderView_->selectFiles(files, false);
selectionTimer_ = new QTimer (this);
selectionTimer_->setSingleShot(true);
selectionTimer_->start(200);
}
else {
folderView_->selectFiles(files, selectionTimer_->isActive());
selectionTimer_->start(200);
}
}
}
void TabPage::onFolderFinishLoading() {
auto fi = folder_->info();
if(fi) { // if loading of the folder fails, it's possible that we don't have FmFileInfo.
setWindowTitle(fi->displayName());
Q_EMIT titleChanged(fi->displayName());
}
folder_->queryFilesystemInfo(); // 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) == nullptr) {
/* 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 = statusText_[StatusTextNormal];
text = formatStatusText();
Q_EMIT statusChanged(StatusTextNormal, text);
if(overrideCursor_) {
QApplication::restoreOverrideCursor(); // remove busy cursor
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.
// For example, the scrollbar ranges are not updated yet. We solve this by installing an Qt timeout handler.
QTimer::singleShot(10, this, SLOT(onUiUpdated()));
}
void TabPage::onFolderError(const Fm::GErrorPtr& err, Fm::Job::ErrorSeverity severity, Fm::Job::ErrorAction& response) {
if(err.domain() == G_IO_ERROR) {
if(err.code() == G_IO_ERROR_NOT_MOUNTED && severity < Fm::Job::ErrorSeverity::CRITICAL) {
auto& path = folder_->path();
MountOperation* op = new MountOperation(true);
op->mountEnclosingVolume(path);
if(op->wait()) { // blocking event loop, wait for mount operation to finish.
// This will reload the folder, which generates a new "start-loading"
// signal, so we get more "start-loading" signals than "finish-loading"
// 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
overrideCursor_ = false;
response = Fm::Job::ErrorAction::RETRY;
return;
}
}
}
if(severity >= Fm::Job::ErrorSeverity::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(this, tr("Error"), err.message());
}
response = Fm::Job::ErrorAction::CONTINUE;
}
void TabPage::onFolderFsInfo() {
guint64 free, total;
QString& msg = statusText_[StatusTextFSInfo];
if(folder_->getFilesystemInfo(&total, &free)) {
msg = tr("Free space: %1 (Total: %2)")
.arg(formatFileSize(free, fm_config->si_unit))
.arg(formatFileSize(total, fm_config->si_unit));
}
else {
msg.clear();
}
Q_EMIT statusChanged(StatusTextFSInfo, msg);
}
QString TabPage::formatStatusText() {
if(proxyModel_ && folder_) {
// FIXME: this is very inefficient
auto files = folder_->files();
int total_files = files.size();
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);
}
auto fi = folder_->info();
if (fi && fi->isSymlink()) {
text += QString(" %2(%1)")
.arg(encloseWithBidiMarks(tr("Link to") + QChar(QChar::Space) + QString::fromStdString(fi->target())),
(layoutDirection() == Qt::RightToLeft) ? QChar(0x200f) : QChar(0x200e));
}
return text;
}
return QString();
}
void TabPage::onFolderRemoved() {
// the folder we're showing is removed, destroy the widget
qDebug("folder removed");
Settings& settings = static_cast<Application*>(qApp)->settings();
// NOTE: call 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, this, SLOT(deleteLater()));
}
else {
chdir(Fm::FilePath::homeDir());
}
}
void TabPage::onFolderUnmount() {
// the folder we're showing is unmounted, destroy the widget
qDebug("folder unmount");
// NOTE: We cannot delete the page or change its directory here
// because unmounting might be done from places view, in which case,
// the mount operation is a child of the places view and should be
// finished before doing anything else.
freeFolder();
Q_EMIT folderUnmounted();
}
void TabPage::onFolderContentChanged() {
/* update status text */
statusText_[StatusTextNormal] = formatStatusText();
Q_EMIT statusChanged(StatusTextNormal, statusText_[StatusTextNormal]);
}
QString TabPage::pathName() {
// auto disp_path = path().displayName();
// FIXME: displayName() returns invalid path sometimes.
auto disp_path = path().toString();
return QString::fromUtf8(disp_path.get());
}
void TabPage::chdir(Fm::FilePath newPath, bool addHistory) {
// qDebug() << "TABPAGE CHDIR:" << newPath.toString().get();
if(filterBar_){
filterBar_->clear();
}
if(folder_) {
// we're already in the specified dir
if(newPath == folder_->path()) {
return;
}
// reset the status selected text
statusText_[StatusTextSelectedFiles] = QString();
// remember the previous folder path that we have browsed.
lastFolderPath_ = folder_->path();
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_) {
disconnect(folderModel_, &Fm::FolderModel::fileSizeChanged, this, &TabPage::onFileSizeChanged);
disconnect(folderModel_, &Fm::FolderModel::filesAdded, this, &TabPage::onFilesAdded);
proxyModel_->setSourceModel(nullptr);
folderModel_->unref(); // unref the cached model
folderModel_ = nullptr;
}
freeFolder();
}
Q_EMIT titleChanged(newPath.baseName().get()); // FIXME: display name
folder_ = Fm::Folder::fromPath(newPath);
if(addHistory) {
// add current path to browse history
history_.add(path());
}
connect(folder_.get(), &Fm::Folder::startLoading, this, &TabPage::onFolderStartLoading);
connect(folder_.get(), &Fm::Folder::finishLoading, this, &TabPage::onFolderFinishLoading);
// FIXME: Fm::Folder::error() is a bad design and might be removed in the future.
connect(folder_.get(), &Fm::Folder::error, this, &TabPage::onFolderError);
connect(folder_.get(), &Fm::Folder::fileSystemChanged, this, &TabPage::onFolderFsInfo);
/* destroy the page when the folder is unmounted or deleted. */
connect(folder_.get(), &Fm::Folder::removed, this, &TabPage::onFolderRemoved);
connect(folder_.get(), &Fm::Folder::unmount, this, &TabPage::onFolderUnmount);
connect(folder_.get(), &Fm::Folder::contentChanged, this, &TabPage::onFolderContentChanged);
Settings& settings = static_cast<Application*>(qApp)->settings();
folderModel_ = CachedFolderModel::modelFromFolder(folder_);
folderModel_->setShowFullName(settings.showFullNames());
// folderSettings_ will be set by saveFolderSorting() when the sort filter is changed below
// (and also by setViewMode()); here, we only need to know whether it should be saved
FolderSettings folderSettings = settings.loadFolderSettings(path());
folderSettings_.setCustomized(folderSettings.isCustomized());
// set sorting
proxyModel_->sort(folderSettings.sortColumn(), folderSettings.sortOrder());
proxyModel_->setFolderFirst(folderSettings.sortFolderFirst());
proxyModel_->setShowHidden(folderSettings.showHidden());
proxyModel_->setSortCaseSensitivity(folderSettings.sortCaseSensitive() ? Qt::CaseSensitive : Qt::CaseInsensitive);
proxyModel_->setSourceModel(folderModel_);
// set view mode
setViewMode(folderSettings.viewMode());
if(folder_->isLoaded()) {
onFolderStartLoading();
onFolderFinishLoading();
onFolderFsInfo();
}
else {
onFolderStartLoading();
}
}
void TabPage::selectAll() {
folderView_->selectAll();
}
void TabPage::invertSelection() {
folderView_->invertSelection();
}
void TabPage::reload() {
if(folder_) {
// don't select or scroll to the previous folder after reload
lastFolderPath_ = Fm::FilePath();
// but remember the current scroll position
BrowseHistoryItem& item = history_.currentItem();
QAbstractItemView* childView = folderView_->childView();
item.setScrollPos(childView->verticalScrollBar()->value());
folder_->reload();
}
}
// 200e LEFT-TO-RIGHT MARK
// 200f RIGHT-TO-LEFT MARK
// 202a LEFT-TO-RIGHT EMBEDDING
// 202b RIGHT-TO-LEFT EMBEDDING
// 202c POP DIRECTIONAL FORMATTING
QString TabPage::encloseWithBidiMarks(const QString& text) {
QChar bidiMark = text.isRightToLeft() ? QChar(0x200f) : QChar(0x200e);
QChar embedBidiMark = text.isRightToLeft() ? QChar(0x202b) : QChar(0x202a);
return embedBidiMark+text+bidiMark+QChar(0x202c);
}
// when the current selection in the folder view is changed
void TabPage::onSelChanged() {
QString msg;
if(folderView_->hasSelection()) {
auto files = folderView_->selectedFiles();
int numSel = files.size();
/* FIXME: display total size of all selected files. */
if(numSel == 1) { /* only one file is selected (also, tell if it is a symlink)*/
auto& fi = files.front();
if(!fi->isDir()) {
if(fi->isSymlink()) {
msg = QString("%5\"%1\" %5(%2) %5%3 %5(%4)")
.arg(encloseWithBidiMarks(fi->displayName()),
encloseWithBidiMarks(Fm::formatFileSize(fi->size(), fm_config->si_unit)),
encloseWithBidiMarks(fi->mimeType()->desc()),
encloseWithBidiMarks(tr("Link to") + QChar(QChar::Space) + QString::fromStdString(fi->target())),
(layoutDirection() == Qt::RightToLeft) ? QChar(0x200f) : QChar(0x200e));
}
else {
msg = QString("%4\"%1\" %4(%2) %4%3")
.arg(encloseWithBidiMarks(fi->displayName()),
encloseWithBidiMarks(Fm::formatFileSize(fi->size(), fm_config->si_unit)), // FIXME: deprecate fm_config
encloseWithBidiMarks(fi->mimeType()->desc()),
(layoutDirection() == Qt::RightToLeft) ? QChar(0x200f) : QChar(0x200e));
}
}
else {
if(fi->isSymlink()) {
msg = QString("%4\"%1\" %4%2 %4(%3)")
.arg(encloseWithBidiMarks(fi->displayName()),
encloseWithBidiMarks(fi->mimeType()->desc()),
encloseWithBidiMarks(tr("Link to") + QChar(QChar::Space) + QString::fromStdString(fi->target())),
(layoutDirection() == Qt::RightToLeft) ? QChar(0x200f) : QChar(0x200e));
}
else {
msg = QString("%3\"%1\" %3%2")
.arg(encloseWithBidiMarks(fi->displayName()),
encloseWithBidiMarks(fi->mimeType()->desc()),
(layoutDirection() == Qt::RightToLeft) ? QChar(0x200f) : QChar(0x200e));
}
}
/* FIXME: should we support statusbar plugins as in the gtk+ version? */
}
else {
goffset sum;
msg = tr("%n item(s) selected", nullptr, numSel);
/* don't count if too many files are selected, that isn't lightweight */
if(numSel < 1000) {
sum = 0;
for(auto& fi: files) {
if(fi->isDir()) {
/* 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 += fi->size();
}
if(sum >= 0) {
msg += QString(" (%1)").arg(Fm::formatFileSize(sum, fm_config->si_unit)); // FIXME: deprecate fm_config
}
/* FIXME: should we support statusbar plugins as in the gtk+ version? */
}
/* 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 && static_cast<size_t>(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() {
auto _path = path();
return (_path && _path.hasParent());
}
void TabPage::up() {
auto _path = path();
if(_path) {
auto parent = _path.parent();
if(parent) {
chdir(parent, true);
}
}
}
void TabPage::updateFromSettings(Settings& settings) {
folderView_->updateFromSettings(settings);
}
void TabPage::setViewMode(Fm::FolderView::ViewMode mode) {
Settings& settings = static_cast<Application*>(qApp)->settings();
if(folderSettings_.viewMode() != mode) {
folderSettings_.setViewMode(mode);
if(folderSettings_.isCustomized()) {
settings.saveFolderSettings(path(), folderSettings_);
}
}
Fm::FolderView::ViewMode prevMode = folderView_->viewMode();
folderView_->setViewMode(mode);
folderView_->childView()->setFocus();
if(prevMode != folderView_->viewMode()) {
// FolderView::setViewMode() may delete the view to switch between list and tree.
// So, the event filter should be re-installed and the status message should be updated.
if(!settings.showFilter()) {
folderView_->childView()->removeEventFilter(this);
folderView_->childView()->installEventFilter(this);
}
onSelChanged();
}
}
void TabPage::sort(int col, Qt::SortOrder order) {
if(proxyModel_) {
proxyModel_->sort(col, order);
}
}
void TabPage::setSortFolderFirst(bool value) {
if(proxyModel_) {
proxyModel_->setFolderFirst(value);
}
}
void TabPage::setSortCaseSensitive(bool value) {
if(proxyModel_) {
proxyModel_->setSortCaseSensitivity(value ? Qt::CaseSensitive : Qt::CaseInsensitive);
}
}
void TabPage::setShowHidden(bool showHidden) {
if(proxyModel_) {
proxyModel_->setShowHidden(showHidden);
}
}
void TabPage::saveFolderSorting() {
if (proxyModel_ == nullptr) {
return;
}
folderSettings_.setSortOrder(proxyModel_->sortOrder());
folderSettings_.setSortColumn(static_cast<Fm::FolderModel::ColumnId>(proxyModel_->sortColumn()));
folderSettings_.setSortFolderFirst(proxyModel_->folderFirst());
folderSettings_.setSortCaseSensitive(proxyModel_->sortCaseSensitivity());
if(folderSettings_.showHidden() != proxyModel_->showHidden()) {
folderSettings_.setShowHidden(proxyModel_->showHidden());
statusText_[StatusTextNormal] = formatStatusText();
Q_EMIT statusChanged(StatusTextNormal, statusText_[StatusTextNormal]);
}
if(folderSettings_.isCustomized()) {
static_cast<Application*>(qApp)->settings().saveFolderSettings(path(), folderSettings_);
}
}
void TabPage::applyFilter() {
if(proxyModel_ == nullptr) {
return;
}
int prevSelSize = folderView_->selectionModel()->selectedIndexes().size();
proxyModel_->updateFilters();
// if some selected files are filtered out, "View::selChanged()" won't be emitted
if(prevSelSize > folderView_->selectionModel()->selectedIndexes().size()) {
onSelChanged();
}
statusText_[StatusTextNormal] = formatStatusText();
Q_EMIT statusChanged(StatusTextNormal, statusText_[StatusTextNormal]);
}
void TabPage::setCustomizedView(bool value) {
if(folderSettings_.isCustomized() == value) {
return;
}
Settings& settings = static_cast<Application*>(qApp)->settings();
folderSettings_.setCustomized(value);
if(value) { // save customized folder view settings
settings.saveFolderSettings(path(), folderSettings_);
}
else { // use default folder view settings
settings.clearFolderSettings(path());
setShowHidden(settings.showHidden());
setSortCaseSensitive(settings.sortCaseSensitive());
setSortFolderFirst(settings.sortFolderFirst());
sort(settings.sortColumn(), settings.sortOrder());
}
}
} // namespace PCManFM

@ -1,318 +0,0 @@
/*
Copyright (C) 2013 Hong Jen Yee (PCMan) <pcman.tw@gmail.com>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#ifndef FM_TABPAGE_H
#define FM_TABPAGE_H
#include <QWidget>
#include <QVBoxLayout>
#include <QLineEdit>
#include <libfm-qt/browsehistory.h>
#include "view.h"
#include "settings.h"
#include <libfm-qt/core/fileinfo.h>
#include <libfm-qt/core/filepath.h>
#include <libfm-qt/core/folder.h>
namespace Fm {
class FileLauncher;
class FolderModel;
class ProxyFolderModel;
class CachedFolderModel;
}
namespace PCManFM {
class Launcher;
class ProxyFilter : public Fm::ProxyFolderModelFilter {
public:
bool filterAcceptsRow(const Fm::ProxyFolderModel* model, const std::shared_ptr<const Fm::FileInfo>& info) const;
virtual ~ProxyFilter() {}
QString getFilterStr() {
return filterStr_;
}
void setFilterStr(QString str) {
filterStr_ = str;
}
private:
QString filterStr_;
};
//==================================================
class FilterEdit : public QLineEdit {
Q_OBJECT
public:
FilterEdit(QWidget *parent = nullptr);
~FilterEdit() {};
void keyPressed(QKeyEvent* event);
protected:
virtual void focusOutEvent(QFocusEvent* event) override {
Q_EMIT lostFocus();
QLineEdit::focusOutEvent(event);
}
virtual void keyPressEvent(QKeyEvent* event) override;
Q_SIGNALS:
void lostFocus();
};
class FilterBar : public QWidget {
Q_OBJECT
public:
FilterBar(QWidget *parent = nullptr);
~FilterBar() {};
void focusBar() {
filterEdit_->setFocus();
}
void clear() {
filterEdit_->clear();
}
void keyPressed(QKeyEvent* event) {
filterEdit_->keyPressed(event);
}
Q_SIGNALS:
void textChanged(const QString &text);
void lostFocus();
private:
FilterEdit* filterEdit_;
};
//==================================================
class TabPage : public QWidget {
Q_OBJECT
public:
enum StatusTextType {
StatusTextNormal,
StatusTextSelectedFiles,
StatusTextFSInfo,
StatusTextNum
};
public:
explicit TabPage(QWidget* parent = nullptr);
virtual ~TabPage();
void chdir(Fm::FilePath newPath, bool addHistory = true);
Fm::FolderView::ViewMode viewMode() {
return folderSettings_.viewMode();
}
void setViewMode(Fm::FolderView::ViewMode mode);
void sort(int col, Qt::SortOrder order = Qt::AscendingOrder);
int sortColumn() {
return folderSettings_.sortColumn();
}
Qt::SortOrder sortOrder() {
return folderSettings_.sortOrder();
}
bool sortFolderFirst() {
return folderSettings_.sortFolderFirst();
}
void setSortFolderFirst(bool value);
bool sortCaseSensitive() {
return folderSettings_.sortCaseSensitive();
}
void setSortCaseSensitive(bool value);
bool showHidden() {
return proxyModel_->showHidden();
}
void setShowHidden(bool showHidden);
void saveFolderSorting();
Fm::FilePath path() {
return folder_ ? folder_->path() : Fm::FilePath();
}
QString pathName();
const std::shared_ptr<Fm::Folder>& folder() {
return folder_;
}
Fm::FolderModel* folderModel() {
return reinterpret_cast<Fm::FolderModel*>(folderModel_);
}
View* folderView() {
return folderView_;
}
Fm::BrowseHistory& browseHistory() {
return history_;
}
Fm::FileInfoList selectedFiles() {
return folderView_->selectedFiles();
}
Fm::FilePathList selectedFilePaths() {
return folderView_->selectedFilePaths();
}
void selectAll();
void invertSelection();
void reload();
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();
bool hasCustomizedView() {
return folderSettings_.isCustomized();
}
void setCustomizedView(bool value);
void transientFilterBar(bool transient);
void showFilterBar();
bool isFilterBarVisible() const {
return (filterBar_ && filterBar_->isVisible());
}
void clearFilter() {
if(filterBar_) {
filterBar_->clear();
}
}
void backspacePressed();
Q_SIGNALS:
void statusChanged(int type, QString statusText);
void titleChanged(QString title);
void openDirRequested(const Fm::FilePath& path, int target);
void sortFilterChanged();
void forwardRequested();
void backwardRequested();
void folderUnmounted();
protected:
virtual bool eventFilter(QObject* watched, QEvent* event);
protected Q_SLOTS:
void onSelChanged();
void onUiUpdated();
void onFileSizeChanged(const QModelIndex& index);
void onFilesAdded(const Fm::FileInfoList files);
void onFilterStringChanged(QString str);
void onLosingFilterBarFocus();
private:
void freeFolder();
QString formatStatusText();
// Adds bidi marks (RLM/LRM/RLE/LRE/POP) around the text for the statusbar.
QString encloseWithBidiMarks(const QString& text);
void onFolderStartLoading();
void onFolderFinishLoading();
// FIXME: this API design is bad and might be removed later
void onFolderError(const Fm::GErrorPtr& err, Fm::Job::ErrorSeverity severity, Fm::Job::ErrorAction& response);
void onFolderFsInfo();
void onFolderRemoved();
void onFolderUnmount();
void onFolderContentChanged();
private:
View* folderView_;
Fm::CachedFolderModel* folderModel_;
Fm::ProxyFolderModel* proxyModel_;
ProxyFilter* proxyFilter_;
QVBoxLayout* verticalLayout;
std::shared_ptr<Fm::Folder> folder_;
QString statusText_[StatusTextNum];
Fm::BrowseHistory history_; // browsing history
Fm::FilePath lastFolderPath_; // last browsed folder
bool overrideCursor_;
FolderSettings folderSettings_;
QTimer* selectionTimer_;
FilterBar* filterBar_;
};
}
#endif // FM_TABPAGE_H

@ -1,3 +0,0 @@
project(pcmanfm-qt)
build_component("." "${CMAKE_INSTALL_FULL_DATADIR}/pcmanfm-qt/translations")

@ -1,4 +0,0 @@
#Translations
Name[ar]=سطح المكتب
GenericName[ar]=تفضيلات سطح المكتب
Comment[ar]=غيّر خلفيّات مدير سطح المكتب وسلوكه

@ -1,3 +0,0 @@
Name[ca]=Escriptori
GenericName[ca]=Ajusts de l'escriptori
Comment[ca]=Canvieu les imatges dels fons i el comportament del gestor d'escriptoris

@ -1,4 +0,0 @@
#Translations
Name[cs]=Pracovní plocha
GenericName[cs]=Nastavení pracovní plochy
Comment[cs]=Změna pozadí plochy a chování jejího správce

@ -1,3 +0,0 @@
Name[da]=Skrivebord
GenericName[da]=Skrivebordsindstillinger
Comment[da]=Skift desktop managerens tapeter og adfærd

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

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

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

@ -1,4 +0,0 @@
#Translations
Name[fr]=Bureau
GenericName[fr]=Paramétrage du bureau
Comment[fr]=Paramètres tels que papier-peint et autres réglages du bureau

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

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

@ -1,4 +0,0 @@
#Translations
Name[ja]=デスクトップ
GenericName[ja]=デスクトップ設定
Comment[ja]=壁紙やその他のデスクトップ設定を変更します

Some files were not shown because too many files have changed in this diff Show More

Loading…
Cancel
Save