Remove pristine-tar files.

ubuntu/cosmic
Simon Quigley 6 years ago
parent 372eae0604
commit 34deeaf154

@ -1,13 +0,0 @@
Upstream Authors:
LXQt team: http://lxqt.org
Razor team: http://razor-qt.org
Copyright:
Copyright (c) 2010-2012 Razor team
Copyright (c) 2012-2017 LXQt team
License: GPL-2 and LGPL-2.1+
The full text of the licenses can be found in the 'LICENSE' file.
The lxqt-config-cursor component is based on the "qt-xcurtheme" project
and is licensed under GPL 2, GPL 3, LGPL-2, LGPL-2.1 and WTFPL 2.

@ -1,559 +0,0 @@
lxqt-config-0.12.0 / 2017-10-21
===============================
* Set patch version
* Use $XDG_CONFIG_HOME/mimeapps.list for mime data instead of $XDG_DATA_HOME/applications/mimeapps.list (#129)
* Don't export github templates
* Update monitorsettingsdialog.ui
* lxqt-config-locale: corrected/reworded Save Changed Settings dialog
* Add/update *lt.desktop files
* lxq-config-monitor: set Qt::AA_UseHighDpiPixmaps to true
* lxqt-config-locale: set Qt::AA_UseHighDpiPixmaps to true
* lxqt-config-input: set Qt::AA_UseHighDpiPixmaps to true
* lxqt-config-file-ass.: set Qt::AA_UseHighDpiPixmaps to true
* lxqt-config-brightness: set Qt::AA_UseHighDpiPixmaps to true
* lxqt-config-appearance: set Qt::AA_UseHighDpiPixmaps to true
* liblxqt-config-cursor: set Qt::AA_UseHighDpiPixmaps to true
* Added QCommandLineParser and basic cli interface to lxqt-config-monitor
* Added QCommandLineParser and basic cli interface to lxqt-config-locale
* Added QCommandLineParser and basic cli interface to lxqt-config-input
* Added QCommandLineParser and basic cli interface to lxqt-config-file-associations
* Added version info to lxqt-config-brightness cli
* Added QCommandLineParser and basic cli interface to lxqt-config-appearance
* Added QCommandLineParser and basic cli interface to lxqt-config
* Added LXQT_CONFIG_PATCH_VERSION
* Fixed typo in appearance_pl_PL.desktop (#124)
* i18n: added some *.desktop for Polish language
* Fixes (#121)
* appearance: Fix typo from @aca544479
* lxqt-config-file-associations: Sets the initial focus (#120)
* appearance: Add icon FollowColorScheme configuration (#119)
* Show non-primary screens in UI. (#116)
* Removes unneeded include_directories() entry
* Fixes a FTBFS with CMake v3.8
* Use const iterators
* Update AUTHORS
0.11.1 / 2017-01-01
===================
* Release 0.11.1: Update changelog
* lxqt-config-monitor: remove unnecessary wait before settings load (#114)
* Fix self icontheme update (#113)
* liblxqt-config-cursor: Don't check for null pointer before deleting it
* liblxqt-config-cursor: Explicitly ignore function return value
* Updated and added *_da.desktop files and removed da_DK
* Use FindXCB CMake module
* Activate items on releasing Enter instead of pressing it. (#78)
* Update and rename lxqt-config_fr_FR.desktop to lxqt-config_fr.desktop
* Fix faulty link in README.md
* if not set, set the build type to Release
* Desktop entry files: Update French translation
* lxqt-config: Avoid multiple spawn on auto-repeat
* Fix loading of translations for brightness
* Create lxqt-config-brightness_it.desktop
* Remove cpack (#104)
* lxqt-config-brightness: Add GenericName and Comment to desktop entry
0.11.0 / 2016-09-24
===================
* Release 0.11.0: Add changelog
* appearance: Avoid blocking when setting wallpaper
* appearance: Do (not) change wallpaper with theme
* all: Remove XdgIcon & XdgIconLoader usage
* brightness: Add change confirmation dialog
* brightness: Correct indentation
* Update README.md
* Replaces deprecated QStyleOptionViewItemVx
* Add Catalan translations
* Add and Update Arabic Translations for Desktop Files
* lxqt-config-monitor: Correct loadsettings.cpp
* lxqt-config-monitor: Use QGuiApplication
* I18n: Fix Plural String (#94)
* fixed crash when selecting "extended view" while second monitor is off (#91)
* build: Add optional build for subcomponents
* lxqt-config-appearance: Fix a null pointer dereference (#93)
* Add README.md
* lxqt-config-brightness: Remove compiler warning
* lxqt-config-brightness: Add libxcb dependency
* lxqt-config-brightness: Use *_LDFLAGS in target_link_libraries
* lxqt-config-appearance: Use fewer XdgIcon* stuff (#92)
* lxqt-config-appearance: Use the new XdgIconLoader library (#90)
* build: Use external translations (#89)
* ts-files removal (#88)
* Use const references with the foreach iterator
* translations: russian translation update (#85)
* font config: make it possible to write custom fontconfig files (#83)
* view: Use icon/decoration size based on styling
* Set grid size according to font and icon sizes.
* lxqt-config-brightness: Use arrow keys to change settings.
* Desktop file translation to Spanish added.
* lxqt-config-brigness: Set brightness value by command line.
* Removed not needed LICENSE
* lxqt-config-brightness: Increase or decrease brightness using command line.
* Create lxqt-config-locale_it.desktop
* Rename from lxqt-config-brightness-settings to lxqt-config-brightness.
* lxqt-config-brightness-settings: Some files changes their licenses from GPL to LGPL.
* lxqt-config-brightness-settings lxqt translations module added.
* lxqt-config-brightness-settings added.
* fix typo skiping -> skipping
* build: Fix FTBFS by reverting the @a7220cb
* Bum year in AUTHORS
* lxqt-config-brightness-settings has been added. It can change brightness and gamma. It's a X11 tool because libKScreen can not change brightness or gamma yet.
* lxqt-config: Load/store window size on begin/end
* categorizedview: Use correct signature
* lxqt-config: Remove homemade "activation logic"
* Settings are saved in QSettings format instead JSON format.
* Set position widget used bad scale. The real widget size is not set until the widget is shown.
* Remove blue square in GUI position
* Fast options added.
* GUI only lets one primary output.
* Icons aren't installed.
* Check KScreen reply is OK. Changes in interface.
* liblxqt is used to write autostart entry.
* Don't track IDE settings
* KScreen is slow loading screen modes at starting. Wait for modes ready.
* KScreen sometimes changes id of modes. If mode exists and it is OK, settings will be applied.
* Save settings dialog added.
* Initial support for different paths of xkb base.lst in different OSes.
* A couple of bug fixes Check if the memory was allocated after malloc() and realloc() calls Fix typo
* Update german translation
* Fix warning on translation
* Replace slang with a more traditional wording
* build: Use CMAKE_INSTALL_FULL_LIBDIR for RPATH
* Fixes an FTBFS on lxqt-config-locale_ru.desktop
* Update Russian translations
* apearance: Support "System" theme preview
* Italian translation update
* lxqt-config: Add CTRL+Q shortcut for closing
*_hu.ts files updated, *hu_HU.ts files deleted
* Mkdir $XDG_CONFIG_HOME/autostart or ~/.config/autostart, if not exists.
* lxqt-config-appearance: Choose the icon with the matching size
0.10.0 / 2015-11-02
===================
* Update translations
* Fix license file
* Set saved settings at session start.
* lxqt-config-monitor: Correctly link to liblxqt
* lxqt-config-monitor: GUI for positioning
* lxqt-config-monito: Handle the clone combobox
* lxqt-config-monitor: Fix activation of second screen
* lxqt-config-monitor: Screen rotation
* lxqt-config-monitor: Tabs to spaces
* lxqt-config-monitor: Remove duplicate modes from list
* lxqt-config-monitor: Sort output modes
* lxqt-config-monitor: clean-up, old code removed
* lxqt-config-monitor: fix for reverting to previous configuration
* lxqt-config-monitor: refactoring and improvements
* lxqt-config-monitor: Use a separate combobox for clones
* lxqt-config-monitor: Actually update the config on setting screen position
* lxqt-config-monitor: Display EDID information in an additional tab
* lxqt-config-monitor: Attempt at an even simpler UI (#502)
* lxqt-config-monitor: Replace xrandr by KScreen
* lxqt-config-monitor: Remove backlight/brightness support
* Make the lxqt-config-locale chosen settings work
* Fix a few typos in file “info-for-developers.txt”
* Removed some compile warnings
* OnlyShowIn=LXQt;
* Add an option to automatically turn on numlock after login (implemented in lxqt-session).
* Initial support for locale config, based on formats KCMS.
* Rename LxQt to LXQt everywhere
* Update Greek (el) translation Remove country variant from language code
* lxqt-config: add correct rpath into lxqt-config-input & lxqt-config-appearance to find liblxqt-config-cursor.so installed into private directory
* Drop country-specific Italian translations
* Updated and created italian .desktop files
* Fix mouse settings persistency
* fixes lxde/lxqt #785 AUTHORS changed, list the used licenses LXQt license header added
* Description: Install private .so file into proper directory. Author: Andrew Lee (李健秋) <ajqlee@debian.org>
* Add copyright headers
* Handles CMake policy CMP0063
* Uses LXQtCompilerSettings CMake module
* Fix cursor settings location
* Updates translations sources
* CMake: Adds Runtime and Devel install COMPONENTs
* Coding style changes
* Removes unneeded include_directories() entries
* Use CMAKE_AUTORCC
* Get rid of qt5_wrap_cpp() MOC variables
* Use CMAKE_AUTOUIC
* Drops LIB_SUFFIX, use GNUInstallDirs
* fix build with qt 5.5
* Makes it compile in superbuild mode
* Updated german translation.
* Updates the build system to the Targets infrastructure
* polish regarding lxqt-config.desktop
* Remove trailing whitespaces
* Fix naming and links
* Include X-LXQt category in lxqt-config menu
* ApplyDialog renamed to SaveSettings.
* Rename and delete saved settings added.
* Bug always unify monitors fixed.
* lxqt-config-appearance: minimum configurable font size -> 4px
* Fix function name
* Update lxqt-config-input_it.ts
* Hungarian translations update, lxqt-config-monitor.desktop.in fixed
* Testing changes in the buttonbar of LxQt::ConfigDialog.
* Update Russian translation
* lxqt-configure-appearance: Reload icons from the user selected theme
* The last xrandr backend commit. Save settings added. Framebuffer screen size fixed.
* First save settings implementation.
* Update lxqt-config-cursor_it_IT.ts
* Framebuffer size is calculated on xrand backend.
* Update to keep up with our QIconLoader
* Added reset values.
* Remove testing parameters
* Apply page added
* Updated to LxQt::ConfigDialog.
* Added SVG icon for monitor in monitor position.
* Polish translation update
* Reorganizing the code. Support for long names in resolution modes .
* Reorganizing the code. Support for long names in resolution modes.
* Reorganizing the code. Support for long names in resolution modes.
* New modes name bug fixed.
* lxqt-config-appearance/icontheme: String performance enhancements
* Handles previews for inherited icon themes
* file-associations:Return from the busy cursor only after the Ui stuff ended
* Remove an unneeded dependency on KWindowSystem
0.9.0 / 2015-01-31
==================
* Delay loading of application icons in the app-chooser dialog for faster loading.
* Make the user aware of still ongoing work (Application Chooser)
* Bad English fixed
* Capitalize themes' names
* Create lxqt-config-monitor_it_IT.ts
* Update lxqt-config-appearance_it.desktop
* Added german translation for file association dialogue
* Added german translation for input device settings.
* Create lxqt-config-file-associations_it.ts
* Update lxqt-config-appearance_it.ts
* Update lxqt-config-appearance_it_IT.ts
* Added german translation for monitor settings.
* Update Japanese translation
* Fix PT desktop file names and paths.
* Portuguese language update
* Updates translations sources
* Documenting the code: Magnetic attraction without javascript.
* Magnetic attraction procedure has been documented.
* Added confirm dialog before saving.
* Added backlight control and position control button.
* Update lxqt-config-cursor_ja.ts
* - Unify naming for a unique lxqt. No more suffixes
* Write to mimeapps.list rather than defaults.list
* If directory ~/.config/autostart/ doesn't exists, it is created. Save doesn't close window.
* Use the new LxQt::SingleApplication
* Add windows icon
* CMakeLists code reformatting
* CMakeLists maintenance
* Renames .ts files that used _template in their name
* Moves and renames translations files around
* Uses the new translations cmake modules
* - Add option autohint - Fix compatibility with KDE fonts settings
* Activate System Settings items with enter key. Fixes lxde/lxde-qt#355
* Update Russian translation
* Drop Qt4 support in code
* Clean up CMakeLists.txt and drop Qt 4 support
0.8.0 / 2014-10-10
==================
* Adapts to translations infrastructure
* Option to set single-click as default and sigle-click handling in system settings' main window
* Qt4 and Qt5 compiling fixed
* Compiling in Qt4 fixed.
* Fix #273 - File fonts.conf is created as folder if doesn't exist.
* Make initial panel receive focus
* Adapt to use QtMimeTypes/XdgMimeType
* Restore translations.
* Use our custom TimeoutDialog to replace QProgressDialog and provide a "cancel" button and show better text in the progress bar.
* Little fix for the broken stacked widget.
* Replace the scrolled UI with a left list and a right stacked widget to provide usability.
* Don't use Qt QObject properties in mode changes. Use MonitorWidget class properties instead.
* Fixed: Some ugly code has been changed.
* Fixed: Error reading monitor name.
* Fixed: Restore position of monitor when user cancels settings.
* Fixed: If no relative monitor is selected, then position is disabled.
* Fixed: Disable position options when output is unified at start. Fixed: No cicles in relative positions at start.
* Fixed: Timeout dialog is now modal.
* Fixed: If monitor is turned off, brightness is set to 0. Fixed: Quick options close window on click.
* Read vendor from EDID.
* Fixed: Gamma error when monitor is turned off.
* Gamma control implemented.
* Added brightness control. Some bugs fixed reading xrandr properties.
* Little adjustment to the UI. Delete unused methods.
* Refactor the code, make things more OOP-style. * Slight adjustment to the UI.
* Add code to determine the position of monitors and their relationship on startup.
* Add a new parser for the output of "xrandr --verbose" to get more detailed monitor info, including gamma.
* Add initial translation support and an incomplete zh_TW locale to lxqt-config-monitor.
* Integrate the Makefile of lxqt-config-monitor to build it as part of lxqt-config.
* Move lxqt-config-monitor into a subdirectory.
* Use QWindow::windowHandle()->winId() to replace QWidget::winId() due to a bug of Qt5.
* Added: Save settings in autostart desktop file.
* Added timeout dialog. When settings are applied, a timeout dialog is shown. If user doesn't press "Yes" button, settings are restored.
* Monitor position can be changed. Outputs can be diferent. Position of outputs can be chosen. If system has got two monitors, wizard will be shown to config them.
* Modules for xrandr and GUI. Now new backends can be added.
* Split xrandr settings from UI.
* Readme updated.
* Remove all Glib dependencies.
* Initial commit
* Fix bug #242: lxqt-config-input: Mouse acceleration & sensitivity settings are not saved.
* Fix missing libxcb linking so building with llvm/clang now works.
* Fixes layout on the Fonts Config Ui
* Avoid putting system programs in "LXQt settings" category since they belong to "System settings".
* Add <OnlyUnallocated /> to lxqt-config.menu to avoid duplicated items in "Other Settings" section. This fixed lxde-qt bug #186.
* Rename lxqt-config-cursor to liblxqt-config-cursor since it's a library.
* Show cursors by using raw xcb calls since Qt5 does not support creating QCursor based on native cursor handle.
* Write Qt settings to lxqt.conf instead of the deprecated Trolltech.conf in Qt5.
* Make the code compile with both Qt4 and Qt5.
* Fix keyboard layout settings reading and writting
* Cleanup header style
* Use new LXQt header files.
* Use preferred header style.
* Make sure all enums are handled in switch
* Fix a null dereference
* Remove unnecessary use of alloca, which is not portable.
0.7.0 / 2014-05-07
==================
* Mention lxqt-config-cursor in AUTHORS
* Include some optional components in LXQt settings.
* Remove duplicate COPYING file
* Update COPYING
* Update categories to match proper ones in .desktop files
* String changes LxQt -> LXQt and LXDE-Qt -> LXQt without refactoring classes, namespaces and so on
* removal of old templates in translations
0.6.99 / 2014-05-01
===================
* Update manpages
* Update AUTHORS
* Add CPack rules for creating tarball
* config-input: Fix a typo
* Preserve the config values in lxqt-session config file. * Support setting key used to switch layouts.
* Add keys used to switch layout to the combox box.
* Add very primitive support for settings keyboard layout via setxkbmap.
* Add a basic skeleton for keyboard layout settings.
* lxqt-config-file-associations: Wording in main window
* Assorted improvements to .desktop files
* Man page improvements
* Correctly save the cursor theme name to lxqt session config file.
* Correctly write current cursor theme name to ~/.icons/default/index.theme. Deprecate the use of XCURSOR_THEME environment variable.
* Support changing double click interval, whell scroll lines, and cursor flash time for Qt programs. Little adjustment of UI.
* Fix incorrect linking to liblxqt-config-cursor.
* Add missing desktop entry file for lxqt-config-input. Some cleanup.
* Rename lxqt-config-mouse to lxqt-config-cursor to reflect what it does. Remove unnecessary desktop entry files and do some makefile cleanup.
* Try to integrate lxqt-config-appearance with lxqt-config-mouse so we can select cursor themes in lxqt-config-appearance, too.
* Total redesign of lxqt-config-input using LxQt::ConfigDialog and integrate lxqt-config-mouse.
* Fix lxqt-config-appearance: write config files on widget destruction properly
* Fix dpi settings and add a timeout to 1.5 sec delay to writing fontconfig file.
* Read/write ~/.config/fontconfig/fonts.conf file for settings antialias, hinting, and dpi.
* Write a fontconfig config file to ~/.config/fonts.conf at the same time.
* Fix bugs in font configurations
* Try to add very basic font configurations
* Add support for toolbar button styles and single click activation for item views
* Add support for Qt style selection to lxqt-config-appearance.
* Removed CMAKE_SOURCE_DIR usage from CMakeLists.txt files
* Fix XDG_MENU_PREFIX and use correct config.menu file.
* Support changing the wallpaper of pcmanfm-qt.
* Fix renaming bugs, replacing lxqt-qt with lxde-qt
* Finish the crazy razor=>lxqt renaming tasks.
* Fix wrong config name.
* Project name added to cmake file
* Fix wrong Exec lines in desktop entry files.
* Fix broken build and rename binaries to lxqt-config-*.
* Add COPYING file for razor-config-mouse since it's GPL'd rather than using LGPL.
* Add COPYING and AUTHORS
* Make razor-config-fileassociations compile with qt 4.6
* Corrected include line in mimetypeviewer.cpp
* X-RAZOR changed to Razor in desktop files
* Make config-file-associations dialogs appear faster
* config-file-associations: removed placeholder text from search field
* config-file-associations: add search icon to search lineedit
* Removed heading from mimetypeviewer in config-file-associations
* razor-config-file-associations: Set focus correctly when opening applicationchooser
* razor-config-file-associations: remove connect to nonexisting ok-slot
* razor-config-file-associations: clean up qDebug lines
* config-file-associations, clear mimeinfo frames in mimetypeviewer, when no mimetype chosen
* Sorting of applications in config-file-associations
* config-file-associations adapt detection of applications to xdg-mime behavior
* razor-config: load model content after the window appears on screen (we need to provide some user feedback immediately)
* config-file-associations, mimetypeviewer: change tab-order and initial focus
* Added search functionality to config-file-associations, MimetypeViewer
* config-file-associations, mimetypeviewer: Replaced QTreeWidget with QTreeView and new class MimetypeItemModel as model
* config-file-associations: minor changes to mimetypeviewer looks
* config-file-associations: Changed application listwidget back to treewidget, and dropped \handles\ listwidget
* Improved (hopefuly) layout and look of config-fileassociations, application chooser
* config-file-associations: changed treewidget to listwidget in applicationchooser
* razor-config-file-associations, improved layout for mimetype-viewer
* Added application razor-config-file-associations
* fixed appearance icons display + huge filesystem access optimization in this area
* Update fixes for qcategorizedview
* Make config center icon labels not wrap as much
* fixed #488 Display a message if no cursor theme is found
* Fix various build falures
* Add translation support for qtconfig entry
* preliminary manpages primary for razorqt and usefully in venenux
* Suppressed warning "variable «currSize» set but not used" in the razorqt-config/src/qcategorizedview/qcategorizedview.cpp:496:29
* Suppressed warning "variable «currSize» set but not used" in the razorqt-config/src/qcategorizedview/qcategorizedview.cpp:496:29
* Translations updated
* Translations updated
* Translations
* Delete bad en_GB translations
* Install translations into correct places
* Update translations
* Enable translations for some components that were missing them
* Minor fixes
* Translations updated
* Removed line num from TS files.
* razor-config: wrap text
* Make it possible to build modules separately
* Translations
* Deleted old translation methods.
* New translation infrastructure
* Translation for razor-config-appearance
* Fix for Issue #290 Fails to build on BSD
* Updated ts.src files
* removed useles window title
* fixed #336: remove the "razor" prefix from razor-config dialog
* config app for notifications
* Remove RazorNotification classes (no license/copyright)
* add module names to includes and tidy up the coding style
* Update razorqt-config/razor-config-mouse/thememodel.h
* Update razorqt-config/razor-config-mouse/selectwnd.h
* Update razorqt-config/razor-config-mouse/previewwidget.h
* Update razorqt-config/razor-config-mouse/itemdelegate.h
* Update razorqt-config/razor-config-mouse/crtheme.h
* fix coding style errors
* fix coding style errors
* fix coding style errors
* fix coding style errors
* fix coding style errors
* fix coding style errors
* fix coding style errors
* fix coding style errors
* Ts.src files updated.
* add module name to include
* add module names to includes
* add module names to includes and fix style errors
* fix coding style errors
* add module names to includes
* add module names to includes
* add module names to includes
* add module names to includes
* Language name zh_CN.GB2312 braked cmake process.
* Translations updated
* Environments should be "Razor", not "RAZOR" Thanks Alec Moskvin
* Renames razor-config-notificationd window title
* Small fixes in the razor-config-appearance Thanks PICCORO Lenz McKAY. still need some fixeds: iconthemeconfig.h:38: error: expected class-name before { token and also the moc ui_mainwindow.h must be renamed too in iconthemeconfig.h
* Fix header
* Small fixes in the razor-config-appearance
* razor-config GUI improvement
* razor-config based on XDG Desktop Menu Specification 2
* fixed #261 Fix missing icons in razor config center
* default arguments for notification client lib
* quick compilation fix
* razor-config based on XDG Desktop Menu Specification
* Composition on by default
* GUI for change razor theme.
* Fixing cmake error
* fixed wrongly set license for new files. It's LGPL2+
* much better razor-config layout for icons
* config center: align icons into grid; do not show self; OnlyShowIn check
* reworked config stuff. No more special config registering. All 'Settings' desktop files are displayed in razor-config (grouped)
* Typos in code. Thanks Aaron Lewis. * In razor-runner , providers item: title() was typed as tile() * For RazorSettings class , settingsChanged() was typed as settigsChanged()
* Minor modifications and code cleanup
* Minor ui modifications. Moving default icon to notificationd instead of widget notification
* Setting min & max position according to QDesktopWidget
* Changing notification ui. Adding default notitifaction icon. Embedding icons in notification
* Properly install config Correct desktop file
* Proper default values
* Proper id number assigned to notifications Properly remove notification by quint32 id
* Proper configuration
* Rename file to match class name
* Remove custom settings, use razor ones
* Adding razor-config-notificationd
* tweaks for qtconfig installation
* qtconfig for razor-config
* Transifex desktop: sr_BA.ts should be a local
* Transifex desktop: local translations
* Transifex desktop: cmake files
* Transifex desktop: Translations pulled
* Transifex desktop: Reomove translations from desktop.in
* Transifex desktop: desktop->desktop.in
* Update Tradidtional Chinese Translations
* Add Traditional Chinese Translations
* Translations update
* Added support for the online translation service. www.transifex.net
* RazorApplication class implemented; all modules ported to this class
* fixed #76: razor-config should respect mouse behaviour
* Serbian translation files
* Serbian translations (2 variants)
* Greek translation by iosifidis
* Added danish translations
* Russian translation
* fix #169: italian translation
* Add function to use alternative icons
* Relicense
* Convert Appearance dialog to use RazorConfigDialog
* Fix gmail.ru -> gmail.com
* Czech translations (cs_CZ) Desktop files
* fixed #138: system settings icons
* SVK translation finalized
* Initial german [de] translation
* Close Issue #120
* License audit
* Add Chinese(simplified) translation files.
* License audit
* HU translation by Kristóf Kiszel
* Initial spanish translation
* Add Slovak (sk) translation
* Removes one empty line from .desktop file
* Adds newline to the end of .desktop files
* Czech translations (cs_CZ)
* Fix a few typos
* XdgDesktopFile is implicitly shared
* huge refactoring of the libraries build organization
* config mouse: close button as in the other tools
* Razor-config-appearance: incorrect translation path
* config: better item layouting in razor-config
* config appearance: make icons fully visible
* Razor-config: Fixes for razor-config-appearance
* Razor-config: New razor-config-appearance
* Razor-config: New razor-config-appearance
* display icon theme fixes
* forgotten debugs
* config icons: show progress when it searches for themes
* icon theme config - initial revision
* Razor-config-mouse: Added check for zlib in CMakeLists.txt
* moc warnings cleanup
* GPL->LGPL where I'm the author
* config: remove toolbars
* Polish translation part X
* Fix: Desktop Menu Specification category must be X-RAZOR.
* Russian translations
* unify razor-config look
* Added razor-application.menu
* razor-config can open items by Enter key too
* fixed desktop files
* fix donfig desktp files install for rpm
* razor-config-mousetheme -> razor-config-mouse rename
* do not use direct lib name for X11 stuff
* issue #37 - Config-mousetheme show not all themes, my KDE show 6 themes but razor only 1. (mHidden attribute fixed)
* homepage updated + auto replacement script
* adding missing libraries to fedora build
* show only in RAZOR; close/undo changes actions
* small refactoring in mouse config
* fixed #35: razor-config-mousetheme saves are not persistent
* final fix for build error #34
* potential fix for #34
* mouse theme configurator
* fix for #33: razorqt doesn't build
* config tools are registered in config center; desktop file for CC
* initial revision of "config tool". Very simple but functional.

@ -1,65 +0,0 @@
cmake_minimum_required(VERSION 3.0.2 FATAL_ERROR)
project(lxqt-config)
set(LXQT_CONFIG_PROJECT "${PROJECT_NAME}")
option(UPDATE_TRANSLATIONS "Update source translation translations/*.ts files" OFF)
option(WITH_INPUT "Build the 'lxqt-config-input'" ON)
option(WITH_FILE_ASSOCIATIONS "Build the 'lxqt-config-file-associations'" ON)
option(WITH_APPEARANCE "Build the 'lxqt-config-appearance'" ON)
option(WITH_MONITOR "Build the 'lxqt-config-monitor'" ON)
option(WITH_BRIGHTNESS "Build the 'lxqt-config-brightness'" ON)
option(WITH_LOCALE "Build the 'lxqt-config-locale'" ON)
include(GNUInstallDirs)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(CMAKE_POSITION_INDEPENDENT_CODE ON)
set(CMAKE_AUTOMOC ON)
set(CMAKE_AUTOUIC ON)
set(CMAKE_AUTORCC ON)
find_package(Qt5Widgets REQUIRED)
find_package(Qt5DBus REQUIRED)
find_package(Qt5Xml REQUIRED)
find_package(Qt5Concurrent REQUIRED)
find_package(Qt5X11Extras REQUIRED)
find_package(Qt5LinguistTools REQUIRED)
find_package(lxqt REQUIRED)
include(LXQtCompilerSettings NO_POLICY_SCOPE)
if(NOT CMAKE_BUILD_TYPE)
set(CMAKE_BUILD_TYPE Release)
endif()
# Patch Version
set(LXQT_CONFIG_PATCH_VERSION 0)
set(LXQT_CONFIG_VERSION ${LXQT_MAJOR_VERSION}.${LXQT_MINOR_VERSION}.${LXQT_CONFIG_PATCH_VERSION})
add_definitions("-DLXQT_CONFIG_VERSION=\"${LXQT_CONFIG_VERSION}\"")
include(LXQtTranslate)
add_subdirectory(src)
if (WITH_INPUT OR WITH_APPEARANCE)
add_subdirectory(liblxqt-config-cursor)
endif()
if (WITH_INPUT)
add_subdirectory(lxqt-config-input)
endif()
if (WITH_FILE_ASSOCIATIONS)
add_subdirectory(lxqt-config-file-associations)
endif()
if (WITH_APPEARANCE)
add_subdirectory(lxqt-config-appearance)
endif()
if (WITH_MONITOR)
add_subdirectory(lxqt-config-monitor)
endif()
if (WITH_BRIGHTNESS)
add_subdirectory(lxqt-config-brightness)
endif()
if (WITH_LOCALE)
add_subdirectory(lxqt-config-locale)
endif()

@ -1,458 +0,0 @@
GNU LESSER GENERAL PUBLIC LICENSE
Version 2.1, February 1999
Copyright (C) 1991, 1999 Free Software Foundation, Inc.
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
[This is the first released version of the Lesser GPL. It also counts
as the successor of the GNU Library Public License, version 2, hence
the version number 2.1.]
Preamble
The licenses for most software are designed to take away your
freedom to share and change it. By contrast, the GNU General Public
Licenses are intended to guarantee your freedom to share and change
free software--to make sure the software is free for all its users.
This license, the Lesser General Public License, applies to some
specially designated software packages--typically libraries--of the
Free Software Foundation and other authors who decide to use it. You
can use it too, but we suggest you first think carefully about whether
this license or the ordinary General Public License is the better
strategy to use in any particular case, based on the explanations below.
When we speak of free software, we are referring to freedom of use,
not price. Our General Public Licenses are designed to make sure that
you have the freedom to distribute copies of free software (and charge
for this service if you wish); that you receive source code or can get
it if you want it; that you can change the software and use pieces of
it in new free programs; and that you are informed that you can do
these things.
To protect your rights, we need to make restrictions that forbid
distributors to deny you these rights or to ask you to surrender these
rights. These restrictions translate to certain responsibilities for
you if you distribute copies of the library or if you modify it.
For example, if you distribute copies of the library, whether gratis
or for a fee, you must give the recipients all the rights that we gave
you. You must make sure that they, too, receive or can get the source
code. If you link other code with the library, you must provide
complete object files to the recipients, so that they can relink them
with the library after making changes to the library and recompiling
it. And you must show them these terms so they know their rights.
We protect your rights with a two-step method: (1) we copyright the
library, and (2) we offer you this license, which gives you legal
permission to copy, distribute and/or modify the library.
To protect each distributor, we want to make it very clear that
there is no warranty for the free library. Also, if the library is
modified by someone else and passed on, the recipients should know
that what they have is not the original version, so that the original
author's reputation will not be affected by problems that might be
introduced by others.
Finally, software patents pose a constant threat to the existence of
any free program. We wish to make sure that a company cannot
effectively restrict the users of a free program by obtaining a
restrictive license from a patent holder. Therefore, we insist that
any patent license obtained for a version of the library must be
consistent with the full freedom of use specified in this license.
Most GNU software, including some libraries, is covered by the
ordinary GNU General Public License. This license, the GNU Lesser
General Public License, applies to certain designated libraries, and
is quite different from the ordinary General Public License. We use
this license for certain libraries in order to permit linking those
libraries into non-free programs.
When a program is linked with a library, whether statically or using
a shared library, the combination of the two is legally speaking a
combined work, a derivative of the original library. The ordinary
General Public License therefore permits such linking only if the
entire combination fits its criteria of freedom. The Lesser General
Public License permits more lax criteria for linking other code with
the library.
We call this license the "Lesser" General Public License because it
does Less to protect the user's freedom than the ordinary General
Public License. It also provides other free software developers Less
of an advantage over competing non-free programs. These disadvantages
are the reason we use the ordinary General Public License for many
libraries. However, the Lesser license provides advantages in certain
special circumstances.
For example, on rare occasions, there may be a special need to
encourage the widest possible use of a certain library, so that it becomes
a de-facto standard. To achieve this, non-free programs must be
allowed to use the library. A more frequent case is that a free
library does the same job as widely used non-free libraries. In this
case, there is little to gain by limiting the free library to free
software only, so we use the Lesser General Public License.
In other cases, permission to use a particular library in non-free
programs enables a greater number of people to use a large body of
free software. For example, permission to use the GNU C Library in
non-free programs enables many more people to use the whole GNU
operating system, as well as its variant, the GNU/Linux operating
system.
Although the Lesser General Public License is Less protective of the
users' freedom, it does ensure that the user of a program that is
linked with the Library has the freedom and the wherewithal to run
that program using a modified version of the Library.
The precise terms and conditions for copying, distribution and
modification follow. Pay close attention to the difference between a
"work based on the library" and a "work that uses the library". The
former contains code derived from the library, whereas the latter must
be combined with the library in order to run.
GNU LESSER GENERAL PUBLIC LICENSE
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
0. This License Agreement applies to any software library or other
program which contains a notice placed by the copyright holder or
other authorized party saying it may be distributed under the terms of
this Lesser General Public License (also called "this License").
Each licensee is addressed as "you".
A "library" means a collection of software functions and/or data
prepared so as to be conveniently linked with application programs
(which use some of those functions and data) to form executables.
The "Library", below, refers to any such software library or work
which has been distributed under these terms. A "work based on the
Library" means either the Library or any derivative work under
copyright law: that is to say, a work containing the Library or a
portion of it, either verbatim or with modifications and/or translated
straightforwardly into another language. (Hereinafter, translation is
included without limitation in the term "modification".)
"Source code" for a work means the preferred form of the work for
making modifications to it. For a library, complete source code means
all the source code for all modules it contains, plus any associated
interface definition files, plus the scripts used to control compilation
and installation of the library.
Activities other than copying, distribution and modification are not
covered by this License; they are outside its scope. The act of
running a program using the Library is not restricted, and output from
such a program is covered only if its contents constitute a work based
on the Library (independent of the use of the Library in a tool for
writing it). Whether that is true depends on what the Library does
and what the program that uses the Library does.
1. You may copy and distribute verbatim copies of the Library's
complete source code as you receive it, in any medium, provided that
you conspicuously and appropriately publish on each copy an
appropriate copyright notice and disclaimer of warranty; keep intact
all the notices that refer to this License and to the absence of any
warranty; and distribute a copy of this License along with the
Library.
You may charge a fee for the physical act of transferring a copy,
and you may at your option offer warranty protection in exchange for a
fee.
2. You may modify your copy or copies of the Library or any portion
of it, thus forming a work based on the Library, and copy and
distribute such modifications or work under the terms of Section 1
above, provided that you also meet all of these conditions:
a) The modified work must itself be a software library.
b) You must cause the files modified to carry prominent notices
stating that you changed the files and the date of any change.
c) You must cause the whole of the work to be licensed at no
charge to all third parties under the terms of this License.
d) If a facility in the modified Library refers to a function or a
table of data to be supplied by an application program that uses
the facility, other than as an argument passed when the facility
is invoked, then you must make a good faith effort to ensure that,
in the event an application does not supply such function or
table, the facility still operates, and performs whatever part of
its purpose remains meaningful.
(For example, a function in a library to compute square roots has
a purpose that is entirely well-defined independent of the
application. Therefore, Subsection 2d requires that any
application-supplied function or table used by this function must
be optional: if the application does not supply it, the square
root function must still compute square roots.)
These requirements apply to the modified work as a whole. If
identifiable sections of that work are not derived from the Library,
and can be reasonably considered independent and separate works in
themselves, then this License, and its terms, do not apply to those
sections when you distribute them as separate works. But when you
distribute the same sections as part of a whole which is a work based
on the Library, the distribution of the whole must be on the terms of
this License, whose permissions for other licensees extend to the
entire whole, and thus to each and every part regardless of who wrote
it.
Thus, it is not the intent of this section to claim rights or contest
your rights to work written entirely by you; rather, the intent is to
exercise the right to control the distribution of derivative or
collective works based on the Library.
In addition, mere aggregation of another work not based on the Library
with the Library (or with a work based on the Library) on a volume of
a storage or distribution medium does not bring the other work under
the scope of this License.
3. You may opt to apply the terms of the ordinary GNU General Public
License instead of this License to a given copy of the Library. To do
this, you must alter all the notices that refer to this License, so
that they refer to the ordinary GNU General Public License, version 2,
instead of to this License. (If a newer version than version 2 of the
ordinary GNU General Public License has appeared, then you can specify
that version instead if you wish.) Do not make any other change in
these notices.
Once this change is made in a given copy, it is irreversible for
that copy, so the ordinary GNU General Public License applies to all
subsequent copies and derivative works made from that copy.
This option is useful when you wish to copy part of the code of
the Library into a program that is not a library.
4. You may copy and distribute the Library (or a portion or
derivative of it, under Section 2) in object code or executable form
under the terms of Sections 1 and 2 above provided that you accompany
it with the complete corresponding machine-readable source code, which
must be distributed under the terms of Sections 1 and 2 above on a
medium customarily used for software interchange.
If distribution of object code is made by offering access to copy
from a designated place, then offering equivalent access to copy the
source code from the same place satisfies the requirement to
distribute the source code, even though third parties are not
compelled to copy the source along with the object code.
5. A program that contains no derivative of any portion of the
Library, but is designed to work with the Library by being compiled or
linked with it, is called a "work that uses the Library". Such a
work, in isolation, is not a derivative work of the Library, and
therefore falls outside the scope of this License.
However, linking a "work that uses the Library" with the Library
creates an executable that is a derivative of the Library (because it
contains portions of the Library), rather than a "work that uses the
library". The executable is therefore covered by this License.
Section 6 states terms for distribution of such executables.
When a "work that uses the Library" uses material from a header file
that is part of the Library, the object code for the work may be a
derivative work of the Library even though the source code is not.
Whether this is true is especially significant if the work can be
linked without the Library, or if the work is itself a library. The
threshold for this to be true is not precisely defined by law.
If such an object file uses only numerical parameters, data
structure layouts and accessors, and small macros and small inline
functions (ten lines or less in length), then the use of the object
file is unrestricted, regardless of whether it is legally a derivative
work. (Executables containing this object code plus portions of the
Library will still fall under Section 6.)
Otherwise, if the work is a derivative of the Library, you may
distribute the object code for the work under the terms of Section 6.
Any executables containing that work also fall under Section 6,
whether or not they are linked directly with the Library itself.
6. As an exception to the Sections above, you may also combine or
link a "work that uses the Library" with the Library to produce a
work containing portions of the Library, and distribute that work
under terms of your choice, provided that the terms permit
modification of the work for the customer's own use and reverse
engineering for debugging such modifications.
You must give prominent notice with each copy of the work that the
Library is used in it and that the Library and its use are covered by
this License. You must supply a copy of this License. If the work
during execution displays copyright notices, you must include the
copyright notice for the Library among them, as well as a reference
directing the user to the copy of this License. Also, you must do one
of these things:
a) Accompany the work with the complete corresponding
machine-readable source code for the Library including whatever
changes were used in the work (which must be distributed under
Sections 1 and 2 above); and, if the work is an executable linked
with the Library, with the complete machine-readable "work that
uses the Library", as object code and/or source code, so that the
user can modify the Library and then relink to produce a modified
executable containing the modified Library. (It is understood
that the user who changes the contents of definitions files in the
Library will not necessarily be able to recompile the application
to use the modified definitions.)
b) Use a suitable shared library mechanism for linking with the
Library. A suitable mechanism is one that (1) uses at run time a
copy of the library already present on the user's computer system,
rather than copying library functions into the executable, and (2)
will operate properly with a modified version of the library, if
the user installs one, as long as the modified version is
interface-compatible with the version that the work was made with.
c) Accompany the work with a written offer, valid for at
least three years, to give the same user the materials
specified in Subsection 6a, above, for a charge no more
than the cost of performing this distribution.
d) If distribution of the work is made by offering access to copy
from a designated place, offer equivalent access to copy the above
specified materials from the same place.
e) Verify that the user has already received a copy of these
materials or that you have already sent this user a copy.
For an executable, the required form of the "work that uses the
Library" must include any data and utility programs needed for
reproducing the executable from it. However, as a special exception,
the materials to be distributed need not include anything that is
normally distributed (in either source or binary form) with the major
components (compiler, kernel, and so on) of the operating system on
which the executable runs, unless that component itself accompanies
the executable.
It may happen that this requirement contradicts the license
restrictions of other proprietary libraries that do not normally
accompany the operating system. Such a contradiction means you cannot
use both them and the Library together in an executable that you
distribute.
7. You may place library facilities that are a work based on the
Library side-by-side in a single library together with other library
facilities not covered by this License, and distribute such a combined
library, provided that the separate distribution of the work based on
the Library and of the other library facilities is otherwise
permitted, and provided that you do these two things:
a) Accompany the combined library with a copy of the same work
based on the Library, uncombined with any other library
facilities. This must be distributed under the terms of the
Sections above.
b) Give prominent notice with the combined library of the fact
that part of it is a work based on the Library, and explaining
where to find the accompanying uncombined form of the same work.
8. You may not copy, modify, sublicense, link with, or distribute
the Library except as expressly provided under this License. Any
attempt otherwise to copy, modify, sublicense, link with, or
distribute the Library is void, and will automatically terminate your
rights under this License. However, parties who have received copies,
or rights, from you under this License will not have their licenses
terminated so long as such parties remain in full compliance.
9. You are not required to accept this License, since you have not
signed it. However, nothing else grants you permission to modify or
distribute the Library or its derivative works. These actions are
prohibited by law if you do not accept this License. Therefore, by
modifying or distributing the Library (or any work based on the
Library), you indicate your acceptance of this License to do so, and
all its terms and conditions for copying, distributing or modifying
the Library or works based on it.
10. Each time you redistribute the Library (or any work based on the
Library), the recipient automatically receives a license from the
original licensor to copy, distribute, link with or modify the Library
subject to these terms and conditions. You may not impose any further
restrictions on the recipients' exercise of the rights granted herein.
You are not responsible for enforcing compliance by third parties with
this License.
11. If, as a consequence of a court judgment or allegation of patent
infringement or for any other reason (not limited to patent issues),
conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License. If you cannot
distribute so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you
may not distribute the Library at all. For example, if a patent
license would not permit royalty-free redistribution of the Library by
all those who receive copies directly or indirectly through you, then
the only way you could satisfy both it and this License would be to
refrain entirely from distribution of the Library.
If any portion of this section is held invalid or unenforceable under any
particular circumstance, the balance of the section is intended to apply,
and the section as a whole is intended to apply in other circumstances.
It is not the purpose of this section to induce you to infringe any
patents or other property right claims or to contest validity of any
such claims; this section has the sole purpose of protecting the
integrity of the free software distribution system which is
implemented by public license practices. Many people have made
generous contributions to the wide range of software distributed
through that system in reliance on consistent application of that
system; it is up to the author/donor to decide if he or she is willing
to distribute software through any other system and a licensee cannot
impose that choice.
This section is intended to make thoroughly clear what is believed to
be a consequence of the rest of this License.
12. If the distribution and/or use of the Library is restricted in
certain countries either by patents or by copyrighted interfaces, the
original copyright holder who places the Library under this License may add
an explicit geographical distribution limitation excluding those countries,
so that distribution is permitted only in or among countries not thus
excluded. In such case, this License incorporates the limitation as if
written in the body of this License.
13. The Free Software Foundation may publish revised and/or new
versions of the Lesser General Public License from time to time.
Such new versions will be similar in spirit to the present version,
but may differ in detail to address new problems or concerns.
Each version is given a distinguishing version number. If the Library
specifies a version number of this License which applies to it and
"any later version", you have the option of following the terms and
conditions either of that version or of any later version published by
the Free Software Foundation. If the Library does not specify a
license version number, you may choose any version ever published by
the Free Software Foundation.
14. If you wish to incorporate parts of the Library into other free
programs whose distribution conditions are incompatible with these,
write to the author to ask for permission. For software which is
copyrighted by the Free Software Foundation, write to the Free
Software Foundation; we sometimes make exceptions for this. Our
decision will be guided by the two goals of preserving the free status
of all derivatives of our free software and of promoting the sharing
and reuse of software generally.
NO WARRANTY
15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY
KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU
FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
DAMAGES.
END OF TERMS AND CONDITIONS

@ -1,77 +0,0 @@
# lxqt-config
## Overview
This repository is providing several tools involved in the configuration of both LXQt and the underlying operating system.
On the one hand it is featuring several GUI tools to configure topics like general appearance, pointer devices or screen resolutions.
On the other hand there's a GUI "Configuration Center" which summarizes all those configuration tools as well as counterparts of other LXQt components or third-party applications.
### Configuration GUI tools
#### LXQt Appearance Configuration
Appearance of LXQt, that is topics like icon and LXQt theme or fonts.
![LXQt Appearance Configuration (lxqt-config-appearance)](lxqt-config-appearance.png)
Binary `lxqt-config-appearance`.
#### Brightness
Brightness settings of output devices.
Technically colors are adjusted to simulate varying brightness if the system LXQt is running on doesn't allow for adjusting the brightness itself.
Binary `lxqt-config-brightness`.
#### File Associations
Assigns MIME types to applications used to handle them. Not too user-friendly so far, see e. g. discussion in https://github.com/lxde/lxqt/issues/433.
Binary `lxqt-config-file-associations`.
#### Keyboard and Mouse
Configures hardware of pointer devices. Settings like repeat delay and interval of keyboards or acceleration of pointer devices.
Binary `lxqt-config-input`.
#### Locale
Locale used within LXQt sessions. Basically this GUI sets the well-known environment variables like `LANG` or `LC_*`. The settings apply to the session as a whole, that is to applications running within LXQt sessions but not belonging to LXQt, too.
Binary `lxqt-config-locale`.
#### Monitor Settings
Adjusts screen resolutions, positioning of screens and the likes.
Binary `lxqt-config-monitor`.
### Configuration Center
The "Configuration Center" (binary `lxqt-config`) is summarizing and providing various configuration GUIs.
![Configuration Center (lxqt-config)](lxqt-config.png)
First of all these are the ones belonging to repository lxqt-config described [above](https://github.com/lxde/lxqt-config#configuration-gui-tools). Next, it is hosting counterparts of several other LXQt components like "Desktop Notifications" of [lxqt-notificationd](https://github.com/lxde/lxqt-notificationd), "Shortcut Keys" of [lxqt-globalkeyshortcuts](https://github.com/lxde/lxqt-globalkeyshortcuts) or the tools provided by [lxqt-admin](https://github.com/lxde/lxqt-admin). Third-party applications can include their configuration tools in "Configuration Center", too. This applies e. g. to "Connman UI Setup" of [cmst](https://github.com/andrew-bibb/cmst) or "SDDM Configuration" of [sddm-config-editor](https://github.com/hagabaka/sddm-config-editor).
## Installation
### Compiling source code
Runtime dependencies are Xcursor, qtsvg, KScreen and [liblxqt](https://github.com/lxde/liblxqt).
Additional build dependencies are CMake and optionally Git to pull latest VCS checkouts. The localization files were outsourced to repository [lxqt-l10n](https://github.com/lxde/lxqt-l10n) so the corresponding dependencies are needed, too. Please refer to this repository's `README.md` for further information.
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
The library is provided by all major Linux distributions like Arch Linux, Debian (as of Debian stretch only), Fedora and openSUSE. Just use your package manager to search for string `lxqt-config`.
## Usage
Both the various configuration tools and the Configuration Center can be launched from the panel's main menu - Preferences - LXQt settings. Obviously the former can be launched from the latter, too.

@ -1,98 +0,0 @@
project(lxqt-config-cursor)
find_package(X11 REQUIRED)
find_package(XCB REQUIRED xcb)
include_directories(${XCB_INCLUDE_DIRS})
link_libraries(${XCB_LIBRARIES})
include_directories (
${X11_INCLUDE_DIR}
${CMAKE_CURRENT_SOURCE_DIR}/xcr
)
set(lxqt-config-cursor_HDRS
thememodel.h
previewwidget.h
itemdelegate.h
selectwnd.h
warninglabel.h
)
set(lxqt-config-cursor_SRCS
crtheme.cpp
selectwnd.cpp
xcr/xcrimg.cpp
xcr/xcrxcur.cpp
xcr/xcrthemefx.cpp
xcr/xcrtheme.cpp
xcr/xcrthemexp.cpp
cfgfile.cpp
previewwidget.cpp
itemdelegate.cpp
thememodel.cpp
warninglabel.cpp
)
set(lxqt-config-cursor_UIS
selectwnd.ui
warninglabel.ui
)
find_package(ZLIB REQUIRED)
# Translations **********************************
lxqt_translate_ts(QM_FILES
UPDATE_TRANSLATIONS
${UPDATE_TRANSLATIONS}
SOURCES
${lxqt-config-cursor_HDRS}
${lxqt-config-cursor_SRCS}
${lxqt-config-cursor_UIS}
INSTALL_DIR
"${LXQT_TRANSLATIONS_DIR}/${PROJECT_NAME}"
PULL_TRANSLATIONS
${PULL_TRANSLATIONS}
CLEAN_TRANSLATIONS
${CLEAN_TRANSLATIONS}
TRANSLATIONS_REPO
${TRANSLATIONS_REPO}
TRANSLATIONS_REFSPEC
${TRANSLATIONS_REFSPEC}
REPO_SUBDIR
"lxqt-config/liblxqt-config-cursor"
)
lxqt_app_translation_loader(lxqt-config-cursor_QM_LOADER ${PROJECT_NAME})
#************************************************
add_library(lxqt-config-cursor
SHARED
${lxqt-config-cursor_SRCS}
${DESKTOP_FILES}
${QM_FILES}
${lxqt-config-cursor_QM_LOADER}
)
target_link_libraries(lxqt-config-cursor
Qt5::X11Extras
Qt5::DBus
Qt5::Xml
${X11_X11_LIB}
${X11_Xcursor_LIB}
lxqt
${ZLIB_LIBRARY}
${X11_Xfixes_LIB}
)
# not needed probably ${X11_Xfixes_LIB})
install(TARGETS
lxqt-config-cursor
DESTINATION "${CMAKE_INSTALL_LIBDIR}/${LXQT_CONFIG_PROJECT}"
COMPONENT Runtime
)
install(FILES
${DESKTOP_FILES}
DESTINATION "${CMAKE_INSTALL_DATAROOTDOR}/applications"
COMPONENT Runtime
)

@ -1,122 +0,0 @@
/* coded by Ketmar // Vampire Avalon (psyc://ketmar.no-ip.org/~Ketmar)
* (c)DWTFYW
*
* This program is free software. It comes without any warranty, to
* the extent permitted by applicable law. You can redistribute it
* and/or modify it under the terms of the Do What The Fuck You Want
* To Public License, Version 2, as published by Sam Hocevar. See
* http://sam.zoy.org/wtfpl/COPYING for more details.
*/
#include "cfgfile.h"
#include <QDir>
#include <QFile>
#include <QStringList>
#include <QTextStream>
QMultiMap<QString, QString> loadCfgFile(const QString &fname, bool forceLoCase)
{
QMultiMap<QString, QString> res;
QFile fl(fname);
if (fl.open(QIODevice::ReadOnly))
{
QTextStream stream;
stream.setDevice(&fl);
stream.setCodec("UTF-8");
QString curPath = "/";
while (1)
{
QString s = stream.readLine();
if (s.isNull()) break;
s = s.trimmed();
if (s.isEmpty() || s[0] == '#' || s[0] == ';') continue;
if (s[0] == '[')
{
// new path
int len = s.length()-1;
if (s[len] == ']') len--;
s = s.mid(1, len).simplified();
s += '/';
curPath = s;
continue;
}
int eqp = s.indexOf('=');
if (eqp < 0) continue; // invalid entry
QString name = s.left(eqp).simplified();
QString value = s.mid(eqp+1).simplified();
if (name.isEmpty()) continue; // invalid entry
name.prepend(curPath);
if (forceLoCase) name = name.toLower();
res.insert(name, value);
}
fl.close();
}
return res;
}
void fixXDefaults(const QString &themeName)
{
QStringList lst;
{
QFile fl(QDir::home().path()+"/.Xdefaults");
if (fl.open(QIODevice::ReadOnly))
{
QTextStream stream;
stream.setDevice(&fl);
while (1)
{
QString s = stream.readLine();
if (s.isNull())
break;
// if the line does not contain Xcursor?theme, save it to a list
if (!(s.startsWith(QLatin1String("Xcursor")) && s.midRef(8).startsWith(QLatin1String("theme"))))
lst << s;
}
fl.close();
}
}
while (lst.size() > 0)
{
QString s(lst[lst.size()-1]);
if (!s.trimmed().isEmpty()) break;
lst.removeAt(lst.size()-1);
}
{
//QByteArray ba(themeName.toUtf8());
QFile fl(QDir::home().path()+"/.Xdefaults");
if (fl.open(QIODevice::WriteOnly))
{
QTextStream stream;
stream.setDevice(&fl);
foreach (const QString &s, lst)
{
stream << s << "\n";
}
stream << "\nXcursor.theme: " << themeName << "\n";
fl.close();
}
}
}
const QString findDefaultTheme()
{
QString res = "default";
QFile fl(QDir::home().path()+"/.Xdefaults");
if (fl.open(QIODevice::ReadOnly))
{
QTextStream stream;
stream.setDevice(&fl);
while (1)
{
QString s = stream.readLine();
if (s.isNull()) break;
if (!s.startsWith("Xcursor.theme:")) continue;
s.remove(0, 14);
s = s.trimmed();
if (s.isEmpty()) s = "default";
res = s;
}
fl.close();
}
return res;
}

@ -1,20 +0,0 @@
/* coded by Ketmar // Vampire Avalon (psyc://ketmar.no-ip.org/~Ketmar)
* (c)DWTFYW
*
* This program is free software. It comes without any warranty, to
* the extent permitted by applicable law. You can redistribute it
* and/or modify it under the terms of the Do What The Fuck You Want
* To Public License, Version 2, as published by Sam Hocevar. See
* http://sam.zoy.org/wtfpl/COPYING for more details.
*/
#ifndef CFGFILE_H
#define CFGFILE_H
#include <QMultiMap>
#include <QString>
QMultiMap<QString, QString> loadCfgFile(const QString &fname, bool forceLoCase=false);
void fixXDefaults(const QString &themeName);
const QString findDefaultTheme();
#endif

@ -1,276 +0,0 @@
/* Copyright © 2006-2007 Fredrik Höglund <fredrik@kde.org>
* (c)GPL2 (c)GPL3
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public
* License version 2 or at your option version 3 as published
* by the Free Software Foundation.
*
* 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; see the file COPYING. If not, write to
* the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301, USA.
*/
/*
* additional code: Ketmar // Vampire Avalon (psyc://ketmar.no-ip.org/~Ketmar)
*/
#include <QDebug>
#include "crtheme.h"
#include <QStyle>
#include <QX11Info>
#include "cfgfile.h"
#include <X11/Xlib.h>
#include <X11/Xcursor/Xcursor.h>
#include <X11/extensions/Xfixes.h>
// Static variable holding alternative names for some cursors
static QHash<QString, QString> alternatives;
///////////////////////////////////////////////////////////////////////////////
XCursorThemeData::XCursorThemeData(const QDir &aDir)
{
mHidden = false;
// parse configs, etc
mPath = aDir.path();
setName(aDir.dirName());
if (aDir.exists("index.theme")) parseIndexFile();
if (mDescription.isEmpty()) mDescription = "no description";
if (mTitle.isEmpty()) mTitle = mName;
}
void XCursorThemeData::parseIndexFile()
{
QMultiMap<QString, QString> cfg = loadCfgFile(mPath+"/index.theme", true);
if (cfg.contains("icon theme/name")) mTitle = cfg.values("icon theme/name").at(0).trimmed();
if (cfg.contains("icon theme/comment")) mDescription = cfg.values("icon theme/comment").at(0).trimmed();
if (cfg.contains("icon theme/example")) mSample = cfg.values("icon theme/example").at(0).trimmed();
if (cfg.contains("icon theme/hidden"))
{
QString hiddenValue = cfg.values("icon theme/hidden").at(0).toLower();
mHidden = hiddenValue=="false" ? false : true;
}
if (cfg.contains("icon theme/inherits"))
{
QStringList i = cfg.values("icon theme/inherits"), res;
for (int f = i.size()-1; f >= 0; f--) res << i.at(f).trimmed();
}
if (mDescription.startsWith("- Converted by")) mDescription.remove(0, 2);
}
QString XCursorThemeData::findAlternative(const QString &name) const
{
if (alternatives.isEmpty())
{
alternatives.reserve(18);
// Qt uses non-standard names for some core cursors.
// If Xcursor fails to load the cursor, Qt creates it with the correct name using the
// core protcol instead (which in turn calls Xcursor). We emulate that process here.
// Note that there's a core cursor called cross, but it's not the one Qt expects.
alternatives.insert("cross", "crosshair");
alternatives.insert("up_arrow", "center_ptr");
alternatives.insert("wait", "watch");
alternatives.insert("ibeam", "xterm");
alternatives.insert("size_all", "fleur");
alternatives.insert("pointing_hand", "hand2");
// Precomputed MD5 hashes for the hardcoded bitmap cursors in Qt and KDE.
// Note that the MD5 hash for left_ptr_watch is for the KDE version of that cursor.
alternatives.insert("size_ver", "00008160000006810000408080010102");
alternatives.insert("size_hor", "028006030e0e7ebffc7f7070c0600140");
alternatives.insert("size_bdiag", "c7088f0f3e6c8088236ef8e1e3e70000");
alternatives.insert("size_fdiag", "fcf1c3c7cd4491d801f1e1c78f100000");
alternatives.insert("whats_this", "d9ce0ab605698f320427677b458ad60b");
alternatives.insert("split_h", "14fef782d02440884392942c11205230");
alternatives.insert("split_v", "2870a09082c103050810ffdffffe0204");
alternatives.insert("forbidden", "03b6e0fcb3499374a867c041f52298f0");
alternatives.insert("left_ptr_watch", "3ecb610c1bf2410f44200f48c40d3599");
alternatives.insert("hand2", "e29285e634086352946a0e7090d73106");
alternatives.insert("openhand", "9141b49c8149039304290b508d208c40");
alternatives.insert("closedhand", "05e88622050804100c20044008402080");
}
return alternatives.value(name, QString());
}
QPixmap XCursorThemeData::icon() const
{
if (mIcon.isNull()) mIcon = createIcon();
return mIcon;
}
QImage XCursorThemeData::autoCropImage(const QImage &image) const
{
// Compute an autocrop rectangle for the image
QRect r(image.rect().bottomRight(), image.rect().topLeft());
const quint32 *pixels = reinterpret_cast<const quint32*>(image.bits());
for (int y = 0; y < image.height(); ++y)
{
for (int x = 0; x < image.width(); ++x)
{
if (*(pixels++))
{
if (x < r.left()) r.setLeft(x);
if (x > r.right()) r.setRight(x);
if (y < r.top()) r.setTop(y);
if (y > r.bottom()) r.setBottom(y);
}
}
}
// Normalize the rectangle
return image.copy(r.normalized());
}
static int nominalCursorSize(int iconSize)
{
for (int i = 512; i > 8; i /= 2)
{
if (i < iconSize) return i;
if ((i*0.75) < iconSize) return int(i*0.75);
}
return 8;
}
QPixmap XCursorThemeData::createIcon() const
{
int iconSize = QApplication::style()->pixelMetric(QStyle::PM_LargeIconSize);
int cursorSize = nominalCursorSize(iconSize);
QSize size = QSize(iconSize, iconSize);
QPixmap pixmap;
QImage image = loadImage(sample(), cursorSize);
if (image.isNull() && sample() != "left_ptr") image = loadImage("left_ptr", cursorSize);
if (!image.isNull())
{
// Scale the image if it's larger than the preferred icon size
if (image.width() > size.width() || image.height() > size.height())
{
image = image.scaled(size, Qt::KeepAspectRatio, Qt::SmoothTransformation);
pixmap = QPixmap::fromImage(image);
}
}
return pixmap;
}
XcursorImage *XCursorThemeData::xcLoadImage(const QString &image, int size) const
{
QByteArray cursorName = QFile::encodeName(image);
QByteArray themeName = QFile::encodeName(name());
return XcursorLibraryLoadImage(cursorName, themeName, size);
}
XcursorImages *XCursorThemeData::xcLoadImages(const QString &image, int size) const
{
QByteArray cursorName = QFile::encodeName(image);
QByteArray themeName = QFile::encodeName(name());
return XcursorLibraryLoadImages(cursorName, themeName, size);
}
unsigned long XCursorThemeData::loadCursorHandle(const QString &name, int size) const
{
if (size == -1) size = XcursorGetDefaultSize(QX11Info::display());
// Load the cursor images
XcursorImages *images = xcLoadImages(name, size);
if (!images) images = xcLoadImages(findAlternative(name), size);
// Fall back to a legacy cursor
//if (!images) return LegacyTheme::loadCursor(name);
if (!images) return 0;
// Create the cursor
unsigned long handle = (unsigned long)XcursorImagesLoadCursor(QX11Info::display(), images);
XcursorImagesDestroy(images);
//setCursorName(cursor, name);
return handle;
}
QImage XCursorThemeData::loadImage(const QString &name, int size) const
{
if (size == -1) size = XcursorGetDefaultSize(QX11Info::display());
// Load the image
XcursorImage *xcimage = xcLoadImage(name, size);
if (!xcimage) xcimage = xcLoadImage(findAlternative(name), size);
// Fall back to a legacy cursor
//if (!xcimage) return LegacyTheme::loadImage(name);
if (!xcimage) return QImage();
// Convert the XcursorImage to a QImage, and auto-crop it
QImage image((uchar *)xcimage->pixels, xcimage->width, xcimage->height, QImage::Format_ARGB32_Premultiplied);
image = autoCropImage(image);
XcursorImageDestroy(xcimage);
return image;
}
bool XCursorThemeData::isWritable() const
{
QFileInfo fi(path());
return fi.isWritable();
}
///////////////////////////////////////////////////////////////////////////////
bool haveXfixes()
{
bool result = false;
int event_base, error_base;
if (XFixesQueryExtension(QX11Info::display(), &event_base, &error_base))
{
int major, minor;
XFixesQueryVersion(QX11Info::display(), &major, &minor);
result = (major >= 2);
}
return result;
}
bool applyTheme(const XCursorThemeData &theme)
{
// Require the Xcursor version that shipped with X11R6.9 or greater, since
// in previous versions the Xfixes code wasn't enabled due to a bug in the
// build system (freedesktop bug #975).
if (!haveXfixes()) return false;
QByteArray themeName = QFile::encodeName(theme.name());
// Set up the proper launch environment for newly started apps
//k8:!!!:KToolInvocation::klauncher()->setLaunchEnv("XCURSOR_THEME", themeName);
// Update the Xcursor X resources
//k8:!!!:runRdb(0);
// Reload the standard cursors
QStringList names;
// Qt cursors
names << "left_ptr" << "up_arrow" << "cross" << "wait"
<< "left_ptr_watch" << "ibeam" << "size_ver" << "size_hor"
<< "size_bdiag" << "size_fdiag" << "size_all" << "split_v"
<< "split_h" << "pointing_hand" << "openhand"
<< "closedhand" << "forbidden" << "whats_this";
// X core cursors
names << "X_cursor" << "right_ptr" << "hand1"
<< "hand2" << "watch" << "xterm"
<< "crosshair" << "left_ptr_watch" << "center_ptr"
<< "sb_h_double_arrow" << "sb_v_double_arrow" << "fleur"
<< "top_left_corner" << "top_side" << "top_right_corner"
<< "right_side" << "bottom_right_corner" << "bottom_side"
<< "bottom_left_corner" << "left_side" << "question_arrow"
<< "pirate";
//QX11Info x11Info;
foreach (const QString &name, names)
{
Cursor cursor = (Cursor)theme.loadCursorHandle(name);
XFixesChangeCursorByName(QX11Info::display(), cursor, QFile::encodeName(name));
// FIXME: do we need to free the cursor?
}
return true;
}
QString getCurrentTheme()
{
return XcursorGetTheme(QX11Info::display());
}

@ -1,119 +0,0 @@
/* Copyright © 2006-2007 Fredrik Höglund <fredrik@kde.org>
* (c)GPL2 (c)GPL3
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public
* License version 2 or at your option version 3 as published
* by the Free Software Foundation.
*
* 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; see the file COPYING. If not, write to
* the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301, USA.
*/
/*
* additional code: Ketmar // Vampire Avalon (psyc://ketmar.no-ip.org/~Ketmar)
*/
#ifndef CRTHEME_H
#define CRTHEME_H
#include <QApplication>
#include <QCursor>
#include <QDir>
#include <QFile>
#include <QIcon>
#include <QImage>
#include <QString>
#include <QStringList>
#include <xcb/xcb.h>
#include <xcb/xproto.h>
///////////////////////////////////////////////////////////////////////////////
// X11 is SHIT!
struct _XcursorImage;
struct _XcursorImages;
typedef _XcursorImage XcursorImage;
typedef _XcursorImages XcursorImages;
///////////////////////////////////////////////////////////////////////////////
class XCursorThemeData
{
public:
enum ItemDataRole {
// Note: use printf "0x%08X\n" $(($RANDOM*$RANDOM))
// to define additional roles.
DisplayDetailRole = 0x24A3DAF8
};
XCursorThemeData(const QDir &aDir);
const QString &name() const { return mName; }
const QString &title() const { return mTitle; }
const QString &description() const { return mDescription; }
const QString &sample() const { return mSample; }
const QString &path() const { return mPath; }
bool isHidden() const { return mHidden; }
QPixmap icon() const;
const QStringList &inherits() const { return mInherits; }
inline void setName(const QString &name)
{
mName = name;
mHash = qHash(name);
}
bool isWritable() const;
/// Hash value for the internal name
uint hash() const { return mHash; }
/// Loads the cursor @p name, with the nominal size @p size.
/// If the theme doesn't have the cursor @p name, it should return
/// the default cursor from the active theme instead.
unsigned long loadCursorHandle(const QString &name, int size=-1) const;
/// Loads the cursor image @p name, with the nominal size @p size.
/// The image should be autocropped to the smallest possible size.
/// If the theme doesn't have the cursor @p name, it should return a null image.
QImage loadImage(const QString &name, int size=-1) const;
XcursorImage *xcLoadImage(const QString &image, int size=-1) const;
XcursorImages *xcLoadImages(const QString &image, int size=-1) const;
QString findAlternative(const QString &name) const;
protected:
void parseIndexFile();
/// Creates the icon returned by @ref icon().
QPixmap createIcon() const;
/// Convenience function for cropping an image.
QImage autoCropImage(const QImage &image) const;
protected:
QString mName;
QString mTitle;
QString mDescription;
QString mPath;
QString mSample;
mutable QPixmap mIcon;
bool mHidden;
uint mHash;
QStringList mInherits;
};
bool haveXfixes();
bool applyTheme(const XCursorThemeData &theme);
QString getCurrentTheme();
#endif

@ -1,141 +0,0 @@
/* Copyright © 2006-2007 Fredrik Höglund <fredrik@kde.org>
* (c)GPL2 (c)GPL3
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public
* License version 2 or at your option version 3 as published
* by the Free Software Foundation.
*
* 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; see the file COPYING. If not, write to
* the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301, USA.
*/
/*
* additional code: Ketmar // Vampire Avalon (psyc://ketmar.no-ip.org/~Ketmar)
*/
#include "itemdelegate.h"
#include "crtheme.h"
#include <QApplication>
#include <QModelIndex>
#include <QPainter>
namespace {
const int decorationMargin = 8;
}
///////////////////////////////////////////////////////////////////////////////
ItemDelegate::ItemDelegate(QObject *parent) : QAbstractItemDelegate(parent)
{
}
ItemDelegate::~ItemDelegate()
{
}
QString ItemDelegate::firstLine(const QModelIndex &index) const
{
if (index.isValid()) return index.model()->data(index, Qt::DisplayRole).toString();
return QString();
}
QString ItemDelegate::secondLine(const QModelIndex &index) const
{
if (index.isValid()) return index.model()->data(index, XCursorThemeData::DisplayDetailRole).toString();
return QString();
}
QPixmap ItemDelegate::decoration(const QModelIndex &index) const
{
if (index.isValid()) return qvariant_cast<QPixmap>(index.model()->data(index, Qt::DecorationRole));
return QPixmap();
}
QSize ItemDelegate::sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const
{
if (!index.isValid()) return QSize();
QFont normalfont = option.font;
QFont boldfont = normalfont;
boldfont.setBold(true);
// Extract the items we want to measure
QString firstRow = firstLine(index);
QString secondRow = secondLine(index);
// Compute the height
QFontMetrics fm1(boldfont);
QFontMetrics fm2(normalfont);
int height = fm1.lineSpacing() + fm2.lineSpacing();
height = qMax(height, option.decorationSize.height());
// Compute the text width
int width = fm1.width(firstRow);
width = qMax(width, fm2.width(secondRow));
// Add decoration width + margin
width += option.decorationSize.width()+decorationMargin;
return QSize(width, height+16);
}
QPalette::ColorRole ItemDelegate::foregroundRole(const QStyleOptionViewItem &option, const QModelIndex &index) const
{
Q_UNUSED(index)
if (option.state & QStyle::State_Selected) return QPalette::HighlightedText;
return QPalette::Text;
}
void ItemDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const
{
if (!index.isValid()) return;
painter->save();
QFont normalfont = option.font;
QFont boldfont = normalfont;
boldfont.setBold(true);
QString firstRow = firstLine(index);
QString secondRow = secondLine(index);
QPixmap pixmap = decoration(index);
QColor textcol = option.palette.color(foregroundRole(option, index));
// Draw the background
QStyleOptionViewItem opt = option;
QStyle *style = opt.widget ? opt.widget->style() : QApplication::style();
style->drawPrimitive(QStyle::PE_PanelItemViewItem, &opt, painter, opt.widget);
// Draw the icon
int x = option.rect.left()+(option.decorationSize.width()-pixmap.width()+decorationMargin)/2;
int y = option.rect.top()+(option.rect.height()-pixmap.height())/2;
QRect pixmapRect = QStyle::visualRect(option.direction, option.rect, QRect(x, y, pixmap.width(), pixmap.height()));
painter->drawPixmap(pixmapRect.x(), pixmapRect.y(), pixmap);
// Draw the text
QFontMetrics fm1(boldfont);
QFontMetrics fm2(normalfont);
int textAreaHeight = fm1.lineSpacing()+fm2.lineSpacing();
x = option.rect.left()+option.decorationSize.width()+decorationMargin;
int y1 = option.rect.top()+(option.rect.height()-textAreaHeight)/2;
int y2 = y1+fm1.lineSpacing();
QRect firstRowRect = QStyle::visualRect(option.direction, option.rect, QRect(x, y1, fm1.width(firstRow), fm1.lineSpacing()));
QRect secondRowRect = QStyle::visualRect(option.direction, option.rect, QRect(x, y2, fm2.width(secondRow), fm2.lineSpacing()));
painter->setPen(textcol);
// First line
painter->setFont(boldfont);
painter->drawText(firstRowRect, Qt::AlignCenter, firstRow);
// Second line
painter->setFont(normalfont);
painter->drawText(secondRowRect, Qt::AlignCenter, secondRow);
painter->restore();
}

@ -1,48 +0,0 @@
/* Copyright © 2006-2007 Fredrik Höglund <fredrik@kde.org>
* (c)GPL2 (c)GPL3
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public
* License version 2 or at your option version 3 as published
* by the Free Software Foundation.
*
* 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; see the file COPYING. If not, write to
* the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301, USA.
*/
/*
* additional code: Ketmar // Vampire Avalon (psyc://ketmar.no-ip.org/~Ketmar)
*/
#ifndef ITEMDELEGATE_H
#define ITEMDELEGATE_H
#include <QAbstractItemDelegate>
class QPainter;
class ItemDelegate : public QAbstractItemDelegate
{
Q_OBJECT
public:
ItemDelegate(QObject *parent = 0);
~ItemDelegate();
QSize sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const;
void paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const;
private:
QString firstLine(const QModelIndex &index) const;
QString secondLine(const QModelIndex &index) const;
QPixmap decoration(const QModelIndex &index) const;
QPalette::ColorRole foregroundRole(const QStyleOptionViewItem &option, const QModelIndex &index) const;
};
#endif

@ -1,44 +0,0 @@
/* coded by Ketmar // Vampire Avalon (psyc://ketmar.no-ip.org/~Ketmar)
* (c)DWTFYW
*
* This program is free software. It comes without any warranty, to
* the extent permitted by applicable law. You can redistribute it
* and/or modify it under the terms of the Do What The Fuck You Want
* To Public License, Version 2, as published by Sam Hocevar. See
* http://sam.zoy.org/wtfpl/COPYING for more details.
*/
//#include <QtCore>
#include <QDebug>
#include <XdgIcon>
#include <LXQt/Settings>
#include "main.h"
#include "lxqttranslate.h"
#include <LXQt/Application>
#include <QFile>
#include <QImage>
#include <QString>
#include <QStringList>
#include <QTextCodec>
#include <QTextStream>
///////////////////////////////////////////////////////////////////////////////
int main (int argc, char *argv[])
{
//QTextCodec::setCodecForCStrings(QTextCodec::codecForName("koi8-r"));
//QTextCodec::setCodecForLocale(QTextCodec::codecForName("koi8-r"));
LXQt::Application app(argc, argv);
app.setAttribute(Qt::AA_UseHighDpiPixmaps, true);
TRANSLATE_APP;
//qDebug() << findDefaultTheme() << getCurrentTheme();
SelectWnd *sw = new SelectWnd;
sw->show();
sw->setCurrent();
return app.exec();
}

@ -1,19 +0,0 @@
/* coded by Ketmar // Vampire Avalon (psyc://ketmar.no-ip.org/~Ketmar)
* (c)DWTFYW
*
* This program is free software. It comes without any warranty, to
* the extent permitted by applicable law. You can redistribute it
* and/or modify it under the terms of the Do What The Fuck You Want
* To Public License, Version 2, as published by Sam Hocevar. See
* http://sam.zoy.org/wtfpl/COPYING for more details.
*/
#ifndef MAIN_H
#define MAIN_H
#include "cfgfile.h"
#include "crtheme.h"
#include "selectwnd.h"
#endif

@ -1,39 +0,0 @@
.TH lxqt-config-cursor "1" "September 2012" "LXQt\ 0.7.0" "LXQt\ Cursor settings"
.SH NAME
lxqt-config-cursor \- Application of \fBLXQt\fR: the faster and lighter Qt Desktop Environment
.SH SYNOPSIS
.B lxqt-config-cursor
.br
.SH DESCRIPTION
This is a simple GUI cursor theme configuration (at the moment) for the LXQt desktop environment.
Also can manage theme installation for it (locally for/per user only).
.P
\fBLXQt\fR is an advanced, easy-to-use, and fast desktop environment based on Qt
technologies, ships several core desktop components, all of which are optional:
.P
* Panel
* Desktop
* Application launcher
* Settings center \fI(related to this)\fR
* Session handler
* Polkit handler
* SSH password access
* Display manager handler
.P
These components perform similar actions to those available in other desktop
environments, and their name is self-descriptive. They are usually not launched
by hand but automatically, when choosing a \fBLXQt\-qt\fR session in the Display
Manager.
.P
.SH "REPORTING BUGS"
Report bugs to https://github.com/lxde/lxqt/issues
.SH "SEE ALSO"
\fBLXQt\fR has been tailored for users who value simplicity, speed, and
an intuitive interface, also intended for less powerful machines. See also:
.\" any module must refers to session app, for more info on start it
.P
\fBlxqt-config(1)\fR LXQt application for performing settings on many applications
.P
.SH AUTHOR
This manual page was created by \fBPICCORO Lenz McKAY\fR \fI<mckaygerhard@gmail.com>\fR
for \fBLXQt\fR project and VENENUX GNU/Linux but can be used by others.

@ -1,221 +0,0 @@
/* Copyright © 2003-2007 Fredrik Höglund <fredrik@kde.org>
* (c)GPL2 (c)GPL3
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public
* License version 2 as published by the Free Software Foundation.
*
* 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; see the file COPYING. If not, write to
* the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301, USA.
*/
/*
* additional code: Ketmar // Vampire Avalon (psyc://ketmar.no-ip.org/~Ketmar)
*/
#include <QDebug>
#include <QPainter>
#include <QMouseEvent>
#include "previewwidget.h"
#include "crtheme.h"
#include <X11/Xlib.h>
#include <X11/Xcursor/Xcursor.h>
#include <QX11Info>
#include <QWindow>
namespace {
// Preview cursors
const char *const cursorNames[] = {
"left_ptr",
"left_ptr_watch",
"wait",
"pointing_hand",
"whats_this",
"ibeam",
"size_all",
"size_fdiag",
"cross",
"split_h",
"size_ver",
"size_hor",
"size_bdiag",
"split_v",
};
const int numCursors = 9; // The number of cursors from the above list to be previewed
const int previewSize = 24; // The nominal cursor size to be used in the preview widget
const int cursorSpacing = 20; // Spacing between preview cursors
const int widgetMinWidth = 10; // The minimum width of the preview widget
const int widgetMinHeight = 48; // The minimum height of the preview widget
}
///////////////////////////////////////////////////////////////////////////////
class PreviewCursor
{
public:
PreviewCursor (const XCursorThemeData &theme, const QString &name);
~PreviewCursor () {}
const QPixmap &pixmap () const { return mPixmap; }
int width () const { return mPixmap.width(); }
int height () const { return mPixmap.height(); }
inline QRect rect () const;
void setPosition (const QPoint &p) { mPos = p; }
void setPosition (int x, int y) { mPos = QPoint(x, y); }
QPoint position () const { return mPos; }
operator const xcb_cursor_t& () const { return mCursorHandle; }
operator const QPixmap& () const { return pixmap(); }
private:
QPixmap mPixmap;
xcb_cursor_t mCursorHandle;
QPoint mPos;
};
///////////////////////////////////////////////////////////////////////////////
PreviewCursor::PreviewCursor(const XCursorThemeData &theme, const QString &name)
{
// Create the preview pixmap
QImage image = theme.loadImage(name, previewSize);
if (image.isNull()) return;
int maxSize = previewSize*2;
if (image.height() > maxSize || image.width() > maxSize)
image = image.scaled(maxSize, maxSize, Qt::KeepAspectRatio, Qt::SmoothTransformation);
mPixmap = QPixmap::fromImage(image);
// load the cursor
mCursorHandle = theme.loadCursorHandle(name, previewSize);
}
QRect PreviewCursor::rect() const
{
return QRect(mPos, mPixmap.size()).adjusted(-(cursorSpacing/2), -(cursorSpacing/2), cursorSpacing/2, cursorSpacing/2);
}
///////////////////////////////////////////////////////////////////////////////
PreviewWidget::PreviewWidget(QWidget *parent) : QWidget(parent)
{
setMouseTracking(true);
mCurrent = NULL;
}
PreviewWidget::~PreviewWidget()
{
qDeleteAll(mList);
mList.clear();
}
// Since Qt5, wrapping a Cursor handle with QCursor is no longer supported.
// So we have to do it ourselves. I really hate Qt 5!
void PreviewWidget::setCursorHandle(xcb_cursor_t cursorHandle)
{
WId wid = nativeParentWidget()->windowHandle()->winId();
xcb_change_window_attributes(QX11Info::connection(), wid, XCB_CW_CURSOR, &cursorHandle);
xcb_flush(QX11Info::connection());
}
QSize PreviewWidget::sizeHint() const
{
int totalWidth = 0, maxHeight = 0;
foreach (const PreviewCursor *c, mList)
{
totalWidth += c->width();
maxHeight = qMax(c->height(), maxHeight);
}
totalWidth += (mList.count()-1)*cursorSpacing;
maxHeight = qMax(maxHeight, widgetMinHeight);
return QSize(qMax(totalWidth, widgetMinWidth), qMax(height(), maxHeight));
}
void PreviewWidget::layoutItems()
{
if (!mList.isEmpty())
{
QSize size = sizeHint();
int cursorWidth = size.width()/mList.count();
int nextX = (width()-size.width())/2;
foreach (PreviewCursor *c, mList)
{
c->setPosition(nextX+(cursorWidth-c->width())/2, (height()-c->height())/2);
nextX += cursorWidth;
}
}
mNeedLayout = false;
}
void PreviewWidget::setTheme(const XCursorThemeData &theme)
{
qDeleteAll(mList);
mList.clear();
for (int i = 0; i < numCursors; ++i) mList << new PreviewCursor(theme, cursorNames[i]);
mNeedLayout = true;
updateGeometry();
mCurrent = NULL;
update();
}
void PreviewWidget::clearTheme()
{
qDeleteAll(mList);
mList.clear();
mCurrent = NULL;
update();
}
void PreviewWidget::paintEvent(QPaintEvent *)
{
QPainter p(this);
if (mNeedLayout) layoutItems();
foreach (const PreviewCursor *c, mList)
{
if (c->pixmap().isNull()) continue;
p.drawPixmap(c->position(), *c);
}
}
void PreviewWidget::mouseMoveEvent(QMouseEvent *e)
{
if (mNeedLayout) layoutItems();
foreach (const PreviewCursor *c, mList)
{
if (c->rect().contains(e->pos()))
{
if (c != mCurrent)
{
// NOTE: we have to set the Qt cursor value to something other than Qt::ArrowCursor
// Otherwise, though we set the xcursor handle to the underlying window, Qt still
// thinks that the current cursor is Qt::ArrowCursor and will not restore the cursor
// later when we call setCursor(Qt::ArrowCursor). So, we set it to BlankCursor to
// cheat Qt so it knows that the current cursor is not Qt::ArrowCursor.
// This is a dirty hack, but without this, Qt cannot restore Qt::ArrowCursor later.
setCursor(Qt::BlankCursor);
setCursorHandle(*c);
mCurrent = c;
}
return;
}
}
setCursor(Qt::ArrowCursor);
mCurrent = NULL;
}
void PreviewWidget::resizeEvent(QResizeEvent *)
{
if (!mList.isEmpty()) mNeedLayout = true;
}

@ -1,60 +0,0 @@
/* Copyright © 2003-2007 Fredrik Höglund <fredrik@kde.org>
* (c)GPL2
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public
* License version 2 as published by the Free Software Foundation.
*
* 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; see the file COPYING. If not, write to
* the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301, USA.
*/
/*
* additional code: Ketmar // Vampire Avalon (psyc://ketmar.no-ip.org/~Ketmar)
*/
#ifndef PREVIEWWIDGET_H
#define PREVIEWWIDGET_H
#include <QWidget>
#include <xcb/xcb.h>
#include <xcb/xproto.h>
class XCursorThemeData;
class PreviewCursor;
class PreviewWidget : public QWidget
{
Q_OBJECT
public:
PreviewWidget (QWidget *parent=0);
~PreviewWidget ();
void setTheme (const XCursorThemeData &theme);
void clearTheme ();
QSize sizeHint () const;
void setCursorHandle(xcb_cursor_t cursorHandle);
protected:
void paintEvent (QPaintEvent *e);
void mouseMoveEvent(QMouseEvent *e);
void resizeEvent (QResizeEvent *e);
private:
void layoutItems ();
QList<PreviewCursor *> mList;
const PreviewCursor *mCurrent;
bool mNeedLayout;
};
#endif

@ -1,233 +0,0 @@
/* coded by Ketmar // Vampire Avalon (psyc://ketmar.no-ip.org/~Ketmar)
* (c)DWTFYW
*
* This program is free software. It comes without any warranty, to
* the extent permitted by applicable law. You can redistribute it
* and/or modify it under the terms of the Do What The Fuck You Want
* To Public License, Version 2, as published by Sam Hocevar. See
* http://sam.zoy.org/wtfpl/COPYING for more details.
*/
// 2014-04-10 modified by Hong Jen Yee (PCMan) for integration with lxqt-config-input
#include <QDebug>
#include "selectwnd.h"
#include "ui_selectwnd.h"
#include <QKeyEvent>
#include <QMessageBox>
#include <QTimer>
#include <QWidget>
#include <QPushButton>
#include <QToolTip>
#include "cfgfile.h"
#include "crtheme.h"
#include "thememodel.h"
#include "itemdelegate.h"
#include "xcrimg.h"
#include "xcrxcur.h"
#include "xcrtheme.h"
#include <LXQt/Settings>
#include <XdgIcon>
#include <QTextStream>
#include <QProcess>
#define HOME_ICON_DIR QDir::homePath() + "/.icons"
SelectWnd::SelectWnd(LXQt::Settings* settings, QWidget *parent)
: QWidget(parent),
mSettings(settings),
ui(new Ui::SelectWnd)
{
ui->setupUi(this);
ui->warningLabel->hide();
mModel = new XCursorThemeModel(this);
int size = style()->pixelMetric(QStyle::PM_LargeIconSize);
ui->lbThemes->setModel(mModel);
ui->lbThemes->setItemDelegate(new ItemDelegate(this));
ui->lbThemes->setIconSize(QSize(size, size));
ui->lbThemes->setSelectionMode(QAbstractItemView::SingleSelection);
// Make sure we find out about selection changes
connect(ui->lbThemes->selectionModel(), SIGNAL(currentChanged(const QModelIndex &, const QModelIndex &)),
SLOT(currentChanged(const QModelIndex &, const QModelIndex &)));
// display/hide warning label
connect(mModel, SIGNAL(modelReset()),
this, SLOT(handleWarning()));
connect(mModel, SIGNAL(rowsInserted(const QModelIndex&, int, int)),
this, SLOT(handleWarning()));
connect(mModel, SIGNAL(rowsRemoved(const QModelIndex&, int, int)),
this, SLOT(handleWarning()));
connect(ui->warningLabel, SIGNAL(showDirInfo()),
this, SLOT(showDirInfo()));
// Disable the install button if we can't install new themes to ~/.icons,
// or Xcursor isn't set up to look for cursor themes there
ui->btInstall->setEnabled(mModel->searchPaths().contains(HOME_ICON_DIR) && iconsIsWritable());
// TODO/FIXME: btInstall functionality
ui->btInstall->hide();
ui->btRemove->hide();
//QTimer::singleShot(0, this, SLOT(setCurrent()));
handleWarning();
}
SelectWnd::~SelectWnd()
{
delete ui;
}
void SelectWnd::setCurrent()
{
ui->lbThemes->selectionModel()->clear();
QString ct = getCurrentTheme();
mAppliedIndex = mModel->defaultIndex();
if (!ct.isEmpty()) mAppliedIndex = mModel->findIndex(ct);
else mAppliedIndex = mModel->defaultIndex();
if (mAppliedIndex.isValid())
{
const XCursorThemeData *theme = mModel->theme(mAppliedIndex);
// Select the current theme
selectRow(mAppliedIndex);
ui->lbThemes->scrollTo(mAppliedIndex, QListView::PositionAtCenter);
// Update the preview widget as well
if (theme) ui->preview->setTheme(*theme);// else ui->preview->clearTheme();
}
}
bool SelectWnd::iconsIsWritable() const
{
const QFileInfo icons = QFileInfo(HOME_ICON_DIR);
const QFileInfo home = QFileInfo(QDir::homePath());
return ((icons.exists() && icons.isDir() && icons.isWritable()) || (!icons.exists() && home.isWritable()));
}
/*
void SelectWnd::keyPressEvent(QKeyEvent *e)
{
if (e->key() == Qt::Key_Escape) close();
}
*/
void SelectWnd::selectRow(int row) const
{
// Create a selection that stretches across all columns
QModelIndex from = mModel->index(row, 0);
QModelIndex to = mModel->index(row, mModel->columnCount()-1);
QItemSelection selection(from, to);
ui->lbThemes->selectionModel()->select(selection, QItemSelectionModel::Select);
ui->lbThemes->selectionModel()->setCurrentIndex(mAppliedIndex, QItemSelectionModel::NoUpdate);
}
void SelectWnd::currentChanged(const QModelIndex &current, const QModelIndex &previous)
{
Q_UNUSED(previous)
if (current.isValid()) {
const XCursorThemeData *theme = mModel->theme(current);
if (theme) {
ui->preview->setTheme(*theme);
ui->btRemove->setEnabled(theme->isWritable());
} else {
ui->preview->clearTheme();
}
// directly apply the current settings
applyCurrent();
} else {
ui->preview->clearTheme();
}
//emit changed(mAppliedIndex != current);
}
void SelectWnd::on_btInstall_clicked()
{
qDebug() << "'install' clicked";
}
void SelectWnd::applyCurrent()
{
//qDebug() << "'set' clicked";
const XCursorThemeData *theme = mModel->theme(ui->lbThemes->currentIndex());
if (!theme) return;
applyTheme(*theme);
fixXDefaults(theme->name());
// call xrdb to merge the new settings in ~/.Xdefaults
// FIXME: need to check if we're running in X?
QProcess xrdb;
xrdb.start("xrdb -merge " + QDir::home().path() + "/.Xdefaults");
xrdb.waitForFinished();
// old razor-qt and lxqt versions use $XCURSOR_THEME environment variable
// for this, but it's less flexible and more problematic. Let's deprecate its use.
mSettings->beginGroup("Environment");
mSettings->remove("XCURSOR_THEME"); // ensure that we're not using XCURSOR_THEME
mSettings->endGroup();
// save to Mouse/cursor_theme instead
mSettings->beginGroup("Mouse");
mSettings->setValue("cursor_theme", theme->name());
mSettings->endGroup();
// The XCURSOR_THEME environment varialbe does not work sometimes.
// Besides, XDefaults values are not used by Qt.
// So, let's write the new theme name to ~/.icons/default/index.theme.
// This is the most reliable way.
// QSettings will encode the group name "Icon Theme" to "Icon%20Theme" and there is no way to turn it off.
// So let's not use it here. :-(
QString dirPath = HOME_ICON_DIR + "/default";
QDir().mkpath(dirPath); // ensure the existence of the ~/.icons/default dir
QFile indexTheme(dirPath + "/index.theme");
if(indexTheme.open(QIODevice::WriteOnly|QIODevice::Truncate))
{
QTextStream(&indexTheme) <<
"# Written by lxqt-config-appearance\n" <<
"[Icon Theme]\n" <<
"Name=Default\n" <<
"Comment=Default cursor theme\n" <<
"Inherits=" << theme->name() << "\n";
indexTheme.close();
}
}
void SelectWnd::on_btRemove_clicked()
{
qDebug() << "'remove' clicked";
const XCursorThemeData *theme = mModel->theme(ui->lbThemes->currentIndex());
if (!theme) return;
QString ct = getCurrentTheme();
if (ct == theme->name())
{
QMessageBox::warning(this, tr("XCurTheme error"),
tr("You can't remove active theme!"), QMessageBox::Ok, QMessageBox::Ok);
return;
}
QDir d(theme->path());
ui->preview->clearTheme();
mModel->removeTheme(ui->lbThemes->currentIndex());
removeXCursorTheme(d);
}
void SelectWnd::handleWarning()
{
bool empty = mModel->rowCount();
ui->warningLabel->setVisible(!empty);
ui->preview->setVisible(empty);
ui->infoLabel->setVisible(empty);
}
void SelectWnd::showDirInfo()
{
QToolTip::showText(mapToGlobal(ui->warningLabel->buttonPos()), mModel->searchPaths().join("\n"));
}

@ -1,65 +0,0 @@
/* coded by Ketmar // Vampire Avalon (psyc://ketmar.no-ip.org/~Ketmar)
* (c)DWTFYW
*
* This program is free software. It comes without any warranty, to
* the extent permitted by applicable law. You can redistribute it
* and/or modify it under the terms of the Do What The Fuck You Want
* To Public License, Version 2, as published by Sam Hocevar. See
* http://sam.zoy.org/wtfpl/COPYING for more details.
*/
// 2014-04-10 modified by Hong Jen Yee (PCMan) for integration with lxqt-config-input
#ifndef SELECTWND_H
#define SELECTWND_H
#include <QObject>
#include <QWidget>
#include <QPersistentModelIndex>
#include <lxqtglobals.h>
namespace LXQt {
class Settings;
}
namespace Ui {
class SelectWnd;
}
class XCursorThemeModel;
class LXQT_API SelectWnd : public QWidget
{
Q_OBJECT
public:
SelectWnd (LXQt::Settings* settings, QWidget *parent=0);
~SelectWnd ();
public slots:
void setCurrent ();
protected:
// void keyPressEvent (QKeyEvent *e);
private:
bool iconsIsWritable () const;
void selectRow (int) const;
void selectRow (const QModelIndex &index) const { selectRow(index.row()); }
void applyCurrent ();
private slots:
void currentChanged (const QModelIndex &current, const QModelIndex &previous);
void on_btInstall_clicked ();
void on_btRemove_clicked ();
void handleWarning();
void showDirInfo();
private:
XCursorThemeModel *mModel;
QPersistentModelIndex mAppliedIndex;
LXQt::Settings* mSettings;
Ui::SelectWnd *ui;
};
#endif

@ -1,114 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>SelectWnd</class>
<widget class="QWidget" name="SelectWnd">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>384</width>
<height>353</height>
</rect>
</property>
<property name="windowTitle">
<string>LXQt Mouse Theme Configuration</string>
</property>
<layout class="QGridLayout" name="gridLayout">
<item row="0" column="0" colspan="4">
<widget class="QLabel" name="infoLabel">
<property name="text">
<string>Select the cursor theme you want to use (hover preview to test cursor). &lt;b&gt;LXQt session needs restart after this change&lt;/b&gt;:</string>
</property>
<property name="wordWrap">
<bool>true</bool>
</property>
</widget>
</item>
<item row="1" column="0" colspan="4">
<widget class="WarningLabel" name="warningLabel" native="true"/>
</item>
<item row="2" column="0" colspan="4">
<widget class="PreviewWidget" name="preview" native="true">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>0</width>
<height>48</height>
</size>
</property>
</widget>
</item>
<item row="3" column="0" colspan="4">
<widget class="QListView" name="lbThemes">
<property name="editTriggers">
<set>QAbstractItemView::NoEditTriggers</set>
</property>
<property name="showDropIndicator" stdset="0">
<bool>false</bool>
</property>
<property name="alternatingRowColors">
<bool>true</bool>
</property>
<property name="verticalScrollMode">
<enum>QAbstractItemView::ScrollPerPixel</enum>
</property>
</widget>
</item>
<item row="4" column="0">
<spacer>
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>174</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item row="4" column="1">
<widget class="QPushButton" name="btInstall">
<property name="enabled">
<bool>false</bool>
</property>
<property name="text">
<string>&amp;Install New Theme...</string>
</property>
</widget>
</item>
<item row="4" column="2">
<widget class="QPushButton" name="btRemove">
<property name="text">
<string>&amp;Remove Theme</string>
</property>
</widget>
</item>
</layout>
</widget>
<customwidgets>
<customwidget>
<class>PreviewWidget</class>
<extends>QWidget</extends>
<header>previewwidget.h</header>
</customwidget>
<customwidget>
<class>WarningLabel</class>
<extends>QWidget</extends>
<header>warninglabel.h</header>
<container>1</container>
</customwidget>
</customwidgets>
<tabstops>
<tabstop>lbThemes</tabstop>
<tabstop>btInstall</tabstop>
<tabstop>btRemove</tabstop>
</tabstops>
<resources/>
<connections/>
</ui>

@ -1,328 +0,0 @@
/* Copyright © 2005-2007 Fredrik Höglund <fredrik@kde.org>
* (c)GPL2 (c)GPL3
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public
* License version 2 or at your option version 3 as published
* by the Free Software Foundation.
*
* 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; see the file COPYING. If not, write to
* the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301, USA.
*/
/*
* additional code: Ketmar // Vampire Avalon (psyc://ketmar.no-ip.org/~Ketmar)
*/
#include <QDebug>
#include "thememodel.h"
#include <QDir>
#include "crtheme.h"
#include "cfgfile.h"
#include <X11/Xlib.h>
#include <X11/Xcursor/Xcursor.h>
//#define DUMP_FOUND_THEMES
///////////////////////////////////////////////////////////////////////////////
XCursorThemeModel::XCursorThemeModel (QObject *parent) : QAbstractTableModel(parent)
{
insertThemes();
}
XCursorThemeModel::~XCursorThemeModel()
{
qDeleteAll(mList);
mList.clear();
}
QVariant XCursorThemeModel::headerData(int section, Qt::Orientation orientation, int role) const
{
// Only provide text for the headers
if (role != Qt::DisplayRole) return QVariant();
// Horizontal header labels
if (orientation == Qt::Horizontal)
{
switch (section)
{
case NameColumn: return tr("Name");
case DescColumn: return tr("Description");
default: return QVariant();
}
}
// Numbered vertical header lables
return QString(section);
}
QVariant XCursorThemeModel::data(const QModelIndex &index, int role) const
{
if (!index.isValid() || index.row() < 0 || index.row() >= mList.count()) return QVariant();
const XCursorThemeData *theme = mList.at(index.row());
// Text label
if (role == Qt::DisplayRole)
{
switch (index.column())
{
case NameColumn: return theme->title();
case DescColumn: return theme->description();
default: return QVariant();
}
}
// Description for the first name column
if (role == XCursorThemeData::DisplayDetailRole && index.column() == NameColumn) return theme->description();
// Icon for the name column
if (role == Qt::DecorationRole && index.column() == NameColumn) return theme->icon();
//
return QVariant();
}
void XCursorThemeModel::sort(int column, Qt::SortOrder order)
{
Q_UNUSED(column);
Q_UNUSED(order);
// Sorting of the model isn't implemented, as the KCM currently uses
// a sorting proxy model.
}
const XCursorThemeData *XCursorThemeModel::theme(const QModelIndex &index)
{
if (!index.isValid()) return NULL;
if (index.row() < 0 || index.row() >= mList.count()) return NULL;
return mList.at(index.row());
}
QModelIndex XCursorThemeModel::findIndex(const QString &name)
{
uint hash = qHash(name);
for (int i = 0; i < mList.count(); ++i)
{
const XCursorThemeData *theme = mList.at(i);
if (theme->hash() == hash) return index(i, 0);
}
return QModelIndex();
}
QModelIndex XCursorThemeModel::defaultIndex()
{
return findIndex(mDefaultName);
}
const QStringList XCursorThemeModel::searchPaths()
{
if (!mBaseDirs.isEmpty()) return mBaseDirs;
// Get the search path from Xcursor
QString path = XcursorLibraryPath();
// Separate the paths
mBaseDirs = path.split(':', QString::SkipEmptyParts);
// Remove duplicates
QMutableStringListIterator i(mBaseDirs);
while (i.hasNext())
{
const QString path = i.next();
QMutableStringListIterator j(i);
while (j.hasNext()) if (j.next() == path) j.remove();
}
// Expand all occurrences of ~/ to the home dir
mBaseDirs.replaceInStrings(QRegExp("^~\\/"), QDir::home().path() + '/');
return mBaseDirs;
}
bool XCursorThemeModel::hasTheme(const QString &name) const
{
const uint hash = qHash(name);
foreach (const XCursorThemeData *theme, mList) if (theme->hash() == hash) return true;
return false;
}
bool XCursorThemeModel::isCursorTheme(const QString &theme, const int depth)
{
// Prevent infinite recursion
if (depth > 10) return false;
// Search each icon theme directory for 'theme'
foreach (const QString &baseDir, searchPaths())
{
QDir dir(baseDir);
if (!dir.exists() || !dir.cd(theme)) continue;
// If there's a cursors subdir, we'll assume this is a cursor theme
if (dir.exists("cursors")) return true;
// If the theme doesn't have an index.theme file, it can't inherit any themes
if (!dir.exists("index.theme")) continue;
// Open the index.theme file, so we can get the list of inherited themes
QMultiMap<QString, QString> cfg = loadCfgFile(dir.path()+"/index.theme", true);
QStringList inherits = cfg.values("icon theme/inherits");
// Recurse through the list of inherited themes, to check if one of them is a cursor theme
// note that items are reversed
for (int f = inherits.size()-1; f >= 0; --f)
{
QString inh = inherits.at(f);
// Avoid possible DoS
if (inh == theme) continue;
if (isCursorTheme(inh, depth+1)) return true;
}
}
return false;
}
bool XCursorThemeModel::handleDefault(const QDir &themeDir)
{
QFileInfo info(themeDir.path());
// If "default" is a symlink
if (info.isSymLink())
{
QFileInfo target(info.symLinkTarget());
if (target.exists() && (target.isDir() || target.isSymLink())) mDefaultName = target.fileName();
return true;
}
// If there's no cursors subdir, or if it's empty
if (!themeDir.exists("cursors") ||
QDir(themeDir.path() + "/cursors").entryList(QDir::Files |
QDir::NoDotAndDotDot).isEmpty())
{
if (themeDir.exists("index.theme"))
{
XCursorThemeData theme(themeDir);
if (!theme.inherits().isEmpty()) mDefaultName = theme.inherits().at(0);
}
return true;
}
mDefaultName = QLatin1String("default");
return false;
}
//#define DUMP_FOUND_THEMES
void XCursorThemeModel::processThemeDir(const QDir &themeDir)
{
#ifdef DUMP_FOUND_THEMES
qDebug() << "looking at:" << themeDir.path();
#endif
bool haveCursors = themeDir.exists("cursors");
// Special case handling of "default", since it's usually either a
// symlink to another theme, or an empty theme that inherits another theme
if (mDefaultName.isNull() && themeDir.dirName() == "default")
{
if (handleDefault(themeDir)) return;
}
// If the directory doesn't have a cursors subdir and lacks an
// index.theme file it can't be a cursor theme.
if (!themeDir.exists("index.theme") && !haveCursors)
{
//qDebug() << "IS NOT THEME" << themeDir;
return;
}
// Create a cursor theme object for the theme dir
XCursorThemeData *theme = new XCursorThemeData(themeDir);
// Skip this theme if it's hidden
#ifdef DUMP_FOUND_THEMES
qDebug() <<
" theme name:" << theme->name() <<
"\n theme title:" << theme->title() <<
"\n theme desc:" << theme->description() <<
"\n theme sample:" << theme->sample() <<
"\n theme inherits:" << theme->inherits();
#endif
if (theme->isHidden())
{
//qDebug() << "HIDDEN THEME" << theme->name() << themeDir;
delete theme;
return;
}
// If there's no cursors subdirectory we'll do a recursive scan
// to check if the theme inherits a theme with one
if (!haveCursors)
{
bool foundCursorTheme = false;
foreach (const QString &name, theme->inherits())
{
if ((foundCursorTheme = isCursorTheme(name))) break;
}
if (!foundCursorTheme)
{
delete theme;
return;
}
}
// Append the theme to the list
mList.append(theme);
}
void XCursorThemeModel::insertThemes()
{
// Scan each base dir for Xcursor themes and add them to the list
foreach (const QString &baseDir, searchPaths())
{
QDir dir(baseDir);
//qDebug() << "TOPLEVEL" << baseDir;
if (!dir.exists()) continue;
//qDebug() << " continue passed";
// Process each subdir in the directory
foreach (const QString &name, dir.entryList(QDir::AllDirs |
QDir::NoDotAndDotDot | QDir::Readable | QDir::Executable))
{
//qDebug() << " SUBDIR" << name;
// Don't process the theme if a theme with the same name already exists
// in the list. Xcursor will pick the first one it finds in that case,
// and since we use the same search order, the one Xcursor picks should
// be the one already in the list
if (hasTheme(name))
{
qDebug() << "duplicate theme:" << dir.path()+name;
}
if (!dir.cd(name))
{
qDebug() << "can't cd:" << dir.path()+name;
continue;
}
processThemeDir(dir);
dir.cdUp(); // Return to the base dir
}
}
// The theme Xcursor will end up using if no theme is configured
//if (mDefaultName.isNull() || !hasTheme(mDefaultName)) mDefaultName = legacy->name();
}
bool XCursorThemeModel::addTheme(const QDir &dir)
{
XCursorThemeData *theme = new XCursorThemeData(dir);
// Don't add the theme to the list if it's hidden
if (theme->isHidden())
{
delete theme;
return false;
}
// If an item with the same name already exists in the list,
// we'll remove it before inserting the new one.
for (int i = 0; i < mList.count(); ++i)
{
if (mList.at(i)->hash() == theme->hash())
{
removeTheme(index(i, 0));
break;
}
}
// Append the theme to the list
beginInsertRows(QModelIndex(), rowCount(), rowCount());
mList.append(theme);
endInsertRows();
return true;
}
void XCursorThemeModel::removeTheme(const QModelIndex &index)
{
if (!index.isValid()) return;
beginRemoveRows(QModelIndex(), index.row(), index.row());
delete mList.takeAt(index.row());
endRemoveRows();
}

@ -1,116 +0,0 @@
/* Copyright © 2005-2007 Fredrik Höglund <fredrik@kde.org>
* (c)GPL2 (c)GPL3
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public
* License version 2 or at your option version 3 as published
* by the Free Software Foundation.
*
* 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; see the file COPYING. If not, write to
* the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301, USA.
*/
/*
* additional code: Ketmar // Vampire Avalon (psyc://ketmar.no-ip.org/~Ketmar)
*/
#ifndef THEMEMODEL_H
#define THEMEMODEL_H
#include <QAbstractTableModel>
#include <QStringList>
class QDir;
class XCursorThemeData;
// The two TableView/TreeView columns provided by the model
enum Columns { NameColumn = 0, DescColumn };
/**
* The XCursorThemeModel class provides a model for all locally installed
* Xcursor themes, and the KDE/Qt legacy bitmap theme.
*
* This class automatically scans the locations in the file system from
* which Xcursor loads cursors, and creates an internal list of all
* available cursor themes.
*
* The model provides this theme list to item views in the form of a list
* of rows with two columns; the first column has the theme's descriptive
* name and its sample cursor as its icon, and the second column contains
* the theme's description.
*
* Additional Xcursor themes can be added to a model after it's been
* created, by calling addTheme(), which takes QDir as a parameter,
* with the themes location. The intention is for this function to be
* called when a new Xcursor theme has been installed, after the model
* was instantiated.
*
* The KDE legacy theme is a read-only entry, with the descriptive name
* "KDE Classic", and the internal name "#kde_legacy#".
*
* Calling defaultIndex() will return the index of the theme Xcursor
* will use if the user hasn't explicitly configured a cursor theme.
*/
class XCursorThemeModel : public QAbstractTableModel
{
Q_OBJECT
public:
XCursorThemeModel (QObject *parent = 0);
~XCursorThemeModel ();
inline int columnCount (const QModelIndex &parent = QModelIndex()) const;
inline int rowCount (const QModelIndex &parent = QModelIndex()) const;
QVariant headerData (int section, Qt::Orientation orientation, int role) const;
QVariant data (const QModelIndex &index, int role) const;
void sort (int column, Qt::SortOrder order = Qt::AscendingOrder);
/// Returns the CursorTheme at @p index.
const XCursorThemeData *theme (const QModelIndex &index);
/// Returns the index for the CursorTheme with the internal name @p name,
/// or an invalid index if no matching theme can be found.
QModelIndex findIndex (const QString &name);
/// Returns the index for the default theme.
QModelIndex defaultIndex ();
/// Adds the theme in @p dir, and returns @a true if successful or @a false otherwise.
bool addTheme (const QDir &dir);
void removeTheme (const QModelIndex &index);
/// Returns the list of base dirs Xcursor looks for themes in.
const QStringList searchPaths ();
private:
bool handleDefault (const QDir &dir);
void processThemeDir (const QDir &dir);
void insertThemes ();
bool hasTheme (const QString &theme) const;
bool isCursorTheme (const QString &theme, const int depth = 0);
private:
QList<XCursorThemeData *>mList;
QStringList mBaseDirs;
QString mDefaultName;
};
int XCursorThemeModel::rowCount (const QModelIndex &) const
{
return mList.count();
}
int XCursorThemeModel::columnCount (const QModelIndex &) const
{
return 2;
}
#endif

@ -1,43 +0,0 @@
/* BEGIN_COMMON_COPYRIGHT_HEADER
* (c)LGPL2+
*
* LXQt - a lightweight, Qt based, desktop toolset
* http://razor-qt.org
*
* Copyright: 2010-2012 Razor team
* Authors:
* Petr Vanek <petr@scribus.info>
*
* This program or library is free software; you can redistribute it
* and/or modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
* 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
*
* END_COMMON_COPYRIGHT_HEADER */
#include <XdgIcon>
#include "warninglabel.h"
WarningLabel::WarningLabel(QWidget *parent)
: QWidget(parent)
{
setupUi(this);
iconLabel->setPixmap(XdgIcon::fromTheme("dialog-warning").pixmap(64, 64));
connect(showDirButton, SIGNAL(pressed()),
this, SIGNAL(showDirInfo()));
}

@ -1,47 +0,0 @@
/* BEGIN_COMMON_COPYRIGHT_HEADER
* (c)LGPL2+
*
* LXQt - a lightweight, Qt based, desktop toolset
* http://razor-qt.org
*
* Copyright: 2010-2012 Razor team
* Authors:
* Petr Vanek <petr@scribus.info>
*
* This program or library is free software; you can redistribute it
* and/or modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
* 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
*
* END_COMMON_COPYRIGHT_HEADER */
#ifndef WARNINGLABEL_H
#define WARNINGLABEL_H
#include "ui_warninglabel.h"
class WarningLabel : public QWidget, public Ui::WarningLabel
{
Q_OBJECT
public:
WarningLabel (QWidget *parent=0);
QPoint buttonPos() { return showDirButton->pos(); }
signals:
void showDirInfo();
};
#endif

@ -1,64 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>WarningLabel</class>
<widget class="QWidget" name="WarningLabel">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>334</width>
<height>72</height>
</rect>
</property>
<property name="windowTitle">
<string>Form</string>
</property>
<layout class="QGridLayout" name="gridLayout">
<item row="0" column="0">
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<widget class="QLabel" name="iconLabel">
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>64</width>
<height>64</height>
</size>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="warningLabel">
<property name="sizePolicy">
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>LXQt could not find any cursor theme. The default X11 cursor theme will be used instead. LXQt looked in the following directories:</string>
</property>
<property name="wordWrap">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="showDirButton">
<property name="text">
<string>Show...</string>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</widget>
<resources/>
<connections/>
</ui>

@ -1,262 +0,0 @@
/* coded by Ketmar // Vampire Avalon (psyc://ketmar.no-ip.org/~Ketmar)
* (c)DWTFYW
*
* This program is free software. It comes without any warranty, to
* the extent permitted by applicable law. You can redistribute it
* and/or modify it under the terms of the Do What The Fuck You Want
* To Public License, Version 2, as published by Sam Hocevar. See
* http://sam.zoy.org/wtfpl/COPYING for more details.
*/
#include <QDebug>
#include "xcrimg.h"
#include <QApplication>
#include <QPaintEngine>
#include <QStringList>
#include <QStyle>
#include <QTextCodec>
#include <QTextStream>
#include <QX11Info>
#include <X11/Xlib.h>
#include <X11/Xcursor/Xcursor.h>
#include <X11/extensions/Xfixes.h>
inline static quint8 alphaPreMul (quint8 clr, quint8 alpha) {
quint32 c32 = clr, a32 = alpha;
c32 = c32*a32/255;
if (c32 > a32) c32 = a32;
return c32&0xff;
}
static int nominalCursorSize (int iconSize) {
for (int i = 512; i > 8; i /= 2) {
if (i < iconSize) return i;
if (int(i*0.75) < iconSize) return int(i*0.75);
}
return 8;
}
static void baPutDW (QByteArray &ba, quint32 v) {
ba.append('\0'); ba.append('\0');
ba.append('\0'); ba.append('\0');
uchar *d = (uchar *)ba.data();
d += ba.size()-4;
for (int f = 4; f > 0; f--, d++) {
*d = (v&0xff);
v >>= 8;
}
}
void XCursorImage::convertARGB2PreMul (QImage &img) {
switch (img.format()) {
case QImage::Format_ARGB32_Premultiplied: return;
case QImage::Format_ARGB32: break;
default: (void) img.convertToFormat(QImage::Format_ARGB32/*_Premultiplied*/);
}
(void) img.convertToFormat(QImage::Format_ARGB32_Premultiplied); // this shouldn't convert anything
// so convert it!
for (int y = img.height()-1; y >= 0; y--) {
quint8 *line = (quint8 *)img.scanLine(y);
for (int x = 0; x < img.width(); x++, line += 4) {
// convert to 'premultiplied'
line[0] = alphaPreMul(line[0], line[3]);
line[1] = alphaPreMul(line[1], line[3]);
line[2] = alphaPreMul(line[2], line[3]);
}
}
}
///////////////////////////////////////////////////////////////////////////////
XCursorImage::XCursorImage (const QString &aName, const QImage &aImg, int aXHot, int aYHot, quint32 aDelay, quint32 aCSize) :
mIsValid(true), mName(aName), mImage(0), mDelay(aDelay), mXHot(aXHot), mYHot(aYHot), mCSize(aCSize)
{
mImage = new QImage(aImg.copy());
convertARGB2PreMul(*mImage);
}
XCursorImage::XCursorImage (const QString &aName) :
mIsValid(false), mName(aName), mImage(0), mDelay(50), mXHot(0), mYHot(0)
{
}
XCursorImage::~XCursorImage () {
delete mImage; // or memory will leak!
}
QPixmap XCursorImage::icon () const {
if (mIcon.isNull()) mIcon = createIcon();
return mIcon;
}
QCursor XCursorImage::cursor () const {
return QCursor(icon(), mXHot, mYHot);
}
QImage XCursorImage::image (int size) const {
if (size == -1) size = XcursorGetDefaultSize(QX11Info::display());
if (!mImage) return QImage();
return mImage->copy();
}
QPixmap XCursorImage::createIcon () const {
QPixmap pixmap;
int iconSize = QApplication::style()->pixelMetric(QStyle::PM_LargeIconSize);
int cursorSize = nominalCursorSize(iconSize);
QSize size = QSize(iconSize, iconSize);
QImage img = image(cursorSize);
if (!img.isNull()) {
// Scale the image if it's larger than the preferred icon size
if (img.width() > size.width() || img.height() > size.height())
img = img.scaled(size, Qt::KeepAspectRatio, Qt::SmoothTransformation);
pixmap = QPixmap::fromImage(img);
}
return pixmap;
}
quint32 XCursorImage::xcurSize () const {
if (!mImage || !mIsValid) return 0;
quint32 res = 9*4; // header
res += mImage->width()*mImage->height()*4;
return res;
}
void XCursorImage::genXCursorImg (QByteArray &res) const {
if (!mImage || !mIsValid) return;
baPutDW(res, 36); // header size
baPutDW(res, 0xfffd0002); // chunk type
baPutDW(res, mCSize); // subtype
baPutDW(res, 1); // version
baPutDW(res, (quint32)mImage->width());
baPutDW(res, (quint32)mImage->height());
baPutDW(res, (quint32)mXHot);
baPutDW(res, (quint32)mYHot);
baPutDW(res, (quint32)mDelay);
// now put the pixels
QImage i = mImage->copy();
(void) i.convertToFormat(QImage::Format_ARGB32_Premultiplied);
//i.convertToFormat(QImage::Format_ARGB32);
for (int y = 0; y < i.height(); y++) {
const uchar *sl = i.scanLine(y);
const quint32 *d = (const quint32 *)sl;
for (int x = 0; x < i.width(); x++, d++) baPutDW(res, *d);
}
}
///////////////////////////////////////////////////////////////////////////////
XCursorImages::XCursorImages (const QString &aName, const QString &aPath) :
mName(aName), mPath(aPath), mTitle(""), mAuthor(""), mLicense(""),
mEMail(""), mSite(""), mDescr(""), mIM("")
{
}
XCursorImages::~XCursorImages () {
qDeleteAll(mList);
mList.clear();
}
QByteArray XCursorImages::genXCursor () const {
QByteArray res;
// build 'credits' block
QByteArray crdBA[7];
{
QStringList crb;
crb << mAuthor << mLicense << mDescr << mTitle << mEMail << mSite << mIM;
for (int f = 0; f < crb.size(); f++) {
QString s(crb[f]);
if (s.isEmpty()) crdBA[f].clear(); else crdBA[f] = s.toUtf8();
}
}
//
res.append("Xcur"); // signature
baPutDW(res, 16); // header size
baPutDW(res, 65536); // version number
// TOC
quint32 cnt = 0;
foreach (const XCursorImage *i, mList) if (i->xcurSize() > 0) cnt++;
// 'credits'
for (int f = 0; f < 7; f++) if (!crdBA[f].isEmpty()) cnt++;
//
baPutDW(res, cnt); // # of chunks
if (!cnt) return res;
quint32 dataOfs = cnt*(3*4)+16;
// add 'credits' chunks
for (int f = 0; f < 7; f++) {
if (crdBA[f].isEmpty()) continue;
baPutDW(res, 0xfffd0001); // entry type
baPutDW(res, f+1); // subtype
baPutDW(res, dataOfs); // offset
dataOfs += crdBA[f].size()+20;
}
// add image chunks
foreach (const XCursorImage *i, mList) {
quint32 isz = i->xcurSize();
if (!isz) continue;
baPutDW(res, 0xfffd0002); // entry type
baPutDW(res, i->csize()); // subtype
baPutDW(res, dataOfs); // offset
dataOfs += isz;
}
// credits
for (int f = 0; f < 7; f++) {
if (crdBA[f].isEmpty()) continue;
baPutDW(res, 20); // header size
baPutDW(res, 0xfffd0001); // entry type
baPutDW(res, f+1); // subtype
baPutDW(res, 1); // version
baPutDW(res, crdBA[f].size()); // length
res.append(crdBA[f]);
}
// images
foreach (const XCursorImage *i, mList) {
quint32 isz = i->xcurSize();
if (!isz) continue;
i->genXCursorImg(res);
}
return res;
}
QImage XCursorImages::buildImage () const {
int width = 0, height = 0, cnt = 0;
foreach (const XCursorImage *i, mList) {
if (i->xcurSize() > 0) {
QImage img = i->image();
width = qMax(width, img.width());
height = qMax(height, img.height());
++cnt;
}
}
//qDebug() << cnt << "images; size" << width << "by" << height;
QImage res(width*cnt, height, QImage::Format_ARGB32);
QPainter p(&res);
int x = 0;
foreach (const XCursorImage *i, mList) {
if (i->xcurSize() > 0) {
QImage img = i->image();
p.drawImage(QPoint(x, 0), img);
x += img.width();
}
}
return res;
}

@ -1,116 +0,0 @@
/* coded by Ketmar // Vampire Avalon (psyc://ketmar.no-ip.org/~Ketmar)
* (c)DWTFYW
*
* This program is free software. It comes without any warranty, to
* the extent permitted by applicable law. You can redistribute it
* and/or modify it under the terms of the Do What The Fuck You Want
* To Public License, Version 2, as published by Sam Hocevar. See
* http://sam.zoy.org/wtfpl/COPYING for more details.
*/
#ifndef XCRIMG_H
#define XCRIMG_H
#include <QtCore>
#include <QCursor>
#include <QPixmap>
class XCursorImage {
public:
XCursorImage (const QString &aName, const QImage &aImg, int aXHot=0, int aYHot=0, quint32 aDelay=50, quint32 aCSize=1);
XCursorImage (const QString &aName);
virtual ~XCursorImage ();
inline bool isValid () const { return mIsValid; }
inline const QString &name () const { return mName; }
inline quint32 delay () const { return mDelay; }
inline int xhot () const { return mXHot; }
inline int yhot () const { return mYHot; }
inline quint32 csize () const { return mCSize; }
inline void setXHot (int v) { mXHot = v; }
inline void setYHot (int v) { mYHot = v; }
inline void setDelay (quint32 v) { mDelay = v; }
inline void setName (const QString &n) { mName = n; }
inline void setCSize (quint32 v) { mCSize = v; }
virtual QPixmap icon () const;
virtual QCursor cursor () const;
virtual QImage image (int size=-1) const;
quint32 xcurSize () const; // size in bytes
virtual void genXCursorImg (QByteArray &res) const; // generate Xcursor image
static void convertARGB2PreMul (QImage &img);
protected:
virtual QPixmap createIcon () const;
protected:
bool mIsValid;
QString mName;
QImage *mImage;
quint32 mDelay; // milliseconds
int mXHot;
int mYHot;
quint32 mCSize;
mutable QPixmap mIcon;
};
class XCursorImages {
public:
XCursorImages (const QString &aName, const QString &aPath="");
virtual ~XCursorImages ();
inline const QString &name () const { return mName; }
inline const QString &path () const { return mPath; }
inline const QString &title () const { return mTitle; }
inline const QString &author () const { return mAuthor; }
inline const QString &license () const { return mLicense; }
inline const QString &mail () const { return mEMail; }
inline const QString &site () const { return mSite; }
inline const QString &descr () const { return mDescr; }
inline const QString &im () const { return mIM; }
inline const QString &script () const { return mScript; }
inline void setName (const QString &v) { mName = v; }
inline void setPath (const QString &v) { mPath = v; }
inline void setTitle (const QString &v) { mTitle = v; }
inline void setAuthor (const QString &v) { mAuthor = v; }
inline void setLicense (const QString &v) { mLicense = v; }
inline void setMail (const QString &v) { mEMail = v; }
inline void setSite (const QString &v) { mSite = v; }
inline void setDescr (const QString &v) { mDescr = v; }
inline void setIM (const QString &v) { mIM = v; }
inline void setScript (const QString &v) { mScript = v; }
inline const QList<XCursorImage *> &list () const { return mList; }
inline XCursorImage *item (int idx) { return mList.at(idx); }
inline const XCursorImage *at (int idx) const { return mList.at(idx); }
inline int count () const { return mList.size(); }
inline int size () const { return mList.size(); }
inline void append (XCursorImage *img) { mList << img; }
QByteArray genXCursor () const; // generate Xcursor file
QImage buildImage () const;
protected:
QString mName;
QString mPath;
QString mTitle;
QString mAuthor;
QString mLicense;
QString mEMail;
QString mSite;
QString mDescr;
QString mIM;
QString mScript; // just for writing it back
QList<XCursorImage *> mList;
};
#endif

@ -1,742 +0,0 @@
/* coded by Ketmar // Vampire Avalon (psyc://ketmar.no-ip.org/~Ketmar)
* (c)DWTFYW
*
* This program is free software. It comes without any warranty, to
* the extent permitted by applicable law. You can redistribute it
* and/or modify it under the terms of the Do What The Fuck You Want
* To Public License, Version 2, as published by Sam Hocevar. See
* http://sam.zoy.org/wtfpl/COPYING for more details.
*/
#include <QDebug>
//#include <QtCore>
#include "xcrtheme.h"
#include <unistd.h>
#include <QStringList>
#include <QTextStream>
#include "xcrimg.h"
#include "xcrxcur.h"
/*
0 standard arrow
1 help arrow (the one with '?')
2 working arrow
3 busy cursor
4 precision select
5 text select
6 handwriting
7 unavailable
8 north (vert) resize
9 south resize
10 west (vert-means horiz???) resize
11 east resize
12 north-west resize
13 south-east resize
14 north-east resize
15 south-west resize
16 move
17 alternate select
18 hand
19 button
*/
static const char *nameTransTbl[] = {
// curFX idx, curXP name, [...altnames], finalname, 0
// end with 0
"", // standard arrow (it's \x00)
"Arrow",
"left_ptr", "X_cursor", "right_ptr", "top_left_arrow", "move",
"4498f0e0c1937ffe01fd06f973665830",
0,
//
"\x04", // precision select
"Cross",
"tcross", "cross", "crosshair", "cross_reverse",
"draped_box",
0,
//
"\x12", // hand
"Hand",
"hand", "hand1", "hand2", "9d800788f1b08800ae810202380a0822",
"e29285e634086352946a0e7090d73106",
0,
//
"\x05", // text select
"IBeam",
"xterm",
0,
//
"\x11", // alternate select
"UpArrow",
"center_ptr",
0,
//
"\x0c",
"SizeNWSE", // north-west resize
"bottom_right_corner", "top_left_corner", "bd_double_arrow", "lr_angle",
"c7088f0f3e6c8088236ef8e1e3e70000",
0,
//
"\x0e", // north-east resize
"SizeNESW",
"bottom_left_corner", "top_right_corner", "fd_double_arrow", "ll_angle",
"fcf1c3c7cd4491d801f1e1c78f100000",
0,
//
"\x0a", // west resize
"SizeWE",
"sb_h_double_arrow", "left_side", "right_side", "h_double_arrow", "028006030e0e7ebffc7f7070c0600140",
"14fef782d02440884392942c11205230",
0,
//
"\x08", // north resize
"SizeNS",
"double_arrow", "bottom_side", "top_side", "v_double_arrow", "sb_v_double_arrow", "00008160000006810000408080010102",
"2870a09082c103050810ffdffffe0204",
0,
//
"\x01", // help arrow
"Help",
"question_arrow",
"d9ce0ab605698f320427677b458ad60b",
0,
//
"\x06", // handwriting
"Handwriting",
"pencil",
0,
//
"\x02", // working arrow
"AppStarting",
"left_ptr_watch", "08e8e1c95fe2fc01f976f1e063a24ccd",
"3ecb610c1bf2410f44200f48c40d3599",
0,
//
"\x10", // move (???)
"SizeAll",
"fleur",
0,
//
"\x03", // busy cursor
"Wait",
"watch",
0,
//
"\x07", // unavailable
"NO",
"crossed_circle",
"03b6e0fcb3499374a867c041f52298f0",
0,
0
};
/*
static QString convertFXIndexToXPName (qint32 idx) {
int f = 0;
do {
if (nameTransTbl[f][0] == idx) return QString(nameTransTbl[f+1]);
f += 2;
while (nameTransTbl[f]) ++f;
++f;
} while (nameTransTbl[f]);
return QString();
}
*/
static void removeFilesAndDirs (QDir &dir) {
//qDebug() << "dir:" << dir.path();
// files
QFileInfoList lst = dir.entryInfoList(QDir::Files | QDir::NoDotAndDotDot | QDir::Hidden);
foreach (const QFileInfo &fi, lst) {
//qDebug() << "removing" << fi.fileName() << fi.absoluteFilePath();
dir.remove(fi.fileName());
}
// dirs
lst = dir.entryInfoList(QDir::AllDirs | QDir::NoDotAndDotDot | QDir::Hidden);
foreach (const QFileInfo &fi, lst) {
dir.cd(fi.fileName());
removeFilesAndDirs(dir);
dir.cd("..");
//qDebug() << "removing dir" << fi.fileName();
dir.rmdir(fi.fileName());
}
}
static void removeFiles (QDir &dir) {
//
QFileInfoList lst = dir.entryInfoList(QDir::Files | QDir::NoDotAndDotDot | QDir::Hidden);
foreach (const QFileInfo &fi, lst) {
qDebug() << "removing" << fi.fileName() << fi.absoluteFilePath();
QFile fl(fi.absoluteFilePath());
fl.remove();
}
//
}
static void removeCursorFiles (QDir &dir) {
QString pt = dir.path();
if (!pt.isEmpty() && pt != "/") pt += "/";
const char **nlst = nameTransTbl;
while (*nlst) {
nlst += 2; // skip non-files
while (*nlst) {
QString n(*nlst);
QFile fl(pt+n);
qDebug() << "removing" << fl.fileName();
fl.remove();
nlst++;
}
nlst++;
}
}
///////////////////////////////////////////////////////////////////////////////
const char **XCursorTheme::findCursorByFXId (int id) {
if (id < 0 || id > 19) return 0; // invalid id
const char **nlst = nameTransTbl;
while (*nlst) {
int lid = (**nlst)&0xff;
nlst += 2; // skip unnecessary
if (lid == id) return nlst;
while (nlst[-1]) nlst++ ; // skip
}
return 0; // none found
}
/*
* type:
* 0: by CursorXP name
* 1: by Xcursor name
* return:
* pointer to Xcursor name list
*/
const char **XCursorTheme::findCursorRecord (const QString &cname, int type) {
QByteArray ba(cname.toUtf8());
const char *name = ba.constData();
const char **nlst = nameTransTbl;
while (*nlst) {
nlst += 2; // skip unnecessary
if (!type) {
// by CursorXP name
if (!strcmp(name, nlst[-1])) return nlst;
} else {
// by Xcursor name
// find name
const char **nx = nlst;
while (*nx && strcmp(*nx, name)) nx++;
if (*nx) return nlst; // we got it!
}
while (nlst[-1]) nlst++ ; // skip
}
return 0; // none found
}
QString XCursorTheme::findCursorFile (const QDir &dir, const char *name) {
QString d(dir.path());
if (d != "/") d += "/";
d += "cursors/";
const char **nlst = nameTransTbl;
while (*nlst) {
nlst += 2; // skip unnecessary
// find name
const char **nx = nlst;
while (*nx && strcmp(*nx, name)) nx++;
if (*nx) {
// we got it!
//qDebug() << "found" << *nx << "(" << *nlst << ")";
nx = nlst;
while (*nx) {
QString s(*nx);
//qDebug() << "checking" << s;
QFileInfo fl(d+s);
if (fl.exists() && fl.isReadable()) {
//qDebug() << " ok" << s;
return s;
}
nx++;
}
}
while (nlst[-1]) nlst++ ; // skip
}
return QString(); // none found
}
///////////////////////////////////////////////////////////////////////////////
XCursorTheme::XCursorTheme () :
mName(""), mPath(""), mTitle(""), mAuthor(""), mLicense(""),
mEMail(""), mSite(""), mDescr(""), mIM(""), mSample("left_ptr")
{
}
XCursorTheme::XCursorTheme (const QDir &aDir, const QString &aName) :
mName(aName), mPath(aDir.path()), mTitle(""), mAuthor(""), mLicense(""),
mEMail(""), mSite(""), mDescr(""), mIM(""), mSample("left_ptr")
{
parseXCursorTheme(aDir);
}
XCursorTheme::~XCursorTheme () {
qDeleteAll(mList);
mList.clear();
}
bool XCursorTheme::writeToDir (const QDir &destDir) {
bool res = true;
QDir dir (destDir);
dir.mkdir("cursors");
if (!dir.exists("cursors")) return false;
dir.cd("cursors");
removeCursorFiles(dir);
//
foreach (const XCursorImages *ci, mList) {
const char **nlst = findCursorRecord(ci->name());
if (!nlst) continue; // unknown cursor, skip it
qDebug() << "writing" << *nlst;
{
QByteArray ba(ci->genXCursor());
QFile fo(dir.path()+"/"+ci->name());
if (fo.open(QIODevice::WriteOnly)) {
fo.write(ba);
fo.close();
} else {
res = false;
break;
}
}
// make symlinks
const char *orig = *nlst;
nlst++;
while (*nlst) {
qDebug() << "symlinking to" << orig << "as" << *nlst;
QByteArray newName(QFile::encodeName(dir.path()+"/"+(*nlst)));
qDebug() << "old" << orig << "new" << newName.constData();
if (symlink(orig, newName.constData())) {
res = false;
break;
}
nlst++;
}
if (!res) break;
nlst++;
}
if (res) res = writeIndexTheme(destDir);
if (!res) removeCursorFiles(dir);
return res;
}
void XCursorTheme::parseThemeIndex (const QDir &dir) {
QString ifn = dir.path();
if (!ifn.isEmpty() && ifn != "/") ifn += "/";
ifn += "index.theme";
qDebug() << "reading theme index:" << ifn;
QFile fl(ifn);
//
QString cmt;
mInherits.clear();
// read config file, drop out 'icon theme' section (IT'S BAD!)
if (fl.open(QIODevice::ReadOnly)) {
QTextStream stream;
stream.setDevice(&fl);
stream.setCodec("UTF-8");
bool inIconTheme = false;
QString curPath;
while (1) {
QString s = stream.readLine();
if (s.isNull()) break;
QString orig(s);
s = s.trimmed();
if (s.isEmpty() || s[0] == '#' || s[0] == ';') continue;
if (s[0] == '[') {
// new path
int len = s.length()-1;
if (s[len] == ']') len--;
s = s.mid(1, len).simplified();
curPath = s.toLower();
inIconTheme = (curPath == "icon theme");
continue;
}
if (!inIconTheme) continue;
int eqp = s.indexOf('=');
if (eqp < 0) continue; // invalid entry
QString name = s.left(eqp).simplified().toLower();
QString value = s.mid(eqp+1).simplified();
qDebug() << name << value;
if (name == "name" && !value.isEmpty()) mTitle = value;
else if (name == "comment" && !value.isEmpty()) cmt = value;
else if (name == "author" && !value.isEmpty()) mAuthor = value;
else if (name == "url" && !value.isEmpty()) mSite = value;
else if (name == "description" && !value.isEmpty()) mDescr = value;
else if (name == "example" && !value.isEmpty()) mSample = value;
else if (name == "inherits" && !value.isEmpty()) mInherits << value;
}
fl.close();
}
if (mDescr.isEmpty() && !cmt.isEmpty()) mDescr = cmt;
if (mSample.isEmpty()) mSample = "left_ptr";
mInherits.removeDuplicates();
}
void XCursorTheme::dumpInfo () {
/*
qDebug() <<
"INFO:" <<
"\n name:" << mName <<
"\n path:" << mPath <<
"\n title:" << mTitle <<
"\n author:" << mAuthor <<
"\n license:" << mLicense <<
"\n mail:" << mEMail <<
"\n site:" << mSite <<
"\n dscr:" << mDescr <<
"\n im:" << mIM <<
"\n sample:" << mSample <<
"\n inherits:" << mInherits
;
*/
}
void XCursorTheme::parseXCursorTheme (const QDir &dir) {
parseThemeIndex(dir);
dumpInfo();
const char **nlst = nameTransTbl;
QDir dr(dir); dr.cd("cursors");
while (*nlst) {
//qDebug() << "CurFX: (" << nlst[1] << ")";
nlst += 2; // skip unnecessary
//qDebug() << "searching" << *nlst;
QString fn = findCursorFile(dir, *nlst);
if (fn.isEmpty()) continue; // no such file
//qDebug() << " Xcrusor: (" << nlst[0] << ")";
while (nlst[-1]) nlst++ ; // skip
//qDebug() << " skiped: (" << nlst[1] << ")";
qDebug() << "loading" << fn;
XCursorImages *ci = new XCursorImagesXCur(dr, fn);
if (ci->count()) {
qDebug() << " OK:" << fn << "name:" << ci->name();
if (mTitle.isEmpty() && !ci->title().isEmpty()) mTitle = ci->title();
if (mAuthor.isEmpty() && !ci->author().isEmpty()) mAuthor = ci->author();
if (mLicense.isEmpty() && !ci->license().isEmpty()) mLicense = ci->license();
if (mEMail.isEmpty() && !ci->mail().isEmpty()) mEMail = ci->mail();
if (mSite.isEmpty() && !ci->site().isEmpty()) mSite = ci->site();
if (mDescr.isEmpty() && !ci->descr().isEmpty()) mDescr = ci->descr();
if (mIM.isEmpty() && !ci->im().isEmpty()) mIM = ci->im();
mList << ci;
dumpInfo();
} else {
qWarning() << "can't load" << fn << nlst[-2];
delete ci;
}
}
dumpInfo();
fixInfoFields();
dumpInfo();
}
void XCursorTheme::fixInfoFields () {
foreach (XCursorImages *ci, mList) {
if (!mTitle.isEmpty() && ci->title().isEmpty()) ci->setTitle(title());
if (!mAuthor.isEmpty() && ci->author().isEmpty()) ci->setAuthor(author());
if (!mLicense.isEmpty() && ci->license().isEmpty()) ci->setLicense(license());
if (!mEMail.isEmpty() && ci->mail().isEmpty()) ci->setMail(mail());
if (!mSite.isEmpty() && ci->site().isEmpty()) ci->setSite(site());
if (!mDescr.isEmpty() && ci->descr().isEmpty()) ci->setDescr(descr());
if (!mIM.isEmpty() && ci->im().isEmpty()) ci->setIM(im());
}
}
bool XCursorTheme::writeIndexTheme (const QDir &destDir) {
QString ifn = destDir.path();
if (!ifn.isEmpty() && ifn != "/") ifn += "/";
ifn += "index.theme";
qDebug() << "writing theme index:" << ifn;
QFile fl(ifn);
//
QStringList cfg, inhs, iconOther;
QString name, cmt, author, url, dscr, sample;
inhs.append(mInherits);
// read config file, drop out 'icon theme' section (IT'S BAD!)
if (fl.open(QIODevice::ReadOnly)) {
QTextStream stream;
stream.setDevice(&fl);
stream.setCodec("UTF-8");
QString curPath;
while (1) {
QString s = stream.readLine();
if (s.isNull()) break;
QString orig(s);
s = s.trimmed();
if (s.isEmpty() || s[0] == '#' || s[0] == ';') {
if (curPath != "icon theme") cfg << orig;
continue;
}
if (s[0] == '[') {
// new path
int len = s.length()-1;
if (s[len] == ']') len--;
s = s.mid(1, len).simplified();
curPath = s.toLower();
if (curPath != "icon theme") cfg << orig;
continue;
}
if (curPath != "icon theme") cfg << orig;
else {
int eqp = s.indexOf('=');
if (eqp < 0) {
// invalid entry
iconOther << orig;
continue;
}
QString name = s.left(eqp).simplified();
QString value = s.mid(eqp+1).simplified();
if (name.isEmpty()) {
// invalid entry
iconOther << orig;
continue;
}
QString nn(name.toLower());
if (nn == "name") name = value;
else if (nn == "comment") cmt = value;
else if (nn == "author") author = value;
else if (nn == "url") url = value;
else if (nn == "description") dscr = value;
else if (nn == "example") sample = value;
else if (nn == "inherits") { if (!value.isEmpty()) inhs << value; }
else iconOther << orig;
/*
Name=Fire Dragon
Comment=Fire Dragon Cursor Theme -- part of the 'Four Dragons' suite; (c) Sleeping Dragon, http://sleeping-dragon.deviantart.com/art/Fire-Dragon-30419542
Author=Sleeping Dragon
Url=http://sleeping-dragon.deviantart.com/art/Fire-Dragon-30419542
Description=Fire Dragon Cursor Theme -- part of the 'Four Dragons' suite
Example=left_ptr
Inherits=core
*/
}
}
fl.close();
}
// theme file parsed; rewrite it!
if (cfg.size() > 0 && !cfg.at(cfg.size()-1).isEmpty()) cfg << "";
if (!fl.open(QIODevice::WriteOnly)) return false;
if (name.isEmpty()) name = mTitle;
if (author.isEmpty()) author = mAuthor;
if (url.isEmpty()) url = mSite;
if (dscr.isEmpty()) dscr = mDescr;
if (cmt.isEmpty()) cmt = dscr;
/*if (sample.isEmpty())*/ sample = "left_ptr";
if (inhs.size() == 0) inhs << "core";
inhs.removeDuplicates();
dumpInfo();
/*
qDebug() <<
"***INFO:" <<
"\n name:" << name <<
"\n cmt:" << cmt <<
"\n author:" << author <<
"\n site:" << url <<
"\n dscr:" << dscr <<
"\n sample:" << mSample <<
"\n inherits:" << inhs
;
*/
{
QTextStream stream;
stream.setDevice(&fl);
stream.setCodec("UTF-8");
foreach (const QString &s, cfg) stream << s << "\n";
stream << "[Icon Theme]\n";
stream << "Name=" << name << "\n";
stream << "Comment=" << cmt << "\n";
stream << "Author=" << author << "\n";
stream << "Url=" << url << "\n";
stream << "Description=" << dscr << "\n";
stream << "Example=" << mSample << "\n";
foreach (const QString &s, inhs) stream << "Inherits=" << s << "\n";
}
fl.close();
return true;
}
///////////////////////////////////////////////////////////////////////////////
static bool removeXCTheme (const QDir &thDir) {
if (thDir.exists("cursors")) {
QDir d(thDir);
d.cd("cursors");
//removeCursorFiles(d);
removeFiles(d);
}
thDir.rmdir("cursors");
// check if there are some other files
QFileInfoList lst = thDir.entryInfoList(QDir::AllDirs | QDir::Files | QDir::NoDotAndDotDot | QDir::Hidden);
bool cantKill = false;
foreach (const QFileInfo &fi, lst) {
QString s(fi.fileName());
if (s != "icon-theme.cache" && s != "index.theme") {
cantKill = true;
break;
}
}
// can kill this?
if (!cantKill) {
QDir d(thDir);
d.remove("icon-theme.cache");
d.remove("index.theme");
}
return true;
}
bool removeXCursorTheme (const QDir &thDir, const QString &name) {
qDebug() << "to kill:" << thDir.path() << name;
QDir d(thDir);
if (!d.exists(name)) return false;
qDebug() << "removing" << d.path() << name;
d.cd(name);
removeXCTheme(d);
d.cd("..");
d.rmdir(name);
return true;
}
bool removeXCursorTheme (const QString &name) {
QDir d(QDir::homePath());
return removeXCursorTheme(d, name);
}
bool removeXCursorTheme (const QDir &thDir) {
QString name(thDir.path());
while (!name.isEmpty() && name.endsWith('/')) name.chop(1);
int i = name.lastIndexOf('/');
if (i < 1) return false;
name = name.mid(i+1);
QDir d(thDir);
d.cd("..");
return removeXCursorTheme(d, name);
}
///////////////////////////////////////////////////////////////////////////////
/*
* returns temporary dir or empty string
*/
static bool tarDir (const QString &destFName, const QDir &pth, const QString &dir) {
QStringList args;
QFile fl(destFName);
fl.remove();
args << "-c"; // create archive...
args << "-z"; // and gzip it
QString ps(pth.path());
if (!ps.isEmpty() && ps != ".") {
args << "-C"; // dir to go
args << ps;
}
args << "-f"; // to file
args << destFName;
QString s(dir);
if (!s.endsWith('/')) s += '/';
args << s;
QProcess pr;
pr.setStandardInputFile("/dev/null");
pr.setStandardOutputFile("/dev/null");
pr.setStandardErrorFile("/dev/null");
pr.start("tar", args);
if (pr.waitForStarted()) {
if (pr.waitForFinished()) return true;
}
// cleanup
fl.remove();
return false;
}
//tar -c -C /home/ketmar/k8prj/xcurtheme/src -f z.tar xcr/
bool packXCursorTheme (const QString &destFName, const QDir &thDir, const QString &thName, bool removeTheme) {
if (destFName.isEmpty() || thName.isEmpty()) return false;
QDir d(thDir);
if (!d.cd(thName)) return false;
bool res = tarDir(destFName, thDir, thName);
if (res && removeTheme) {
removeFilesAndDirs(d);
d.cd("..");
d.rmdir(thName);
}
return res;
}
bool XCursorTheme::writeXPTheme (const QDir &destDir) {
QString ifn = destDir.path();
if (!ifn.isEmpty() && ifn != "/") ifn += '/';
QFile fl(ifn+"Scheme.ini");
if (fl.open(QIODevice::WriteOnly)) {
QTextStream stream;
stream.setDevice(&fl);
stream.setCodec("UTF-8");
stream << "[General]\r\n";
stream << "Version=130\r\n";
qDebug() << "writing images...";
foreach (XCursorImages *ci, mList) {
const char **nlst = findCursorRecord(ci->name());
if (!nlst) continue; // unknown cursor, skip it
qDebug() << "image:" << *(nlst-1);
QImage img(ci->buildImage());
if (!img.save(ifn+(*(nlst-1))+".png")) return false;
stream << "["+QString(*(nlst-1))+"]\r\n";
stream << "StdCursor=0\r\n";
stream << "Frames=" << ci->count() << "\r\n";
stream << "Hot spot x=" << ci->at(0)->xhot() << "\r\n";
stream << "Hot spot y=" << ci->at(0)->yhot() << "\r\n";
stream << "Interval=" << (ci->at(0)->delay() == 2147483647 ? 100 : ci->at(0)->delay()) << "\r\n";
// x2, y2? wtf?
if (ci->count() > 1) {
stream << "Frames=" << ci->count() << "\r\n";
stream << "Animation style=0\r\n";
} else {
stream << "Frames=1\r\n";
stream << "Animation style=0\r\n";
}
}
stream << "[[Description]\r\n";
if (!mName.isEmpty()) stream << mName << "\r\n";
if (!mTitle.isEmpty()) stream << mTitle << "\r\n";
if (!mAuthor.isEmpty()) stream << mAuthor << "\r\n";
if (!mLicense.isEmpty()) stream << mLicense << "\r\n";
if (!mEMail.isEmpty()) stream << mEMail << "\r\n";
if (!mSite.isEmpty()) stream << mSite << "\r\n";
if (!mDescr.isEmpty()) stream << mDescr << "\r\n";
if (!mIM.isEmpty()) stream << mIM << "\r\n";
}
fl.close();
return true;
}

@ -1,97 +0,0 @@
/* coded by Ketmar // Vampire Avalon (psyc://ketmar.no-ip.org/~Ketmar)
* (c)DWTFYW
*
* This program is free software. It comes without any warranty, to
* the extent permitted by applicable law. You can redistribute it
* and/or modify it under the terms of the Do What The Fuck You Want
* To Public License, Version 2, as published by Sam Hocevar. See
* http://sam.zoy.org/wtfpl/COPYING for more details.
*/
#ifndef XCRTHEME_H
#define XCRTHEME_H
#include <QtCore>
#include <QCursor>
#include <QPixmap>
#include "xcrimg.h"
class XCursorTheme {
public:
XCursorTheme (const QDir &aDir, const QString &aName);
XCursorTheme ();
virtual ~XCursorTheme ();
inline const QString &name () const { return mName; }
inline const QString &path () const { return mPath; }
inline const QString &title () const { return mTitle; }
inline const QString &author () const { return mAuthor; }
inline const QString &license () const { return mLicense; }
inline const QString &mail () const { return mEMail; }
inline const QString &site () const { return mSite; }
inline const QString &descr () const { return mDescr; }
inline const QString &im () const { return mIM; }
inline const QString &sample () const { return mSample; }
inline const QStringList &inherits () const { return mInherits; }
inline void setName (const QString &v) { mName = v; }
inline void setPath (const QString &v) { mPath = v; }
inline void setTitle (const QString &v) { mTitle = v; }
inline void setAuthor (const QString &v) { mAuthor = v; }
inline void setLicense (const QString &v) { mLicense = v; }
inline void setMail (const QString &v) { mEMail = v; }
inline void setSite (const QString &v) { mSite = v; }
inline void setDescr (const QString &v) { mDescr = v; }
inline void setIM (const QString &v) { mIM = v; }
inline void setSample (const QString &v) { mSample = v; }
inline void setInherits (const QStringList &v) { mInherits.clear(); mInherits.append(v); }
inline const QList<XCursorImages *> &list () const { return mList; }
inline const XCursorImages *at (int idx) const { return mList.at(idx); }
inline int count () const { return mList.size(); }
inline int size () const { return mList.size(); }
inline void append (XCursorImages *img) { mList << img; }
bool writeToDir (const QDir &destDir);
void fixInfoFields ();
bool writeXPTheme (const QDir &destDir);
protected:
static const char **findCursorByFXId (int id);
static QString findCursorFile (const QDir &dir, const char *name);
static const char **findCursorRecord (const QString &cname, int type=1);
bool writeIndexTheme (const QDir &destDir);
void parseXCursorTheme (const QDir &dir);
void parseThemeIndex (const QDir &dir);
void dumpInfo ();
protected:
QString mName;
QString mPath;
QString mTitle;
QString mAuthor;
QString mLicense;
QString mEMail;
QString mSite;
QString mDescr;
QString mIM;
QString mSample;
QStringList mInherits;
QList<XCursorImages *> mList;
};
bool removeXCursorTheme (const QDir &thDir, const QString &name);
bool removeXCursorTheme (const QString &name);
bool removeXCursorTheme (const QDir &thDir);
bool packXCursorTheme (const QString &destFName, const QDir &thDir, const QString &thName, bool removeTheme=false);
#endif

@ -1,400 +0,0 @@
/* coded by Ketmar // Vampire Avalon (psyc://ketmar.no-ip.org/~Ketmar)
* (c)DWTFYW
*
* This program is free software. It comes without any warranty, to
* the extent permitted by applicable law. You can redistribute it
* and/or modify it under the terms of the Do What The Fuck You Want
* To Public License, Version 2, as published by Sam Hocevar. See
* http://sam.zoy.org/wtfpl/COPYING for more details.
*/
#include <QDebug>
//#include <QtCore>
#include "xcrthemefx.h"
#include <unistd.h>
#include <zlib.h>
#include <QSet>
#include <QStringList>
#include <QTextStream>
#include "xcrimg.h"
#include "xcrxcur.h"
#include "xcrtheme.h"
static const char *curShapeName[] = {
"standard arrow",
"help arrow (the one with '?')",
"working arrow",
"busy cursor",
"precision select",
"text select",
"handwriting",
"unavailable",
"north (vert) resize",
"south resize",
"west (vert-means horiz?) resize",
"east resize",
"north-west resize",
"south-east resize",
"north-east resize",
"south-west resize",
"move",
"alternate select",
"hand",
"button"
};
bool XCursorThemeFX::str2num (const QString &s, quint32 &res) {
quint64 n = 0;
if (s.isEmpty()) return false;
for (int f = 0; f < s.length(); f++) {
QChar ch = s.at(f);
if (!ch.isDigit()) return false;
n = n*10+ch.unicode()-'0';
}
//if (n >= (quint64)0x100000000LL) n = 0xffffffffLL;
if (n >= (quint64)0x80000000LL) n = 0x7fffffffLL;
res = n;
return true;
}
QList<XCursorThemeFX::tAnimSeq> XCursorThemeFX::parseScript (const QString &script, quint32 maxFrame) {
QList<tAnimSeq> res;
QString scp = script; scp.replace("\r", "\n");
QStringList scpL = scp.split('\n', QString::SkipEmptyParts);
foreach (QString s, scpL) {
s = s.simplified();
//qDebug() << s;
QStringList fld = s.split(',', QString::SkipEmptyParts); //BUG!BUG!BUG!
if (fld.size() != 2) {
qDebug() << "script error:" << s;
qWarning() << "script error:" << s;
continue;
}
// frame[s]
int hyph = fld[0].indexOf('-');
tAnimSeq a;
if (hyph == -1) {
// just a number
if (!str2num(fld[0], a.from)) {
qDebug() << "script error (frame):" << s;
qWarning() << "script error (frame):" << s;
continue;
}
a.from = qMax(qMin(maxFrame, a.from), (quint32)1)-1;
a.to = a.from;
} else {
// a..b
if (!str2num(fld[0].left(hyph), a.from)) {
qDebug() << "script error (frame from):" << s;
qWarning() << "script error (frame from):" << s;
continue;
}
a.from = qMax(qMin(maxFrame, a.from), (quint32)1)-1;
if (!str2num(fld[0].mid(hyph+1), a.to)) {
qDebug() << "script error (frame to):" << s;
qWarning() << "script error (frame to):" << s;
continue;
}
a.to = qMax(qMin(maxFrame, a.to), (quint32)1)-1;
}
// delay
if (!str2num(fld[1], a.delay)) {
qDebug() << "script error (delay):" << s;
qWarning() << "script error (delay):" << s;
continue;
}
if (a.delay < 10) a.delay = 10;
qDebug() << "from" << a.from << "to" << a.to << "delay" << a.delay;
res << a;
}
return res;
}
///////////////////////////////////////////////////////////////////////////////
static QByteArray zlibInflate (const void *buf, int bufSz, int destSz) {
QByteArray res;
z_stream stream;
int err;
res.resize(destSz+1);
stream.next_in = (Bytef *)buf;
stream.avail_in = bufSz;
stream.zalloc = (alloc_func)0;
stream.zfree = (free_func)0;
stream.next_out = (Bytef *)res.data();
stream.avail_out = destSz;
err = inflateInit(&stream);
if (err != Z_OK) return QByteArray();
err = inflate(&stream, Z_SYNC_FLUSH);
fprintf(stderr, "inflate result: %i\n", err);
switch (err) {
case Z_STREAM_END:
err = inflateEnd(&stream);
fprintf(stderr, "Z_STREAM_END: inflate result: %i\n", err);
if (err != Z_OK) return QByteArray();
break;
case Z_OK:
err = inflateEnd(&stream);
fprintf(stderr, "Z_OK: inflate result: %i\n", err);
if (err != Z_OK) return QByteArray();
break;
default: return QByteArray();
}
return res;
}
static quint32 baGetDW (QByteArray &ba, int &pos) {
const uchar *d = (const uchar *)ba.constData();
d += pos+3;
pos += 4;
quint32 res = 0;
for (int f = 4; f > 0; f--, d--) {
res <<= 8;
res |= *d;
}
return res;
}
///////////////////////////////////////////////////////////////////////////////
XCursorThemeFX::XCursorThemeFX (const QString &aFileName) : XCursorTheme() {
if (!parseCursorFXTheme(aFileName)) {
qDeleteAll(mList);
mList.clear();
}
}
bool XCursorThemeFX::parseCursorFXTheme (const QString &aFileName) {
qDebug() << "loading" << aFileName;
QFile fl(aFileName);
if (!fl.open(QIODevice::ReadOnly)) return false; // shit!
QByteArray ba(fl.readAll());
fl.close();
if (ba.size() < 0xb8) return false; // shit!
int pos = 0;
if (baGetDW(ba, pos) != 1) return false; // invalid version
quint32 mainHdrSize = baGetDW(ba, pos);
if (mainHdrSize < 0xb8) return false; // invalid header size
quint32 unDataSize = baGetDW(ba, pos);
if (unDataSize < 0x4c) return false; // no cursors anyway
struct {
quint32 ofs;
quint32 len;
} infoFields[6];
pos = 0x84;
for (int f = 0; f < 6; f++) {
infoFields[f].ofs = baGetDW(ba, pos);
infoFields[f].len = baGetDW(ba, pos);
}
pos = 0xb4;
quint32 ihdrSize = baGetDW(ba, pos);
// now read data
pos = mainHdrSize;
qDebug() << "reading data from" << pos;
QByteArray unp(zlibInflate(ba.constData()+pos, ba.size()-pos, unDataSize));
if (unp.isEmpty()) {
qDebug() << "CursorFX: can't depack data";
qWarning() << "CursorFX: can't depack data";
return false;
}
// process info section
for (int f = 0; f < 6; f++) {
int len = infoFields[f].len;
if (!len) continue;
pos = infoFields[f].ofs;
if ((quint32)pos >= ihdrSize || (quint32)pos+len >= ihdrSize) continue; // skip invalid one
QByteArray sBA(unp.mid(pos, len));
sBA.append('\0'); sBA.append('\0');
QString s = QString::fromUtf16((const ushort *)sBA.constData()).simplified();
switch (f) {
case 0: setTitle(s); break;
case 1: setAuthor(s); break;
//case 2: setVersion(s); break;
case 3: setSite(s); break;
case 4: setMail(s); break;
case 5: setDescr(s); break;
default: ;
}
}
// process resources
QSet<quint8> shapesSeen;
pos = ihdrSize;
qDebug() << "resources started at hex" << QString::number(pos, 16);
while (pos <= unp.size()-12) {
quint32 ipos = pos; // will be fixed later
quint32 rtype = baGetDW(unp, pos);
quint32 basicHdrSize = baGetDW(unp, pos);
quint32 itemSize = baGetDW(unp, pos);
qDebug() << "pos hex:" << QString::number(pos, 16) << "rtype:" << rtype << "bhdrsz hex:" << QString::number(basicHdrSize, 16) << "itemsz hex:" << QString::number(itemSize, 16);
if (itemSize < 12) {
// invalid data
qDebug() << "CursorFX: invalid data chunk size";
qWarning() << "CursorFX: invalid data chunk size";
return false;
}
pos = ipos+itemSize; // skip it
if (rtype != 2) continue; // not cursor resource
if (itemSize < 0x4c) {
qDebug() << "CursorFX: invalid cursor chunk size:" << itemSize;
qWarning() << "CursorFX: invalid cursor chunk size:" << itemSize;
return false;
}
// cursor
int cps = ipos+3*4;
rtype = baGetDW(unp, cps);
if (rtype != 2) {
qDebug() << "CursorFX: invalid cursor chunk type:" << rtype;
qWarning() << "CursorFX: invalid cursor chunk type:" << rtype;
return false;
}
quint32 curShape = baGetDW(unp, cps);
quint32 curType = baGetDW(unp, cps);
if (curShape > 19) {
qDebug() << "CursorFX: unknown cursor shape:" << curShape;
qWarning() << "CursorFX: unknown cursor shape:" << curShape;
return false;
}
if (curType != 1) {
qDebug() << "skipping 'press' cursor; shape no" << curShape << "named" << curShapeName[curShape];
continue;
// we need only 'normal' cursors
}
qDebug() << "cursor shape:" << curShape;
const char **nlst = findCursorByFXId((int)curShape);
if (!nlst) {
// unknown cursor type, skip it
qDebug() << "CursorFX: skipping cursor shape:" << curShapeName[curShape];
qWarning() << "CursorFX: skipping cursor shape:" << curShapeName[curShape];
continue;
}
if (shapesSeen.contains(curShape&0xff)) {
// unknown cursor type, skip it
qDebug() << "CursorFX: skipping duplicate cursor shape:" << curShapeName[curShape];
qWarning() << "CursorFX: skipping duplicate cursor shape:" << curShapeName[curShape];
continue;
}
shapesSeen << (curShape&0xff);
qDebug() << "importing cursor" << *nlst;
quint32 unk0 = baGetDW(unp, cps); // unknown field
quint32 frameCnt = baGetDW(unp, cps);
if (frameCnt < 1) frameCnt = 1; // just in case
quint32 imgWdt = baGetDW(unp, cps);
quint32 imgHgt = baGetDW(unp, cps);
quint32 imgDelay = baGetDW(unp, cps);
quint32 aniFlags = baGetDW(unp, cps);
quint32 unk1 = baGetDW(unp, cps); // unknown field
quint32 imgXHot = baGetDW(unp, cps);
quint32 imgYHot = baGetDW(unp, cps);
quint32 realHdrSize = baGetDW(unp, cps);
quint32 imgDataSize = baGetDW(unp, cps);
quint32 addonOfs = baGetDW(unp, cps);
quint32 addonLen = baGetDW(unp, cps);
if (imgDelay < 10) imgDelay = 10;
if (imgDelay >= (quint32)0x80000000LL) imgDelay = 0x7fffffffLL;
qDebug() <<
"cursor data:" <<
"\n frames:" << frameCnt <<
"\n width:" << imgWdt <<
"\n height:" << imgHgt <<
"\n delay:" << imgDelay <<
"\n flags:" << QString::number(aniFlags, 2) <<
"\n xhot:" << imgXHot <<
"\n yhot:" << imgYHot <<
"\n unk0:" << unk0 <<
"\n unk1:" << unk1 <<
"\n rhdata:" << QString::number(realHdrSize, 16) <<
"\n dataOfs:" << QString::number(ipos+realHdrSize, 16) <<
"\n cdataOfs:" << QString::number(ipos+basicHdrSize+addonLen, 16)
;
// now check if we have enought data
if (ipos+realHdrSize+imgDataSize > (quint32)pos) {
qDebug() << "CursorFX: cursor data too big";
qWarning() << "CursorFX: cursor data too big";
return false;
}
// addon is the script; parse it later
QList<tAnimSeq> aseq;
QString script;
if (addonLen) {
// script
if (addonOfs < 0x4c || addonOfs > realHdrSize) {
qDebug() << "CursorFX: invalid addon data offset";
qWarning() << "CursorFX: invalid addon data offset";
return false;
}
QByteArray bs(unp.mid(ipos+addonOfs, addonLen));
bs.append('\0'); bs.append('\0');
script = QString::fromUtf16((const ushort *)bs.constData());
qDebug() << "script:\n" << script;
// create animseq
aseq = parseScript(script, frameCnt);
} else {
// create 'standard' animseq
tAnimSeq a;
a.from = 0; a.to = frameCnt-1; a.delay = imgDelay;
aseq << a;
// and back if 'alternate' flag set
if (aniFlags&0x01) {
a.from = frameCnt-1; a.to = 0;
aseq << a;
}
}
if (imgWdt*imgHgt*4 != imgDataSize) {
qDebug() << "data size:" << imgDataSize << "but should be" << imgWdt*imgHgt*4;
continue;
}
// decode image
QImage img((const uchar *)unp.constData()+ipos+realHdrSize, imgWdt, imgHgt, QImage::Format_ARGB32);
img = img.mirrored(false, true);
//
XCursorImages *cim = new XCursorImages(*nlst);
cim->setScript(script);
//!!!
//!!!img.save(QString("_png/%1.png").arg(cim->name()));
//!!!
quint32 frameWdt = img.width()/frameCnt;
qDebug() << "frameWdt:" << frameWdt << "left:" << img.width()%(frameWdt*frameCnt);
// now build animation sequence
int fCnt = 0;
foreach (const tAnimSeq &a, aseq) {
bool back = a.from > a.to; // going backwards
quint32 fNo = a.from;
for (;; fCnt++) {
//k8:qDebug() << " frame:" << fNo << "delay:" << a.delay;
// copy frame
QImage frame(img.copy(fNo*frameWdt, 0, frameWdt, img.height()));
//frame.save(QString("_png/%1_%2.png").arg(cim->name()).arg(QString::number(f)));
XCursorImage *i = new XCursorImage(QString("%1%2").arg(cim->name()).arg(QString::number(fCnt)),
frame, imgXHot, imgYHot, a.delay, 1
);
cim->append(i);
//
if (fNo == a.to) break;
if (back) fNo--; else fNo++;
}
}
// append if not empty
if (cim->count()) {
// now check if it is looped and cancel looping if necessary
if ((aniFlags & 0x02) == 0) {
// not looped
qDebug() << " anti-loop fix";
XCursorImage *i = cim->item(cim->count()-1);
i->setDelay(0x7fffffffL);
//i->setCSize(2); // ???
}
mList << cim;
}
}
return true;
}

@ -1,40 +0,0 @@
/* coded by Ketmar // Vampire Avalon (psyc://ketmar.no-ip.org/~Ketmar)
* (c)DWTFYW
*
* This program is free software. It comes without any warranty, to
* the extent permitted by applicable law. You can redistribute it
* and/or modify it under the terms of the Do What The Fuck You Want
* To Public License, Version 2, as published by Sam Hocevar. See
* http://sam.zoy.org/wtfpl/COPYING for more details.
*/
#ifndef XCRTHEMEFX_H
#define XCRTHEMEFX_H
#include <QtCore>
#include <QCursor>
#include <QPixmap>
#include "xcrimg.h"
#include "xcrtheme.h"
class XCursorThemeFX : public XCursorTheme {
public:
XCursorThemeFX (const QString &aFileName);
public:
class tAnimSeq {
public:
quint32 from, to;
quint32 delay;
};
static QList<tAnimSeq> parseScript (const QString &script, quint32 maxFrame);
static bool str2num (const QString &s, quint32 &res);
protected:
bool parseCursorFXTheme (const QString &aFileName);
};
#endif

@ -1,352 +0,0 @@
/* coded by Ketmar // Vampire Avalon (psyc://ketmar.no-ip.org/~Ketmar)
* (c)DWTFYW
*
* This program is free software. It comes without any warranty, to
* the extent permitted by applicable law. You can redistribute it
* and/or modify it under the terms of the Do What The Fuck You Want
* To Public License, Version 2, as published by Sam Hocevar. See
* http://sam.zoy.org/wtfpl/COPYING for more details.
*/
#include <QDebug>
//#include <QtCore>
#include "xcrthemexp.h"
#include <unistd.h>
#include <zlib.h>
#include <QSet>
#include <QStringList>
#include <QTextStream>
#include "xcrimg.h"
#include "xcrxcur.h"
#include "xcrtheme.h"
#include "xcrthemefx.h"
static const char *curShapeName[] = {
"Arrow",
"Cross",
"Hand",
"IBeam",
"UpArrow",
"SizeNWSE",
"SizeNESW",
"SizeWE",
"SizeNS",
"Help",
"Handwriting",
"AppStarting",
"SizeAll",
"Wait",
"NO",
0
};
static const char *findCurShapeName (const QString &s) {
QByteArray ba(s.toUtf8());
const char *name = ba.constData();
const char **nlst = curShapeName;
while (*nlst) {
if (!strcasecmp(name, *nlst)) return *nlst;
nlst++;
}
return 0;
}
static QString findFile (const QDir &dir, const QString &name, bool fullName=false) {
QFileInfoList lst = dir.entryInfoList(QDir::Files | QDir::NoDotAndDotDot | QDir::Hidden);
foreach (const QFileInfo &fi, lst) {
if (!name.compare(fi.fileName(), Qt::CaseInsensitive)) {
if (fullName) return fi.absoluteFilePath();
return fi.fileName();
}
}
return QString();
}
class CursorInfo {
public:
CursorInfo () { clear(); curSection.clear(); }
void clear () {
frameCnt = 1; delay = 50; xhot = yhot = 0;
script.clear();
wasFrameCnt = wasXHot = wasYHot = wasDelay = wasScript = wasAStyle = wasStdCur = false;
isStdCursor = false;
isLooped = true; is2way = false;
}
public:
quint32 frameCnt, delay, xhot, yhot;
QString script;
bool wasFrameCnt, wasXHot, wasYHot, wasDelay, wasScript, wasAStyle, wasStdCur;
bool isStdCursor;
bool isLooped, is2way;
QString curSection;
QString nextSection;
};
/* true: EOF */
static bool readNextSection (QTextStream &stream, CursorInfo &info) {
info.clear();
if (info.nextSection.isEmpty()) {
// find next section
//qDebug() << "searching section...";
for (;;) {
QString s;
info.curSection.clear();
info.nextSection.clear();
for (;;) {
s = stream.readLine();
if (s.isNull()) return true;
s = s.trimmed();
//qDebug() << "*" << s;
if (s.isEmpty() || s[0] == '#' || s[0] == ';') continue;
if (s[0] == '[') break;
}
int len = s.length()-1;
if (s[len] == ']') len--;
s = s.mid(1, len);
const char *csn = findCurShapeName(s);
if (!csn) continue;
// section found
info.curSection = csn;
break;
}
} else {
info.curSection = info.nextSection;
info.nextSection.clear();
}
// section found; read it
for (;;) {
QString s = stream.readLine();
if (s.isNull()) return true;
s = s.trimmed();
//qDebug() << "+" << s;
if (s.isEmpty() || s[0] == '#' || s[0] == ';') continue;
if (s[0] == '[') {
int len = s.length()-1;
if (s[len] == ']') len--;
s = s.mid(1, len);
const char *csn = findCurShapeName(s);
if (csn) info.nextSection = csn; else info.nextSection.clear();
break;
}
QStringList nv(s.split('='));
if (nv.size() != 2) continue; // invalid
QString name = nv[0].simplified().toLower();
quint32 num = 0;
bool numOk = XCursorThemeFX::str2num(nv[1].trimmed(), num);
if (!numOk) num = 0;
if (name == "frames") {
info.frameCnt = qMax(num, (quint32)1);
info.wasFrameCnt = true;
} else if (name == "interval") {
info.delay = qMax(qMin(num, (quint32)0x7fffffffL), (quint32)10);
info.wasDelay = true;
} else if (name == "animation style") {
info.isLooped = true;
info.is2way = (num != 0);
info.wasAStyle = true;
} else if (name == "hot spot x") {
info.xhot = num;
info.wasXHot = true;
} else if (name == "hot spot y") {
info.yhot = num;
info.wasYHot = true;
} else if (name == "framescript") {
// 1 or 0
} else if (name == "stdcursor") {
info.isStdCursor = (num!=0);
info.wasStdCur = true;
} else if (name == "hot spot x2" || name == "hot spot y2") {
} else if (name == "stdcursor" || name == "hot spot x2" || name == "hot spot y2") {
// nothing
} else {
qDebug() << "unknown param:" << name << nv[1];
qWarning() << "unknown param:" << name << nv[1];
}
}
return false;
}
static void removeFilesAndDirs (QDir &dir) {
//qDebug() << "dir:" << dir.path();
// files
QFileInfoList lst = dir.entryInfoList(QDir::Files | QDir::NoDotAndDotDot | QDir::Hidden);
foreach (const QFileInfo &fi, lst) {
//qDebug() << "removing" << fi.fileName() << fi.absoluteFilePath();
dir.remove(fi.fileName());
}
// dirs
lst = dir.entryInfoList(QDir::AllDirs | QDir::NoDotAndDotDot | QDir::Hidden);
foreach (const QFileInfo &fi, lst) {
dir.cd(fi.fileName());
removeFilesAndDirs(dir);
dir.cd("..");
//qDebug() << "removing dir" << fi.fileName();
dir.rmdir(fi.fileName());
}
}
/*
* returns temporary dir or empty string
*/
static QString unzipFile (const QString &zipFile) {
QStringList args;
char tmpDirName[18];
strcpy(tmpDirName, "/tmp/unzXXXXXX");
char *td = mkdtemp(tmpDirName);
if (!td) return QString();
QDir dir(td);
args << "-b"; // all files are binary
args << "-D"; // skip timestamps
args << "-n"; // never overwrite (just in case)
args << "-qq"; // be very quiet
args << zipFile;
args << "-d" << dir.absolutePath(); // dest dir
QProcess pr;
pr.setStandardInputFile("/dev/null");
pr.setStandardOutputFile("/dev/null");
pr.setStandardErrorFile("/dev/null");
pr.start("unzip", args);
if (pr.waitForStarted()) {
if (pr.waitForFinished()) return QLatin1String(td);
}
// cleanup
removeFilesAndDirs(dir);
dir.cd("..");
QString s = QLatin1String(strchr(td+1, '/')+1);
//qDebug() << s;
dir.rmdir(s);
return QString();
}
///////////////////////////////////////////////////////////////////////////////
XCursorThemeXP::XCursorThemeXP (const QString &aFileName) : XCursorTheme() {
QFileInfo fi(aFileName);
if (fi.exists() && fi.isReadable()) {
QString dst = unzipFile(aFileName);
if (!dst.isEmpty()) {
QDir d(dst);
if (!parseCursorXPTheme(d)) {
qDeleteAll(mList);
mList.clear();
}
qDebug() << "doing cleanup...";
dst.remove(0, dst.indexOf('/', 1)+1);
removeFilesAndDirs(d);
d.cd("..");
qDebug() << dst;
d.rmdir(dst);
}
}
}
bool XCursorThemeXP::parseCursorXPTheme (const QDir &thDir) {
qDebug() << "loading" << thDir.path();
QString ifn = findFile(thDir, "scheme.ini", true);
if (ifn.isEmpty()) return false;
qDebug() << "reading scheme:" << ifn;
//
QFile fl(ifn);
if (!fl.open(QIODevice::ReadOnly)) return false; // no scheme --> no fun!
QTextStream stream;
stream.setDevice(&fl);
stream.setCodec("UTF-8");
CursorInfo info;
QSet<QString> sectionsSeen;
bool eof = false;
do {
eof = readNextSection(stream, info);
if (info.curSection.isEmpty()) break;
/*
qDebug() << "section:" << info.curSection <<
"\n stdcr was:" << info.wasStdCur << "value:" << info.isStdCursor <<
"\n frame was:" << info.wasFrameCnt << "value:" << info.frameCnt <<
"\n delay was:" << info.wasDelay << "value:" << info.delay <<
"\n xhot was:" << info.wasXHot << "value:" << info.xhot <<
"\n yhot was:" << info.wasYHot << "value:" << info.yhot <<
"\n style was:" << info.wasAStyle << "loop:" << info.isLooped << "2way:" << info.is2way <<
"\n scrpt was:" << info.wasScript << "value:" << info.script <<
"\n next section:" << info.nextSection
;
*/
const char ** nlst = XCursorTheme::findCursorRecord(info.curSection, 0);
QString imgFile = findFile(thDir, info.curSection+".png", true);
if (!sectionsSeen.contains(info.curSection) && nlst && !imgFile.isEmpty()) {
qDebug() << "section" << info.curSection << "file:" << imgFile;
sectionsSeen << info.curSection;
//TODO: script
QList<XCursorThemeFX::tAnimSeq> aseq;
{
// create 'standard' animseq
XCursorThemeFX::tAnimSeq a;
a.from = 0; a.to = info.frameCnt-1; a.delay = info.delay;
aseq << a;
// and back if 'alternate' flag set
if (info.is2way) {
a.from = info.frameCnt-1; a.to = 0;
aseq << a;
}
}
// load image
QImage img(imgFile);
if (!img.isNull()) {
XCursorImages *cim = new XCursorImages(*nlst);
quint32 frameWdt = img.width()/info.frameCnt;
qDebug() << "frameWdt:" << frameWdt << "left:" << img.width()%(frameWdt*info.frameCnt);
// now build animation sequence
int fCnt = 0;
foreach (const XCursorThemeFX::tAnimSeq &a, aseq) {
bool back = a.from > a.to; // going backwards
quint32 fNo = a.from;
for (;; fCnt++) {
//k8:qDebug() << " frame:" << fNo << "delay:" << a.delay;
// copy frame
QImage frame(img.copy(fNo*frameWdt, 0, frameWdt, img.height()));
//frame.save(QString("_png/%1_%2.png").arg(cim->name()).arg(QString::number(f)));
XCursorImage *i = new XCursorImage(QString("%1%2").arg(cim->name()).arg(QString::number(fCnt)),
frame, info.xhot, info.yhot, a.delay, 1
);
cim->append(i);
//
if (fNo == a.to) break;
if (back) fNo--; else fNo++;
}
}
// append if not empty
if (cim->count()) {
// now check if it is looped and cancel looping if necessary
if (!info.isLooped) {
// not looped
qDebug() << " anti-loop fix";
XCursorImage *i = cim->item(cim->count()-1);
i->setDelay(0x7fffffffL);
//i->setCSize(2); // ???
}
mList << cim;
}
}
}
} while (!eof);
return true;
}

@ -1,31 +0,0 @@
/* coded by Ketmar // Vampire Avalon (psyc://ketmar.no-ip.org/~Ketmar)
* (c)DWTFYW
*
* This program is free software. It comes without any warranty, to
* the extent permitted by applicable law. You can redistribute it
* and/or modify it under the terms of the Do What The Fuck You Want
* To Public License, Version 2, as published by Sam Hocevar. See
* http://sam.zoy.org/wtfpl/COPYING for more details.
*/
#ifndef XCRTHEMEXP_H
#define XCRTHEMEXP_H
#include <QtCore>
#include <QCursor>
#include <QPixmap>
#include "xcrimg.h"
#include "xcrtheme.h"
#include "xcrthemefx.h"
class XCursorThemeXP : public XCursorTheme {
public:
XCursorThemeXP (const QString &aFileName);
protected:
bool parseCursorXPTheme (const QDir &thDir);
};
#endif

@ -1,248 +0,0 @@
/* coded by Ketmar // Vampire Avalon (psyc://ketmar.no-ip.org/~Ketmar)
* (c)DWTFYW
*
* This program is free software. It comes without any warranty, to
* the extent permitted by applicable law. You can redistribute it
* and/or modify it under the terms of the Do What The Fuck You Want
* To Public License, Version 2, as published by Sam Hocevar. See
* http://sam.zoy.org/wtfpl/COPYING for more details.
*/
#include <QDebug>
//#include <QtCore>
#include "xcrxcur.h"
#include <QApplication>
#include <QStringList>
#include <QStyle>
#include <QTextCodec>
#include <QTextStream>
#include <QX11Info>
#include <X11/Xlib.h>
#include <X11/Xcursor/Xcursor.h>
#include <X11/extensions/Xfixes.h>
/*
static QImage autoCropImage (const QImage &image) {
// Compute an autocrop rectangle for the image
QRect r(image.rect().bottomRight(), image.rect().topLeft());
const quint32 *pixels = reinterpret_cast<const quint32*>(image.bits());
for (int y = 0; y < image.height(); y++) {
for (int x = 0; x < image.width(); x++) {
if (*(pixels++)) {
if (x < r.left()) r.setLeft(x);
if (x > r.right()) r.setRight(x);
if (y < r.top()) r.setTop(y);
if (y > r.bottom()) r.setBottom(y);
}
}
}
// Normalize the rectangle
return image.copy(r.normalized());
}
*/
inline static quint32 getDW (const void *data) {
const quint8 *d = (const quint8 *)data;
d += 3;
quint32 res = 0;
for (int f = 4; f > 0; f--, d--) {
res <<= 8;
res |= *d;
}
return res;
}
static quint32 baGetDW (QByteArray &ba, int &pos) {
const uchar *d = (const uchar *)ba.constData();
d += pos+3;
pos += 4;
quint32 res = 0;
for (int f = 4; f > 0; f--, d--) {
res <<= 8;
res |= *d;
}
return res;
}
///////////////////////////////////////////////////////////////////////////////
XCursorImageXCur::XCursorImageXCur (const QString &aName, const void *aImgData) : XCursorImage(aName) {
parseImgData(aImgData);
}
XCursorImageXCur::~XCursorImageXCur () {
}
void XCursorImageXCur::parseImgData (const void *aImgData) {
mIsValid = false;
delete mImage; // It's fine to delete a null pointer
mImage = 0;
const quint32 *data = (const quint32 *)aImgData;
if (getDW(data) != 36) return; // header size
if (getDW(data+1) != 0xfffd0002L) return; // magic
//if (getDW(data+2) != 1) return; // image subtype
if (getDW(data+3) != 1) return; // version
mCSize = getDW(data+2);
data += 4;
quint32 wdt = getDW(data++); // width
quint32 hgt = getDW(data++); // height
if (wdt > 0x7fff) return;
if (hgt > 0x7fff) return;
/*
quint32 xhot = getDW(data++);
quint32 yhot = getDW(data++);
assert(xhot <= wdt);
assert(yhot <= hgt);
*/
mXHot = *((const qint32 *)data); data++;
mYHot = *((const qint32 *)data); data++;
mDelay = getDW(data++); // milliseconds
// got to pixels (ARGB)
QImage img((const uchar *)data, wdt, hgt, QImage::Format_ARGB32_Premultiplied);
mImage = new QImage(img.copy());
mIsValid = true;
}
///////////////////////////////////////////////////////////////////////////////
XCursorImagesXCur::XCursorImagesXCur (const QDir &aDir, const QString &aName) : XCursorImages(aName, aDir.path()) {
parseCursorFile(aDir.path()+"/"+aName);
}
XCursorImagesXCur::XCursorImagesXCur (const QString &aFileName) : XCursorImages("", "") {
QString name(aFileName);
if (name.isEmpty() || name.endsWith('/')) return;
int i = name.lastIndexOf('/');
QString dir;
if (i < 0) dir = "./"; else dir = name.left(i);
name = name.mid(i+1);
setName(name); setPath(dir);
parseCursorFile(aFileName);
}
bool XCursorImagesXCur::parseCursorFile (const QString &fname) {
//qDebug() << fname;
qDeleteAll(mList);
mList.clear();
QFile fl(fname);
if (!fl.open(QIODevice::ReadOnly)) return false; // shit!
QByteArray ba(fl.readAll());
fl.close();
if (ba.size() < 4*4) return false; // shit!
if (ba[0] != 'X' || ba[1] != 'c' || ba[2] != 'u' || ba[3] != 'r') return false; // shit!
//FIXME: add more checks!
int pos = 4;
quint32 hdrSize = baGetDW(ba, pos);
if (hdrSize < 16) return false; // invalid header size
quint32 version = baGetDW(ba, pos);
if (version != 65536) return false; // invalid version
quint32 ntoc = baGetDW(ba, pos);
if (!ntoc) return true; // nothing to parse
if (ntoc >= 65536) return false; // idiot or what?
quint32 tocEndOfs = hdrSize+(ntoc*(3*4));
if (tocEndOfs > (quint32)ba.size()) return false; // out of data
pos = hdrSize;
// parse TOC
int cnt = -1;
bool wasTitle = false, wasAuthor = false, wasLic = false;
bool wasMail = false, wasSite = false, wasDescr = false, wasIM = false;
while (ntoc-- > 0) {
cnt++;
quint32 type = baGetDW(ba, pos);
pos += 4; // skip the shit
quint32 dataOfs = baGetDW(ba, pos);
if (type == 0xfffd0001) {
// text
if (dataOfs < tocEndOfs || dataOfs > (quint32)ba.size()-20) continue; // invalid text
// parse text
int ipos = dataOfs;
if (baGetDW(ba, ipos) != 20) continue; // invalid header size
if (baGetDW(ba, ipos) != 0xfffd0001) continue; // invalid type
quint32 subT = baGetDW(ba, ipos);
if (baGetDW(ba, ipos) != 1) continue; // invalid version
quint32 len = baGetDW(ba, ipos);
// check for data presence
if (ipos+len > (quint32)ba.size()) continue; // out of data
QByteArray stBA(ba.mid(ipos, len));
QString s(QString::fromUtf8(stBA));
switch (subT) {
case 1: // copyright (author)
if (!wasAuthor) {
wasAuthor = true;
mAuthor = s;
}
break;
case 2: // license
if (!wasLic) {
wasLic = true;
mLicense = s;
}
break;
case 3: // other (description)
if (!wasDescr) {
wasDescr = true;
mDescr = s;
}
break;
// my extensions
case 4: // title
if (!wasTitle) {
wasTitle = true;
mTitle = s;
}
break;
case 5: // e-mail
if (!wasMail) {
wasMail = true;
mEMail = s;
}
break;
case 6: // site
if (!wasSite) {
wasSite = true;
mSite = s;
}
break;
case 7: // IM
if (!wasIM) {
wasIM = true;
mIM = s;
}
break;
}
continue;
}
if (type != 0xfffd0002) continue; // not an image, skip this one
// image
// check
if (dataOfs < tocEndOfs || dataOfs > (quint32)ba.size()-36) continue; // invalid image
// parse image
int ipos = dataOfs;
if (baGetDW(ba, ipos) != 36) continue; // invalid image (header size)
if (baGetDW(ba, ipos) != 0xfffd0002) continue; // invalid type
ipos += 4; // skip the shit
if (baGetDW(ba, ipos) != 1) continue; // invalid image (version)
quint32 wdt = baGetDW(ba, ipos);
quint32 hgt = baGetDW(ba, ipos);
if (wdt > 0x7fff || hgt > 0x7fff) continue; // invalid sizes
// check for data presence
if ((ipos+3*4)+(wdt*hgt*4) > (quint32)ba.size()) continue; // out of data
// load image
const uchar *dta = (const uchar *)ba.constData();
dta += dataOfs;
XCursorImage *img = new XCursorImageXCur(mName+"_"+QString::number(cnt), dta);
if (img->isValid()) mList << img; else delete img;
}
return true;
}

@ -1,40 +0,0 @@
/* coded by Ketmar // Vampire Avalon (psyc://ketmar.no-ip.org/~Ketmar)
* (c)DWTFYW
*
* This program is free software. It comes without any warranty, to
* the extent permitted by applicable law. You can redistribute it
* and/or modify it under the terms of the Do What The Fuck You Want
* To Public License, Version 2, as published by Sam Hocevar. See
* http://sam.zoy.org/wtfpl/COPYING for more details.
*/
#ifndef XCRXCUR_H
#define XCRXCUR_H
#include <QtCore>
#include <QCursor>
#include <QPixmap>
#include "xcrimg.h"
class XCursorImageXCur : public XCursorImage {
public:
XCursorImageXCur (const QString &aName, const void *aImgData); // create from Xcursor file contents (ptr to image)
virtual ~XCursorImageXCur ();
protected:
void parseImgData (const void *aImgData);
};
class XCursorImagesXCur : public XCursorImages {
public:
XCursorImagesXCur (const QDir &aDir, const QString &aName);
XCursorImagesXCur (const QString &aFileName);
protected:
bool parseCursorFile (const QString &fname);
};
#endif

Binary file not shown.

Before

Width:  |  Height:  |  Size: 29 KiB

@ -1,101 +0,0 @@
project(lxqt-config-appearance)
include_directories(
${Qt5Gui_PRIVATE_INCLUDE_DIRS}
"${CMAKE_CURRENT_SOURCE_DIR}/../liblxqt-config-cursor"
)
set(H_FILES
iconthemeinfo.h
)
set(MOC_FILES
iconthemeconfig.h
lxqtthemeconfig.h
fontsconfig.h
styleconfig.h
fontconfigfile.h
)
set(CPP_FILES
main.cpp
iconthemeconfig.cpp
iconthemeinfo.cpp
lxqtthemeconfig.cpp
fontsconfig.cpp
styleconfig.cpp
fontconfigfile.cpp
)
set(UI_FILES
iconthemeconfig.ui
lxqtthemeconfig.ui
fontsconfig.ui
styleconfig.ui
)
set(QRC_FILES "")
set(LIBRARIES
lxqt
)
# Translations **********************************
lxqt_translate_ts(QM_FILES
UPDATE_TRANSLATIONS ${UPDATE_TRANSLATIONS}
SOURCES
${H_FILES}
${CPP_FILES}
${UI_FILES}
INSTALL_DIR
"${LXQT_TRANSLATIONS_DIR}/${PROJECT_NAME}"
PULL_TRANSLATIONS
${PULL_TRANSLATIONS}
CLEAN_TRANSLATIONS
${CLEAN_TRANSLATIONS}
TRANSLATIONS_REPO
${TRANSLATIONS_REPO}
TRANSLATIONS_REFSPEC
${TRANSLATIONS_REFSPEC}
REPO_SUBDIR
"lxqt-config/${PROJECT_NAME}"
)
lxqt_app_translation_loader(QM_LOADER ${PROJECT_NAME})
lxqt_translate_desktop(DESKTOP_FILES SOURCES ${PROJECT_NAME}.desktop.in)
#************************************************
add_executable(${PROJECT_NAME}
${CPP_FILES}
${RESOURCES}
${QRC_FILES}
${QM_FILES}
${QM_LOADER}
${DESKTOP_FILES}
)
target_link_libraries(${PROJECT_NAME}
Qt5::Widgets
Qt5::X11Extras
Qt5::Xml
${LIBRARIES}
lxqt-config-cursor
)
set_target_properties("${PROJECT_NAME}"
PROPERTIES
INSTALL_RPATH "${CMAKE_INSTALL_FULL_LIBDIR}/${LXQT_CONFIG_PROJECT}"
)
install(TARGETS
${PROJECT_NAME}
RUNTIME DESTINATION "${CMAKE_INSTALL_BINDIR}"
COMPONENT Runtime
)
install(FILES
${DESKTOP_FILES}
DESTINATION "${CMAKE_INSTALL_DATAROOTDIR}/applications"
COMPONENT Runtime
)

@ -1,236 +0,0 @@
/*
* Copyright (C) 2014 Hong Jen Yee (PCMan) <pcman.tw@gmail.com>
* LXQt project: http://lxde.org/
*
* 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 "fontconfigfile.h"
#include <QTextStream>
#include <QByteArray>
#include <QFile>
#include <QDir>
#include <QDesktopServices>
#include <QStringBuilder>
#include <QDomDocument>
#include <QTimer>
#include <QDebug>
#include <QStandardPaths>
FontConfigFile::FontConfigFile(QObject* parent):
QObject(parent),
mAntialias(true),
mHinting(true),
mSubpixel("rgb"),
mHintStyle("hintslight"),
mDpi(96),
mAutohint(false),
mSaveTimer(NULL)
{
mDirPath = QString::fromLocal8Bit(qgetenv("XDG_CONFIG_HOME"));
QString homeDir = QStandardPaths::writableLocation(QStandardPaths::HomeLocation);
if(mDirPath.isEmpty())
mDirPath = homeDir % "/.config";
mDirPath += "/fontconfig";
mFilePath = mDirPath + "/fonts.conf";
load();
}
FontConfigFile::~FontConfigFile()
{
if(mSaveTimer) // has pending save request
{
delete mSaveTimer;
mSaveTimer = NULL;
save();
}
}
void FontConfigFile::setAntialias(bool value)
{
mAntialias = value;
queueSave();
}
void FontConfigFile::setSubpixel(QByteArray value)
{
mSubpixel = value;
queueSave();
}
void FontConfigFile::setHinting(bool value)
{
mHinting = value;
queueSave();
}
void FontConfigFile::setHintStyle(QByteArray value)
{
mHintStyle = value;
queueSave();
}
void FontConfigFile::setDpi(int value)
{
mDpi = value;
queueSave();
}
void FontConfigFile::setAutohint(bool value)
{
mAutohint = value;
queueSave();
}
void FontConfigFile::load()
{
QFile file(mFilePath);
if(file.open(QIODevice::ReadOnly))
{
QByteArray buffer = file.readAll();
file.close();
if(buffer.contains("lxqt-config-appearance")) // the config file is created by us
{
// doing full xml parsing is over-kill. let's use some simpler brute-force methods.
QDomDocument doc;
doc.setContent(&file);
file.close();
QDomElement docElem = doc.documentElement();
QDomNodeList editNodes = docElem.elementsByTagName("edit");
for(int i = 0; i < editNodes.count(); ++i)
{
QDomElement editElem = editNodes.at(i).toElement();
QByteArray name = editElem.attribute("name").toLatin1();
if(name == "antialias")
{
QString value = editElem.firstChildElement("bool").text();
mAntialias = value[0] == 't' ? true : false;
}
else if(name == "rgba")
{
QString value = editElem.firstChildElement("const").text();
mSubpixel = value.toLatin1();
}
else if(name == "hinting")
{
QString value = editElem.firstChildElement("bool").text();
mHinting = value[0] == 't' ? true : false;
}
else if(name == "hintstyle")
{
QString value = editElem.firstChildElement("const").text();
mHintStyle = value.toLatin1();
}
else if(name == "dpi")
{
QString value = editElem.firstChildElement("double").text();
mDpi = value.toInt();
}
else if(name == "autohint")
{
QString value = editElem.firstChildElement("bool").text();
mAutohint = value[0] == 't' ? true : false;
}
}
}
else // the config file is created by others => make a backup and write our config
{
QFile backup(mFilePath + ".bak");
if(backup.open(QIODevice::WriteOnly))
{
backup.write(buffer);
backup.close();
}
queueSave(); // overwrite with our file
}
}
}
void FontConfigFile::save()
{
if(mSaveTimer)
{
mSaveTimer->deleteLater();
mSaveTimer = NULL;
}
QFile file(mFilePath);
QDir().mkdir(mDirPath);
// References: https://wiki.archlinux.org/index.php/Font_Configuration
if(file.open(QIODevice::WriteOnly))
{
QTextStream s(&file);
s <<
"<?xml version=\"1.0\"?>\n"
"<!DOCTYPE fontconfig SYSTEM \"fonts.dtd\">\n"
"<!-- created by lxqt-config-appearance (DO NOT EDIT!) -->\n"
"<fontconfig>\n"
" <include ignore_missing=\"yes\">conf.d</include>\n"
" <match target=\"font\">\n"
" <edit name=\"antialias\" mode=\"assign\">\n"
" <bool>" << (mAntialias ? "true" : "false") << "</bool>\n"
" </edit>\n"
" </match>\n"
" <match target=\"font\">\n"
" <edit name=\"rgba\" mode=\"assign\">\n"
" <const>" << mSubpixel << "</const>\n"
" </edit>\n"
" </match>\n"
" <match target=\"font\">\n"
" <edit name=\"lcdfilter\" mode=\"assign\">\n"
" <const>lcddefault</const>\n"
" </edit>\n"
" </match>\n"
" <match target=\"font\">\n"
" <edit name=\"hinting\" mode=\"assign\">\n"
" <bool>" << (mHinting ? "true" : "false") << "</bool>\n"
" </edit>\n"
" </match>\n"
" <match target=\"font\">\n"
" <edit name=\"hintstyle\" mode=\"assign\">\n"
" <const>" << mHintStyle << "</const>\n"
" </edit>\n"
" </match>\n"
" <match target=\"font\">\n"
" <edit name=\"autohint\" mode=\"assign\">\n"
" <bool>" << (mAutohint ? "true" : "false") << "</bool>\n"
" </edit>\n"
" </match>\n"
" <match target=\"pattern\">\n"
" <edit name=\"dpi\" mode=\"assign\">\n"
" <double>" << mDpi << "</double>\n"
" </edit>\n"
" </match>\n"
"</fontconfig>";
s.flush();
file.close();
}
}
void FontConfigFile::queueSave()
{
if(mSaveTimer)
mSaveTimer->start(1500);
else
{
mSaveTimer = new QTimer();
mSaveTimer->setSingleShot(true);
connect(mSaveTimer, SIGNAL(timeout()), this, SLOT(save()));
mSaveTimer->start(1500);
}
}

@ -1,86 +0,0 @@
/*
* Copyright (C) 2014 Hong Jen Yee (PCMan) <pcman.tw@gmail.com>
* LXQt project: http://lxde.org/
*
* 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 FONTCONFIGFILE_H
#define FONTCONFIGFILE_H
#include <QString>
#include <QByteArray>
#include <QObject>
class QTimer;
class FontConfigFile: public QObject
{
Q_OBJECT
public:
explicit FontConfigFile(QObject* parent = 0);
virtual ~FontConfigFile();
bool antialias() const {
return mAntialias;
}
void setAntialias(bool value);
bool hinting() const {
return mHinting;
}
void setHinting(bool value);
QByteArray subpixel() const {
return mSubpixel;
}
void setSubpixel(QByteArray value);
QByteArray hintStyle() const {
return mHintStyle;
}
void setHintStyle(QByteArray value);
int dpi() const {
return mDpi;
}
void setDpi(int value);
bool autohint() const {
return mAutohint;
}
void setAutohint(bool value);
private Q_SLOTS:
void save();
private:
void load();
void queueSave();
private:
bool mAntialias;
bool mHinting;
QByteArray mSubpixel;
QByteArray mHintStyle;
int mDpi;
bool mAutohint;
QString mDirPath;
QString mFilePath;
QTimer* mSaveTimer;
};
#endif // FONTCONFIGFILE_H

@ -1,196 +0,0 @@
/* BEGIN_COMMON_COPYRIGHT_HEADER
* (c)LGPL2+
*
* LXQt - a lightweight, Qt based, desktop toolset
* http://lxde.org/
*
* Copyright: 2014 LXQt team
* Authors:
* Hong Jen Yee (PCMan) <pcman.tw@gmail.com>
*
* This program or library is free software; you can redistribute it
* and/or modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
* 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
*
* END_COMMON_COPYRIGHT_HEADER */
#include "fontsconfig.h"
#include "ui_fontsconfig.h"
#include <QTreeWidget>
#include <QDebug>
#include <QSettings>
#include <QFont>
#include <QFile>
#include <QDir>
#include <QDesktopServices>
#include <QTextStream>
#include <QStringBuilder>
#include <QDomDocument>
#ifdef Q_WS_X11
extern void qt_x11_apply_settings_in_all_apps();
#endif
static const char* subpixelNames[] = {"none", "rgb", "bgr", "vrgb", "vbgr"};
static const char* hintStyleNames[] = {"hintnone", "hintslight", "hintmedium", "hintfull"};
FontsConfig::FontsConfig(LXQt::Settings* settings, QSettings* qtSettings, QWidget* parent) :
QWidget(parent),
ui(new Ui::FontsConfig),
mQtSettings(qtSettings),
mSettings(settings),
mFontConfigFile()
{
ui->setupUi(this);
initControls();
connect(ui->fontName, SIGNAL(currentFontChanged(QFont)), SLOT(updateQtFont()));
connect(ui->fontStyle, SIGNAL(currentIndexChanged(int)), SLOT(updateQtFont()));
connect(ui->fontSize, SIGNAL(valueChanged(int)), SLOT(updateQtFont()));
connect(ui->antialias, SIGNAL(toggled(bool)), SLOT(antialiasToggled(bool)));
connect(ui->subpixel, SIGNAL(currentIndexChanged(int)), SLOT(subpixelChanged(int)));
connect(ui->hinting, SIGNAL(toggled(bool)), SLOT(hintingToggled(bool)));
connect(ui->hintStyle, SIGNAL(currentIndexChanged(int)), SLOT(hintStyleChanged(int)));
connect(ui->dpi, SIGNAL(valueChanged(int)), SLOT(dpiChanged(int)));
connect(ui->autohint, SIGNAL(toggled(bool)), SLOT(autohintToggled(bool)));
}
FontsConfig::~FontsConfig()
{
delete ui;
}
void FontsConfig::initControls()
{
// read Qt style settings from Qt Trolltech.conf config
mQtSettings->beginGroup(QLatin1String("Qt"));
QString fontName = mQtSettings->value("font").toString();
QFont font;
font.fromString(fontName);
ui->fontName->setCurrentFont(font);
ui->fontSize->setValue(font.pointSize());
int fontStyle = 0;
if(font.bold())
fontStyle = font.italic() ? 3 : 1;
else if(font.italic())
fontStyle = 2;
ui->fontStyle->setCurrentIndex(fontStyle);
mQtSettings->endGroup();
// load fontconfig config
ui->antialias->setChecked(mFontConfigFile.antialias());
ui->autohint->setChecked(mFontConfigFile.autohint());
QByteArray subpixelStr = mFontConfigFile.subpixel();
int subpixel;
for(subpixel = 0; subpixel < 5; ++subpixel)
{
if(subpixelStr == subpixelNames[subpixel])
break;
}
if(subpixel < 5)
ui->subpixel->setCurrentIndex(subpixel);
ui->hinting->setChecked(mFontConfigFile.hinting());
QByteArray hintStyleStr = mFontConfigFile.hintStyle();
int hintStyle;
for(hintStyle = 0; hintStyle < 4; ++hintStyle)
{
if(hintStyleStr == hintStyleNames[hintStyle])
break;
}
if(hintStyle < 4)
ui->hintStyle->setCurrentIndex(hintStyle);
int dpi = mFontConfigFile.dpi();
ui->dpi->setValue(dpi);
update();
}
void FontsConfig::antialiasToggled(bool toggled)
{
mFontConfigFile.setAntialias(toggled);
}
void FontsConfig::dpiChanged(int value)
{
mFontConfigFile.setDpi(value);
}
void FontsConfig::hintingToggled(bool toggled)
{
mFontConfigFile.setHinting(toggled);
}
void FontsConfig::subpixelChanged(int index)
{
mFontConfigFile.setSubpixel(subpixelNames[index]);
}
void FontsConfig::hintStyleChanged(int index)
{
mFontConfigFile.setHintStyle(hintStyleNames[index]);
}
void FontsConfig::autohintToggled(bool toggled)
{
mFontConfigFile.setAutohint(toggled);
}
void FontsConfig::updateQtFont()
{
// FIXME: the change does not apply to some currently running Qt programs.
// FIXME: does not work with KDE apps
// TODO: also write the config values to GTK+ config files (gtk-2.0.rc and gtk3/settings.ini)
// FIXME: the selected font does not apply to our own application. Why?
QFont font = ui->fontName->currentFont();
int size = ui->fontSize->value();
bool bold = false;
bool italic = false;
switch(ui->fontStyle->currentIndex())
{
case 1:
bold = true;
break;
case 2:
italic = true;
break;
case 3:
bold = italic = true;
}
font.setPointSize(size);
font.setBold(bold);
font.setItalic(italic);
mQtSettings->beginGroup(QLatin1String("Qt"));
mQtSettings->setValue("font", font.toString());
mQtSettings->endGroup();
mQtSettings->sync();
#ifdef Q_WS_X11
qt_x11_apply_settings_in_all_apps();
#endif
update();
}

@ -1,70 +0,0 @@
/* BEGIN_COMMON_COPYRIGHT_HEADER
* (c)LGPL2+
*
* LXQt - a lightweight, Qt based, desktop toolset
* http://razor-qt.org
*
* Copyright: 2012 Razor team
* Authors:
* Alexander Sokoloff <sokoloff.a@gmail.com>
*
* This program or library is free software; you can redistribute it
* and/or modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
* 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
*
* END_COMMON_COPYRIGHT_HEADER */
#ifndef FONTSCONFIG_H
#define FONTSCONFIG_H
#include <QWidget>
#include <QFont>
#include <LXQt/Settings>
#include "fontconfigfile.h"
class QTreeWidgetItem;
class QSettings;
namespace Ui {
class FontsConfig;
}
class FontsConfig : public QWidget
{
Q_OBJECT
public:
explicit FontsConfig(LXQt::Settings *settings, QSettings *qtSettings, QWidget *parent = 0);
~FontsConfig();
public Q_SLOTS:
void initControls();
private Q_SLOTS:
void updateQtFont();
void antialiasToggled(bool toggled);
void hintingToggled(bool toggled);
void subpixelChanged(int index);
void hintStyleChanged(int index);
void dpiChanged(int value);
void autohintToggled(bool toggled);
private:
Ui::FontsConfig *ui;
QSettings *mQtSettings;
LXQt::Settings *mSettings;
FontConfigFile mFontConfigFile;
};
#endif // FONTSCONFIG_H

@ -1,261 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>FontsConfig</class>
<widget class="QWidget" name="FontsConfig">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>421</width>
<height>379</height>
</rect>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<widget class="QLabel" name="label">
<property name="font">
<font>
<weight>75</weight>
<bold>true</bold>
</font>
</property>
<property name="text">
<string>Font</string>
</property>
</widget>
</item>
<item>
<widget class="QGroupBox" name="groupBox">
<property name="title">
<string>Default font for user interface</string>
</property>
<layout class="QFormLayout" name="formLayout_3">
<item row="0" column="0">
<widget class="QLabel" name="label_2">
<property name="text">
<string>Font name:</string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QFontComboBox" name="fontName"/>
</item>
<item row="1" column="0">
<widget class="QLabel" name="label_6">
<property name="text">
<string>Style:</string>
</property>
</widget>
</item>
<item row="2" column="0">
<widget class="QLabel" name="label_7">
<property name="text">
<string>Point size:</string>
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="QSpinBox" name="fontSize">
<property name="minimum">
<number>4</number>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QComboBox" name="fontStyle">
<item>
<property name="text">
<string>Normal</string>
</property>
</item>
<item>
<property name="text">
<string>Bold</string>
</property>
</item>
<item>
<property name="text">
<string>Italic</string>
</property>
</item>
<item>
<property name="text">
<string>Bold Italic</string>
</property>
</item>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QGroupBox" name="xftSettings">
<property name="title">
<string>The following settings only affect newly started applications</string>
</property>
<layout class="QFormLayout" name="formLayout_2">
<item row="0" column="0" colspan="2">
<widget class="QCheckBox" name="antialias">
<property name="text">
<string>Use antialias fonts</string>
</property>
</widget>
</item>
<item row="3" column="0">
<widget class="QLabel" name="label_3">
<property name="text">
<string>Font hinting style:</string>
</property>
</widget>
</item>
<item row="3" column="1">
<widget class="QComboBox" name="hintStyle">
<property name="enabled">
<bool>false</bool>
</property>
<item>
<property name="text">
<string>None</string>
</property>
</item>
<item>
<property name="text">
<string>Slight</string>
</property>
</item>
<item>
<property name="text">
<string>Medium</string>
</property>
</item>
<item>
<property name="text">
<string>Full</string>
</property>
</item>
</widget>
</item>
<item row="2" column="0" colspan="2">
<widget class="QCheckBox" name="hinting">
<property name="text">
<string>Font hinting</string>
</property>
</widget>
</item>
<item row="5" column="0">
<widget class="QLabel" name="label_5">
<property name="text">
<string>Resolution (DPI):</string>
</property>
</widget>
</item>
<item row="6" column="0" colspan="2">
<widget class="QCheckBox" name="autohint">
<property name="text">
<string>Autohint</string>
</property>
</widget>
</item>
<item row="5" column="1">
<widget class="QSpinBox" name="dpi">
<property name="minimum">
<number>-1</number>
</property>
<property name="maximum">
<number>1048576</number>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QLabel" name="label_4">
<property name="text">
<string>Subpixel antialiasing:</string>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QComboBox" name="subpixel">
<property name="enabled">
<bool>false</bool>
</property>
<item>
<property name="text">
<string>None</string>
</property>
</item>
<item>
<property name="text">
<string>RGB</string>
</property>
</item>
<item>
<property name="text">
<string>BGR</string>
</property>
</item>
<item>
<property name="text">
<string>VRGB</string>
</property>
</item>
<item>
<property name="text">
<string>VBGR</string>
</property>
</item>
</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>
<resources/>
<connections>
<connection>
<sender>antialias</sender>
<signal>toggled(bool)</signal>
<receiver>subpixel</receiver>
<slot>setEnabled(bool)</slot>
<hints>
<hint type="sourcelabel">
<x>225</x>
<y>109</y>
</hint>
<hint type="destinationlabel">
<x>298</x>
<y>140</y>
</hint>
</hints>
</connection>
<connection>
<sender>hinting</sender>
<signal>toggled(bool)</signal>
<receiver>hintStyle</receiver>
<slot>setEnabled(bool)</slot>
<hints>
<hint type="sourcelabel">
<x>225</x>
<y>171</y>
</hint>
<hint type="destinationlabel">
<x>298</x>
<y>202</y>
</hint>
</hints>
</connection>
</connections>
</ui>

@ -1,155 +0,0 @@
/* BEGIN_COMMON_COPYRIGHT_HEADER
* (c)LGPL2+
*
* LXQt - a lightweight, Qt based, desktop toolset
* http://razor-qt.org
*
* Copyright: 2010-2011 Razor team
* Authors:
* Petr Vanek <petr@scribus.info>
*
* This program or library is free software; you can redistribute it
* and/or modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
* 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
*
* END_COMMON_COPYRIGHT_HEADER */
#include "iconthemeconfig.h"
#include <LXQt/Settings>
#include <QStringList>
#include <QStringBuilder>
#include <QIcon>
IconThemeConfig::IconThemeConfig(LXQt::Settings* settings, QWidget* parent):
QWidget(parent),
m_settings(settings)
{
setupUi(this);
initIconsThemes();
initControls();
connect(iconThemeList, SIGNAL(itemClicked(QTreeWidgetItem*,int)),
this, SLOT(iconThemeSelected(QTreeWidgetItem*,int)));
connect(iconFollowColorSchemeCB, &QAbstractButton::toggled, this, [this] (bool checked) {
m_settings->setValue("icon_follow_color_scheme", checked);
});
}
void IconThemeConfig::initIconsThemes()
{
QStringList processed;
const QStringList baseDirs = QIcon::themeSearchPaths();
static const QStringList iconNames = QStringList()
<< QStringLiteral("document-open")
<< QStringLiteral("document-new")
<< QStringLiteral("edit-undo")
<< QStringLiteral("media-playback-start");
const int iconNamesN = iconNames.size();
iconThemeList->setColumnCount(iconNamesN + 2);
QList<QTreeWidgetItem *> items;
foreach (const QString &baseDirName, baseDirs)
{
QDir baseDir(baseDirName);
if (!baseDir.exists())
continue;
const QFileInfoList dirs = baseDir.entryInfoList(QDir::AllDirs | QDir::NoDotAndDotDot, QDir::Name);
foreach (const QFileInfo &dir, dirs)
{
if (!processed.contains(dir.canonicalFilePath()))
{
processed << dir.canonicalFilePath();
IconThemeInfo theme(QDir(dir.canonicalFilePath()));
if (theme.isValid() && (!theme.isHidden()))
{
QTreeWidgetItem *item = new QTreeWidgetItem((QTreeWidget*)0);
item->setSizeHint(0, QSize(42,42)); // make icons non-cropped
item->setData(0, Qt::UserRole, theme.name());
const QVector<QIcon> icons = theme.icons(iconNames);
const int K = icons.size();
for (int i = 0; i < K; ++i)
{
item->setIcon(i, icons.at(i));
}
QString themeDescription;
if (theme.comment().isEmpty())
{
themeDescription = theme.text();
}
else
{
themeDescription = theme.text() % QStringLiteral(" (") % theme.comment() % QStringLiteral(")");
}
item->setText(iconNamesN + 1, themeDescription);
items.append(item);
}
}
}
}
iconThemeList->insertTopLevelItems(0, items);
for (int i=0; i<iconThemeList->header()->count()-1; ++i)
{
iconThemeList->resizeColumnToContents(i);
}
}
void IconThemeConfig::initControls()
{
QString currentTheme = QIcon::themeName();
QTreeWidgetItemIterator it(iconThemeList);
while (*it) {
if ((*it)->data(0, Qt::UserRole).toString() == currentTheme)
{
iconThemeList->setCurrentItem((*it));
break;
}
++it;
}
iconFollowColorSchemeCB->setChecked(m_settings->value("icon_follow_color_scheme", true).toBool());
update();
}
IconThemeConfig::~IconThemeConfig()
{
}
void IconThemeConfig::iconThemeSelected(QTreeWidgetItem *item, int column)
{
Q_UNUSED(column);
const QString theme = item->data(0, Qt::UserRole).toString();
if (!theme.isEmpty())
{
// Ensure that this widget also updates it's own icons
QIcon::setThemeName(theme);
m_settings->setValue("icon_theme", theme);
m_settings->sync();
}
}

@ -1,58 +0,0 @@
/* BEGIN_COMMON_COPYRIGHT_HEADER
* (c)LGPL2+
*
* LXQt - a lightweight, Qt based, desktop toolset
* http://razor-qt.org
*
* Copyright: 2010-2011 Razor team
* Authors:
* Petr Vanek <petr@scribus.info>
*
* This program or library is free software; you can redistribute it
* and/or modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
* 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
*
* END_COMMON_COPYRIGHT_HEADER */
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include "ui_iconthemeconfig.h"
#include "iconthemeinfo.h"
namespace LXQt {
class Settings;
}
class IconThemeConfig : public QWidget, public Ui::IconThemeConfig
{
Q_OBJECT
public:
IconThemeConfig(LXQt::Settings *settings, QWidget *parent = 0);
~IconThemeConfig();
private:
LXQt::Settings *m_settings;
void initIconsThemes();
public slots:
void initControls();
private slots:
void iconThemeSelected(QTreeWidgetItem *item, int column);
};
#endif

@ -1,98 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>IconThemeConfig</class>
<widget class="QWidget" name="IconThemeConfig">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>450</width>
<height>327</height>
</rect>
</property>
<property name="windowTitle">
<string>LXQt Appearance Configuration</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<widget class="QLabel" name="label">
<property name="font">
<font>
<weight>75</weight>
<bold>true</bold>
</font>
</property>
<property name="text">
<string>Icons Theme</string>
</property>
</widget>
</item>
<item>
<widget class="QTreeWidget" name="iconThemeList">
<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="alternatingRowColors">
<bool>true</bool>
</property>
<property name="iconSize">
<size>
<width>22</width>
<height>22</height>
</size>
</property>
<property name="rootIsDecorated">
<bool>false</bool>
</property>
<property name="uniformRowHeights">
<bool>true</bool>
</property>
<property name="columnCount">
<number>4</number>
</property>
<attribute name="headerVisible">
<bool>false</bool>
</attribute>
<column>
<property name="text">
<string notr="true">1</string>
</property>
</column>
<column>
<property name="text">
<string notr="true">2</string>
</property>
</column>
<column>
<property name="text">
<string notr="true">3</string>
</property>
</column>
<column>
<property name="text">
<string notr="true">4</string>
</property>
</column>
</widget>
</item>
<item>
<widget class="QCheckBox" name="iconFollowColorSchemeCB">
<property name="toolTip">
<string>The KDE extension of XDG icon themes -&gt; FollowsColorScheme</string>
</property>
<property name="text">
<string>Colorize icons based on widget style (palette)</string>
</property>
</widget>
</item>
</layout>
</widget>
<resources/>
<connections/>
</ui>

@ -1,80 +0,0 @@
/* BEGIN_COMMON_COPYRIGHT_HEADER
* (c)LGPL2+
*
* LXQt - a lightweight, Qt based, desktop toolset
* https://sourceforge.net/projects/lxde-qt/
*
* Copyright: 2010-2011 Razor team
* Authors:
* Alexander Sokoloff <sokoloff.a@gmail.com>
* Luis Pereira <luis.artur.pereira@gmail.com>
*
* The directoryMatchesSize() and thedirectorySizeDistance() functions were
* taken from Qt5 qtbase/src/gui/image/qiconloader.cpp
* Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
*
* This program or library is free software; you can redistribute it
* and/or modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
* 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
*
* END_COMMON_COPYRIGHT_HEADER */
#include "iconthemeinfo.h"
#define PREVIEW_ICON_SIZE 22
IconThemeInfo::IconThemeInfo(const QDir &dir):
mValid(false),
mHidden(false)
{
mName = dir.dirName();
if (dir.exists(QStringLiteral("index.theme")))
load(dir.absoluteFilePath(QStringLiteral("index.theme")));
}
void IconThemeInfo::load(const QString &fileName)
{
mFileName = fileName;
mValid = false;
QSettings file(mFileName, QSettings::IniFormat);
if (file.status() != QSettings::NoError)
return;
if (file.value(QStringLiteral("Icon Theme/Directories")).toStringList().join(QLatin1Char(' ')).isEmpty())
return;
mHidden = file.value(QStringLiteral("Icon Theme/Hidden"), false).toBool();
mText = file.value(QStringLiteral("Icon Theme/Name")).toString();
mComment = file.value(QStringLiteral("Icon Theme/Comment")).toString();
mValid = true;
}
QVector<QIcon> IconThemeInfo::icons(const QStringList &iconNames) const
{
QVector<QIcon> icons;
QString current_theme = QIcon::themeName();
QIcon::setThemeName(mName);
for (const auto & i : iconNames)
{
icons.push_back({QIcon::fromTheme(i).pixmap({PREVIEW_ICON_SIZE, PREVIEW_ICON_SIZE})});
}
QIcon::setThemeName(current_theme);
return icons;
}

@ -1,65 +0,0 @@
/* BEGIN_COMMON_COPYRIGHT_HEADER
* (c)LGPL2+
*
* LXQt - a lightweight, Qt based, desktop toolset
* https://sourceforge.net/projects/lxde-qt/
*
* Copyright: 2010-2011 Razor team
* Authors:
* Alexander Sokoloff <sokoloff.a@gmail.com>
*
* This program or library is free software; you can redistribute it
* and/or modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
* 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
*
* END_COMMON_COPYRIGHT_HEADER */
#ifndef ICONTHEMEINFO_H
#define ICONTHEMEINFO_H
#include <QObject>
#include <QIcon>
#include <QDir>
#include <QSettings>
#include <QVector>
class IconThemeInfo
{
public:
IconThemeInfo(const QDir &dir);
QString fileName() const { return mFileName; }
QString name() const { return mName; }
QString text() const { return mText; }
QString comment() const { return mComment; }
bool isValid() const { return mValid; }
bool isHidden() const { return mHidden; }
QVector<QIcon> icons(const QStringList &iconNames) const;
private:
QString mFileName;
QString mName;
QString mText;
QString mComment;
bool mValid;
bool mHidden;
void load(const QString &fileName);
};
#endif // ICONTHEMEINFO_H

@ -1,11 +0,0 @@
[Desktop Entry]
Type=Application
Name=Appearance
GenericName=Appearance settings
Comment=Appearance settings for LXQt
Exec=lxqt-config-appearance
Icon=preferences-desktop-theme
Categories=Settings;DesktopSettings;Qt;LXQt;
OnlyShowIn=LXQt;
#TRANSLATIONS_DIR=translations

@ -1,152 +0,0 @@
/* BEGIN_COMMON_COPYRIGHT_HEADER
* (c)LGPL2+
*
* LXQt - a lightweight, Qt based, desktop toolset
* http://razor-qt.org
*
* Copyright: 2012 Razor team
* Authors:
* Alexander Sokoloff <sokoloff.a@gmail.com>
*
* This program or library is free software; you can redistribute it
* and/or modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
* 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
*
* END_COMMON_COPYRIGHT_HEADER */
#include "lxqtthemeconfig.h"
#include "ui_lxqtthemeconfig.h"
#include <QTreeWidget>
#include <QStandardPaths>
#include <QProcess>
#include <QItemDelegate>
#include <QPainter>
/*!
* \brief Simple delegate to draw system background color below decoration/icon
* (needed by System theme, which uses widget background and therefore provides semi-transparent preview)
*/
class ThemeDecorator : public QItemDelegate
{
public:
using QItemDelegate::QItemDelegate;
protected:
virtual void drawDecoration(QPainter * painter, const QStyleOptionViewItem & option, const QRect & rect, const QPixmap & pixmap) const override
{
//Note: can't use QItemDelegate::drawDecoration, because it is ignoring pixmap,
//if the icon is valid (and that is set in paint())
if (pixmap.isNull() || !rect.isValid())
return;
QPoint p = QStyle::alignedRect(option.direction, option.decorationAlignment, pixmap.size(), rect).topLeft();
painter->fillRect(QRect{p, pixmap.size()}, QApplication::palette().color(QPalette::Window));
painter->drawPixmap(p, pixmap);
}
};
/*!
* \brief Check if currently configured wallpaper (read from pcmanfm-qt's
* settings) is the same as \param themeWallpaper
*/
static bool isWallpaperChanged(const QString & themeWallpaper)
{
static const QString config_path = QStandardPaths::writableLocation(QStandardPaths::ConfigLocation)
+ QStringLiteral("/pcmanfm-qt/lxqt/settings.conf");
static const QString wallpaper_key = QStringLiteral("Desktop/Wallpaper");
const QString current_wallpaper = QSettings{config_path, QSettings::IniFormat}.value(wallpaper_key).toString();
return themeWallpaper != current_wallpaper;
}
LXQtThemeConfig::LXQtThemeConfig(LXQt::Settings *settings, QWidget *parent) :
QWidget(parent),
ui(new Ui::LXQtThemeConfig),
mSettings(settings)
{
ui->setupUi(this);
{
QScopedPointer<QAbstractItemDelegate> p{ui->lxqtThemeList->itemDelegate()};
ui->lxqtThemeList->setItemDelegate(new ThemeDecorator{this});
}
connect(ui->lxqtThemeList, SIGNAL(itemClicked(QTreeWidgetItem*,int)),
this, SLOT(lxqtThemeSelected(QTreeWidgetItem*,int)));
connect(ui->wallpaperOverride, &QAbstractButton::toggled, [this] (bool checked) {
if (checked)
lxqtThemeSelected(ui->lxqtThemeList->currentItem(), 0/*not used*/);
});
const QList<LXQt::LXQtTheme> themes = LXQt::LXQtTheme::allThemes();
foreach(const LXQt::LXQtTheme &theme, themes)
{
QString themeName = theme.name();
themeName[0] = themeName[0].toTitleCase();
QTreeWidgetItem *item = new QTreeWidgetItem(QStringList(themeName));
if (!theme.previewImage().isEmpty())
{
item->setIcon(0, QIcon(theme.previewImage()));
}
item->setSizeHint(0, QSize(42,42)); // make icons non-cropped
item->setData(0, Qt::UserRole, theme.name());
ui->lxqtThemeList->addTopLevelItem(item);
}
initControls();
}
LXQtThemeConfig::~LXQtThemeConfig()
{
delete ui;
}
void LXQtThemeConfig::initControls()
{
QString currentTheme = mSettings->value("theme").toString();
QTreeWidgetItemIterator it(ui->lxqtThemeList);
while (*it) {
if ((*it)->data(0, Qt::UserRole).toString() == currentTheme)
{
ui->lxqtThemeList->setCurrentItem((*it));
break;
}
++it;
}
update();
}
void LXQtThemeConfig::lxqtThemeSelected(QTreeWidgetItem* item, int column)
{
Q_UNUSED(column);
if (!item)
return;
LXQt::LXQtTheme currentTheme{mSettings->value("theme").toString()};
QVariant themeName = item->data(0, Qt::UserRole);
mSettings->setValue("theme", themeName);
LXQt::LXQtTheme theme(themeName.toString());
if(theme.isValid()) {
QString wallpaper = theme.desktopBackground();
if(!wallpaper.isEmpty() && (ui->wallpaperOverride->isChecked() || !isWallpaperChanged(currentTheme.desktopBackground()))) {
// call pcmanfm-qt to update wallpaper
QStringList args;
args << "--set-wallpaper" << wallpaper;
QProcess::startDetached("pcmanfm-qt", args);
}
}
}

@ -1,59 +0,0 @@
/* BEGIN_COMMON_COPYRIGHT_HEADER
* (c)LGPL2+
*
* LXQt - a lightweight, Qt based, desktop toolset
* http://razor-qt.org
*
* Copyright: 2012 Razor team
* Authors:
* Alexander Sokoloff <sokoloff.a@gmail.com>
*
* This program or library is free software; you can redistribute it
* and/or modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
* 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
*
* END_COMMON_COPYRIGHT_HEADER */
#ifndef LXQTTHEMECONFIG_H
#define LXQTTHEMECONFIG_H
#include <QWidget>
#include <LXQt/Settings>
class QTreeWidgetItem;
namespace Ui {
class LXQtThemeConfig;
}
class LXQtThemeConfig : public QWidget
{
Q_OBJECT
public:
explicit LXQtThemeConfig(LXQt::Settings *settings, QWidget *parent = 0);
~LXQtThemeConfig();
public slots:
void initControls();
private slots:
void lxqtThemeSelected(QTreeWidgetItem* item, int column);
private:
Ui::LXQtThemeConfig *ui;
LXQt::Settings *mSettings;
};
#endif // LXQTTHEMECONFIG_H

@ -1,65 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>LXQtThemeConfig</class>
<widget class="QWidget" name="LXQtThemeConfig">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>400</width>
<height>300</height>
</rect>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<widget class="QLabel" name="label">
<property name="font">
<font>
<weight>75</weight>
<bold>true</bold>
</font>
</property>
<property name="text">
<string>LXQt Theme</string>
</property>
</widget>
</item>
<item>
<widget class="QTreeWidget" name="lxqtThemeList">
<property name="alternatingRowColors">
<bool>true</bool>
</property>
<property name="iconSize">
<size>
<width>100</width>
<height>32</height>
</size>
</property>
<property name="rootIsDecorated">
<bool>false</bool>
</property>
<property name="uniformRowHeights">
<bool>true</bool>
</property>
<attribute name="headerVisible">
<bool>false</bool>
</attribute>
<column>
<property name="text">
<string notr="true">1</string>
</property>
</column>
</widget>
</item>
<item>
<widget class="QCheckBox" name="wallpaperOverride">
<property name="text">
<string>Override user-defined wallpaper</string>
</property>
</widget>
</item>
</layout>
</widget>
<resources/>
<connections/>
</ui>

@ -1,88 +0,0 @@
/* BEGIN_COMMON_COPYRIGHT_HEADER
* (c)LGPL2+
*
* LXQt - a lightweight, Qt based, desktop toolset
* http://razor-qt.org
*
* Copyright: 2010-2011 Razor team
* Authors:
* Petr Vanek <petr@scribus.info>
*
* This program or library is free software; you can redistribute it
* and/or modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
* 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
*
* END_COMMON_COPYRIGHT_HEADER */
#include <LXQt/SingleApplication>
#include <LXQt/Settings>
#include <LXQt/ConfigDialog>
#include <QCommandLineParser>
#include "iconthemeconfig.h"
#include "lxqtthemeconfig.h"
#include "styleconfig.h"
#include "fontsconfig.h"
#include "../liblxqt-config-cursor/selectwnd.h"
int main (int argc, char **argv)
{
LXQt::SingleApplication app(argc, argv);
app.setAttribute(Qt::AA_UseHighDpiPixmaps, true);
QCommandLineParser parser;
parser.setApplicationDescription(QStringLiteral("LXQt Config Appearance"));
const QString VERINFO = QStringLiteral(LXQT_CONFIG_VERSION
"\nliblxqt " LXQT_VERSION
"\nQt " QT_VERSION_STR);
app.setApplicationVersion(VERINFO);
parser.addVersionOption();
parser.addHelpOption();
parser.process(app);
LXQt::Settings* settings = new LXQt::Settings("lxqt");
LXQt::Settings* sessionSettings = new LXQt::Settings("session");
LXQt::ConfigDialog* dialog = new LXQt::ConfigDialog(QObject::tr("LXQt Appearance Configuration"), settings);
app.setActivationWindow(dialog);
QSettings& qtSettings = *settings; // use lxqt config file for Qt settings in Qt5.
StyleConfig* stylePage = new StyleConfig(settings, &qtSettings, dialog);
dialog->addPage(stylePage, QObject::tr("Widget Style"), QStringList() << "preferences-desktop-theme" << "preferences-desktop");
QObject::connect(dialog, SIGNAL(reset()), stylePage, SLOT(initControls()));
IconThemeConfig* iconPage = new IconThemeConfig(settings, dialog);
dialog->addPage(iconPage, QObject::tr("Icons Theme"), QStringList() << "preferences-desktop-icons" << "preferences-desktop");
QObject::connect(dialog, SIGNAL(reset()), iconPage, SLOT(initControls()));
LXQtThemeConfig* themePage = new LXQtThemeConfig(settings, dialog);
dialog->addPage(themePage, QObject::tr("LXQt Theme"), QStringList() << "preferences-desktop-color" << "preferences-desktop");
QObject::connect(dialog, SIGNAL(reset()), themePage, SLOT(initControls()));
FontsConfig* fontsPage = new FontsConfig(settings, &qtSettings, dialog);
dialog->addPage(fontsPage, QObject::tr("Font"), QStringList() << "preferences-desktop-font" << "preferences-desktop");
QObject::connect(dialog, SIGNAL(reset()), fontsPage, SLOT(initControls()));
SelectWnd* cursorPage = new SelectWnd(sessionSettings, dialog);
cursorPage->setCurrent();
dialog->addPage(cursorPage, QObject::tr("Cursor"), QStringList() << "input-mouse" << "preferences-desktop");
dialog->setAttribute(Qt::WA_DeleteOnClose);
dialog->setWindowIcon(QIcon::fromTheme("preferences-desktop-theme"));
dialog->show();
return app.exec();
}

@ -1,50 +0,0 @@
.TH lxqt-config-appearance "1" "September 2012" "LXQt\ 0.7.0" "LXQt\ GUI settings"
.SH NAME
lxqt-config-appearance \- GUI appearance application of \fBLXQt\fR: the faster and lighter QT Desktop Environment
.SH SYNOPSIS
.B lxqt-config-appearance
.br
.SH DESCRIPTION
With this application you can setting and configuring qt/lxqt gui appearance of programs.
.P
The GUI applications in linux depends of their respective subsystem, in lxqt the overal aspect of
many apps relies on QT4 framework gui. The \fBlxqt-config-appearance\fR application its the configuration center
to provide all aspects of setting \fBLXQt\fR desktop in session settings related programs.
.P
All remaining mayor aspect for lxqt appearance relies over qt4 config application (\fBqtconfig\-qt4\fR), due
the \fBLXQt\fR DE are based on Qt framework.
.P
\fBLXQt\fR is an advanced, easy-to-use, and fast desktop environment based on Qt
technologies, ships several core desktop components, all of which are optional:
.P
* Panel
* Desktop
* Application launcher
* Settings center \fI(related to this)\fR
* Session handler
* Polkit handler
* SSH pasword manager
* Display manager handler
* Power manager
.P
These components perform similar actions to those available in other desktop
environments, and their name is self-descriptive. They are usually not launched
by hand but automatically, when choosing a \fBLXQt\-qt\fR session in the Display
Manager.
.P
.SH "REPORTING BUGS"
Report bugs to https://github.com/lxde/lxqt/issues
.SH "SEE ALSO"
\fBLXQt\fR it has been tailored for users who value simplicity, speed, and
an intuitive interface, also intended for less powerful machines. See also:
.\" any module must refers to session app, for more info on start it
.P
\fBlxqt-session.1\fR LXQt module for manage LXQt complete environment.
.P
\fBlxqt-config.1\fR LXQt application for general config and settings.
.P
\fBqtconfig-qt4.1\fR Qt4 application for gui and appereance settings over all qt4 based software.
.P
.SH AUTHOR
This manual page was created by \fBPICCORO Lenz McKAY\fR \fI<mckaygerhard@gmail.com>\fR
for \fBLXQt\fR project and VENENUX GNU/Linux but can be used by others.

@ -1,142 +0,0 @@
/* BEGIN_COMMON_COPYRIGHT_HEADER
* (c)LGPL2+
*
* LXQt - a lightweight, Qt based, desktop toolset
* http://lxde.org/
*
* Copyright: 2014 LXQt team
* Authors:
* Hong Jen Yee (PCMan) <pcman.tw@gmail.com>
*
* This program or library is free software; you can redistribute it
* and/or modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
* 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
*
* END_COMMON_COPYRIGHT_HEADER */
#include "styleconfig.h"
#include "ui_styleconfig.h"
#include <QTreeWidget>
#include <QDebug>
#include <QStyleFactory>
#include <QToolBar>
#include <QSettings>
#include <QMetaObject>
#include <QMetaProperty>
#include <QMetaEnum>
#include <QToolBar>
#ifdef Q_WS_X11
extern void qt_x11_apply_settings_in_all_apps();
#endif
StyleConfig::StyleConfig(LXQt::Settings* settings, QSettings* qtSettings, QWidget* parent) :
QWidget(parent),
ui(new Ui::StyleConfig),
mQtSettings(qtSettings),
mSettings(settings)
{
ui->setupUi(this);
connect(ui->styleList, SIGNAL(itemClicked(QTreeWidgetItem*,int)),
this, SLOT(styleSelected(QTreeWidgetItem*,int)));
Q_FOREACH(const QString& name, QStyleFactory::keys())
{
QTreeWidgetItem *item = new QTreeWidgetItem(QStringList(name));
ui->styleList->addTopLevelItem(item);
}
initControls();
connect(ui->toolButtonStyle, SIGNAL(currentIndexChanged(int)), SLOT(toolButtonStyleSelected(int)));
connect(ui->singleClickActivate, SIGNAL(toggled(bool)), SLOT(singleClickActivateToggled(bool)));
}
StyleConfig::~StyleConfig()
{
delete ui;
}
void StyleConfig::initControls()
{
// read Qt style settings from Qt Trolltech.conf config
mQtSettings->beginGroup(QLatin1String("Qt"));
QString currentTheme = mQtSettings->value("style").toString();
mQtSettings->endGroup();
QTreeWidgetItemIterator it(ui->styleList);
while (*it) {
if ((*it)->data(0, Qt::DisplayRole).toString() == currentTheme)
{
ui->styleList->setCurrentItem((*it));
break;
}
++it;
}
// read other widget related settings form LXQt settings.
QByteArray tb_style = mSettings->value("tool_button_style").toByteArray();
// convert toolbar style name to value
QMetaEnum me = QToolBar::staticMetaObject.property(QToolBar::staticMetaObject.indexOfProperty("toolButtonStyle")).enumerator();
int val = me.keyToValue(tb_style.constData());
if(val == -1)
val = Qt::ToolButtonTextBesideIcon;
ui->toolButtonStyle->setCurrentIndex(val);
// activate item views with single click
ui->singleClickActivate->setChecked( mSettings->value("single_click_activate", false).toBool());
update();
}
void StyleConfig::styleSelected(QTreeWidgetItem* item, int column)
{
Q_UNUSED(column);
if (!item)
return;
QVariant themeName = item->data(0, Qt::DisplayRole);
mQtSettings->beginGroup(QLatin1String("Qt"));
mQtSettings->setValue("style", themeName);
mQtSettings->endGroup();
mQtSettings->sync();
#ifdef Q_WS_X11
qt_x11_apply_settings_in_all_apps();
#endif
}
void StyleConfig::toolButtonStyleSelected(int index)
{
// convert style value to string
QMetaEnum me = QToolBar::staticMetaObject.property(QToolBar::staticMetaObject.indexOfProperty("toolButtonStyle")).enumerator();
if(index == -1)
index = Qt::ToolButtonTextBesideIcon;
const char* str = me.valueToKey(index);
if(str)
{
mSettings->setValue("tool_button_style", str);
mSettings->sync();
}
}
void StyleConfig::singleClickActivateToggled(bool toggled)
{
mSettings->setValue("single_click_activate", toggled);
mSettings->sync();
}

@ -1,63 +0,0 @@
/* BEGIN_COMMON_COPYRIGHT_HEADER
* (c)LGPL2+
*
* LXQt - a lightweight, Qt based, desktop toolset
* http://razor-qt.org
*
* Copyright: 2012 Razor team
* Authors:
* Alexander Sokoloff <sokoloff.a@gmail.com>
*
* This program or library is free software; you can redistribute it
* and/or modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
* 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
*
* END_COMMON_COPYRIGHT_HEADER */
#ifndef STYLECONFIG_H
#define STYLECONFIG_H
#include <QWidget>
#include <LXQt/Settings>
class QTreeWidgetItem;
class QSettings;
namespace Ui {
class StyleConfig;
}
class StyleConfig : public QWidget
{
Q_OBJECT
public:
explicit StyleConfig(LXQt::Settings *settings, QSettings *qtSettings, QWidget *parent = 0);
~StyleConfig();
public slots:
void initControls();
private slots:
void styleSelected(QTreeWidgetItem* item, int column);
void toolButtonStyleSelected(int index);
void singleClickActivateToggled(bool toggled);
private:
Ui::StyleConfig *ui;
QSettings *mQtSettings;
LXQt::Settings *mSettings;
};
#endif // STYLECONFIG_H

@ -1,98 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>StyleConfig</class>
<widget class="QWidget" name="StyleConfig">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>490</width>
<height>363</height>
</rect>
</property>
<layout class="QFormLayout" name="formLayout">
<item row="0" column="0">
<widget class="QLabel" name="label">
<property name="font">
<font>
<weight>75</weight>
<bold>true</bold>
</font>
</property>
<property name="text">
<string>Widget Style</string>
</property>
</widget>
</item>
<item row="1" column="0" colspan="2">
<widget class="QTreeWidget" name="styleList">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Expanding">
<horstretch>0</horstretch>
<verstretch>1</verstretch>
</sizepolicy>
</property>
<property name="alternatingRowColors">
<bool>true</bool>
</property>
<property name="rootIsDecorated">
<bool>false</bool>
</property>
<attribute name="headerVisible">
<bool>false</bool>
</attribute>
<column>
<property name="text">
<string notr="true">1</string>
</property>
</column>
</widget>
</item>
<item row="2" column="0">
<widget class="QLabel" name="label_2">
<property name="text">
<string>Toolbar button style:</string>
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="QComboBox" name="toolButtonStyle">
<item>
<property name="text">
<string>Only display the icon</string>
</property>
</item>
<item>
<property name="text">
<string>Only display the text</string>
</property>
</item>
<item>
<property name="text">
<string>The text appears beside the icon</string>
</property>
</item>
<item>
<property name="text">
<string>The text appears under the icon</string>
</property>
</item>
<item>
<property name="text">
<string>Default</string>
</property>
</item>
</widget>
</item>
<item row="3" column="0" colspan="2">
<widget class="QCheckBox" name="singleClickActivate">
<property name="text">
<string>Activate item on single click</string>
</property>
</widget>
</item>
</layout>
</widget>
<resources/>
<connections/>
</ui>

@ -1,4 +0,0 @@
# Translations
Comment[ar]=إعدادات مظهر لكسكيوت
GenericName[ar]=إعدادات المظهر
Name[ar]=المظهر

@ -1,4 +0,0 @@
# Translations
Name[ca]=Aparença
GenericName[ca]=Ajusts de l'aparença
Comment[ca]=Ajusts de l'aparença per a LXQt

@ -1,4 +0,0 @@
# Translations
Comment[cs]=Nastavit vzhled pracovní plochy LXQt
GenericName[cs]=Nastavení vzhledu
Name[cs]=Nastavení vzhledu

@ -1,4 +0,0 @@
# Translations
Comment[cs_CZ]=Nastavit vzhled pracovní plochy LXQt
GenericName[cs_CZ]=Nastavení vzhledu
Name[cs_CZ]=Nastavení vzhledu

@ -1,4 +0,0 @@
# Translations
Name[da]=Udseende
GenericName[da]=Udseendeindstillinger
Comment[da]=Udseendeindstillinger for LXQt

@ -1,3 +0,0 @@
Name[de]=Erscheinungsbild
GenericName[de]=Erscheinungsbild Einstellungen
Comment[de]=Einstellungen zum Aussehen der LXQt Arbeitsfläche

@ -1,4 +0,0 @@
# Translations
Comment[el]=Διαμόρφωση εμφάνισης της επιφάνειας εργασίας LXQt
GenericName[el]=Διαμόρφωση εμφάνισης LXQt
Name[el]=Διαμόρφωση εμφάνισης LXQt

@ -1,4 +0,0 @@
# Translations
Comment[eo]=Agordi aperon de LXQt-labortablo
GenericName[eo]=Agordoj de apero de LXQt
Name[eo]=Agordoj de apero de LXQt

@ -1,4 +0,0 @@
# Translations
Comment[es]=Configura el aspecto del escritorio LXQt
GenericName[es]=Configuración de Aspecto LXQt
Name[es]=Configuración de Aspecto LXQt

@ -1,4 +0,0 @@
# Translations
Comment[es_VE]=Configurar apariencia del escritorio LXQt
GenericName[es_VE]=Configuración de apariencia de LXQt
Name[es_VE]=Configuración de apariencia de LXQt

@ -1,4 +0,0 @@
# Translations
Comment[eu]=Konfiguratu LXQt mahaigainaren itxura
GenericName[eu]=LXQt itxuraren konfigurazioa
Name[eu]=LXQt itxuraren konfigurazioa

@ -1,4 +0,0 @@
# Translations
Comment[fi]=Hallitse LXQt-työpöydän ulkoasua
GenericName[fi]=LXQtin ulkoasun hallinta
Name[fi]=LXQtin ulkoasun hallinta

@ -1,4 +0,0 @@
# Translations
Name[fr]=Apparence
GenericName[fr]=Configurer l'apparence
Comment[fr]=Configurer l'apparence de LXQt

@ -1,4 +0,0 @@
# Translations
Comment[hu]=A LXQt asztal megjelenésének beállítása
GenericName[hu]=LXQt megjelenésbeállító
Name[hu]=LXQt megjelenésbeállító

@ -1,4 +0,0 @@
# Translations
GenericName[it]=Aspetto
Name[it]=Aspetto
Comment[it]=Configura l'aspetto di LXQt

@ -1,4 +0,0 @@
# Translations
Comment[ja]=LXQtデスクトップの外観を設定
GenericName[ja]=LXQt外観の設定
Name[ja]=LXQt外観の設定

@ -1,4 +0,0 @@
# Translations
Comment[lt]=LXQt išvaizdos nustatymai
GenericName[lt]=Išvaizdos nustatymai
Name[lt]=Išvaizda

@ -1,4 +0,0 @@
# Translations
Comment[nl]=Configureer het uiterlijk van het LXQt bureaublad
GenericName[nl]=LXQt Uiterlijk Configuratie
Name[nl]=LXQt Uiterlijk Configuratie

@ -1,4 +0,0 @@
# Translations
Comment[pl_PL]=Konfiguruj wygląd pulpitu LXQt
GenericName[pl_PL]=Konfiguracja wyglądu LXQt
Name[pl_PL]=Konfiguracja wyglądu LXQt

@ -1,4 +0,0 @@
# Translations
Comment[pt]=Configurar o aspeto do LXQt
GenericName[pt]=Configuração da aparência do LXQt
Name[pt]=Configuração da aparência do LXQt

@ -1,4 +0,0 @@
# Translations
Comment[pt_BR]=Configure a aparência da área de trabalho LXQt
GenericName[pt_BR]=Configuração da aparência do LXQt
Name[pt_BR]=Configuração da aparência do LXQt

@ -1,4 +0,0 @@
# Translations
Comment[ro_RO]=Configurează aspectul desktopului LXQt
GenericName[ro_RO]=Configurare aspect LXQt
Name[ro_RO]=Configurare aspect LXQt

@ -1,4 +0,0 @@
# Translations
Comment[ru]=Настройки внешнего вида LXQt
GenericName[ru]=Настройка внешнего вида
Name[ru]=Внешний вид

@ -1,4 +0,0 @@
# Translations
Comment[sk]=Nastavenie vzhľadu prostredia LXQt
GenericName[sk]=Nastavenie vzhľadu
Name[sk]=Nastavenie vzhľadu

@ -1,4 +0,0 @@
# Translations
Comment[sl]=Nastavite videz namizja LXQt
GenericName[sl]=Nastavitev videza
Name[sl]=Nastavitev videza namizja LXQt

@ -1,4 +0,0 @@
# Translations
Comment[sr]=Подесите изглед Рејзорове радне површи
GenericName[sr]=Подешавање изгледа
Name[sr]=Подешавање изгледа Рејзора

@ -1,3 +0,0 @@
Name[sr@ijekavian]=Подешавање изгледа Рејзора
Comment[sr@ijekavian]=Подесите изглед Рејзорове радне површи
GenericName[sr@ijekavian]=Подешавање изгледа

@ -1,3 +0,0 @@
Name[sr@ijekavianlatin]=Podešavanje izgleda Rejzora
Comment[sr@ijekavianlatin]=Podesite izgled Rejzorove radne površi
GenericName[sr@ijekavianlatin]=Podešavanje izgleda

@ -1,4 +0,0 @@
# Translations
Comment[sr@latin]=Podesite izgled Rejzorove radne površi
GenericName[sr@latin]=Podešavanje izgleda
Name[sr@latin]=Podešavanje izgleda Rejzora

@ -1,4 +0,0 @@
# Translations
Comment[th_TH]=ตั้งค่ารูปลักษณ์ของเดสก์ท็อป LXQt
GenericName[th_TH]=การตั้งค่ารูปลักษณ์ LXQt
Name[th_TH]=การตั้งค่ารูปลักษณ์ LXQt

@ -1,4 +0,0 @@
# Translations
Comment[tr]=LXQt masaüstünün görünümünü yapılandırın
GenericName[tr]=LXQt Görünüm Yapılandırıcı
Name[tr]=LXQt Görünüm Yapılandırıcı

@ -1,4 +0,0 @@
# Translations
Comment[uk]=Налаштувати вигляд стільниці LXQt
GenericName[uk]=Налаштування вигляду LXQt
Name[uk]=Налаштування вигляду LXQt

@ -1,4 +0,0 @@
# Translations
Comment[zh_CN]=配置 LXQt 桌面的外观
GenericName[zh_CN]=LXQt 外观配置
Name[zh_CN]=LXQt 外观配置

@ -1,4 +0,0 @@
# Translations
Comment[zh_TW]=自定LXQt桌面的外觀
GenericName[zh_TW]=LXQt外觀設定
Name[zh_TW]=LXQt外觀設定

@ -1,84 +0,0 @@
project(lxqt-config-brightness)
find_package(Qt5Widgets REQUIRED QUIET)
find_package(Qt5X11Extras REQUIRED QUIET)
find_package(XCB REQUIRED xcb xcb-randr)
set(QTX_LIBRARIES Qt5::Widgets Qt5::X11Extras)
include_directories (
${XCB_INCLUDE_DIRS}
)
set(H_FILES
brightnesssettings.h
xrandrbrightness.h
monitorinfo.h
outputwidget.h
)
set(CPP_FILES
main.cpp
brightnesssettings.cpp
xrandrbrightness.cpp
monitorinfo.cpp
outputwidget.cpp
)
set(UI_FILES
brightnesssettings.ui
outputwidget.ui
)
qt5_wrap_ui(UI_HEADERS ${UI_FILES})
# Translations **********************************
lxqt_translate_ts(QM_FILES
UPDATE_TRANSLATIONS
${UPDATE_TRANSLATIONS}
SOURCES
${H_FILES}
${CPP_FILES}
${UI_FILES}
INSTALL_DIR
"${LXQT_TRANSLATIONS_DIR}/${PROJECT_NAME}"
PULL_TRANSLATIONS
${PULL_TRANSLATIONS}
CLEAN_TRANSLATIONS
${CLEAN_TRANSLATIONS}
TRANSLATIONS_REPO
${TRANSLATIONS_REPO}
TRANSLATIONS_REFSPEC
${TRANSLATIONS_REFSPEC}
REPO_SUBDIR
"lxqt-config/${PROJECT_NAME}"
)
lxqt_app_translation_loader(QM_LOADER ${PROJECT_NAME})
lxqt_translate_desktop(DESKTOP_FILES SOURCES "resources/${PROJECT_NAME}.desktop.in")
add_executable(${PROJECT_NAME} ${CPP_FILES} ${UI_FILES} ${QM_FILES} ${DESKTOP_FILES} ${QM_LOADER})
target_link_libraries(
${PROJECT_NAME}
${QTX_LIBRARIES}
${XCB_LIBRARIES}
lxqt
)
add_definitions(
-DICON_DIR="${CMAKE_INSTALL_PREFIX}/share/icons/hicolor/48x48/apps"
)
install(TARGETS ${PROJECT_NAME} RUNTIME DESTINATION bin)
install(FILES ${DESKTOP_FILES} DESTINATION ${CMAKE_INSTALL_PREFIX}/share/applications)
install(
FILES icons/brightnesssettings.svg
DESTINATION "${CMAKE_INSTALL_PREFIX}/share/icons/hicolor/48x48/apps"
)

@ -1,4 +0,0 @@
# brightness-settings
This tool changes brightness and gamma of your screen. It is a X11 tool. LibKScreen can not change brightness or gamma yet.

@ -1,101 +0,0 @@
/*
Copyright (C) 2016 P.L. Lucas <selairi@gmail.com>
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include "brightnesssettings.h"
#include "outputwidget.h"
#include <QMessageBox>
#include <QPushButton>
BrightnessSettings::BrightnessSettings(QWidget *parent):QDialog(parent)
{
ui = new Ui::BrightnessSettings();
ui->setupUi(this);
mBrightness = new XRandrBrightness();
mMonitors = mBrightness->getMonitorsInfo();
for(const MonitorInfo &monitor: mMonitors)
{
OutputWidget *output = new OutputWidget(monitor, this);
ui->layout->addWidget(output);
output->show();
connect(output, SIGNAL(changed(MonitorInfo)), this, SLOT(monitorSettingsChanged(MonitorInfo)));
connect(this, &BrightnessSettings::monitorReverted, output, &OutputWidget::setRevertedValues);
}
mConfirmRequestTimer.setSingleShot(true);
mConfirmRequestTimer.setInterval(1000);
connect(&mConfirmRequestTimer, &QTimer::timeout, this, &BrightnessSettings::requestConfirmation);
}
void BrightnessSettings::monitorSettingsChanged(MonitorInfo monitor)
{
mBrightness->setMonitorsSettings(QList<MonitorInfo>{} << monitor);
if (ui->confirmCB->isChecked())
{
mConfirmRequestTimer.start();
} else
{
for (auto & m : mMonitors)
{
if (m.id() == monitor.id() && m.name() == monitor.name())
{
m.setBacklight(monitor.backlight());
m.setBrightness(monitor.brightness());
}
}
}
}
void BrightnessSettings::requestConfirmation()
{
QMessageBox msg{QMessageBox::Question, tr("Brightness settings changed")
, tr("Confirmation required. Are the settings correct?")
, QMessageBox::Yes | QMessageBox::No};
int timeout = 5; // seconds
QString no_text = msg.button(QMessageBox::No)->text();
no_text += QStringLiteral("(%1)");
msg.setButtonText(QMessageBox::No, no_text.arg(timeout));
msg.setDefaultButton(QMessageBox::No);
QTimer timeoutTimer;
timeoutTimer.setSingleShot(false);
timeoutTimer.setInterval(1000);
connect(&timeoutTimer, &QTimer::timeout, [&] {
msg.setButtonText(QMessageBox::No, no_text.arg(--timeout));
if (timeout == 0)
{
timeoutTimer.stop();
msg.reject();
}
});
timeoutTimer.start();
if (QMessageBox::Yes == msg.exec())
{
// re-read current values
mMonitors = mBrightness->getMonitorsInfo();
} else
{
// revert the changes
mBrightness->setMonitorsSettings(mMonitors);
for (const auto & monitor : mMonitors)
emit monitorReverted(monitor);
}
}

@ -1,53 +0,0 @@
/*
Copyright (C) 2016 P.L. Lucas <selairi@gmail.com>
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef __BRIGHTNESS_SETTINGS_H__
#define __BRIGHTNESS_SETTINGS_H__
#include <QDialog>
#include <QTimer>
#include "xrandrbrightness.h"
#include "ui_brightnesssettings.h"
class BrightnessSettings: public QDialog
{
Q_OBJECT
public:
BrightnessSettings(QWidget *parent =0);
signals:
void monitorReverted(const MonitorInfo & monitor);
public slots:
void monitorSettingsChanged(MonitorInfo monitor);
void requestConfirmation();
private:
XRandrBrightness *mBrightness;
QList<MonitorInfo> mMonitors;
QTimer mConfirmRequestTimer;
Ui::BrightnessSettings *ui;
};
#endif

@ -1,89 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>BrightnessSettings</class>
<widget class="QDialog" name="BrightnessSettings">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>406</width>
<height>110</height>
</rect>
</property>
<property name="windowTitle">
<string>Brightness Settings</string>
</property>
<property name="windowIcon">
<iconset theme="system">
<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-weight:600;&quot;&gt;Backlight and brightness settings:&lt;/span&gt;&lt;/p&gt;&lt;p&gt;Use arrow keys to change settings.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
</widget>
</item>
<item>
<layout class="QVBoxLayout" name="layout"/>
</item>
<item>
<widget class="QCheckBox" name="confirmCB">
<property name="text">
<string>Require confirmation after settings change</string>
</property>
<property name="checked">
<bool>true</bool>
</property>
</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>BrightnessSettings</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>BrightnessSettings</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,141 +0,0 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="48"
height="48"
viewBox="0 0 48 48"
id="svg2"
version="1.1"
inkscape:version="0.91 r13725"
sodipodi:docname="brightnesssettings.svg">
<defs
id="defs4">
<linearGradient
inkscape:collect="always"
id="linearGradient4150">
<stop
style="stop-color:#000000;stop-opacity:1;"
offset="0"
id="stop4152" />
<stop
style="stop-color:#000000;stop-opacity:0;"
offset="1"
id="stop4154" />
</linearGradient>
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient4150"
id="linearGradient4156"
x1="10.571428"
y1="1028.9692"
x2="36.571429"
y2="1028.9692"
gradientUnits="userSpaceOnUse" />
</defs>
<sodipodi:namedview
id="base"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageopacity="0.0"
inkscape:pageshadow="2"
inkscape:zoom="5.6"
inkscape:cx="-22.125592"
inkscape:cy="27.983921"
inkscape:document-units="px"
inkscape:current-layer="layer1"
showgrid="false"
units="px"
inkscape:window-width="1366"
inkscape:window-height="747"
inkscape:window-x="0"
inkscape:window-y="21"
inkscape:window-maximized="1" />
<metadata
id="metadata7">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title />
</cc:Work>
</rdf:RDF>
</metadata>
<g
inkscape:label="Capa 1"
inkscape:groupmode="layer"
id="layer1"
transform="translate(0,-1004.3622)">
<circle
style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1.21739125px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
id="path3344-0"
cx="23.642857"
cy="1029.0765"
r="12.391305" />
<circle
style="fill:url(#linearGradient4156);fill-rule:evenodd;stroke:#000000;stroke-width:1.21739125px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;fill-opacity:1"
id="path3344"
cx="23.571428"
cy="1028.9692"
r="12.391305" />
<circle
style="fill:#000000;fill-rule:evenodd;stroke:#ffffff;stroke-width:0.24749167px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
id="path3344-6"
cx="23.392857"
cy="1009.6837"
r="2.5191119" />
<circle
style="fill:#999999;fill-rule:evenodd;stroke:#ffffff;stroke-width:0.24749167px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
id="path3344-6-4"
cx="24.464287"
cy="1048.3622"
r="2.5191119" />
<circle
style="fill:#333333;fill-rule:evenodd;stroke:#ffffff;stroke-width:0.24749167px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
id="path3344-6-5"
cx="41.42857"
cy="1029.005"
r="2.5191119" />
<circle
style="fill:#f2f2f2;fill-rule:evenodd;stroke:#000000;stroke-width:0.24749167px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
id="path3344-6-40"
cx="4.3214302"
cy="1029.7194"
r="2.5191119" />
<circle
style="fill:#4d4d4d;fill-rule:evenodd;stroke:#ffffff;stroke-width:0.24749167px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
id="path3344-6-1"
cx="37.42857"
cy="1041.2908"
r="2.5191119" />
<circle
style="fill:#cccccc;fill-rule:evenodd;stroke:#000000;stroke-width:0.24749167px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
id="path3344-6-8"
cx="9.4642859"
cy="1042.7194"
r="2.5191119" />
<circle
style="fill:#1a1a1a;fill-rule:evenodd;stroke:#ffffff;stroke-width:0.24749167px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
id="path3344-6-2"
cx="38.535713"
cy="1014.3622"
r="2.5191119" />
<circle
style="fill:#ffffff;fill-rule:evenodd;stroke:#000000;stroke-width:0.24749167px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
id="path3344-6-14"
cx="8.8214302"
cy="1015.9694"
r="2.5191119" />
</g>
</svg>

Before

Width:  |  Height:  |  Size: 4.7 KiB

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

Loading…
Cancel
Save