Compare commits
155 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
55c4da8f14 | ||
|
|
1ea311c99a | ||
|
|
a67273baee | ||
|
|
3e1af78e68 | ||
|
|
690eb414cb | ||
|
|
689df1196d | ||
|
|
009841d96f | ||
|
|
b1de78f49c | ||
|
|
50db1aa131 | ||
|
|
ef888ffb03 | ||
|
|
bf3f73935a | ||
|
|
ec59d41d95 | ||
|
|
321b62439a | ||
|
|
076554379f | ||
|
|
5fb204781c | ||
|
|
df390a2d58 | ||
|
|
e7f5d53457 | ||
|
|
2d8f17006f | ||
|
|
dfe78834b4 | ||
|
|
34a96eee19 | ||
|
|
136f731c32 | ||
|
|
41648dad9f | ||
|
|
e03e1e08bb | ||
|
|
933ef2f682 | ||
|
|
061ce1aeb3 | ||
|
|
0936bc098a | ||
|
|
116442edb3 | ||
|
|
dc924f640b | ||
|
|
b3cba63f06 | ||
|
|
7ab65011ab | ||
|
|
adc440f793 | ||
|
|
2208b9c301 | ||
|
|
2085196638 | ||
|
|
6e5bafd3fd | ||
|
|
4daf99ad3a | ||
|
|
ac9055aac3 | ||
|
|
467089b8cd | ||
|
|
1335f85c7b | ||
|
|
7066feab5e | ||
|
|
3fbd0ba7da | ||
|
|
3ed6b8cc4e | ||
|
|
c1f37877c4 | ||
|
|
b81449836d | ||
|
|
156f9f503c | ||
|
|
553ebc3c6e | ||
|
|
ee8a64a184 | ||
|
|
8f76e1fb93 | ||
|
|
e03fe497a8 | ||
|
|
8bcd8fdb88 | ||
|
|
438dee2585 | ||
|
|
9901e697ee | ||
|
|
8e8b89c000 | ||
|
|
57def32b32 | ||
|
|
c929b64cd2 | ||
|
|
18aed24592 | ||
|
|
ab63e495e4 | ||
|
|
14aa827aaa | ||
|
|
91b2885ce1 | ||
|
|
d59b6e79ab | ||
|
|
6c6513913e | ||
|
|
157ac67ace | ||
|
|
c7b618f873 | ||
|
|
5a8f72176a | ||
|
|
2434b6006f | ||
|
|
d32d75c638 | ||
|
|
a91f0e620a | ||
|
|
da3723e7d0 | ||
|
|
c44953c776 | ||
|
|
5087cf97e1 | ||
|
|
8e0a0f7672 | ||
|
|
4ae8f1a369 | ||
|
|
0000570007 | ||
|
|
1e69fe0e40 | ||
|
|
e4c67b67e9 | ||
|
|
b771c3b972 | ||
|
|
2eeee2e097 | ||
|
|
706b7bdc41 | ||
|
|
a5b66b405f | ||
|
|
86c996e006 | ||
|
|
4012ca17fd | ||
|
|
63025db137 | ||
|
|
36f53768ca | ||
|
|
f69926a95a | ||
|
|
a91663d714 | ||
|
|
ddfd4343e2 | ||
|
|
608aac8fff | ||
|
|
6f6fcb463c | ||
|
|
2145e0d8de | ||
|
|
19d95a72fa | ||
|
|
9d7d3d1781 | ||
|
|
0fbe64d6d9 | ||
|
|
ae9f9df102 | ||
|
|
8052e1bc89 | ||
|
|
55b09def37 | ||
|
|
7ac1301b26 | ||
|
|
2ca936f0e8 | ||
|
|
8a3cc50ed6 | ||
|
|
086aaacab2 | ||
|
|
210d11b974 | ||
|
|
9cafaf0606 | ||
|
|
3eba181d7b | ||
|
|
7e726c0c46 | ||
|
|
1f28814b88 | ||
|
|
00c3fad3b1 | ||
|
|
9c864bf34a | ||
|
|
28af0f16d3 | ||
|
|
4a20dcb2ed | ||
|
|
a8c1b82ed8 | ||
|
|
8ae2d124c7 | ||
|
|
f794b14bc9 | ||
|
|
51fc40a60e | ||
|
|
aad990ed17 | ||
|
|
41e2f537e6 | ||
|
|
bf0e6ccff2 | ||
|
|
7d884a6e9b | ||
|
|
fe26b96b14 | ||
|
|
afadaf363c | ||
|
|
ed5693624b | ||
|
|
cbcb717f68 | ||
|
|
3005d4abc1 | ||
|
|
ff5ab8f715 | ||
|
|
0151a0ac25 | ||
|
|
e6cc73fd1d | ||
|
|
b068891cf3 | ||
|
|
063d89abe8 | ||
|
|
8e6b89dbbd | ||
|
|
a8b62b25e0 | ||
|
|
b593dc4e64 | ||
|
|
0d0504aea1 | ||
|
|
c928bd14b8 | ||
|
|
107685efdc | ||
|
|
0bbcc3b8b3 | ||
|
|
099948e3ff | ||
|
|
c6a111c15e | ||
|
|
3b8fb9c0f3 | ||
|
|
f185cda349 | ||
|
|
af469c99b6 | ||
|
|
60e3f003bb | ||
|
|
3b9e94a03f | ||
|
|
79c2c4578b | ||
|
|
44bd8b4d9b | ||
|
|
0a64988649 | ||
|
|
c1520aac66 | ||
|
|
a23cd79762 | ||
|
|
8df3f8c9e5 | ||
|
|
d39ec251af | ||
|
|
4ed667e4e5 | ||
|
|
01a42dfea1 | ||
|
|
49f5fd9b78 | ||
|
|
d8aaec6a98 | ||
|
|
3481206fa9 | ||
|
|
da2f0e52c7 | ||
|
|
f8a05fe2dc | ||
|
|
946919c850 | ||
|
|
2d263f5ea9 |
4
.gitignore
vendored
@@ -1,5 +1,3 @@
|
||||
__pycache__
|
||||
_build/
|
||||
**/*~
|
||||
/subprojects/*
|
||||
!/subprojects/*.wrap
|
||||
**/*~
|
||||
@@ -31,12 +31,6 @@ stages:
|
||||
|
||||
.Build procedure: &build_procedure
|
||||
echo "== Building ==" &&
|
||||
git clone https://gitlab.gnome.org/GNOME/gtk.git &&
|
||||
cd gtk &&
|
||||
dnf install -y dnf-plugins-core && dnf builddep -y gtk4 &&
|
||||
meson setup . _build -Dprefix=/usr -Dlibdir=lib64 &&
|
||||
ninja -C _build install &&
|
||||
cd .. &&
|
||||
rm -rf _build/ &&
|
||||
meson . _build ${BUILD_OPTS} -Dprofile=development &&
|
||||
ninja -C _build 2>&1 | tee compilation.log
|
||||
@@ -58,7 +52,7 @@ stages:
|
||||
# stable branch.
|
||||
# Could probably also switch away from rawhide,
|
||||
# to stable fedora branch as well.
|
||||
FDO_DISTRIBUTION_TAG: '2023-03-14.0-main'
|
||||
FDO_DISTRIBUTION_TAG: '2022-10-25.0-main'
|
||||
FDO_DISTRIBUTION_VERSION: rawhide
|
||||
|
||||
#############################################
|
||||
@@ -112,7 +106,7 @@ build.container.fedora@x86_64:
|
||||
libnotify-devel
|
||||
libpwquality-devel
|
||||
libsmbclient-devel
|
||||
libsoup3-devel
|
||||
libsoup-devel
|
||||
libudisks2-devel
|
||||
libwacom-devel
|
||||
libX11-devel
|
||||
@@ -128,14 +122,13 @@ build.container.fedora@x86_64:
|
||||
xorg-x11-server-Xvfb
|
||||
mesa-dri-drivers
|
||||
libsecret-devel
|
||||
geocode-glib2-devel
|
||||
geocode-glib-devel
|
||||
libgweather-devel
|
||||
lcms2-devel
|
||||
geoclue2-devel
|
||||
libnotify-devel
|
||||
alsa-lib-devel
|
||||
nss-devel
|
||||
gcr3-devel
|
||||
gcr-devel
|
||||
setxkbmap
|
||||
FDO_DISTRIBUTION_EXEC: |-
|
||||
@@ -256,7 +249,7 @@ coverage:
|
||||
BUILD_OPTS: "-Db_coverage=true"
|
||||
coverage: '/^Lines:.\d+.\d+.(\d+\.\d+\%)/'
|
||||
only:
|
||||
- main@GNOME/gnome-control-center
|
||||
- master@GNOME/gnome-control-center
|
||||
|
||||
script:
|
||||
- *environment_information
|
||||
@@ -296,7 +289,7 @@ pages:
|
||||
paths:
|
||||
- public
|
||||
only:
|
||||
- main@GNOME/gnome-control-center
|
||||
- master@GNOME/gnome-control-center
|
||||
|
||||
except:
|
||||
variables:
|
||||
@@ -310,7 +303,7 @@ pages:
|
||||
##
|
||||
flatpak:
|
||||
stage: manual
|
||||
image: quay.io/gnome_infrastructure/gnome-runtime-images:gnome-master
|
||||
image: registry.gitlab.gnome.org/gnome/gnome-runtime-images/gnome:master
|
||||
artifacts:
|
||||
name: package
|
||||
paths:
|
||||
@@ -356,7 +349,7 @@ flatpak:
|
||||
except:
|
||||
- tags
|
||||
- gnome-3-.*
|
||||
- main@GNOME/gnome-control-center
|
||||
- master@GNOME/gnome-control-center
|
||||
|
||||
|
||||
# Runs the sanitizers [address, thread, undefined, and memory].
|
||||
|
||||
@@ -4,7 +4,7 @@ Not following the communication guidelines [1] will mean your issue or comment
|
||||
will be removed. Read it carefully before submitting this issue.
|
||||
|
||||
|
||||
[1] https://gitlab.gnome.org/GNOME/gnome-control-center/blob/main/docs/CODE_OF_CONDUCT.md#communication-guidelines
|
||||
[1] https://gitlab.gnome.org/GNOME/gnome-control-center/blob/master/docs/CONTRIBUTING.md#communication-guideline
|
||||
|
||||
-->
|
||||
|
||||
|
||||
@@ -4,7 +4,7 @@ Not following the communication guidelines [1] will mean your issue or comment
|
||||
will be removed. Read it carefully before submitting this issue.
|
||||
|
||||
|
||||
[1] https://gitlab.gnome.org/GNOME/gnome-control-center/blob/main/docs/CODE_OF_CONDUCT.md#communication-guidelines
|
||||
[1] https://gitlab.gnome.org/GNOME/gnome-control-center/blob/master/docs/CONTRIBUTING.md#communication-guideline
|
||||
|
||||
-->
|
||||
|
||||
|
||||
321
NEWS
@@ -1,276 +1,151 @@
|
||||
================
|
||||
Version 44.4
|
||||
Version 42.10
|
||||
================
|
||||
|
||||
- Hide QR Code button for unsupported security.
|
||||
- Fix issue when icon theme changes to HighContrast can't be reverted.
|
||||
- Write to mru-sources setting if it has never been set before.
|
||||
- Fix critical debug messages when keyboard input chooser is destroyed.
|
||||
- Fix issue on network connection editor not closing when changes are applied.
|
||||
- Fix out-of-bounds write in printer names.
|
||||
- Fix input row movement in Search and Keyboard settings.
|
||||
- Hide "Automatic Suspend" row in virtual machines.
|
||||
- Various memory leak fixes.
|
||||
- Update translations.
|
||||
- Fix monitor order in display settings
|
||||
- Add 32:9 aspect ration in display settings
|
||||
- Fix warning in user panel in initialization of avatar widget
|
||||
- Updated translations
|
||||
|
||||
================
|
||||
Version 44.3
|
||||
================
|
||||
|
||||
- Updated translations.
|
||||
|
||||
================
|
||||
Version 44.2
|
||||
================
|
||||
|
||||
- Updated translations.
|
||||
- Various small accessibility fixes.
|
||||
- Fixes in Gtk template usage that causes crashes on some systems.
|
||||
|
||||
Appearance
|
||||
- Clear dconf when resetting to defaults.
|
||||
|
||||
Mouse
|
||||
- Hide entire "Touchpad" row when touchpad cannot be disabled
|
||||
|
||||
Network
|
||||
- Fix racy radio buttons in connection editor.
|
||||
|
||||
Users:
|
||||
- Remove autologin row tooltip when unlocked.
|
||||
|
||||
================
|
||||
Version 44.1
|
||||
Version 42.9
|
||||
================
|
||||
|
||||
- Updated translations
|
||||
|
||||
Common
|
||||
- Update hostname only after apply is clicked
|
||||
- Add widget name and css class to CcIllustratedRow and CcSplitRow
|
||||
|
||||
Color
|
||||
- Do not try to access to null pointer in destruction
|
||||
|
||||
Date & Time
|
||||
- Fix NTP switch getting out of sync
|
||||
|
||||
Display
|
||||
- Allow configuring all monitors and apply settings at once
|
||||
- Disconnect config manager changed handler
|
||||
- Don't leak config manager proxy
|
||||
|
||||
Network
|
||||
- Fix crash when removing a connection
|
||||
|
||||
Region
|
||||
- Fix label of formats for the login screen
|
||||
|
||||
Sharing
|
||||
- Fix network row visible name bug
|
||||
|
||||
Shell
|
||||
- Add workaround to make disabled pictures are painted as such
|
||||
|
||||
Sound
|
||||
- Prevent duplicate sound device entries
|
||||
- Revert accidental libgvc downgrade
|
||||
Network:
|
||||
- Fix possible race in tests
|
||||
|
||||
================
|
||||
Version 44.0
|
||||
Version 42.4
|
||||
================
|
||||
|
||||
- Updated translations
|
||||
|
||||
Mouse
|
||||
- Prevent infinit loop on Mouse setting changes
|
||||
|
||||
Usage
|
||||
- Fix confirmation dialog when clearing file history
|
||||
|
||||
Notifications
|
||||
- Replace occurrence of "Applications" with "Apps" string
|
||||
|
||||
Power
|
||||
- Label the main "batery" as UPS when that's what it is
|
||||
|
||||
================
|
||||
Version 44.rc
|
||||
================
|
||||
|
||||
- Improve state of switchers throughout the app
|
||||
- Updated translations
|
||||
|
||||
Keyboard
|
||||
- Various fixes to the shortcut editor
|
||||
|
||||
Mouse & Touchpad
|
||||
- Polish the panel redesign
|
||||
|
||||
Printers
|
||||
- Update to more modern CUPS APIs
|
||||
|
||||
================
|
||||
Version 44.beta
|
||||
================
|
||||
|
||||
- Redesigned Sound panel
|
||||
- Redesigned Mouse & Touchpad panel
|
||||
- Share Wi-Fi networks using QR code
|
||||
- Many consistency improvements
|
||||
- WireGuard support
|
||||
- Updated translations
|
||||
|
||||
Mouse & Touchpad
|
||||
- Redesign the panel with videos of the preferences
|
||||
- Move mouse test into a separate dialog
|
||||
|
||||
Network
|
||||
- Add support for sharing Wi-Fi networks through QR code
|
||||
- Add WireGuard support
|
||||
|
||||
Sound
|
||||
- Move application volumes to a dialog
|
||||
- Move sound themes to a dialog
|
||||
|
||||
================
|
||||
Version 44.alpha
|
||||
================
|
||||
|
||||
- Redesigned Accessibility panel
|
||||
- Many consistency improvements
|
||||
- Updated translations
|
||||
- Added various accessibility labels
|
||||
- Initialize locale early
|
||||
|
||||
About
|
||||
- Add "Firmware Version" row
|
||||
- Don't load version.xml info we don't use
|
||||
|
||||
Accessibility
|
||||
- Redesign the panel with new a navigation pattern
|
||||
Applications
|
||||
- Don't recurse into symlinks when clearing app cache
|
||||
|
||||
Color
|
||||
- Fix crash when there's no device rows to show
|
||||
|
||||
Cellular
|
||||
- Various fixes
|
||||
- Improve dbus error messaging
|
||||
- Handle cases when SIM ID is not present
|
||||
- Prevent duplicate entries in the SIM providers list
|
||||
|
||||
Date & Time
|
||||
- Improve month selector
|
||||
Keyboard
|
||||
- Fix activation of input source toggle button
|
||||
- Fix permission_acquired always returning FALSE
|
||||
|
||||
Device Security
|
||||
- Improve date and time formatting
|
||||
- Simplify technical descriptions
|
||||
|
||||
Display
|
||||
- Improve error state of Night Light
|
||||
|
||||
Sound
|
||||
- Start implementing the new designs
|
||||
|
||||
Thunderbolt
|
||||
- Hide panel if no Thunderbolt device is found
|
||||
|
||||
================
|
||||
Version 43.1
|
||||
================
|
||||
|
||||
- Updated translations
|
||||
Mouse
|
||||
- Set rows as actiavatable widgets
|
||||
|
||||
Network
|
||||
- Fix crashes editing networks
|
||||
- Fix crashes when EAP password is missing
|
||||
- Fix wrong signal of SEA password visibility toggle
|
||||
- Prevent crash when disconnecting wifi device
|
||||
- Use mime-types for file chooser filtering TLS files
|
||||
|
||||
Online Accounts
|
||||
- Fix crash when failing to find GOA helper executable
|
||||
|
||||
Power
|
||||
- Don't assert if we can't find the widget for a profile
|
||||
- Prevent terminal from getting spammed with ALS logs
|
||||
|
||||
Printers
|
||||
- Small visual improvements
|
||||
- Fix loading of UI resources
|
||||
- Show empty-state when removing the last printer
|
||||
|
||||
Region
|
||||
- Fix creating rows for locales without a country
|
||||
- Fix critical when changing language
|
||||
- Fix permission_acquired always returning FALSE
|
||||
|
||||
Search
|
||||
- Fix reordering of list rows
|
||||
|
||||
Users
|
||||
- Show a fallback avatar when failing to load one
|
||||
|
||||
Wifi
|
||||
- Allow accessing settings of known wifi networks
|
||||
|
||||
================
|
||||
Version 43.0
|
||||
Version 42.4
|
||||
================
|
||||
|
||||
- Updated translations
|
||||
|
||||
================
|
||||
Version 43.rc
|
||||
================
|
||||
|
||||
- Fix initial AM/PM label value
|
||||
- Remove no longer used icon
|
||||
- Select panel only if non-folded when search is canceled
|
||||
- Updated translations
|
||||
|
||||
Appearance
|
||||
- Allow backgrounds to use any image format
|
||||
|
||||
Device Security
|
||||
- Several UI improvements
|
||||
Background
|
||||
- Restore support for multiple file selection
|
||||
- Allow more image formats
|
||||
|
||||
Display
|
||||
- Fix primary monitor selection
|
||||
|
||||
Info
|
||||
- Improve dark theme support
|
||||
|
||||
Keyboard
|
||||
- Fix activation of input source toggle button
|
||||
- Improve handling of Shift shortcuts
|
||||
Network
|
||||
- Fix network profiles shown on wrong device
|
||||
- Various crash fixes
|
||||
|
||||
Power
|
||||
- Fix blank screen and power button behavior settings
|
||||
|
||||
Printers
|
||||
- Show empty state after removing last printer
|
||||
|
||||
Search
|
||||
- Fix Move Up and Move Down actions
|
||||
|
||||
Sound
|
||||
- Fix sound alert selection
|
||||
|
||||
Wacom
|
||||
- Better support Wacom Express Key Remote
|
||||
|
||||
================
|
||||
Version 43.beta
|
||||
================
|
||||
|
||||
- Updated translations
|
||||
|
||||
Cellular
|
||||
- Add WWAN 5G connection support
|
||||
|
||||
Device Security
|
||||
- Polish failure messages
|
||||
- Various style updates
|
||||
|
||||
Display
|
||||
- Support privacy screens
|
||||
|
||||
Info
|
||||
- Show build id in a separate row
|
||||
|
||||
Network
|
||||
- Fix VPN empty state
|
||||
|
||||
Sound
|
||||
- Update default sounds
|
||||
- Fix blank-screen settings not applying
|
||||
- Fix "Power Button Behavior" setting not applying
|
||||
|
||||
User Accounts
|
||||
- Fix back button not appearing sometimes
|
||||
- Disconnect fingerprint reading devices when closing dialog
|
||||
|
||||
Sharing
|
||||
- Don't set remote-desktop password entry if pw_generate fails
|
||||
- Don't assert if we can't find the widget for a profile
|
||||
|
||||
================
|
||||
Version 43.alpha
|
||||
Version 42.3
|
||||
================
|
||||
|
||||
- Improved accessibility in various panels
|
||||
- New Device Security panel
|
||||
- Updated translations
|
||||
|
||||
Date & Time
|
||||
- Update visual style of the timezone map
|
||||
|
||||
Display
|
||||
- Various visual improvements
|
||||
- Use virtual clone modes when mirroring
|
||||
|
||||
Network
|
||||
- Prevent crash by disconnecting device.
|
||||
- Fix Wi-Fi network with "&" in name not appearing.
|
||||
- Fix warning when panel closed.
|
||||
|
||||
================
|
||||
Version 42.2
|
||||
================
|
||||
|
||||
- Updated translations
|
||||
|
||||
Applications
|
||||
- Fix Snap permissions support failing to compile
|
||||
- Fix CcInfoRow having the wrong parent
|
||||
- Fix crash crash when switching between two apps
|
||||
|
||||
Background
|
||||
- Make sure the size of the light/dark previews are the same
|
||||
|
||||
Keyboard
|
||||
- Fix crash resetting all keyboard shortcuts
|
||||
|
||||
Network:
|
||||
- Stop freeze when closing wired connection properties with Escape
|
||||
|
||||
Sharing
|
||||
- Fix close button on Verify Encryption dialog
|
||||
- Turn off RDP gsettings key when turning off RDP
|
||||
|
||||
Shell
|
||||
- Initialise locale early
|
||||
|
||||
Sound
|
||||
- Remove dog barking sounds
|
||||
- Update theme correctly so other apps respond to change
|
||||
|
||||
================
|
||||
Version 42.1
|
||||
|
||||
10
README.md
@@ -1,6 +1,6 @@
|
||||
[](https://gitlab.gnome.org/GNOME/gnome-control-center/pipelines)
|
||||
[](https://gnome.pages.gitlab.gnome.org/gnome-control-center/)
|
||||
[](https://gitlab.gnome.org/GNOME/gnome-control-center/blob/main/COPYING)
|
||||
[](https://gitlab.gnome.org/GNOME/gnome-control-center/pipelines)
|
||||
[](https://gnome.pages.gitlab.gnome.org/gnome-control-center/)
|
||||
[](https://gitlab.gnome.org/GNOME/gnome-control-center/blob/master/COPYING)
|
||||
|
||||
GNOME Settings
|
||||
====================
|
||||
@@ -9,7 +9,7 @@ GNOME Settings is GNOME's main interface for configuration of various aspects of
|
||||
|
||||
## Contributing
|
||||
|
||||
See `docs/CONTRIBUTING.md` for details on the contribution process, and `docs/CODING_STYLE.md`
|
||||
See `docs/CONTRIBUTING.md` for details on the contribution process, and `docs/HACKING.md`
|
||||
for the coding style guidelines.
|
||||
|
||||
## Reporting Bugs
|
||||
@@ -60,4 +60,4 @@ Note that GNOME Settings Flatpak will only work if you are running
|
||||
the latest GNOME version in your host system.
|
||||
|
||||
|
||||
[communication-guidelines]: https://gitlab.gnome.org/GNOME/gnome-control-center/blob/main/docs/CODE_OF_CONDUCT.md#communication-guidelines
|
||||
[communication-guidelines]: https://gitlab.gnome.org/GNOME/gnome-control-center/blob/master/docs/CONTRIBUTING.md#communication-guidelines
|
||||
|
||||
@@ -26,10 +26,7 @@
|
||||
"cxxflags" : "-O2 -g",
|
||||
"env" : {
|
||||
"V" : "1"
|
||||
},
|
||||
"build-args": [
|
||||
"--share=network"
|
||||
]
|
||||
}
|
||||
},
|
||||
"x-run-args" : [
|
||||
"--verbose"
|
||||
@@ -59,13 +56,13 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"name" : "intltool",
|
||||
"cleanup" : [ "*" ],
|
||||
"sources" : [
|
||||
"name": "intltool",
|
||||
"cleanup": [ "*" ],
|
||||
"sources": [
|
||||
{
|
||||
"type" : "archive",
|
||||
"url" : "https://launchpad.net/intltool/trunk/0.51.0/+download/intltool-0.51.0.tar.gz",
|
||||
"sha256" : "67c74d94196b153b774ab9f89b2fa6c6ba79352407037c8c14d5aeb334e959cd"
|
||||
"type": "archive",
|
||||
"url": "https://launchpad.net/intltool/trunk/0.51.0/+download/intltool-0.51.0.tar.gz",
|
||||
"sha256": "67c74d94196b153b774ab9f89b2fa6c6ba79352407037c8c14d5aeb334e959cd"
|
||||
}
|
||||
]
|
||||
},
|
||||
@@ -75,6 +72,7 @@
|
||||
"config-opts" : [
|
||||
"--disable-polkitd",
|
||||
"--disable-man-pages",
|
||||
"--disable-introspection",
|
||||
"--disable-examples",
|
||||
"--disable-gtk-doc",
|
||||
"--disable-libelogind",
|
||||
@@ -110,18 +108,20 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"name" : "accountsservice",
|
||||
"name" : "accountservice",
|
||||
"buildsystem" : "meson",
|
||||
"config-opts" : [
|
||||
"-Dsystemdsystemunitdir=no",
|
||||
"-Ddocbook=false",
|
||||
"-Delogind=false",
|
||||
"-Dgtk_doc=false",
|
||||
"-Dintrospection=false",
|
||||
"-Dvapi=false"
|
||||
"-Dsystemd=false",
|
||||
"-Dsystemdsystemunitdir=no"
|
||||
],
|
||||
"sources" : [
|
||||
{
|
||||
"type" : "git",
|
||||
"url" : "https://gitlab.freedesktop.org/accountsservice/accountsservice",
|
||||
"branch" : "main"
|
||||
"url" : "git://anongit.freedesktop.org/accountsservice"
|
||||
}
|
||||
]
|
||||
},
|
||||
@@ -186,6 +186,20 @@
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name" : "gudev",
|
||||
"buildsystem" : "meson",
|
||||
"config-opts" : [
|
||||
"-Dtests=disabled",
|
||||
"-Dintrospection=disabled"
|
||||
],
|
||||
"sources" : [
|
||||
{
|
||||
"type" : "git",
|
||||
"url" : "https://gitlab.gnome.org/GNOME/libgudev.git"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name" : "colord",
|
||||
"buildsystem" : "meson",
|
||||
@@ -224,14 +238,11 @@
|
||||
},
|
||||
{
|
||||
"name" : "rest",
|
||||
"buildsystem" : "meson",
|
||||
"config-opts" : [
|
||||
"-Dgtk_doc=false"
|
||||
],
|
||||
"buildsystem" : "autotools",
|
||||
"sources" : [
|
||||
{
|
||||
"type" : "git",
|
||||
"branch" : "master",
|
||||
"branch" : "librest-0-7",
|
||||
"url" : "https://gitlab.gnome.org/GNOME/librest.git"
|
||||
}
|
||||
]
|
||||
@@ -268,10 +279,9 @@
|
||||
"name" : "geocode-glib",
|
||||
"buildsystem" : "meson",
|
||||
"config-opts" : [
|
||||
"-Denable-installed-tests=false",
|
||||
"-Denable-introspection=false",
|
||||
"-Denable-gtk-doc=false",
|
||||
"-Dsoup2=false"
|
||||
"-Denable-introspection=false",
|
||||
"-Denable-installed-tests=false"
|
||||
],
|
||||
"sources" : [
|
||||
{
|
||||
@@ -284,10 +294,9 @@
|
||||
"name" : "libgweather",
|
||||
"buildsystem" : "meson",
|
||||
"config-opts" : [
|
||||
"-Dglade_catalog=false",
|
||||
"-Denable_vala=false",
|
||||
"-Dgtk_doc=false",
|
||||
"-Dintrospection=false",
|
||||
"-Dtests=false"
|
||||
"-Dgtk_doc=false"
|
||||
],
|
||||
"sources" : [
|
||||
{
|
||||
@@ -348,10 +357,14 @@
|
||||
"config-opts" : [
|
||||
"-Dlibaudit=no",
|
||||
"-Ddbus_conf_dir=/app/etc/dbus-1/system.d",
|
||||
"-Ddbus_ifaces_dir=/app/share/dbus-1/interfaces",
|
||||
"-Ddbus_sys_dir=/app/share/dbus-1/system.d",
|
||||
"-Ddnsmasq=/usr/bin/true",
|
||||
"-Ddocs=false",
|
||||
"-Dintrospection=false",
|
||||
"-Diptables=/usr/bin/true",
|
||||
"-Djson_validation=false",
|
||||
"-Dlibnm_glib=false",
|
||||
"-Dlibpsl=false",
|
||||
"-Dmodem_manager=false",
|
||||
"-Dnmtui=false",
|
||||
@@ -406,9 +419,12 @@
|
||||
"buildsystem" : "meson",
|
||||
"config-opts" : [
|
||||
"-Dappindicator=no",
|
||||
"-Dwwan=false",
|
||||
"-Dgtk_doc=false",
|
||||
"-Dintrospection=false",
|
||||
"-Dlibnm_gtk=false",
|
||||
"-Dselinux=false",
|
||||
"-Dteam=false"
|
||||
"-Dteam=false",
|
||||
"-Dwwan=false"
|
||||
],
|
||||
"sources" : [
|
||||
{
|
||||
@@ -618,142 +634,6 @@
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name" : "mutter",
|
||||
"buildsystem" : "meson",
|
||||
"config-opts" : [
|
||||
"-Dgles2=false",
|
||||
"-Dglx=false",
|
||||
"-Dxwayland=false",
|
||||
"-Dwayland=false",
|
||||
"-Dsystemd=false",
|
||||
"-Dnative_backend=false",
|
||||
"-Dremote_desktop=false",
|
||||
"-Degl_device=false",
|
||||
"-Dudev=false",
|
||||
"-Dstartup_notification=false",
|
||||
"-Dsm=false",
|
||||
"-Dintrospection=true",
|
||||
"-Ddocs=false",
|
||||
"-Dtests=false",
|
||||
"-Dprofiler=false"
|
||||
],
|
||||
"sources" : [
|
||||
{
|
||||
"type" : "git",
|
||||
"branch" : "main",
|
||||
"url" : "https://gitlab.gnome.org/gnome/mutter.git"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name" : "libical",
|
||||
"buildsystem" : "cmake",
|
||||
"config-opts" : [
|
||||
"-DICAL_BUILD_DOCS=false",
|
||||
"-DICAL_GLIB=true",
|
||||
"-DLIBICAL_BUILD_TESTING=false"
|
||||
],
|
||||
"sources" : [
|
||||
{
|
||||
"type" : "git",
|
||||
"url" : "https://github.com/libical/libical.git"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name" : "evolution-data-server",
|
||||
"buildsystem" : "cmake",
|
||||
"config-opts" : [
|
||||
"-DWITH_LIBDB=OFF"
|
||||
],
|
||||
"sources" : [
|
||||
{
|
||||
"type" : "git",
|
||||
"url" : "https://gitlab.gnome.org/GNOME/evolution-data-server.git"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name" : "libstartup-notification",
|
||||
"buildsystem" : "autotools",
|
||||
"sources" : [
|
||||
{
|
||||
"type" : "git",
|
||||
"url" : "https://gitlab.freedesktop.org/xdg/startup-notification.git"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name" : "sassc",
|
||||
"buildsystem" : "simple",
|
||||
"sources" : [
|
||||
{
|
||||
"type" : "git",
|
||||
"url" : "https://github.com/sass/libsass"
|
||||
},
|
||||
{
|
||||
"type" : "git",
|
||||
"url" : "https://github.com/sass/sassc.git",
|
||||
"dest" : "sassc"
|
||||
}
|
||||
],
|
||||
"build-commands" : [
|
||||
"make -C sassc",
|
||||
"PREFIX=/app make -C sassc install"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name" : "cogl",
|
||||
"buildsystem" : "autotools",
|
||||
"sources" : [
|
||||
{
|
||||
"type" : "git",
|
||||
"tag" : "cogl-1.22",
|
||||
"url" : "https://gitlab.gnome.org/Archive/cogl.git"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name" : "clutter",
|
||||
"buildsystem" : "meson",
|
||||
"config-opts" : [
|
||||
"-Dbackends='system'",
|
||||
"-Ddrivers='all'",
|
||||
"-Dbuild_tests=false",
|
||||
"-Dbuild_examples=false",
|
||||
"-Ddocumentation=false",
|
||||
"-Dintrospection=true",
|
||||
"-Dpixbuf_tests=false"
|
||||
],
|
||||
"sources" : [
|
||||
{
|
||||
"type" : "git",
|
||||
"url" : "https://gitlab.gnome.org/GNOME/clutter.git"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name" : "gnome-shell",
|
||||
"buildsystem" : "meson",
|
||||
"config-opts" : [
|
||||
"-Dextensions_tool=false",
|
||||
"-Dextensions_app=false",
|
||||
"-Dgtk_doc=false",
|
||||
"-Dman=false",
|
||||
"-Dtests=false",
|
||||
"-Dnetworkmanager=false",
|
||||
"-Dsystemd=false"
|
||||
],
|
||||
"sources" : [
|
||||
{
|
||||
"type" : "git",
|
||||
"branch" : "main",
|
||||
"url" : "https://gitlab.gnome.org/GNOME/gnome-shell.git"
|
||||
}
|
||||
]
|
||||
},
|
||||
|
||||
{
|
||||
"name" : "gnome-backgrounds",
|
||||
"buildsystem" : "meson",
|
||||
@@ -770,11 +650,12 @@
|
||||
"buildsystem" : "meson",
|
||||
"sources" : [
|
||||
{
|
||||
"type" : "dir",
|
||||
"path" : "../../"
|
||||
"type" : "git",
|
||||
"url" : "https://gitlab.gnome.org/GNOME/gnome-control-center.git"
|
||||
}
|
||||
],
|
||||
"config-opts" : [
|
||||
"-Dtracing=true",
|
||||
"-Dprofile=development"
|
||||
]
|
||||
}
|
||||
|
||||
1
build-aux/meson.build
Normal file
@@ -0,0 +1 @@
|
||||
meson.add_install_script('meson/meson_post_install.py', control_center_datadir)
|
||||
15
build-aux/meson/meson_post_install.py
Normal file
@@ -0,0 +1,15 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
import os
|
||||
import subprocess
|
||||
import sys
|
||||
|
||||
gsettingsschemadir = os.path.join(sys.argv[1], 'glib-2.0', 'schemas')
|
||||
icondir = os.path.join(sys.argv[1], 'icons', 'hicolor')
|
||||
|
||||
if not os.environ.get('DESTDIR'):
|
||||
print('Compiling gsettings schemas...')
|
||||
subprocess.call(['glib-compile-schemas', gsettingsschemadir])
|
||||
|
||||
print('Update icon cache...')
|
||||
subprocess.call(['gtk-update-icon-cache', '-f', '-t', icondir])
|
||||
@@ -1,184 +0,0 @@
|
||||
# Code of Conduct
|
||||
|
||||
GNOME Settings is a project developed based on GNOME Code of Conduct and GitHub's community
|
||||
guidelines. You can read it below:
|
||||
|
||||
## Summary
|
||||
|
||||
GNOME creates software for a better world. We achieve this by behaving well towards
|
||||
each other.
|
||||
|
||||
Therefore this document suggests what we consider ideal behaviour, so you know what
|
||||
to expect when getting involved in GNOME. This is who we are and what we want to be.
|
||||
There is no official enforcement of these principles, and this should not be interpreted
|
||||
like a legal document.
|
||||
|
||||
## Advice
|
||||
|
||||
* **Be respectful and considerate**: Disagreement is no excuse for poor behaviour or personal
|
||||
attacks. Remember that a community where people feel uncomfortable is not a productive one.
|
||||
|
||||
* **Be patient and generous**: If someone asks for help it is because they need it. Do politely
|
||||
suggest specific documentation or more appropriate venues where appropriate, but avoid
|
||||
aggressive or vague responses such as "RTFM".
|
||||
|
||||
* **Assume people mean well**: Remember that decisions are often a difficult choice between
|
||||
competing priorities. If you disagree, please do so politely. If something seems outrageous,
|
||||
check that you did not misinterpret it. Ask for clarification, but do not assume the worst.
|
||||
|
||||
* **Try to be concise**: Avoid repeating what has been said already. Making a conversation larger
|
||||
makes it difficult to follow, and people often feel personally attacked if they receive multiple
|
||||
messages telling them the same thing.
|
||||
|
||||
|
||||
In the interest of fostering an open and welcoming environment, we as
|
||||
contributors and maintainers pledge to making participation in our project and
|
||||
our community a harassment-free experience for everyone, regardless of age, body
|
||||
size, disability, ethnicity, gender identity and expression, level of experience,
|
||||
nationality, personal appearance, race, religion, or sexual identity and
|
||||
orientation.
|
||||
|
||||
## Communication Guidelines
|
||||
|
||||
It is of ultimate importance to maintain a community in which everyone feels free to express
|
||||
themselves, review, and comment on each others ideas, both technical and otherwise. Correspondingly,
|
||||
an environment in which individuals are silenced, berated, or are otherwise afraid to speak up is
|
||||
unlikely to foster fruitful dialog.
|
||||
|
||||
Everyone interacting with members of the community should always keep in mind the asymmetry of
|
||||
communication: while your interaction with community members (and in particular, maintainers and
|
||||
long-term contributors) may be singular and fleeting, these members generally interact with a high
|
||||
volume of individuals each day. Before writing a comment, opening a new issue, or engaging as part
|
||||
of any forum or IRC discussion, please take a moment to appreciate that fact.
|
||||
|
||||
While communicating, it is expected that all involved participants be respectful and civil at all
|
||||
times and refrain from personal attacks.
|
||||
|
||||
### Communication Rules
|
||||
|
||||
The following behavior will not be tolerated on any occasion:
|
||||
|
||||
* **Threats of violence**: You may not threaten violence towards others or use the site to organize,
|
||||
promote, or incite acts of real-world violence or terrorism. Think carefully about the words you
|
||||
use, the images you post, and even the software you write, and how they may be interpreted by
|
||||
others. Even if you mean something as a joke, it might not be received that way. If you think
|
||||
that someone else might interpret the content you post as a threat or as promoting violence or
|
||||
terrorism, stop. Don't post it. In extraordinary cases, we may report threats of violence to law
|
||||
enforcement if we think there may be a genuine risk of physical harm or a threat to public safety.
|
||||
|
||||
* **Hate speech and discrimination**: While it is not forbidden to broach topics such as age, body
|
||||
size, disability, ethnicity, gender identity and expression, level of experience, nationality,
|
||||
personal appearance, race, religion, or sexual identity and orientation, we do not tolerate speech
|
||||
that attacks a person or group of people on the basis of who they are. When approached in an
|
||||
aggressive or insulting manner these (and other) sensitive topics can make others feel unwelcome,
|
||||
or perhaps even unsafe. While there's always the potential for misunderstandings, we expect our
|
||||
community members to remain respectful and civil when discussing sensitive topics.
|
||||
|
||||
* **Bullying and harassment**: We do not tolerate bullying, harassment, or any other means of
|
||||
habitual badgering or intimidation targeted at a specific person or group of people. In general,
|
||||
if your actions are unwanted and you cease to terminate this form of engagement, there is a good
|
||||
chance that your behavior will be classified as bullying or harassment.
|
||||
|
||||
* **Impersonation**: You may not seek to mislead others as to your identity by copying another
|
||||
person's avatar, posting content under their email address, using a similar username, or otherwise
|
||||
posing as someone else. Impersonation and identity theft is a form of harassment.
|
||||
|
||||
* **Doxxing and invasion of privacy**: Don't post other people's personal information, such as phone
|
||||
numbers, private email addresses, physical addresses, credit card numbers, Social Security/National
|
||||
Identity numbers, or passwords. Depending on the context, we may consider such behavior to be an
|
||||
invasion of privacy, with particularly egregious examples potentially escalating to the point of
|
||||
legal action, such as when the released material presents a safety risk to the subject.
|
||||
|
||||
* **Obscene content**: In essence, do not post pornography, gore, or any other depiction of violence.
|
||||
|
||||
### General Advice
|
||||
|
||||
The following advice will help to increase the efficiency of communication with community members:
|
||||
|
||||
* Do not post "me too" comments. Use the GitLab reactions instead, e.g. “thumbs up” or “thumbs down”.
|
||||
* Avoid adding priority, time, or relevance hints if you are not involved with the development of
|
||||
the application. For example, `“This is an urgent issue”`, or `“This should be fixed now”`, or
|
||||
even `“The majority of users need this feature”`.
|
||||
* Do not use passive-aggressive communication tactics.
|
||||
* When reporting technical problems with the application, such as misbehavior or crashes, focus on
|
||||
sharing as many details as possible and avoid adding non-technical information to it.
|
||||
|
||||
An example of a **good** issue report:
|
||||
|
||||
```
|
||||
GNOME Settings crashes when opening the Wi-Fi panel with 3+ Wi-Fi adapters
|
||||
|
||||
Steps to reproduce (assuming 3+ Wi-Fi adapters are present):
|
||||
|
||||
1. Open GNOME Settings
|
||||
2. Select the Wi-Fi panel
|
||||
3. Observe the crash
|
||||
|
||||
This does not happen with 2 or less adapters. Here is a backtrace of the
|
||||
crash: backtrace.txt
|
||||
```
|
||||
|
||||
In contrast, here is an example of a **bad** issue report:
|
||||
|
||||
```
|
||||
GNOME Settings crashed while I was trying to connect to the internet. How can such
|
||||
a thing happen and nobody notice? Did you not test it before releasing it?
|
||||
|
||||
This should be fixed as quick as possible!
|
||||
```
|
||||
|
||||
* When asking for new features, try and add as much information as possible to justify its relevance,
|
||||
why should it not be implemented as an auxiliary program, what problems it would solve, and offer
|
||||
suggestions about how you think it should be implemented.
|
||||
|
||||
Example of a **good** feature request:
|
||||
|
||||
```
|
||||
GNOME Settings needs to expose IPv6 options
|
||||
|
||||
As of now, the connection editor dialog does not allow editing various IPv6
|
||||
options. This is relevant because without some of these options, it is not
|
||||
possible to have a valid IPv6 configuration and, consequently, not have access
|
||||
to various websites and services.
|
||||
|
||||
The list of missing configurations that are essential is:
|
||||
|
||||
* <Feature A>
|
||||
* <Feature B>
|
||||
|
||||
Optionally, the following configurations can also be added:
|
||||
|
||||
* <Feature C>
|
||||
* <Feature D>
|
||||
|
||||
Here is a quick sketch I have made showing how I think these options
|
||||
should be exposed as a user interface: sketch.png.
|
||||
```
|
||||
|
||||
Example of a **bad** feature request:
|
||||
|
||||
```
|
||||
Merge GNOME Tweaks in GNOME Settings
|
||||
|
||||
The options in GNOME Tweaks are absolutely essential to the majority of us
|
||||
users. Why was it not merged already? This is an urgent issue and should
|
||||
have been addressed years ago. You should allocate all your resources on
|
||||
merging those two applications.
|
||||
```
|
||||
|
||||
### What happens if someone breaks these rules or guidelines?
|
||||
|
||||
Actions that may be taken in response to an abusive comment include but are not limited to:
|
||||
|
||||
* Content removal (when breaking any of the guidelines or rules)
|
||||
* Content blocking (when breaking any of the guidelines or rules)
|
||||
* Formal report to the Code of Conduct Committee (when breaking any of the rules)
|
||||
|
||||
## Attribution
|
||||
|
||||
This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4,
|
||||
available at [http://contributor-covenant.org/version/1/4][version]
|
||||
|
||||
[homepage]: http://contributor-covenant.org
|
||||
[version]: http://contributor-covenant.org/version/1/4/
|
||||
[maintainers]: https://gitlab.gnome.org/GNOME/gnome-control-center/blob/main/docs/MAINTAINERS.md
|
||||
@@ -1,97 +1,212 @@
|
||||
# Contributing
|
||||
|
||||
Thank you for considering contributing to Settings!
|
||||
|
||||
All code contributions are made using merge requests.
|
||||
When contributing to the development of GNOME Settings, please first discuss the change you wish to
|
||||
make via issue, email, or any other method with the maintainers before making a change.
|
||||
|
||||
Please note we have a Code of Conduct, please follow it in all your interactions with the project.
|
||||
|
||||
## Creating Merge Requests
|
||||
## Pull Request Process
|
||||
|
||||
To open a merge request fork the Settings project, and then create a branch for your change.
|
||||
When the change is ready, submit a merge request.
|
||||
1. Create a fork in GitLab and push your work to there
|
||||
2. Open a Merge Request
|
||||
1. Always allow maintainer edits
|
||||
2. Mark the Merge Request as WIP if your work is not ready to be reviewed
|
||||
3. Assign the correct maintainer to the Merge Request (see [`MAINTAINERS.md`][maintainers] to select
|
||||
the correct maintainer)
|
||||
4. Format commit messages as follows:
|
||||
```
|
||||
component: <summary>
|
||||
|
||||
A paragraph explaining the problem and its context.
|
||||
|
||||
Another one explaining how you solved that.
|
||||
|
||||
<link to the issue>
|
||||
```
|
||||
4. You may merge the pull request in once you have the sign-off of the maintainers, or if you
|
||||
do not have permission to do that, you may request the second reviewer to merge it for you.
|
||||
|
||||
The following guidelines will help your change be successfully merged:
|
||||
## Code of Conduct
|
||||
|
||||
* Keep the change as small as possible. If you can split it into multiple merge requests please do
|
||||
so.
|
||||
* Use multiple commits. This makes is easier to review and helps to diagnose bugs in the future.
|
||||
* Use clear commit messages (see below).
|
||||
* Attach screenshots of the change.
|
||||
* Link to relevant issues this change is related to.
|
||||
* Always set the merge request to allow maintainer edits - this makes it easier
|
||||
for a maintainer to make small improvements to land the change faster.
|
||||
GNOME Settings is a project developed based on GNOME Code of Conduct and GitHub's community
|
||||
guidelines. You can read it below:
|
||||
|
||||
Please format commit messages as follows:
|
||||
### Summary
|
||||
|
||||
```
|
||||
component: <summary>
|
||||
GNOME creates software for a better world. We achieve this by behaving well towards
|
||||
each other.
|
||||
|
||||
A paragraph explaining the problem and its context.
|
||||
Therefore this document suggests what we consider ideal behaviour, so you know what
|
||||
to expect when getting involved in GNOME. This is who we are and what we want to be.
|
||||
There is no official enforcement of these principles, and this should not be interpreted
|
||||
like a legal document.
|
||||
|
||||
Another one explaining how you solved that.
|
||||
### Advice
|
||||
|
||||
<link to issue(s) this change fixes>
|
||||
```
|
||||
* **Be respectful and considerate**: Disagreement is no excuse for poor behaviour or personal
|
||||
attacks. Remember that a community where people feel uncomfortable is not a productive one.
|
||||
|
||||
## Bug Fixes
|
||||
* **Be patient and generous**: If someone asks for help it is because they need it. Do politely
|
||||
suggest specific documentation or more appropriate venues where appropriate, but avoid
|
||||
aggressive or vague responses such as "RTFM".
|
||||
|
||||
Changes that fix bugs include:
|
||||
* **Assume people mean well**: Remember that decisions are often a difficult choice between
|
||||
competing priorities. If you disagree, please do so politely. If something seems outrageous,
|
||||
check that you did not misinterpret it. Ask for clarification, but do not assume the worst.
|
||||
|
||||
* Correcting code that crashes.
|
||||
* Spelling mistakes in labels.
|
||||
* Small layout issues (e.g. spacing).
|
||||
* Use of deprecated APIs.
|
||||
* Restructuring of code for improved safety.
|
||||
* **Try to be concise**: Avoid repeating what has been said already. Making a conversation larger
|
||||
makes it difficult to follow, and people often feel personally attacked if they receive multiple
|
||||
messages telling them the same thing.
|
||||
|
||||
Please include clear information in the commit message(s) and merge request that indicate what is
|
||||
being fixed by the change.
|
||||
|
||||
These changes will be reviewed for correctness, and then merged once this is complete.
|
||||
In the interest of fostering an open and welcoming environment, we as
|
||||
contributors and maintainers pledge to making participation in our project and
|
||||
our community a harassment-free experience for everyone, regardless of age, body
|
||||
size, disability, ethnicity, gender identity and expression, level of experience,
|
||||
nationality, personal appearance, race, religion, or sexual identity and
|
||||
orientation.
|
||||
|
||||
## User Experience Changes
|
||||
### Communication Guideline
|
||||
|
||||
Changes that impact the user experience of Settings require approval from the
|
||||
[Design Team][design-team]. This includes:
|
||||
It is of ultimate importance to maintain a community in which everyone feels free to express
|
||||
themselves, review, and comment on each others ideas, both technical and otherwise. Correspondingly,
|
||||
an environment in which individuals are silenced, berated, or are otherwise afraid to speak up is
|
||||
unlikely to foster fruitful dialog.
|
||||
|
||||
* Addition or removal of features in existing panels.
|
||||
* Changes to the layout of panels.
|
||||
* New panels.
|
||||
Everyone interacting with members of the community should always keep in mind the asymmetry of
|
||||
communication: while your interaction with community members (and in particular, maintainers and
|
||||
long-term contributors) may be singular and fleeting, these members generally interact with a high
|
||||
volume of individuals each day. Before writing a comment, opening a new issue, or engaging as part
|
||||
of any forum or IRC discussion, please take a moment to appreciate that fact.
|
||||
|
||||
Please include before/after screenshots in the merge request to show what is being changed.
|
||||
While communicating, it is expected that all involved participants be respectful and civil at all
|
||||
times and refrain from personal attacks.
|
||||
|
||||
For one of these changes to be merged one of the following is required:
|
||||
#### Communication Rules
|
||||
|
||||
* The change is shown in an existing mockup done by the design team (linked to in the merge request
|
||||
or issue).
|
||||
* A comment from a design team member in the merge request or issue approving the change.
|
||||
The following behavior will not be tolerated on any occasion:
|
||||
|
||||
If a merge request is opened without the above the "Needs Design" label attached to it and will not
|
||||
be merged until design approval is received.
|
||||
* **Threats of violence**: You may not threaten violence towards others or use the site to organize,
|
||||
promote, or incite acts of real-world violence or terrorism. Think carefully about the words you
|
||||
use, the images you post, and even the software you write, and how they may be interpreted by
|
||||
others. Even if you mean something as a joke, it might not be received that way. If you think
|
||||
that someone else might interpret the content you post as a threat or as promoting violence or
|
||||
terrorism, stop. Don't post it. In extraordinary cases, we may report threats of violence to law
|
||||
enforcement if we think there may be a genuine risk of physical harm or a threat to public safety.
|
||||
|
||||
Once design approval is obtained, the change will be reviewed for correctness, and then merged once
|
||||
this is complete.
|
||||
If design approval is not obtained, the merge request will be closed.
|
||||
* **Hate speech and discrimination**: While it is not forbidden to broach topics such as age, body
|
||||
size, disability, ethnicity, gender identity and expression, level of experience, nationality,
|
||||
personal appearance, race, religion, or sexual identity and orientation, we do not tolerate speech
|
||||
that attacks a person or group of people on the basis of who they are. When approached in an
|
||||
aggressive or insulting manner these (and other) sensitive topics can make others feel unwelcome,
|
||||
or perhaps even unsafe. While there's always the potential for misunderstandings, we expect our
|
||||
community members to remain respectful and civil when discussing sensitive topics.
|
||||
|
||||
[design-team]: https://gitlab.gnome.org/Teams/Design
|
||||
* **Bullying and harassment**: We do not tolerate bullying, harassment, or any other means of
|
||||
habitual badgering or intimidation targeted at a specific person or group of people. In general,
|
||||
if your actions are unwanted and you cease to terminate this form of engagement, there is a good
|
||||
chance that your behavior will be classified as bullying or harassment.
|
||||
|
||||
## Reviews
|
||||
* **Impersonation**: You may not seek to mislead others as to your identity by copying another
|
||||
person's avatar, posting content under their email address, using a similar username, or otherwise
|
||||
posing as someone else. Impersonation and identity theft is a form of harassment.
|
||||
|
||||
All changes require approval from one or more Settings maintainers.
|
||||
Reviews are likely to ask for changes to be made, please respond to these as soon as you are able
|
||||
and ask for clarification if the requests are not clear.
|
||||
* **Doxxing and invasion of privacy**: Don't post other people's personal information, such as phone
|
||||
numbers, private email addresses, physical addresses, credit card numbers, Social Security/National
|
||||
Identity numbers, or passwords. Depending on the context, we may consider such behavior to be an
|
||||
invasion of privacy, with particularly egregious examples potentially escalating to the point of
|
||||
legal action, such as when the released material presents a safety risk to the subject.
|
||||
|
||||
When the change is ready to land a maintainer will mark it as approved.
|
||||
Then the change can be merged by either a maintainer or the submitter if they have suitable
|
||||
permissions.
|
||||
* **Obscene content**: In essence, do not post pornography, gore, or any other depiction of violence.
|
||||
|
||||
## Draft Merge Requests
|
||||
#### General Advice
|
||||
|
||||
Merge requests marked as draft will not be reviewed by Settings maintainers or merged.
|
||||
When the change is ready for review please mark the merge request as ready.
|
||||
The following advice will help to increase the efficiency of communication with community members:
|
||||
|
||||
## Inactive Merge Requests
|
||||
* Do not post "me too" comments. Use the GitLab reactions instead, e.g. “thumbs up” or “thumbs down”.
|
||||
* Avoid adding priority, time, or relevance hints if you are not involved with the development of
|
||||
the application. For example, `“This is an urgent issue”`, or `“This should be fixed now”`, or
|
||||
even `“The majority of users need this feature”`.
|
||||
* Do not use passive-aggressive communication tactics.
|
||||
* When reporting technical problems with the application, such as misbehavior or crashes, focus on
|
||||
sharing as many details as possible and avoid adding non-technical information to it.
|
||||
|
||||
If a merge request has comments from maintainers that have not been responded to within 4 weeks this
|
||||
merge request is considered to be inactive and will be closed. The reporter may re-open it at a
|
||||
later date if they respond to the comments.
|
||||
An example of a **good** issue report:
|
||||
|
||||
```
|
||||
GNOME Settings crashes when opening the Wi-Fi panel with 3+ Wi-Fi adapters
|
||||
|
||||
Steps to reproduce (assuming 3+ Wi-Fi adapters are present):
|
||||
|
||||
1. Open GNOME Settings
|
||||
2. Select the Wi-Fi panel
|
||||
3. Observe the crash
|
||||
|
||||
This does not happen with 2 or less adapters. Here is a backtrace of the
|
||||
crash: backtrace.txt
|
||||
```
|
||||
|
||||
In contrast, here is an example of a **bad** issue report:
|
||||
|
||||
```
|
||||
GNOME Settings crashed while I was trying to connect to the internet. How can such
|
||||
a thing happen and nobody notice? Did you not test it before releasing it?
|
||||
|
||||
This should be fixed as quick as possible!
|
||||
```
|
||||
|
||||
* When asking for new features, try and add as much information as possible to justify its relevance,
|
||||
why should it not be implemented as an auxiliary program, what problems it would solve, and offer
|
||||
suggestions about how you think it should be implemented.
|
||||
|
||||
Example of a **good** feature request:
|
||||
|
||||
```
|
||||
GNOME Settings needs to expose IPv6 options
|
||||
|
||||
As of now, the connection editor dialog does not allow editing various IPv6
|
||||
options. This is relevant because without some of these options, it is not
|
||||
possible to have a valid IPv6 configuration and, consequently, not have access
|
||||
to various websites and services.
|
||||
|
||||
The list of missing configurations that are essential is:
|
||||
|
||||
* <Feature A>
|
||||
* <Feature B>
|
||||
|
||||
Optionally, the following configurations can also be added:
|
||||
|
||||
* <Feature C>
|
||||
* <Feature D>
|
||||
|
||||
Here is a quick sketch I have made showing how I think these options
|
||||
should be exposed as a user interface: sketch.png.
|
||||
```
|
||||
|
||||
Example of a **bad** feature request:
|
||||
|
||||
```
|
||||
Merge GNOME Tweaks in GNOME Settings
|
||||
|
||||
The options in GNOME Tweaks are absolutely essential to the majority of us
|
||||
users. Why was it not merged already? This is an urgent issue and should
|
||||
have been addressed years ago. You should allocate all your resources on
|
||||
merging those two applications.
|
||||
```
|
||||
|
||||
#### What happens if someone breaks these rules or guidelines?
|
||||
|
||||
Actions that may be taken in response to an abusive comment include but are not limited to:
|
||||
|
||||
* Content removal (when breaking any of the guidelines or rules)
|
||||
* Content blocking (when breaking any of the guidelines or rules)
|
||||
* Formal report to the Code of Conduct Committee (when breaking any of the rules)
|
||||
|
||||
### Attribution
|
||||
|
||||
This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4,
|
||||
available at [http://contributor-covenant.org/version/1/4][version]
|
||||
|
||||
[homepage]: http://contributor-covenant.org
|
||||
[version]: http://contributor-covenant.org/version/1/4/
|
||||
[maintainers]: https://gitlab.gnome.org/GNOME/gnome-control-center/blob/master/docs/MAINTAINERS.md
|
||||
|
||||
@@ -50,7 +50,7 @@ by being explicit. Suggested acceptance phrase:
|
||||
Urgency commits should never happen, but in case they're needed, they are defined by the following
|
||||
criteria:
|
||||
|
||||
* On stable branches (or `main` right after a stable release)
|
||||
* On stable branches (or master right after a stable release)
|
||||
* Symptoms:
|
||||
* Always OR often reproducible; AND
|
||||
* Crash; OR
|
||||
@@ -59,4 +59,4 @@ criteria:
|
||||
* Quickly followed by an emergency release (at most 2 days after the commit)
|
||||
|
||||
|
||||
[doap]: https://gitlab.gnome.org/GNOME/gnome-control-center/blob/main/gnome-control-center.doap
|
||||
[doap]: https://gitlab.gnome.org/GNOME/gnome-control-center/blob/master/gnome-control-center.doap
|
||||
|
||||
@@ -13,6 +13,15 @@
|
||||
<category rdf:resource="http://api.gnome.org/doap-extensions#core" />
|
||||
<programming-language>C</programming-language>
|
||||
|
||||
<!-- General, Multitasking -->
|
||||
<maintainer>
|
||||
<foaf:Person>
|
||||
<foaf:name>Georges Basile Stavracas Neto</foaf:name>
|
||||
<foaf:mbox rdf:resource="mailto:gbsneto@gnome.org" />
|
||||
<gnome:userid>gbsneto</gnome:userid>
|
||||
</foaf:Person>
|
||||
</maintainer>
|
||||
|
||||
<!-- General, Region & Language -->
|
||||
<maintainer>
|
||||
<foaf:Person>
|
||||
@@ -40,7 +49,7 @@
|
||||
</foaf:Person>
|
||||
</maintainer>
|
||||
|
||||
<!-- About, Camera, File History & Trash, Location, Microphone, Mouse & Touchpad, Printers, Search, Thunderbolt, User Accounts -->
|
||||
<!-- Mouse & Touchpad, Printers -->
|
||||
<maintainer>
|
||||
<foaf:Person>
|
||||
<foaf:name>Felipe Borges</foaf:name>
|
||||
@@ -66,6 +75,15 @@
|
||||
</foaf:Person>
|
||||
</maintainer>
|
||||
|
||||
<!-- Thunderbolt -->
|
||||
<maintainer>
|
||||
<foaf:Person>
|
||||
<foaf:name>Christian Kellner</foaf:name>
|
||||
<foaf:mbox rdf:resource="mailto:gicmo@gnome.org" />
|
||||
<gnome:userid>gicmo</gnome:userid>
|
||||
</foaf:Person>
|
||||
</maintainer>
|
||||
|
||||
<!-- Wacom -->
|
||||
<maintainer>
|
||||
<foaf:Person>
|
||||
|
||||
63
meson.build
@@ -1,8 +1,8 @@
|
||||
project(
|
||||
'gnome-control-center', 'c',
|
||||
version : '44.4',
|
||||
version : '42.10',
|
||||
license : 'GPL2+',
|
||||
meson_version : '>= 0.57.0'
|
||||
meson_version : '>= 0.53.0'
|
||||
)
|
||||
|
||||
control_center_prefix = get_option('prefix')
|
||||
@@ -25,19 +25,15 @@ host_is_linux_not_s390 = host_is_linux and not host_machine.cpu().contains('s390
|
||||
|
||||
cc = meson.get_compiler('c')
|
||||
|
||||
# Tracing
|
||||
enable_tracing = get_option('tracing')
|
||||
|
||||
config_h = configuration_data()
|
||||
|
||||
py = import('python')
|
||||
python = py.find_installation('python3')
|
||||
|
||||
config_h.set_quoted('TEST_NM_PYTHON', python.full_path())
|
||||
|
||||
if get_option('profile') == 'development'
|
||||
profile = 'Devel'
|
||||
else
|
||||
profile = ''
|
||||
endif
|
||||
application_id = 'org.gnome.Settings@0@'.format(profile)
|
||||
config_h.set_quoted('TEST_NM_PYTHON', python.path())
|
||||
|
||||
# defines
|
||||
set_defines = [
|
||||
@@ -54,17 +50,6 @@ foreach define: set_defines
|
||||
config_h.set_quoted(define[0], define[1])
|
||||
endforeach
|
||||
|
||||
distributor_logo = get_option('distributor_logo')
|
||||
if (distributor_logo != '')
|
||||
config_h.set_quoted('DISTRIBUTOR_LOGO', distributor_logo,
|
||||
description: 'Define to absolute path of distributor logo')
|
||||
dark_mode_distributor_logo = get_option('dark_mode_distributor_logo')
|
||||
if (dark_mode_distributor_logo != '')
|
||||
config_h.set_quoted('DARK_MODE_DISTRIBUTOR_LOGO', dark_mode_distributor_logo,
|
||||
description: 'Define to absolute path of distributor logo for use in dark mode')
|
||||
endif
|
||||
endif
|
||||
|
||||
# meson does not support octal values, so it must be handled as a
|
||||
# string. See: https://github.com/mesonbuild/meson/issues/2047
|
||||
config_h.set('USER_DIR_MODE', '0700',
|
||||
@@ -117,22 +102,9 @@ libgvc_dep = libgvc.get_variable('libgvc_dep')
|
||||
goa_req_version = '>= 3.25.3'
|
||||
pulse_req_version = '>= 2.0'
|
||||
|
||||
gtk_dep = dependency(
|
||||
'gtk4',
|
||||
version: '>= 4.9.3',
|
||||
fallback: ['gtk', 'gtk_dep'],
|
||||
default_options: [
|
||||
'introspection=disabled',
|
||||
'demos=false',
|
||||
'build-testsuite=false',
|
||||
'build-tests=false',
|
||||
'build-examples=false',
|
||||
]
|
||||
)
|
||||
|
||||
libadwaita_dep = dependency(
|
||||
'libadwaita-1',
|
||||
version: '>= 1.2.alpha',
|
||||
version: '>= 1.1',
|
||||
fallback: ['libadwaita', 'libadwaita_dep'],
|
||||
default_options: ['examples=false', 'introspection=disabled', 'tests=false', 'vapi=false'],
|
||||
)
|
||||
@@ -141,7 +113,7 @@ accounts_dep = dependency('accountsservice', version: '>= 0.6.39')
|
||||
colord_dep = dependency('colord', version: '>= 0.1.34')
|
||||
gdk_pixbuf_dep = dependency('gdk-pixbuf-2.0', version: '>= 2.23.0')
|
||||
gio_dep = dependency('gio-2.0')
|
||||
glib_dep = dependency('glib-2.0', version: '>= 2.75.0')
|
||||
glib_dep = dependency('glib-2.0', version: '>= 2.68.0')
|
||||
gnome_desktop_dep = dependency('gnome-desktop-4')
|
||||
gnome_bg_dep = dependency('gnome-bg-4')
|
||||
gnome_rr_dep = dependency('gnome-rr-4')
|
||||
@@ -153,7 +125,7 @@ pulse_dep = dependency('libpulse', version: pulse_req_version)
|
||||
pulse_mainloop_dep = dependency('libpulse-mainloop-glib', version: pulse_req_version)
|
||||
upower_glib_dep = dependency('upower-glib', version: '>= 0.99.8')
|
||||
gudev_dep = dependency('gudev-1.0', version: '>= 232')
|
||||
x11_dep = dependency('x11', version: '>= 1.8')
|
||||
x11_dep = dependency('x11')
|
||||
xi_dep = dependency('xi', version: '>= 1.2')
|
||||
epoxy_dep = dependency('epoxy')
|
||||
gcr_dep = dependency('gcr-base-3')
|
||||
@@ -168,7 +140,7 @@ common_deps = [
|
||||
libadwaita_dep,
|
||||
dependency('gio-unix-2.0'),
|
||||
dependency('gthread-2.0'),
|
||||
gtk_dep,
|
||||
dependency('gtk4', version: '>= 4.4'),
|
||||
]
|
||||
|
||||
polkit_gobject_dep = dependency('polkit-gobject-1', version: '>= 0.103')
|
||||
@@ -239,11 +211,10 @@ config_h.set('HAVE_MALCONTENT', enable_malcontent,
|
||||
|
||||
if host_is_linux
|
||||
# network manager
|
||||
mm_dep = dependency('mm-glib', version: '>= 0.7')
|
||||
network_manager_deps = [
|
||||
dependency('libnm', version: '>= 1.24.0'),
|
||||
dependency('libnma-gtk4', version: '>= 1.10.2'),
|
||||
mm_dep,
|
||||
dependency('libnma-gtk4', version: '>= 1.8.0'),
|
||||
dependency('mm-glib', version: '>= 0.7')
|
||||
]
|
||||
endif
|
||||
config_h.set('BUILD_NETWORK', host_is_linux,
|
||||
@@ -285,6 +256,9 @@ gnome = import('gnome')
|
||||
i18n = import('i18n')
|
||||
pkg = import('pkgconfig')
|
||||
|
||||
desktop_conf = configuration_data()
|
||||
desktop_conf.set('VERSION', meson.project_version())
|
||||
|
||||
po_dir = join_paths(meson.source_root(), 'po')
|
||||
its_dir = join_paths(meson.source_root(), 'gettext')
|
||||
|
||||
@@ -296,6 +270,7 @@ install_subdir(
|
||||
top_inc = include_directories('.')
|
||||
shell_inc = include_directories('shell')
|
||||
|
||||
subdir('build-aux')
|
||||
subdir('data/icons')
|
||||
subdir('po')
|
||||
subdir('panels')
|
||||
@@ -310,11 +285,6 @@ if get_option('documentation')
|
||||
subdir('man')
|
||||
endif
|
||||
|
||||
gnome.post_install(
|
||||
glib_compile_schemas: true,
|
||||
gtk_update_icon_cache: true,
|
||||
)
|
||||
|
||||
configure_file(
|
||||
output: 'config.h',
|
||||
configuration: config_h
|
||||
@@ -323,6 +293,7 @@ configure_file(
|
||||
summary({
|
||||
'Documentation': get_option('documentation'),
|
||||
'Tests': get_option('tests'),
|
||||
'Tracing': enable_tracing,
|
||||
'Optimized': control_center_optimized,
|
||||
})
|
||||
|
||||
|
||||
@@ -3,8 +3,7 @@ option('ibus', type: 'boolean', value: true, description: 'build with IBus suppo
|
||||
option('privileged_group', type: 'string', value: 'wheel', description: 'name of group that has elevated permissions')
|
||||
option('snap', type: 'boolean', value: false, description: 'build with Snap support')
|
||||
option('tests', type: 'boolean', value: true, description: 'build tests')
|
||||
option('tracing', type: 'boolean', value: false, description: 'add extra debugging information')
|
||||
option('wayland', type: 'boolean', value: true, description: 'build with Wayland support')
|
||||
option('profile', type: 'combo', choices: ['default','development'], value: 'default')
|
||||
option('malcontent', type: 'boolean', value: false, description: 'build with malcontent support')
|
||||
option('distributor_logo', type: 'string', description: 'absolute path to distributor logo for the About panel')
|
||||
option('dark_mode_distributor_logo', type: 'string', description: 'absolute path to distributor logo dark mode variant')
|
||||
|
||||
@@ -96,7 +96,6 @@ struct _CcApplicationsPanel
|
||||
CcToggleRow *notification;
|
||||
CcToggleRow *background;
|
||||
CcToggleRow *wallpaper;
|
||||
CcToggleRow *screenshot;
|
||||
CcToggleRow *sound;
|
||||
CcInfoRow *no_sound;
|
||||
CcToggleRow *search;
|
||||
@@ -516,37 +515,6 @@ wallpaper_cb (CcApplicationsPanel *self)
|
||||
set_wallpaper_allowed (self, cc_toggle_row_get_allowed (self->wallpaper));
|
||||
}
|
||||
|
||||
/* --- screenshot --- */
|
||||
|
||||
static void
|
||||
get_screenshot_allowed (CcApplicationsPanel *self,
|
||||
const gchar *app_id,
|
||||
gboolean *set,
|
||||
gboolean *allowed)
|
||||
{
|
||||
g_auto(GStrv) perms = get_portal_permissions (self, "screenshot", "screenshot", app_id);
|
||||
|
||||
*set = perms != NULL;
|
||||
*allowed = perms == NULL || strcmp (perms[0], "no") != 0;
|
||||
}
|
||||
|
||||
static void
|
||||
set_screenshot_allowed (CcApplicationsPanel *self,
|
||||
gboolean allowed)
|
||||
{
|
||||
const gchar *perms[2] = { NULL, NULL };
|
||||
|
||||
perms[0] = allowed ? "yes" : "no";
|
||||
set_portal_permissions (self, "screenshot", "screenshot", self->current_app_id, perms);
|
||||
}
|
||||
|
||||
static void
|
||||
screenshot_cb (CcApplicationsPanel *self)
|
||||
{
|
||||
if (self->current_app_id)
|
||||
set_screenshot_allowed (self, cc_toggle_row_get_allowed (self->screenshot));
|
||||
}
|
||||
|
||||
/* --- shortcuts permissions (flatpak) --- */
|
||||
|
||||
static void
|
||||
@@ -576,7 +544,7 @@ set_shortcuts_allowed (CcApplicationsPanel *self,
|
||||
|
||||
/* "GRANTED" and "DENIED" here match the values set by the "inhibit shortcut
|
||||
* dialog" is GNOME Shell:
|
||||
* https://gitlab.gnome.org/GNOME/gnome-shell/-/blob/main/js/ui/inhibitShortcutsDialog.js
|
||||
* https://gitlab.gnome.org/GNOME/gnome-shell/-/blob/master/js/ui/inhibitShortcutsDialog.js
|
||||
*/
|
||||
perms[0] = granted ? "GRANTED" : "DENIED";
|
||||
perms[1] = NULL;
|
||||
@@ -847,7 +815,7 @@ add_static_permissions (CcApplicationsPanel *self,
|
||||
if (str && g_str_equal (str, "talk"))
|
||||
added += add_static_permission_row (self, _("Settings"), _("Can change settings"));
|
||||
|
||||
text = g_strdup_printf (_("%s requires access to the following system resources. To stop this access, the app must be removed."), g_app_info_get_display_name (info));
|
||||
text = g_strdup_printf (_("%s has the following permissions built-in. These cannot be altered. If you are concerned about these permissions, consider removing this application."), g_app_info_get_display_name (info));
|
||||
adw_preferences_group_set_description (self->builtin_group, text);
|
||||
|
||||
return added > 0;
|
||||
@@ -901,7 +869,7 @@ update_integration_section (CcApplicationsPanel *self,
|
||||
}
|
||||
else
|
||||
{
|
||||
gtk_widget_set_visible (GTK_WIDGET (self->shortcuts), FALSE);
|
||||
gtk_widget_hide (GTK_WIDGET (self->shortcuts));
|
||||
}
|
||||
|
||||
#ifdef HAVE_SNAP
|
||||
@@ -926,11 +894,6 @@ update_integration_section (CcApplicationsPanel *self,
|
||||
gtk_widget_set_visible (GTK_WIDGET (self->wallpaper), set);
|
||||
has_any |= set;
|
||||
|
||||
get_screenshot_allowed (self, portal_app_id, &set, &allowed);
|
||||
cc_toggle_row_set_allowed (self->screenshot, allowed);
|
||||
gtk_widget_set_visible (GTK_WIDGET (self->screenshot), set);
|
||||
has_any |= set;
|
||||
|
||||
disabled = g_settings_get_boolean (self->privacy_settings, "disable-sound-output");
|
||||
get_device_allowed (self, "speakers", portal_app_id, &set, &allowed);
|
||||
cc_toggle_row_set_allowed (self->sound, allowed);
|
||||
@@ -970,17 +933,16 @@ update_integration_section (CcApplicationsPanel *self,
|
||||
gtk_widget_set_visible (GTK_WIDGET (self->notification), set);
|
||||
has_any |= set;
|
||||
|
||||
gtk_widget_set_visible (GTK_WIDGET (self->background), FALSE);
|
||||
gtk_widget_set_visible (GTK_WIDGET (self->wallpaper), FALSE);
|
||||
gtk_widget_set_visible (GTK_WIDGET (self->screenshot), FALSE);
|
||||
gtk_widget_set_visible (GTK_WIDGET (self->sound), FALSE);
|
||||
gtk_widget_set_visible (GTK_WIDGET (self->no_sound), FALSE);
|
||||
gtk_widget_set_visible (GTK_WIDGET (self->camera), FALSE);
|
||||
gtk_widget_set_visible (GTK_WIDGET (self->no_camera), FALSE);
|
||||
gtk_widget_set_visible (GTK_WIDGET (self->microphone), FALSE);
|
||||
gtk_widget_set_visible (GTK_WIDGET (self->no_microphone), FALSE);
|
||||
gtk_widget_set_visible (GTK_WIDGET (self->location), FALSE);
|
||||
gtk_widget_set_visible (GTK_WIDGET (self->no_location), FALSE);
|
||||
gtk_widget_hide (GTK_WIDGET (self->background));
|
||||
gtk_widget_hide (GTK_WIDGET (self->wallpaper));
|
||||
gtk_widget_hide (GTK_WIDGET (self->sound));
|
||||
gtk_widget_hide (GTK_WIDGET (self->no_sound));
|
||||
gtk_widget_hide (GTK_WIDGET (self->camera));
|
||||
gtk_widget_hide (GTK_WIDGET (self->no_camera));
|
||||
gtk_widget_hide (GTK_WIDGET (self->microphone));
|
||||
gtk_widget_hide (GTK_WIDGET (self->no_microphone));
|
||||
gtk_widget_hide (GTK_WIDGET (self->location));
|
||||
gtk_widget_hide (GTK_WIDGET (self->no_location));
|
||||
}
|
||||
|
||||
gtk_widget_set_visible (GTK_WIDGET (self->integration_section), has_any);
|
||||
@@ -1029,7 +991,7 @@ add_scheme (CcApplicationsPanel *self,
|
||||
g_object_set_data_full (G_OBJECT (button), "type", g_strdup (type), g_free);
|
||||
g_signal_connect_object (button, "clicked", G_CALLBACK (unset_cb), self, G_CONNECT_SWAPPED);
|
||||
|
||||
gtk_widget_set_visible (GTK_WIDGET (self->handler_link_group), TRUE);
|
||||
gtk_widget_show (GTK_WIDGET (self->handler_link_group));
|
||||
adw_preferences_group_add (self->handler_link_group, GTK_WIDGET (row));
|
||||
|
||||
self->link_handler_rows = g_list_prepend (self->link_handler_rows, row);
|
||||
@@ -1061,7 +1023,7 @@ add_file_type (CcApplicationsPanel *self,
|
||||
g_object_set_data_full (G_OBJECT (button), "type", g_strdup (type), g_free);
|
||||
g_signal_connect_object (button, "clicked", G_CALLBACK (unset_cb), self, G_CONNECT_SWAPPED);
|
||||
|
||||
gtk_widget_set_visible (GTK_WIDGET (self->handler_file_group), TRUE);
|
||||
gtk_widget_show (GTK_WIDGET (self->handler_file_group));
|
||||
adw_preferences_group_add (self->handler_file_group, GTK_WIDGET (row));
|
||||
|
||||
self->file_handler_rows = g_list_prepend (self->file_handler_rows, row);
|
||||
@@ -1071,7 +1033,7 @@ static void
|
||||
add_handler_row (CcApplicationsPanel *self,
|
||||
const gchar *type)
|
||||
{
|
||||
gtk_widget_set_visible (GTK_WIDGET (self->handler_row), TRUE);
|
||||
gtk_widget_show (GTK_WIDGET (self->handler_row));
|
||||
|
||||
if (g_content_type_is_a (type, "x-scheme-handler/*"))
|
||||
add_scheme (self, type);
|
||||
@@ -1154,9 +1116,9 @@ update_handler_dialog (CcApplicationsPanel *self,
|
||||
|
||||
remove_all_handler_rows (self);
|
||||
|
||||
gtk_widget_set_visible (GTK_WIDGET (self->handler_row), FALSE);
|
||||
gtk_widget_set_visible (GTK_WIDGET (self->handler_file_group), FALSE);
|
||||
gtk_widget_set_visible (GTK_WIDGET (self->handler_link_group), FALSE);
|
||||
gtk_widget_hide (GTK_WIDGET (self->handler_row));
|
||||
gtk_widget_hide (GTK_WIDGET (self->handler_file_group));
|
||||
gtk_widget_hide (GTK_WIDGET (self->handler_link_group));
|
||||
|
||||
types = g_app_info_get_supported_types (info);
|
||||
if (types == NULL || types[0] == NULL)
|
||||
@@ -1248,7 +1210,7 @@ update_total_size (CcApplicationsPanel *self)
|
||||
g_object_set (self->total, "info", formatted_size, NULL);
|
||||
|
||||
/* Translators: '%s' is the formatted size, e.g. "26.2 MB" */
|
||||
subtitle = g_strdup_printf (_("%s of disk space used."), formatted_size);
|
||||
subtitle = g_strdup_printf (_("%s of disk space used"), formatted_size);
|
||||
g_object_set (self->storage, "subtitle", subtitle, NULL);
|
||||
}
|
||||
|
||||
@@ -1412,9 +1374,9 @@ update_panel (CcApplicationsPanel *self,
|
||||
|
||||
if (row == NULL)
|
||||
{
|
||||
adw_window_title_set_title (self->header_title, _("Apps"));
|
||||
adw_window_title_set_title (self->header_title, _("Applications"));
|
||||
gtk_stack_set_visible_child (self->stack, self->empty_box);
|
||||
gtk_widget_set_visible (GTK_WIDGET (self->view_details_button), FALSE);
|
||||
gtk_widget_hide (GTK_WIDGET (GTK_WIDGET (self->view_details_button)));
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -1782,7 +1744,6 @@ cc_applications_panel_class_init (CcApplicationsPanelClass *klass)
|
||||
gtk_widget_class_bind_template_child (widget_class, CcApplicationsPanel, notification);
|
||||
gtk_widget_class_bind_template_child (widget_class, CcApplicationsPanel, background);
|
||||
gtk_widget_class_bind_template_child (widget_class, CcApplicationsPanel, wallpaper);
|
||||
gtk_widget_class_bind_template_child (widget_class, CcApplicationsPanel, screenshot);
|
||||
gtk_widget_class_bind_template_child (widget_class, CcApplicationsPanel, shortcuts);
|
||||
gtk_widget_class_bind_template_child (widget_class, CcApplicationsPanel, sidebar_box);
|
||||
gtk_widget_class_bind_template_child (widget_class, CcApplicationsPanel, sidebar_listbox);
|
||||
@@ -1804,7 +1765,6 @@ cc_applications_panel_class_init (CcApplicationsPanelClass *klass)
|
||||
gtk_widget_class_bind_template_callback (widget_class, notification_cb);
|
||||
gtk_widget_class_bind_template_callback (widget_class, background_cb);
|
||||
gtk_widget_class_bind_template_callback (widget_class, wallpaper_cb);
|
||||
gtk_widget_class_bind_template_callback (widget_class, screenshot_cb);
|
||||
gtk_widget_class_bind_template_callback (widget_class, shortcuts_cb);
|
||||
gtk_widget_class_bind_template_callback (widget_class, privacy_link_cb);
|
||||
gtk_widget_class_bind_template_callback (widget_class, sound_cb);
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
</child>
|
||||
<property name="title-widget">
|
||||
<object class="AdwWindowTitle" id="header_title">
|
||||
<property name="title" translatable="yes">Apps</property>
|
||||
<property name="title" translatable="yes">Applications</property>
|
||||
</object>
|
||||
</property>
|
||||
</object>
|
||||
@@ -28,7 +28,7 @@
|
||||
<child>
|
||||
<object class="AdwStatusPage" id="empty_box">
|
||||
<property name="icon-name">org.gnome.Software-symbolic</property>
|
||||
<property name="title" translatable="yes">No apps</property>
|
||||
<property name="title" translatable="yes">No applications</property>
|
||||
<child>
|
||||
<object class="GtkButton" id="install_button">
|
||||
<property name="label" translatable="yes">Install some…</property>
|
||||
@@ -91,7 +91,7 @@
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkButton" id="view_details_button">
|
||||
<property name="label" translatable="yes">App Details</property>
|
||||
<property name="label" translatable="yes">View Details</property>
|
||||
<style>
|
||||
<class name="pill" />
|
||||
</style>
|
||||
@@ -110,38 +110,31 @@
|
||||
<child>
|
||||
<object class="CcToggleRow" id="search">
|
||||
<property name="title" translatable="yes">Search</property>
|
||||
<property name="subtitle" translatable="yes">Receive system searches and send results</property>
|
||||
<property name="subtitle" translatable="yes">Receive system searches and send results.</property>
|
||||
<signal name="notify::allowed" handler="search_cb" object="CcApplicationsPanel" swapped="yes"/>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="CcInfoRow" id="no_search">
|
||||
<property name="title" translatable="yes">Search</property>
|
||||
<property name="subtitle" translatable="yes">Receive system searches and send results</property>
|
||||
<property name="subtitle" translatable="yes">Receive system searches and send results.</property>
|
||||
<property name="info" translatable="yes">Disabled</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="CcToggleRow" id="notification">
|
||||
<property name="title" translatable="yes">Notifications</property>
|
||||
<property name="subtitle" translatable="yes">Show system notifications</property>
|
||||
<property name="subtitle" translatable="yes">Show system notifications.</property>
|
||||
<signal name="notify::allowed" handler="notification_cb" object="CcApplicationsPanel" swapped="yes"/>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="CcToggleRow" id="background">
|
||||
<property name="title" translatable="yes">Run in Background</property>
|
||||
<property name="subtitle" translatable="yes">Allow activity when the app is closed</property>
|
||||
<property name="title" translatable="yes">Run in background</property>
|
||||
<property name="subtitle" translatable="yes">Allow activity when the app is closed.</property>
|
||||
<signal name="notify::allowed" handler="background_cb" swapped="yes"/>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="CcToggleRow" id="screenshot">
|
||||
<property name="title" translatable="yes">Screenshots</property>
|
||||
<property name="subtitle" translatable="yes">Take pictures of the screen at any time</property>
|
||||
<signal name="notify::allowed" handler="screenshot_cb" object="CcApplicationsPanel" swapped="yes"/>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="CcToggleRow" id="wallpaper">
|
||||
<property name="title" translatable="yes">Change Wallpaper</property>
|
||||
@@ -159,56 +152,56 @@
|
||||
<child>
|
||||
<object class="CcInfoRow" id="no_sound">
|
||||
<property name="title" translatable="yes">Sounds</property>
|
||||
<property name="subtitle" translatable="yes">Reproduce sounds</property>
|
||||
<property name="subtitle" translatable="yes">Reproduce sounds.</property>
|
||||
<property name="info" translatable="yes">Disabled</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="CcToggleRow" id="shortcuts">
|
||||
<property name="title" translatable="yes">Inhibit Shortcuts</property>
|
||||
<property name="subtitle" translatable="yes">Block standard keyboard shortcuts</property>
|
||||
<property name="subtitle" translatable="yes">Block standard keyboard shortcuts.</property>
|
||||
<signal name="notify::allowed" handler="shortcuts_cb" swapped="yes"/>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="CcToggleRow" id="camera">
|
||||
<property name="title" translatable="yes">Camera</property>
|
||||
<property name="subtitle" translatable="yes">Take pictures with the camera</property>
|
||||
<property name="subtitle" translatable="yes">Take pictures with the camera.</property>
|
||||
<signal name="notify::allowed" handler="camera_cb" object="CcApplicationsPanel" swapped="yes"/>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="CcInfoRow" id="no_camera">
|
||||
<property name="title" translatable="yes">Camera</property>
|
||||
<property name="subtitle" translatable="yes">Take pictures with the camera</property>
|
||||
<property name="subtitle" translatable="yes">Take pictures with the camera.</property>
|
||||
<property name="info" translatable="yes">Disabled</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="CcToggleRow" id="microphone">
|
||||
<property name="title" translatable="yes">Microphone</property>
|
||||
<property name="subtitle" translatable="yes">Record audio with the microphone</property>
|
||||
<property name="subtitle" translatable="yes">Record audio with the microphone.</property>
|
||||
<signal name="notify::allowed" handler="microphone_cb" object="CcApplicationsPanel" swapped="yes"/>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="CcInfoRow" id="no_microphone">
|
||||
<property name="title" translatable="yes">Microphone</property>
|
||||
<property name="subtitle" translatable="yes">Record audio with the microphone</property>
|
||||
<property name="subtitle" translatable="yes">Record audio with the microphone.</property>
|
||||
<property name="info" translatable="yes">Disabled</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="CcToggleRow" id="location">
|
||||
<property name="title" translatable="yes">Location Services</property>
|
||||
<property name="subtitle" translatable="yes">Access device location data</property>
|
||||
<property name="subtitle" translatable="yes">Access device location data.</property>
|
||||
<signal name="notify::allowed" handler="location_cb" object="CcApplicationsPanel" swapped="yes"/>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="CcInfoRow" id="no_location">
|
||||
<property name="title" translatable="yes">Location Services</property>
|
||||
<property name="subtitle" translatable="yes">Access device location data</property>
|
||||
<property name="subtitle" translatable="yes">Access device location data.</property>
|
||||
<property name="info" translatable="yes">Disabled</property>
|
||||
</object>
|
||||
</child>
|
||||
@@ -219,7 +212,7 @@
|
||||
<object class="AdwPreferencesGroup" id="usage_section">
|
||||
<child>
|
||||
<object class="CcInfoRow" id="builtin">
|
||||
<property name="title" translatable="yes">Required Access</property>
|
||||
<property name="title" translatable="yes">Built-in Permissions</property>
|
||||
<property name="subtitle" translatable="yes">System access that is required by the app</property>
|
||||
<property name="has-expander">True</property>
|
||||
<property name="is-link">True</property>
|
||||
@@ -323,15 +316,11 @@
|
||||
|
||||
<!-- Built-in Permissions dialog -->
|
||||
<object class="GtkDialog" id="builtin_dialog">
|
||||
<property name="title" translatable="yes">Required Access</property>
|
||||
<property name="title" translatable="yes">Built-in Permissions</property>
|
||||
<property name="modal">1</property>
|
||||
<property name="use-header-bar">1</property>
|
||||
<property name="resizable">True</property>
|
||||
<property name="hide-on-close">True</property>
|
||||
<property name="default-width">500</property>
|
||||
<property name="default-height">400</property>
|
||||
<property name="width-request">360</property>
|
||||
<property name="height-request">294</property>
|
||||
<child>
|
||||
<object class="AdwPreferencesPage">
|
||||
<child>
|
||||
@@ -359,8 +348,6 @@
|
||||
<property name="hide-on-close">True</property>
|
||||
<property name="default-width">500</property>
|
||||
<property name="default-height">400</property>
|
||||
<property name="width-request">360</property>
|
||||
<property name="height-request">294</property>
|
||||
<child>
|
||||
<object class="AdwPreferencesPage">
|
||||
|
||||
@@ -420,10 +407,10 @@
|
||||
<object class="AdwPreferencesPage">
|
||||
<child>
|
||||
<object class="AdwPreferencesGroup">
|
||||
<property name="description" translatable="yes">How much disk space this app is occupying with app data and caches.</property>
|
||||
<property name="description" translatable="yes">How much disk space this application is occupying with app data and caches.</property>
|
||||
<child>
|
||||
<object class="CcInfoRow" id="app">
|
||||
<property name="title" translatable="yes">App</property>
|
||||
<property name="title" translatable="yes">Application</property>
|
||||
<property name="info">Unknown</property>
|
||||
</object>
|
||||
</child>
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
[Desktop Entry]
|
||||
Name=Apps
|
||||
Comment=Control various app permissions and settings
|
||||
Name=Applications
|
||||
Comment=Control various application permissions and settings
|
||||
Exec=gnome-control-center applications
|
||||
# FIXME
|
||||
# Translators: Do NOT translate or transliterate this text (this is an icon file name)!
|
||||
@@ -11,6 +11,6 @@ NoDisplay=true
|
||||
StartupNotify=true
|
||||
Categories=GNOME;GTK;Settings;DesktopSettings;X-GNOME-Settings-Panel;X-GNOME-AccountSettings;
|
||||
OnlyShowIn=GNOME;Unity;
|
||||
# Translators: Search terms to find the Apps panel. Do NOT translate or localize the semicolons! The list MUST also end with a semicolon!
|
||||
# Translators: Search terms to find the Privacy panel. Do NOT translate or localize the semicolons! The list MUST also end with a semicolon!
|
||||
Keywords=application;flatpak;permission;setting;
|
||||
X-GNOME-ControlCenter-HasSidebar=true
|
||||
@@ -1,9 +1,15 @@
|
||||
panels_list += cappletname
|
||||
desktop = 'gnome-@0@-panel.desktop'.format(cappletname)
|
||||
|
||||
desktop_in = configure_file(
|
||||
input : desktop + '.in.in',
|
||||
output : desktop + '.in',
|
||||
configuration : desktop_conf
|
||||
)
|
||||
|
||||
i18n.merge_file(
|
||||
type : 'desktop',
|
||||
input : desktop + '.in',
|
||||
input : desktop_in,
|
||||
output : desktop,
|
||||
po_dir : po_dir,
|
||||
install : true,
|
||||
|
||||
@@ -35,32 +35,6 @@ struct _BgWallpapersSource
|
||||
|
||||
G_DEFINE_TYPE (BgWallpapersSource, bg_wallpapers_source, BG_TYPE_SOURCE)
|
||||
|
||||
static int
|
||||
sort_func (gconstpointer a,
|
||||
gconstpointer b,
|
||||
gpointer user_data)
|
||||
{
|
||||
CcBackgroundItem *item_a;
|
||||
CcBackgroundItem *item_b;
|
||||
const char *name_a;
|
||||
const char *name_b;
|
||||
|
||||
item_a = (CcBackgroundItem *) a;
|
||||
item_b = (CcBackgroundItem *) b;
|
||||
|
||||
name_a = cc_background_item_get_name (item_a);
|
||||
name_b = cc_background_item_get_name (item_b);
|
||||
|
||||
if (name_a && strcmp (name_a, "Default Background") == 0)
|
||||
return -1;
|
||||
if (name_b && strcmp (name_b, "Default Background") == 0)
|
||||
return 1;
|
||||
|
||||
|
||||
return strcmp (cc_background_item_get_name (item_a),
|
||||
cc_background_item_get_name (item_b));
|
||||
}
|
||||
|
||||
static void
|
||||
load_wallpapers (gchar *key,
|
||||
CcBackgroundItem *item,
|
||||
@@ -74,7 +48,7 @@ load_wallpapers (gchar *key,
|
||||
if (deleted)
|
||||
return;
|
||||
|
||||
g_list_store_insert_sorted (store, item, sort_func, NULL);
|
||||
g_list_store_append (store, item);
|
||||
}
|
||||
|
||||
static void
|
||||
|
||||
@@ -157,10 +157,10 @@ create_widget_func (gpointer model_item,
|
||||
gtk_overlay_add_overlay (GTK_OVERLAY (overlay), check);
|
||||
if (button)
|
||||
gtk_overlay_add_overlay (GTK_OVERLAY (overlay), button);
|
||||
gtk_accessible_update_property (GTK_ACCESSIBLE (overlay),
|
||||
GTK_ACCESSIBLE_PROPERTY_LABEL,
|
||||
cc_background_item_get_name (item),
|
||||
-1);
|
||||
gtk_accessible_update_property (GTK_ACCESSIBLE (overlay),
|
||||
GTK_ACCESSIBLE_PROPERTY_LABEL,
|
||||
cc_background_item_get_name (item),
|
||||
-1);
|
||||
|
||||
|
||||
child = gtk_flow_box_child_new ();
|
||||
|
||||
@@ -57,14 +57,15 @@ struct _CcBackgroundPanel
|
||||
GSettings *lock_settings;
|
||||
GSettings *interface_settings;
|
||||
|
||||
GnomeDesktopThumbnailFactory *thumb_factory;
|
||||
GDBusProxy *proxy;
|
||||
|
||||
CcBackgroundItem *current_background;
|
||||
|
||||
CcBackgroundChooser *background_chooser;
|
||||
CcBackgroundPreview *default_preview;
|
||||
CcBackgroundPreview *light_preview;
|
||||
CcBackgroundPreview *dark_preview;
|
||||
GtkToggleButton *default_toggle;
|
||||
GtkToggleButton *light_toggle;
|
||||
GtkToggleButton *dark_toggle;
|
||||
};
|
||||
|
||||
@@ -83,7 +84,7 @@ load_custom_css (CcBackgroundPanel *self)
|
||||
}
|
||||
|
||||
static void
|
||||
reload_color_scheme_toggles (CcBackgroundPanel *self)
|
||||
reload_light_dark_toggles (CcBackgroundPanel *self)
|
||||
{
|
||||
GDesktopColorScheme scheme;
|
||||
|
||||
@@ -91,7 +92,7 @@ reload_color_scheme_toggles (CcBackgroundPanel *self)
|
||||
|
||||
if (scheme == G_DESKTOP_COLOR_SCHEME_DEFAULT)
|
||||
{
|
||||
gtk_toggle_button_set_active (self->default_toggle, TRUE);
|
||||
gtk_toggle_button_set_active (self->light_toggle, TRUE);
|
||||
}
|
||||
else if (scheme == G_DESKTOP_COLOR_SCHEME_PREFER_DARK)
|
||||
{
|
||||
@@ -99,7 +100,7 @@ reload_color_scheme_toggles (CcBackgroundPanel *self)
|
||||
}
|
||||
else
|
||||
{
|
||||
gtk_toggle_button_set_active (self->default_toggle, FALSE);
|
||||
gtk_toggle_button_set_active (self->light_toggle, FALSE);
|
||||
gtk_toggle_button_set_active (self->dark_toggle, FALSE);
|
||||
}
|
||||
}
|
||||
@@ -148,9 +149,9 @@ set_color_scheme (CcBackgroundPanel *self,
|
||||
/* Color schemes */
|
||||
|
||||
static void
|
||||
on_color_scheme_toggle_active_cb (CcBackgroundPanel *self)
|
||||
on_light_dark_toggle_active_cb (CcBackgroundPanel *self)
|
||||
{
|
||||
if (gtk_toggle_button_get_active (self->default_toggle))
|
||||
if (gtk_toggle_button_get_active (self->light_toggle))
|
||||
set_color_scheme (self, G_DESKTOP_COLOR_SCHEME_DEFAULT);
|
||||
else if (gtk_toggle_button_get_active (self->dark_toggle))
|
||||
set_color_scheme (self, G_DESKTOP_COLOR_SCHEME_PREFER_DARK);
|
||||
@@ -181,7 +182,7 @@ update_preview (CcBackgroundPanel *panel)
|
||||
CcBackgroundItem *current_background;
|
||||
|
||||
current_background = panel->current_background;
|
||||
cc_background_preview_set_item (panel->default_preview, current_background);
|
||||
cc_background_preview_set_item (panel->light_preview, current_background);
|
||||
cc_background_preview_set_item (panel->dark_preview, current_background);
|
||||
}
|
||||
|
||||
@@ -268,54 +269,6 @@ create_save_dir (void)
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
reset_settings_if_defaults (CcBackgroundPanel *panel,
|
||||
GSettings *settings,
|
||||
gboolean check_dark)
|
||||
{
|
||||
gsize i;
|
||||
const char *keys[] = {
|
||||
WP_URI_KEY, /* this key needs to be first */
|
||||
WP_URI_DARK_KEY,
|
||||
WP_OPTIONS_KEY,
|
||||
WP_SHADING_KEY,
|
||||
WP_PCOLOR_KEY,
|
||||
WP_SCOLOR_KEY,
|
||||
NULL
|
||||
};
|
||||
|
||||
for (i = 0; keys[i] != NULL; i++)
|
||||
{
|
||||
g_autoptr (GVariant) default_value = NULL;
|
||||
g_autoptr (GVariant) user_value = NULL;
|
||||
gboolean setting_is_default;
|
||||
|
||||
if (!check_dark && g_str_equal (keys[i], WP_URI_DARK_KEY))
|
||||
continue;
|
||||
|
||||
default_value = g_settings_get_default_value (settings, keys[i]);
|
||||
user_value = g_settings_get_value (settings, keys[i]);
|
||||
|
||||
setting_is_default = g_variant_equal (default_value, user_value);
|
||||
|
||||
/* As a courtesy to distros that are a little lackadaisical about making sure
|
||||
* schema defaults match the settings in the background item with the default
|
||||
* picture, we only look at the URI to determine if we shouldn't clean out dconf.
|
||||
*
|
||||
* In otherwords, we still clean out the picture-uri key from dconf when a user
|
||||
* selects the default background in control-center, even if after selecting it
|
||||
* e.g., primary-color still mismatches with schema defaults.
|
||||
*/
|
||||
if (g_str_equal (keys[i], WP_URI_KEY) && !setting_is_default)
|
||||
return;
|
||||
|
||||
if (setting_is_default)
|
||||
g_settings_reset (settings, keys[i]);
|
||||
}
|
||||
|
||||
g_settings_apply (settings);
|
||||
}
|
||||
|
||||
static void
|
||||
set_background (CcBackgroundPanel *panel,
|
||||
GSettings *settings,
|
||||
@@ -368,9 +321,6 @@ set_background (CcBackgroundPanel *panel,
|
||||
/* Apply all changes */
|
||||
g_settings_apply (settings);
|
||||
|
||||
/* Clean out dconf if the user went back to distro defaults */
|
||||
reset_settings_if_defaults (panel, settings, set_dark);
|
||||
|
||||
/* Save the source XML if there is one */
|
||||
filename = get_save_path ();
|
||||
if (create_save_dir ())
|
||||
@@ -405,6 +355,7 @@ cc_background_panel_dispose (GObject *object)
|
||||
g_clear_object (&panel->settings);
|
||||
g_clear_object (&panel->lock_settings);
|
||||
g_clear_object (&panel->interface_settings);
|
||||
g_clear_object (&panel->thumb_factory);
|
||||
g_clear_object (&panel->proxy);
|
||||
|
||||
G_OBJECT_CLASS (cc_background_panel_parent_class)->dispose (object);
|
||||
@@ -438,12 +389,12 @@ cc_background_panel_class_init (CcBackgroundPanelClass *klass)
|
||||
gtk_widget_class_set_template_from_resource (widget_class, "/org/gnome/control-center/background/cc-background-panel.ui");
|
||||
|
||||
gtk_widget_class_bind_template_child (widget_class, CcBackgroundPanel, background_chooser);
|
||||
gtk_widget_class_bind_template_child (widget_class, CcBackgroundPanel, default_preview);
|
||||
gtk_widget_class_bind_template_child (widget_class, CcBackgroundPanel, light_preview);
|
||||
gtk_widget_class_bind_template_child (widget_class, CcBackgroundPanel, dark_preview);
|
||||
gtk_widget_class_bind_template_child (widget_class, CcBackgroundPanel, default_toggle);
|
||||
gtk_widget_class_bind_template_child (widget_class, CcBackgroundPanel, light_toggle);
|
||||
gtk_widget_class_bind_template_child (widget_class, CcBackgroundPanel, dark_toggle);
|
||||
|
||||
gtk_widget_class_bind_template_callback (widget_class, on_color_scheme_toggle_active_cb);
|
||||
gtk_widget_class_bind_template_callback (widget_class, on_light_dark_toggle_active_cb);
|
||||
gtk_widget_class_bind_template_callback (widget_class, on_chooser_background_chosen_cb);
|
||||
gtk_widget_class_bind_template_callback (widget_class, on_add_picture_button_clicked_cb);
|
||||
}
|
||||
@@ -464,6 +415,8 @@ cc_background_panel_init (CcBackgroundPanel *panel)
|
||||
|
||||
panel->connection = g_application_get_dbus_connection (g_application_get_default ());
|
||||
|
||||
panel->thumb_factory = gnome_desktop_thumbnail_factory_new (GNOME_DESKTOP_THUMBNAIL_SIZE_LARGE);
|
||||
|
||||
panel->settings = g_settings_new (WP_PATH_ID);
|
||||
g_settings_delay (panel->settings);
|
||||
|
||||
@@ -480,11 +433,11 @@ cc_background_panel_init (CcBackgroundPanel *panel)
|
||||
g_signal_connect_object (panel->settings, "changed", G_CALLBACK (on_settings_changed), panel, G_CONNECT_SWAPPED);
|
||||
|
||||
/* Interface settings */
|
||||
reload_color_scheme_toggles (panel);
|
||||
reload_light_dark_toggles (panel);
|
||||
|
||||
g_signal_connect_object (panel->interface_settings,
|
||||
"changed::" INTERFACE_COLOR_SCHEME_KEY,
|
||||
G_CALLBACK (reload_color_scheme_toggles),
|
||||
G_CALLBACK (reload_light_dark_toggles),
|
||||
panel,
|
||||
G_CONNECT_SWAPPED);
|
||||
|
||||
|
||||
@@ -27,13 +27,13 @@
|
||||
<property name="margin-bottom">12</property>
|
||||
<property name="hexpand">True</property>
|
||||
<child>
|
||||
<object class="GtkToggleButton" id="default_toggle">
|
||||
<object class="GtkToggleButton" id="light_toggle">
|
||||
<accessibility>
|
||||
<relation name="labelled-by">default_label</relation>
|
||||
<relation name="labelled-by">light_label</relation>
|
||||
</accessibility>
|
||||
<signal name="notify::active" handler="on_color_scheme_toggle_active_cb" swapped="true"/>
|
||||
<signal name="notify::active" handler="on_light_dark_toggle_active_cb" swapped="true"/>
|
||||
<child>
|
||||
<object class="CcBackgroundPreview" id="default_preview"/>
|
||||
<object class="CcBackgroundPreview" id="light_preview"/>
|
||||
</child>
|
||||
<style>
|
||||
<class name="background-preview-button"/>
|
||||
@@ -45,8 +45,8 @@
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel" id="default_label">
|
||||
<property name="label" translatable="yes">Default</property>
|
||||
<object class="GtkLabel" id="light_label">
|
||||
<property name="label" translatable="yes">Light</property>
|
||||
<layout>
|
||||
<property name="column">0</property>
|
||||
<property name="row">1</property>
|
||||
@@ -55,11 +55,11 @@
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkToggleButton" id="dark_toggle">
|
||||
<property name="group">default_toggle</property>
|
||||
<property name="group">light_toggle</property>
|
||||
<accessibility>
|
||||
<relation name="labelled-by">dark_label</relation>
|
||||
</accessibility>
|
||||
<signal name="notify::active" handler="on_color_scheme_toggle_active_cb" swapped="true"/>
|
||||
<signal name="notify::active" handler="on_light_dark_toggle_active_cb" swapped="true"/>
|
||||
<child>
|
||||
<object class="CcBackgroundPreview" id="dark_preview">
|
||||
<property name="is-dark">True</property>
|
||||
|
||||
@@ -11,4 +11,4 @@ StartupNotify=true
|
||||
Categories=GNOME;GTK;Settings;DesktopSettings;X-GNOME-Settings-Panel;X-GNOME-PersonalizationSettings;
|
||||
OnlyShowIn=GNOME;
|
||||
# Translators: Search terms to find the Appearance panel. Do NOT translate or localize the semicolons! The list MUST also end with a semicolon!
|
||||
Keywords=Background;Wallpaper;Screen;Desktop;Style;Light;Dark;Appearance;
|
||||
Keywords=Background;Wallpaper;Screen;Desktop;Style;Light;Dark;
|
||||
@@ -1,9 +1,15 @@
|
||||
panels_list += cappletname
|
||||
desktop = 'gnome-@0@-panel.desktop'.format(cappletname)
|
||||
|
||||
desktop_in = configure_file(
|
||||
input: desktop + '.in.in',
|
||||
output: desktop + '.in',
|
||||
configuration: desktop_conf
|
||||
)
|
||||
|
||||
i18n.merge_file(
|
||||
type: 'desktop',
|
||||
input: desktop + '.in',
|
||||
input: desktop_in,
|
||||
output: desktop,
|
||||
po_dir: po_dir,
|
||||
install: true,
|
||||
|
||||
@@ -12,6 +12,7 @@ background-preview .window {
|
||||
|
||||
background-preview .window .header-bar {
|
||||
min-height: 15px;
|
||||
box-shadow: inset 0 -1px @borders;
|
||||
}
|
||||
|
||||
background-preview .window.light {
|
||||
@@ -19,10 +20,6 @@ background-preview .window.light {
|
||||
color: alpha(black, .8);
|
||||
}
|
||||
|
||||
background-preview .window.light .header-bar {
|
||||
box-shadow: inset 0 -1px alpha(black, .07);
|
||||
}
|
||||
|
||||
background-preview .window.front.light .header-bar {
|
||||
background-color: #ebebeb;
|
||||
}
|
||||
@@ -32,10 +29,6 @@ background-preview .window.dark {
|
||||
color: white;
|
||||
}
|
||||
|
||||
background-preview .window.dark .header-bar {
|
||||
box-shadow: inset 0 -1px alpha(black, .36);
|
||||
}
|
||||
|
||||
background-preview .window.front.dark .header-bar {
|
||||
background-color: #303030;
|
||||
}
|
||||
|
||||
@@ -117,8 +117,8 @@ class GccDBusTestCase(DBusTestCase):
|
||||
adapter.UpdateProperties('org.bluez.Adapter1',
|
||||
{'Powered': dbus.Boolean(self.hci0_powered, variant_level=1)})
|
||||
self.devices = []
|
||||
self.add_device('hci0', '22:33:44:55:66:77', "Bastienʼs mouse", True, 0x580, 'input-mouse')
|
||||
self.add_device('hci0', '22:33:44:55:66:78', 'Bloutouf keyboard & keys', True, 0x540, 'input-keyboard')
|
||||
self.add_device('hci0', '22:33:44:55:66:77', "Bastien's mouse", True, 0x580, 'input-mouse')
|
||||
self.add_device('hci0', '22:33:44:55:66:78', 'Bloutouf keyboard', True, 0x540, 'input-keyboard')
|
||||
self.add_device('hci0', '60:8B:0E:55:66:79', 'iPhoone 19S', True, 0x20C, 'phone')
|
||||
# Uncategorised audio device
|
||||
self.add_device('hci0', '22:33:44:55:66:79', 'MEGA Speakers', True, 0x200400, 'audio-card')
|
||||
|
||||
@@ -80,29 +80,25 @@ airplane_mode_changed_cb (GObject *source_object,
|
||||
{
|
||||
g_autoptr(GVariant) ret = NULL;
|
||||
g_autoptr(GError) error = NULL;
|
||||
gboolean state = GPOINTER_TO_UINT (user_data);
|
||||
|
||||
if (!g_dbus_proxy_call_finish (G_DBUS_PROXY (source_object),
|
||||
res, &error)) {
|
||||
if (!g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) {
|
||||
CcBluetoothPanel *self = CC_BLUETOOTH_PANEL (user_data);
|
||||
gboolean state = gtk_switch_get_active (self->enable_switch);
|
||||
if (!g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED))
|
||||
g_warning ("Failed to change Bluetooth killswitch state to %s: %s",
|
||||
state ? "on" : "off", error->message);
|
||||
}
|
||||
} else {
|
||||
CcBluetoothPanel *self = CC_BLUETOOTH_PANEL (user_data);
|
||||
gboolean state = gtk_switch_get_active (self->enable_switch);
|
||||
CcBluetoothPanel *self = user_data;
|
||||
|
||||
g_debug ("Changed Bluetooth killswitch state to %s",
|
||||
state ? "on" : "off");
|
||||
|
||||
gtk_switch_set_state (self->enable_switch, state);
|
||||
if (!bluetooth_settings_widget_get_default_adapter_powered (self->settings_widget))
|
||||
bluetooth_settings_widget_set_default_adapter_powered(self->settings_widget, TRUE);
|
||||
}
|
||||
}
|
||||
|
||||
static gboolean
|
||||
static void
|
||||
enable_switch_state_set_cb (CcBluetoothPanel *self, gboolean state)
|
||||
{
|
||||
g_debug ("Power switched to %s", state ? "on" : "off");
|
||||
@@ -114,8 +110,6 @@ enable_switch_state_set_cb (CcBluetoothPanel *self, gboolean state)
|
||||
-1,
|
||||
cc_panel_get_cancellable (CC_PANEL (self)),
|
||||
airplane_mode_changed_cb, self);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -162,7 +156,7 @@ adapter_status_changed_cb (CcBluetoothPanel *self)
|
||||
gtk_widget_set_valign (GTK_WIDGET (self->stack), valign);
|
||||
gtk_widget_set_sensitive (GTK_WIDGET (self->header_box), sensitive);
|
||||
g_signal_handlers_block_by_func (self->enable_switch, enable_switch_state_set_cb, self);
|
||||
gtk_switch_set_active (self->enable_switch, powered);
|
||||
gtk_switch_set_state (self->enable_switch, powered);
|
||||
g_signal_handlers_unblock_by_func (self->enable_switch, enable_switch_state_set_cb, self);
|
||||
|
||||
gtk_stack_set_visible_child (self->stack, page);
|
||||
|
||||
@@ -29,14 +29,14 @@
|
||||
<object class="AdwStatusPage" id="disabled_page">
|
||||
<property name="icon-name">bluetooth-active-symbolic</property>
|
||||
<property name="title" translatable="yes">Bluetooth Turned Off</property>
|
||||
<property name="description" translatable="yes">Turn on to connect devices and receive file transfers</property>
|
||||
<property name="description" translatable="yes">Turn on to connect devices and receive file transfers.</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="AdwStatusPage" id="airplane_page">
|
||||
<property name="icon-name">airplane-mode-symbolic</property>
|
||||
<property name="title" translatable="yes">Airplane Mode is On</property>
|
||||
<property name="description" translatable="yes">Bluetooth is disabled when airplane mode is on</property>
|
||||
<property name="description" translatable="yes">Bluetooth is disabled when airplane mode is on.</property>
|
||||
<property name="child">
|
||||
<object class="GtkButton">
|
||||
<property name="label" translatable="yes">Turn Off Airplane Mode</property>
|
||||
@@ -45,7 +45,6 @@
|
||||
<signal name="clicked" handler="airplane_mode_off_button_clicked_cb" object="CcBluetoothPanel" swapped="yes"/>
|
||||
<style>
|
||||
<class name="pill"/>
|
||||
<class name="suggested-action"/>
|
||||
</style>
|
||||
</object>
|
||||
</property>
|
||||
|
||||
@@ -10,5 +10,9 @@ NoDisplay=true
|
||||
Categories=GTK;GNOME;Settings;X-GNOME-NetworkSettings;HardwareSettings;X-GNOME-Settings-Panel;X-GNOME-ConnectivitySettings;
|
||||
OnlyShowIn=GNOME;Unity;
|
||||
StartupNotify=true
|
||||
X-GNOME-Bugzilla-Bugzilla=GNOME
|
||||
X-GNOME-Bugzilla-Product=gnome-bluetooth
|
||||
X-GNOME-Bugzilla-Component=properties
|
||||
X-GNOME-Bugzilla-Version=@VERSION@
|
||||
# Translators: Search terms to find the Bluetooth panel. Do NOT translate or localize the semicolons! The list MUST also end with a semicolon!
|
||||
Keywords=share;sharing;bluetooth;obex;
|
||||
@@ -1,9 +1,15 @@
|
||||
panels_list += cappletname
|
||||
desktop = 'gnome-@0@-panel.desktop'.format(cappletname)
|
||||
|
||||
desktop_in = configure_file(
|
||||
input: desktop + '.in.in',
|
||||
output: desktop + '.in',
|
||||
configuration: desktop_conf
|
||||
)
|
||||
|
||||
i18n.merge_file(
|
||||
type: 'desktop',
|
||||
input: desktop + '.in',
|
||||
input: desktop_in,
|
||||
output: desktop,
|
||||
po_dir: po_dir,
|
||||
install: true,
|
||||
|
||||
@@ -20,7 +20,6 @@
|
||||
|
||||
#include "cc-camera-panel.h"
|
||||
#include "cc-camera-resources.h"
|
||||
#include "cc-list-row.h"
|
||||
#include "cc-util.h"
|
||||
|
||||
#include <adwaita.h>
|
||||
@@ -34,8 +33,9 @@ struct _CcCameraPanel
|
||||
{
|
||||
CcPanel parent_instance;
|
||||
|
||||
GtkStack *stack;
|
||||
GtkListBox *camera_apps_list_box;
|
||||
CcListRow *camera_row;
|
||||
GtkSwitch *main_switch;
|
||||
|
||||
GSettings *privacy_settings;
|
||||
|
||||
@@ -101,17 +101,14 @@ on_camera_app_state_set (GtkSwitch *widget,
|
||||
GVariant *params;
|
||||
const gchar *key;
|
||||
gchar **value;
|
||||
gboolean active_camera;
|
||||
|
||||
self = data->self;
|
||||
|
||||
if (data->changing_state)
|
||||
return TRUE;
|
||||
|
||||
active_camera = !g_settings_get_boolean (self->privacy_settings,
|
||||
"disable-camera");
|
||||
data->changing_state = TRUE;
|
||||
data->pending_state = active_camera && state;
|
||||
data->pending_state = state;
|
||||
|
||||
g_variant_iter_init (&iter, self->camera_apps_perms);
|
||||
g_variant_builder_init (&builder, G_VARIANT_TYPE_ARRAY);
|
||||
@@ -154,25 +151,6 @@ on_camera_app_state_set (GtkSwitch *widget,
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
update_app_switch_state (GValue *value,
|
||||
GVariant *variant,
|
||||
gpointer data)
|
||||
{
|
||||
GtkSwitch *w = GTK_SWITCH (data);
|
||||
gboolean active_camera;
|
||||
gboolean active_app;
|
||||
gboolean state;
|
||||
|
||||
active_camera = !g_variant_get_boolean (variant);
|
||||
active_app = gtk_switch_get_active (w);
|
||||
state = active_camera && active_app;
|
||||
|
||||
g_value_set_boolean (value, state);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
add_camera_app (CcCameraPanel *self,
|
||||
const gchar *app_id,
|
||||
@@ -212,17 +190,11 @@ add_camera_app (CcCameraPanel *self,
|
||||
gtk_switch_set_active (GTK_SWITCH (w), enabled);
|
||||
gtk_widget_set_valign (w, GTK_ALIGN_CENTER);
|
||||
adw_action_row_add_suffix (ADW_ACTION_ROW (row), w);
|
||||
|
||||
g_settings_bind_with_mapping (self->privacy_settings,
|
||||
"disable-camera",
|
||||
w,
|
||||
"state",
|
||||
G_SETTINGS_BIND_GET,
|
||||
update_app_switch_state,
|
||||
NULL,
|
||||
g_object_ref (w),
|
||||
g_object_unref);
|
||||
|
||||
g_settings_bind (self->privacy_settings,
|
||||
"disable-camera",
|
||||
w,
|
||||
"sensitive",
|
||||
G_SETTINGS_BIND_INVERT_BOOLEAN);
|
||||
g_hash_table_insert (self->camera_app_switches,
|
||||
g_strdup (app_id),
|
||||
g_object_ref (w));
|
||||
@@ -241,6 +213,20 @@ add_camera_app (CcCameraPanel *self,
|
||||
}
|
||||
|
||||
/* Steals permissions and permissions_data references */
|
||||
|
||||
static gboolean
|
||||
to_child_name (GBinding *binding,
|
||||
const GValue *from,
|
||||
GValue *to,
|
||||
gpointer user_data)
|
||||
{
|
||||
if (g_value_get_boolean (from))
|
||||
g_value_set_string (to, "content");
|
||||
else
|
||||
g_value_set_string (to, "empty");
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
update_perm_store (CcCameraPanel *self,
|
||||
GVariant *permissions,
|
||||
@@ -386,8 +372,9 @@ cc_camera_panel_class_init (CcCameraPanelClass *klass)
|
||||
|
||||
gtk_widget_class_set_template_from_resource (widget_class, "/org/gnome/control-center/camera/cc-camera-panel.ui");
|
||||
|
||||
gtk_widget_class_bind_template_child (widget_class, CcCameraPanel, stack);
|
||||
gtk_widget_class_bind_template_child (widget_class, CcCameraPanel, camera_apps_list_box);
|
||||
gtk_widget_class_bind_template_child (widget_class, CcCameraPanel, camera_row);
|
||||
gtk_widget_class_bind_template_child (widget_class, CcCameraPanel, main_switch);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -402,9 +389,16 @@ cc_camera_panel_init (CcCameraPanel *self)
|
||||
self->privacy_settings = g_settings_new ("org.gnome.desktop.privacy");
|
||||
|
||||
g_settings_bind (self->privacy_settings, "disable-camera",
|
||||
self->camera_row, "active",
|
||||
self->main_switch, "active",
|
||||
G_SETTINGS_BIND_INVERT_BOOLEAN);
|
||||
|
||||
g_object_bind_property_full (self->main_switch, "active",
|
||||
self->stack, "visible-child-name",
|
||||
G_BINDING_SYNC_CREATE,
|
||||
to_child_name,
|
||||
NULL,
|
||||
NULL, NULL);
|
||||
|
||||
self->camera_app_switches = g_hash_table_new_full (g_str_hash,
|
||||
g_str_equal,
|
||||
g_free,
|
||||
|
||||
@@ -2,50 +2,73 @@
|
||||
<interface>
|
||||
<template class="CcCameraPanel" parent="CcPanel">
|
||||
|
||||
<child type="titlebar-end">
|
||||
<object class="GtkSwitch" id="main_switch">
|
||||
<accessibility>
|
||||
<property name="label" translatable="yes">Enable</property>
|
||||
</accessibility>
|
||||
<property name="valign">center</property>
|
||||
</object>
|
||||
</child>
|
||||
|
||||
<child type="content">
|
||||
<object class="AdwPreferencesPage">
|
||||
<object class="GtkStack" id="stack">
|
||||
|
||||
<!-- Empty page -->
|
||||
<child>
|
||||
<object class="AdwPreferencesGroup">
|
||||
<child>
|
||||
<object class="CcListRow" id="camera_row">
|
||||
<property name="title" translatable="yes">_Camera Access</property>
|
||||
<property name="subtitle" translatable="yes">Allow permitted apps to use cameras</property>
|
||||
<property name="use-underline">True</property>
|
||||
<property name="show-switch">True</property>
|
||||
<object class="GtkStackPage">
|
||||
<property name="name">empty</property>
|
||||
<property name="child">
|
||||
<object class="AdwStatusPage">
|
||||
<property name="icon-name">camera-disabled-symbolic</property>
|
||||
<property name="title" translatable="yes">Camera is Turned Off</property>
|
||||
<property name="description" translatable="yes">No applications can capture photos or video.</property>
|
||||
</object>
|
||||
</child>
|
||||
</property>
|
||||
</object>
|
||||
</child>
|
||||
|
||||
<!-- Cameras -->
|
||||
<child>
|
||||
<object class="AdwPreferencesGroup">
|
||||
<property name="title" translatable="yes">Permitted Apps</property>
|
||||
<property name="description" translatable="yes">The following sandboxed apps have been given permission to use cameras. Apps that are not sandboxed can use cameras without asking for permission.</property>
|
||||
<child>
|
||||
<object class="GtkListBox" id="camera_apps_list_box">
|
||||
<property name="selection-mode">none</property>
|
||||
<style>
|
||||
<class name="boxed-list"/>
|
||||
</style>
|
||||
<object class="GtkStackPage">
|
||||
<property name="name">content</property>
|
||||
<property name="child">
|
||||
<object class="AdwPreferencesPage">
|
||||
<child>
|
||||
<object class="AdwPreferencesGroup">
|
||||
<property name="description" translatable="yes">Use of the camera allows applications to capture photos and video. Disabling the camera may cause some applications to not function properly.
|
||||
|
||||
<child type="placeholder">
|
||||
<object class="GtkLabel">
|
||||
<property name="margin-start">18</property>
|
||||
<property name="margin-end">18</property>
|
||||
<property name="margin-top">18</property>
|
||||
<property name="margin-bottom">18</property>
|
||||
<property name="label" translatable="yes">No sandboxed apps have asked for camera access</property>
|
||||
<property name="wrap">true</property>
|
||||
<property name="max-width-chars">50</property>
|
||||
<style>
|
||||
<class name="dim-label" />
|
||||
</style>
|
||||
Allow the applications below to use your camera.</property>
|
||||
<child>
|
||||
<object class="GtkListBox" id="camera_apps_list_box">
|
||||
<property name="selection-mode">none</property>
|
||||
<style>
|
||||
<class name="boxed-list"/>
|
||||
</style>
|
||||
|
||||
<child type="placeholder">
|
||||
<object class="GtkLabel">
|
||||
<property name="margin-start">18</property>
|
||||
<property name="margin-end">18</property>
|
||||
<property name="margin-top">18</property>
|
||||
<property name="margin-bottom">18</property>
|
||||
<property name="label" translatable="yes">No Applications Have Asked for Camera Access</property>
|
||||
<property name="wrap">true</property>
|
||||
<property name="max-width-chars">50</property>
|
||||
<style>
|
||||
<class name="dim-label" />
|
||||
</style>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</property>
|
||||
</object>
|
||||
</child>
|
||||
|
||||
</object>
|
||||
</child>
|
||||
</template>
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
[Desktop Entry]
|
||||
Name=Cameras
|
||||
Comment=Restrict camera access
|
||||
Name=Camera
|
||||
Comment=Protect your pictures
|
||||
Exec=gnome-control-center camera
|
||||
# FIXME
|
||||
# Translators: Do NOT translate or transliterate this text (this is an icon file name)!
|
||||
@@ -11,5 +11,9 @@ NoDisplay=true
|
||||
StartupNotify=true
|
||||
Categories=GNOME;GTK;Settings;DesktopSettings;X-GNOME-Settings-Panel;X-GNOME-PrivacySettings;
|
||||
OnlyShowIn=GNOME;Unity;
|
||||
# Translators: Search terms to find the Cameras panel. Do NOT translate or localize the semicolons! The list MUST also end with a semicolon!
|
||||
Keywords=camera;photos;video;webcam;lock;private;privacy;
|
||||
X-GNOME-Bugzilla-Bugzilla=GNOME
|
||||
X-GNOME-Bugzilla-Product=gnome-control-center
|
||||
X-GNOME-Bugzilla-Component=privacy
|
||||
X-GNOME-Bugzilla-Version=@VERSION@
|
||||
# Translators: Search terms to find the Privacy panel. Do NOT translate or localize the semicolons! The list MUST also end with a semicolon!
|
||||
Keywords=screen;lock;diagnostics;crash;private;recent;temporary;tmp;index;name;network;identity;
|
||||
@@ -1,9 +1,15 @@
|
||||
panels_list += cappletname
|
||||
desktop = 'gnome-@0@-panel.desktop'.format(cappletname)
|
||||
|
||||
desktop_in = configure_file(
|
||||
input: desktop + '.in.in',
|
||||
output: desktop + '.in',
|
||||
configuration: desktop_conf
|
||||
)
|
||||
|
||||
i18n.merge_file(
|
||||
type: 'desktop',
|
||||
input: desktop + '.in',
|
||||
input: desktop_in,
|
||||
output: desktop,
|
||||
po_dir: po_dir,
|
||||
install: true,
|
||||
|
||||
@@ -603,6 +603,96 @@ cc_color_calibrate_cancel (CcColorCalibrate *calibrate)
|
||||
g_main_loop_quit (calibrate->loop);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
cc_color_calibrate_move_and_resize_window (GtkWindow *window,
|
||||
CdDevice *device,
|
||||
GError **error)
|
||||
{
|
||||
g_autoptr(GListModel) monitors = NULL;
|
||||
g_autoptr(GdkMonitor) monitor = NULL;
|
||||
const gchar *xrandr_name;
|
||||
gboolean ret = TRUE;
|
||||
GdkRectangle rect;
|
||||
GdkDisplay *display;
|
||||
gint i;
|
||||
gint monitor_num = -1;
|
||||
gint num_monitors;
|
||||
|
||||
/* find the monitor num of the device output */
|
||||
display = gdk_display_get_default ();
|
||||
monitors = gdk_display_get_monitors (display);
|
||||
num_monitors = g_list_model_get_n_items (monitors);
|
||||
xrandr_name = cd_device_get_metadata_item (device, CD_DEVICE_METADATA_XRANDR_NAME);
|
||||
for (i = 0; i < num_monitors; i++)
|
||||
{
|
||||
g_autoptr(GdkMonitor) m = NULL;
|
||||
const gchar *plug_name;
|
||||
|
||||
m = g_list_model_get_item (monitors, i);
|
||||
plug_name = gdk_monitor_get_model (m);
|
||||
|
||||
if (g_strcmp0 (plug_name, xrandr_name) == 0)
|
||||
monitor_num = i;
|
||||
}
|
||||
if (monitor_num == -1)
|
||||
{
|
||||
ret = FALSE;
|
||||
g_set_error (error,
|
||||
CD_SESSION_ERROR,
|
||||
CD_SESSION_ERROR_INTERNAL,
|
||||
"failed to find output %s",
|
||||
xrandr_name);
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* move the window, and set it to the right size */
|
||||
monitor = g_list_model_get_item (monitors, monitor_num);
|
||||
gdk_monitor_get_geometry (monitor, &rect);
|
||||
g_debug ("Setting window to %ix%i with size %ix%i",
|
||||
rect.x, rect.y, rect.width, rect.height);
|
||||
out:
|
||||
return ret;
|
||||
}
|
||||
#if 0
|
||||
static void
|
||||
cc_color_calibrate_window_realize_cb (CcColorCalibrate *self)
|
||||
{
|
||||
GtkWidget *widget;
|
||||
|
||||
widget = GTK_WIDGET (gtk_builder_get_object (self->builder,
|
||||
"dialog_calibrate"));
|
||||
gtk_window_fullscreen (GTK_WINDOW (widget));
|
||||
gtk_window_maximize (GTK_WINDOW (widget));
|
||||
}
|
||||
|
||||
static gboolean
|
||||
cc_color_calibrate_window_state_cb (CcColorCalibrate *calibrate,
|
||||
GdkEvent *event)
|
||||
{
|
||||
gboolean ret;
|
||||
g_autoptr(GError) error = NULL;
|
||||
GdkEventWindowState *event_state = (GdkEventWindowState *) event;
|
||||
GtkWindow *window;
|
||||
|
||||
window = GTK_WINDOW (gtk_builder_get_object (calibrate->builder,
|
||||
"dialog_calibrate"));
|
||||
|
||||
/* check event */
|
||||
if (event->type != GDK_WINDOW_STATE)
|
||||
return TRUE;
|
||||
if (event_state->changed_mask != GDK_WINDOW_STATE_FULLSCREEN)
|
||||
return TRUE;
|
||||
|
||||
/* resize to the correct screen */
|
||||
ret = cc_color_calibrate_move_and_resize_window (window,
|
||||
calibrate->device,
|
||||
&error);
|
||||
if (!ret)
|
||||
g_warning ("Failed to resize window: %s", error->message);
|
||||
return TRUE;
|
||||
}
|
||||
#endif
|
||||
|
||||
static void
|
||||
cc_color_calibrate_button_done_cb (CcColorCalibrate *calibrate)
|
||||
{
|
||||
@@ -899,6 +989,14 @@ cc_color_calibrate_start (CcColorCalibrate *calibrate,
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
cc_color_calibrate_delete_event_cb (CcColorCalibrate *calibrate)
|
||||
{
|
||||
/* do not destroy the window */
|
||||
cc_color_calibrate_cancel (calibrate);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
cc_color_calibrate_finalize (GObject *object)
|
||||
{
|
||||
@@ -981,6 +1079,19 @@ cc_color_calibrate_init (CcColorCalibrate *calibrate)
|
||||
/* setup the specialist calibration window */
|
||||
window = GTK_WINDOW (gtk_builder_get_object (calibrate->builder,
|
||||
"dialog_calibrate"));
|
||||
/*
|
||||
g_signal_connect_object (window, "draw",
|
||||
G_CALLBACK (cc_color_calibrate_alpha_window_draw), calibrate, G_CONNECT_SWAPPED);
|
||||
g_signal_connect_object (window, "realize",
|
||||
G_CALLBACK (cc_color_calibrate_window_realize_cb), calibrate, G_CONNECT_SWAPPED);
|
||||
g_signal_connect_object (window, "window-state-event",
|
||||
G_CALLBACK (cc_color_calibrate_window_state_cb), calibrate, G_CONNECT_SWAPPED);
|
||||
g_signal_connect_object (window, "delete-event",
|
||||
G_CALLBACK (cc_color_calibrate_delete_event_cb), calibrate, G_CONNECT_SWAPPED);
|
||||
cc_color_calibrate_alpha_screen_changed_cb (calibrate);
|
||||
g_signal_connect_object (window, "screen-changed",
|
||||
G_CALLBACK (cc_color_calibrate_alpha_screen_changed_cb), calibrate, G_CONNECT_SWAPPED);
|
||||
*/
|
||||
calibrate->window = window;
|
||||
}
|
||||
|
||||
|
||||
@@ -253,6 +253,7 @@ cc_color_device_clicked_expander_cb (CcColorDevice *color_device)
|
||||
static void
|
||||
cc_color_device_init (CcColorDevice *color_device)
|
||||
{
|
||||
GtkStyleContext *context;
|
||||
GtkWidget *box;
|
||||
|
||||
/* description */
|
||||
@@ -289,7 +290,8 @@ cc_color_device_init (CcColorDevice *color_device)
|
||||
|
||||
/* not calibrated */
|
||||
color_device->widget_nocalib = gtk_label_new (_("Not calibrated"));
|
||||
gtk_widget_add_css_class (color_device->widget_nocalib, "dim-label");
|
||||
context = gtk_widget_get_style_context (color_device->widget_nocalib);
|
||||
gtk_style_context_add_class (context, "dim-label");
|
||||
gtk_widget_set_margin_end (color_device->widget_nocalib, 18);
|
||||
gtk_box_append (GTK_BOX (box), color_device->widget_nocalib);
|
||||
|
||||
|
||||
@@ -1705,8 +1705,7 @@ static void
|
||||
gcm_prefs_list_box_row_selected_cb (CcColorPanel *panel,
|
||||
GtkListBoxRow *row)
|
||||
{
|
||||
if (!panel->toolbar_devices ||
|
||||
gtk_widget_in_destruction (panel->toolbar_devices))
|
||||
if (gtk_widget_in_destruction (panel->toolbar_devices))
|
||||
return;
|
||||
|
||||
gcm_prefs_refresh_toolbar_buttons (panel);
|
||||
|
||||
@@ -10,6 +10,10 @@ NoDisplay=true
|
||||
StartupNotify=true
|
||||
Categories=GNOME;GTK;Settings;X-GNOME-Settings-Panel;HardwareSettings;X-GNOME-DevicesSettings;
|
||||
OnlyShowIn=GNOME;Unity;
|
||||
X-GNOME-Bugzilla-Bugzilla=GNOME
|
||||
X-GNOME-Bugzilla-Product=gnome-control-center
|
||||
X-GNOME-Bugzilla-Component=color
|
||||
X-GNOME-Bugzilla-Version=@VERSION@
|
||||
# Translators: Search terms to find the Color panel. Do NOT translate or localize the semicolons! The list MUST also end with a semicolon!
|
||||
Keywords=Color;ICC;Profile;Calibrate;Printer;Display;
|
||||
# Notifications are emitted by gnome-settings-daemon
|
||||
@@ -1,9 +1,15 @@
|
||||
panels_list += cappletname
|
||||
desktop = 'gnome-@0@-panel.desktop'.format(cappletname)
|
||||
|
||||
desktop_in = configure_file(
|
||||
input: desktop + '.in.in',
|
||||
output: desktop + '.in',
|
||||
configuration: desktop_conf
|
||||
)
|
||||
|
||||
i18n.merge_file(
|
||||
type: 'desktop',
|
||||
input: desktop + '.in',
|
||||
input: desktop_in,
|
||||
output: desktop,
|
||||
po_dir: po_dir,
|
||||
install: true,
|
||||
|
||||
@@ -27,13 +27,13 @@
|
||||
|
||||
struct _CcHostnameEntry
|
||||
{
|
||||
AdwEntryRow parent;
|
||||
GtkEntry parent;
|
||||
|
||||
GDBusProxy *hostnamed_proxy;
|
||||
guint set_hostname_timeout_source_id;
|
||||
};
|
||||
|
||||
G_DEFINE_TYPE (CcHostnameEntry, cc_hostname_entry, ADW_TYPE_ENTRY_ROW)
|
||||
G_DEFINE_TYPE (CcHostnameEntry, cc_hostname_entry, GTK_TYPE_ENTRY)
|
||||
|
||||
#define SET_HOSTNAME_TIMEOUT 1
|
||||
|
||||
@@ -234,9 +234,7 @@ cc_hostname_entry_constructed (GObject *object)
|
||||
else
|
||||
gtk_editable_set_text (GTK_EDITABLE (self), "");
|
||||
|
||||
g_signal_connect (self, "apply", G_CALLBACK (text_changed_cb), NULL);
|
||||
|
||||
adw_entry_row_set_show_apply_button (ADW_ENTRY_ROW (self), TRUE);
|
||||
g_signal_connect (self, "changed", G_CALLBACK (text_changed_cb), NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
|
||||
@@ -19,13 +19,13 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <adwaita.h>
|
||||
#include <gtk/gtk.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define CC_TYPE_HOSTNAME_ENTRY (cc_hostname_entry_get_type())
|
||||
|
||||
G_DECLARE_FINAL_TYPE (CcHostnameEntry, cc_hostname_entry, CC, HOSTNAME_ENTRY, AdwEntryRow)
|
||||
G_DECLARE_FINAL_TYPE (CcHostnameEntry, cc_hostname_entry, CC, HOSTNAME_ENTRY, GtkEntry)
|
||||
|
||||
CcHostnameEntry *cc_hostname_entry_new (void);
|
||||
gchar* cc_hostname_entry_get_hostname (CcHostnameEntry *entry);
|
||||
|
||||
@@ -1,153 +0,0 @@
|
||||
/* cc-illustrated-row.c
|
||||
*
|
||||
* Copyright 2018 Purism SPC
|
||||
* 2021 Georges Basile Stavracas Neto <georges.stavracas@gmail.com>
|
||||
* 2023 Red Hat, Inc
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-3.0-or-later
|
||||
*/
|
||||
|
||||
#include "cc-illustrated-row.h"
|
||||
|
||||
struct _CcIllustratedRow
|
||||
{
|
||||
CcVerticalRow parent;
|
||||
|
||||
GtkBox *picture_box;
|
||||
GtkPicture *picture;
|
||||
const gchar *resource_path;
|
||||
|
||||
GtkMediaStream *media_stream;
|
||||
};
|
||||
|
||||
G_DEFINE_FINAL_TYPE (CcIllustratedRow, cc_illustrated_row, CC_TYPE_VERTICAL_ROW);
|
||||
|
||||
enum
|
||||
{
|
||||
PROP_0,
|
||||
PROP_RESOURCE,
|
||||
N_PROPS,
|
||||
};
|
||||
|
||||
static GParamSpec *props[N_PROPS] = { NULL, };
|
||||
|
||||
static void
|
||||
on_picture_leave_cb (CcIllustratedRow *self)
|
||||
{
|
||||
GtkMediaStream *stream = GTK_MEDIA_STREAM (gtk_picture_get_paintable (self->picture));
|
||||
|
||||
gtk_media_stream_set_loop (stream, FALSE);
|
||||
gtk_media_stream_pause (stream);
|
||||
}
|
||||
|
||||
static void
|
||||
on_picture_hover_cb (CcIllustratedRow *self)
|
||||
{
|
||||
GtkMediaStream *stream = GTK_MEDIA_STREAM (gtk_picture_get_paintable (self->picture));
|
||||
|
||||
gtk_media_stream_set_loop (stream, TRUE);
|
||||
gtk_media_stream_play (stream);
|
||||
}
|
||||
|
||||
static void
|
||||
cc_illustrated_row_get_property (GObject *object,
|
||||
guint prop_id,
|
||||
GValue *value,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
CcIllustratedRow *self = CC_ILLUSTRATED_ROW (object);
|
||||
|
||||
switch (prop_id)
|
||||
{
|
||||
case PROP_RESOURCE:
|
||||
g_value_set_string (value, self->resource_path);
|
||||
break;
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
cc_illustrated_row_set_property (GObject *object,
|
||||
guint prop_id,
|
||||
const GValue *value,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
CcIllustratedRow *self = CC_ILLUSTRATED_ROW (object);
|
||||
|
||||
switch (prop_id)
|
||||
{
|
||||
case PROP_RESOURCE:
|
||||
cc_illustrated_row_set_resource (self, g_value_get_string (value));
|
||||
break;
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
cc_illustrated_row_class_init (CcIllustratedRowClass *klass)
|
||||
{
|
||||
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
||||
GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
|
||||
|
||||
object_class->get_property = cc_illustrated_row_get_property;
|
||||
object_class->set_property = cc_illustrated_row_set_property;
|
||||
|
||||
props[PROP_RESOURCE] =
|
||||
g_param_spec_string ("resource",
|
||||
"Resource",
|
||||
"Resource",
|
||||
"",
|
||||
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_EXPLICIT_NOTIFY);
|
||||
|
||||
g_object_class_install_properties (object_class, N_PROPS, props);
|
||||
|
||||
gtk_widget_class_set_template_from_resource (widget_class, "/org/gnome/control-center/common/cc-illustrated-row.ui");
|
||||
|
||||
gtk_widget_class_bind_template_child (widget_class, CcIllustratedRow, picture);
|
||||
gtk_widget_class_bind_template_child (widget_class, CcIllustratedRow, picture_box);
|
||||
|
||||
gtk_widget_class_bind_template_callback (widget_class, on_picture_hover_cb);
|
||||
gtk_widget_class_bind_template_callback (widget_class, on_picture_leave_cb);
|
||||
}
|
||||
|
||||
static void
|
||||
cc_illustrated_row_init (CcIllustratedRow *self)
|
||||
{
|
||||
gtk_widget_init_template (GTK_WIDGET (self));
|
||||
gtk_widget_set_name (GTK_WIDGET (self), "illustrated-row");
|
||||
gtk_widget_add_css_class (GTK_WIDGET (self), "illustrated-row");
|
||||
}
|
||||
|
||||
void
|
||||
cc_illustrated_row_set_resource (CcIllustratedRow *self,
|
||||
const gchar *resource_path)
|
||||
{
|
||||
g_return_if_fail (CC_IS_ILLUSTRATED_ROW (self));
|
||||
|
||||
if (self->media_stream != NULL)
|
||||
g_clear_object (&self->media_stream);
|
||||
|
||||
self->resource_path = resource_path;
|
||||
self->media_stream = gtk_media_file_new_for_resource (resource_path);
|
||||
|
||||
gtk_picture_set_paintable (self->picture, GDK_PAINTABLE (self->media_stream));
|
||||
gtk_widget_set_visible (GTK_WIDGET (self->picture_box),
|
||||
resource_path != NULL && g_strcmp0 (resource_path, "") != 0);
|
||||
|
||||
g_object_notify_by_pspec (G_OBJECT (self), props[PROP_RESOURCE]);
|
||||
}
|
||||
@@ -1,45 +0,0 @@
|
||||
/* cc-illustrated-row.h
|
||||
*
|
||||
* Copyright 2018 Purism SPC
|
||||
* 2021 Georges Basile Stavracas Neto <georges.stavracas@gmail.com>
|
||||
* 2023 Red Hat, Inc
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-3.0-or-later
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <adwaita.h>
|
||||
|
||||
#include "cc-vertical-row.h"
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define CC_TYPE_ILLUSTRATED_ROW (cc_illustrated_row_get_type())
|
||||
G_DECLARE_FINAL_TYPE (CcIllustratedRow, cc_illustrated_row, CC, ILLUSTRATED_ROW, CcVerticalRow)
|
||||
|
||||
struct _CcIllustratedRowClass
|
||||
{
|
||||
CcVerticalRowClass parent_class;
|
||||
|
||||
/*< private >*/
|
||||
gpointer padding[4];
|
||||
};
|
||||
|
||||
void cc_illustrated_row_set_resource (CcIllustratedRow *self,
|
||||
const gchar *resource_path);
|
||||
|
||||
G_END_DECLS
|
||||
@@ -1,34 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<interface>
|
||||
<template class="CcIllustratedRow" parent="CcVerticalRow">
|
||||
<child>
|
||||
<object class="GtkEventControllerMotion">
|
||||
<signal name="enter" handler="on_picture_hover_cb" object="CcIllustratedRow" swapped="yes"/>
|
||||
<signal name="leave" handler="on_picture_leave_cb" object="CcIllustratedRow" swapped="yes"/>
|
||||
</object>
|
||||
</child>
|
||||
<child type="content">
|
||||
<object class="GtkBox" id="picture_box">
|
||||
<property name="visible">False</property>
|
||||
<property name="hexpand">True</property>
|
||||
<property name="margin-top">12</property>
|
||||
<property name="margin-bottom">12</property>
|
||||
<style>
|
||||
<class name="frame" />
|
||||
<class name="background" />
|
||||
</style>
|
||||
<child>
|
||||
<object class="GtkPicture" id="picture">
|
||||
<property name="hexpand">True</property>
|
||||
<property name="halign">center</property>
|
||||
<property name="margin-top">18</property>
|
||||
<property name="margin-bottom">18</property>
|
||||
<property name="margin-start">18</property>
|
||||
<property name="margin-end">18</property>
|
||||
<property name="height-request">128</property>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</template>
|
||||
</interface>
|
||||
@@ -61,14 +61,6 @@ enum {
|
||||
|
||||
static GParamSpec *properties[N_PROPS];
|
||||
|
||||
static void
|
||||
update_checked_state (CcListRow *self)
|
||||
{
|
||||
gtk_accessible_update_state (GTK_ACCESSIBLE (self),
|
||||
GTK_ACCESSIBLE_STATE_CHECKED, self->switch_active,
|
||||
-1);
|
||||
}
|
||||
|
||||
static void
|
||||
cc_list_row_switch_active_cb (CcListRow *self)
|
||||
{
|
||||
@@ -83,7 +75,6 @@ cc_list_row_switch_active_cb (CcListRow *self)
|
||||
return;
|
||||
|
||||
self->switch_active = switch_active;
|
||||
update_checked_state (self);
|
||||
g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_ACTIVE]);
|
||||
}
|
||||
|
||||
@@ -142,7 +133,6 @@ cc_list_row_set_property (GObject *object,
|
||||
gtk_switch_set_active (self->enable_switch,
|
||||
g_value_get_boolean (value));
|
||||
self->switch_active = g_value_get_boolean (value);
|
||||
update_checked_state (self);
|
||||
g_signal_handlers_unblock_by_func (self->enable_switch,
|
||||
cc_list_row_switch_active_cb, self);
|
||||
break;
|
||||
@@ -238,8 +228,6 @@ cc_list_row_set_show_switch (CcListRow *self,
|
||||
|
||||
adw_action_row_set_activatable_widget (ADW_ACTION_ROW (self),
|
||||
self->show_switch ? GTK_WIDGET (self->enable_switch) : NULL);
|
||||
|
||||
update_checked_state (self);
|
||||
}
|
||||
|
||||
gboolean
|
||||
|
||||
@@ -20,7 +20,6 @@
|
||||
<object class="GtkSwitch" id="enable_switch">
|
||||
<property name="visible">False</property>
|
||||
<property name="valign">center</property>
|
||||
<property name="can-focus">false</property>
|
||||
<signal name="notify::active" handler="cc_list_row_switch_active_cb" swapped="yes"/>
|
||||
</object>
|
||||
</child>
|
||||
|
||||
@@ -27,7 +27,6 @@
|
||||
<child>
|
||||
<object class="GtkLabel" id="title">
|
||||
<property name="halign">start</property>
|
||||
<property name="wrap">True</property>
|
||||
<!-- Actual string set in code -->
|
||||
<property name="label"></property>
|
||||
<attributes>
|
||||
@@ -38,7 +37,6 @@
|
||||
<child>
|
||||
<object class="GtkLabel">
|
||||
<property name="halign">start</property>
|
||||
<property name="wrap">True</property>
|
||||
<property name="label" translatable="yes">Some settings must be unlocked before they can be changed.</property>
|
||||
</object>
|
||||
</child>
|
||||
@@ -57,7 +55,6 @@
|
||||
<object class="GtkLockButton" id="lock_button">
|
||||
<property name="receives-default">True</property>
|
||||
<property name="label" translatable="yes">Unlock…</property>
|
||||
<property name="valign">GTK_ALIGN_CENTER</property>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
|
||||
@@ -1,413 +0,0 @@
|
||||
/* cc-split-row.c
|
||||
*
|
||||
* Copyright 2018 Purism SPC
|
||||
* 2021 Georges Basile Stavracas Neto <georges.stavracas@gmail.com>
|
||||
* 2023 Red Hat, Inc
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-3.0-or-later
|
||||
*/
|
||||
|
||||
#include "cc-split-row.h"
|
||||
|
||||
struct _CcSplitRow
|
||||
{
|
||||
CcVerticalRow parent;
|
||||
|
||||
GtkPicture *default_option_picture;
|
||||
GtkPicture *alternative_option_picture;
|
||||
|
||||
GtkCheckButton *alternative_option_checkbutton;
|
||||
GtkCheckButton *default_option_checkbutton;
|
||||
|
||||
const gchar *alternative_resource_path;
|
||||
const gchar *default_resource_path;
|
||||
|
||||
gchar *alternative_option_title;
|
||||
gchar *alternative_option_subtitle;
|
||||
gchar *default_option_title;
|
||||
gchar *default_option_subtitle;
|
||||
|
||||
gboolean use_default;
|
||||
};
|
||||
|
||||
G_DEFINE_FINAL_TYPE (CcSplitRow, cc_split_row, CC_TYPE_VERTICAL_ROW);
|
||||
|
||||
enum
|
||||
{
|
||||
PROP_0,
|
||||
PROP_USE_DEFAULT,
|
||||
PROP_ALTERNATIVE_ILLUSTRATION_RESOURCE,
|
||||
PROP_ALTERNATIVE_OPTION_TITLE,
|
||||
PROP_ALTERNATIVE_OPTION_SUBTITLE,
|
||||
PROP_DEFAULT_ILLUSTRATION_RESOURCE,
|
||||
PROP_DEFAULT_OPTION_TITLE,
|
||||
PROP_DEFAULT_OPTION_SUBTITLE,
|
||||
N_PROPS,
|
||||
};
|
||||
|
||||
static GParamSpec *props[N_PROPS] = { NULL, };
|
||||
|
||||
static void
|
||||
on_option_click_released_cb (GtkGestureClick *self,
|
||||
gint n_press,
|
||||
gdouble x,
|
||||
gdouble y,
|
||||
GtkCheckButton *check_button)
|
||||
{
|
||||
gtk_widget_activate (GTK_WIDGET (check_button));
|
||||
}
|
||||
|
||||
static void
|
||||
on_option_focus_leave_cb (GtkEventControllerMotion *controller,
|
||||
GtkPicture *picture)
|
||||
{
|
||||
GtkMediaStream *stream;
|
||||
GdkPaintable *paintable;
|
||||
|
||||
paintable = gtk_picture_get_paintable (GTK_PICTURE (picture));
|
||||
|
||||
if (!GTK_IS_MEDIA_STREAM (paintable))
|
||||
return;
|
||||
|
||||
stream = GTK_MEDIA_STREAM (paintable);
|
||||
gtk_media_stream_set_loop (stream, FALSE);
|
||||
gtk_media_stream_pause (stream);
|
||||
}
|
||||
|
||||
static void
|
||||
on_option_focus_enter_cb (GtkEventControllerMotion *controller,
|
||||
gdouble x,
|
||||
gdouble y,
|
||||
GtkPicture *picture)
|
||||
{
|
||||
GtkMediaStream *stream;
|
||||
GdkPaintable *paintable;
|
||||
|
||||
paintable = gtk_picture_get_paintable (GTK_PICTURE (picture));
|
||||
|
||||
if (!GTK_IS_MEDIA_STREAM (paintable))
|
||||
return;
|
||||
|
||||
stream = GTK_MEDIA_STREAM (paintable);
|
||||
gtk_media_stream_set_loop (stream, TRUE);
|
||||
gtk_media_stream_play (stream);
|
||||
}
|
||||
|
||||
static void
|
||||
on_checkbutton_toggled_cb (CcSplitRow *self)
|
||||
{
|
||||
g_object_notify_by_pspec (G_OBJECT (self), props[PROP_USE_DEFAULT]);
|
||||
}
|
||||
|
||||
static void
|
||||
cc_split_row_dispose (GObject *object)
|
||||
{
|
||||
CcSplitRow *self = CC_SPLIT_ROW (object);
|
||||
|
||||
g_clear_pointer (&self->alternative_option_title, g_free);
|
||||
g_clear_pointer (&self->alternative_option_subtitle, g_free);
|
||||
g_clear_pointer (&self->default_option_title, g_free);
|
||||
g_clear_pointer (&self->default_option_subtitle, g_free);
|
||||
|
||||
G_OBJECT_CLASS (cc_split_row_parent_class)->dispose (object);
|
||||
}
|
||||
|
||||
static void
|
||||
cc_split_row_get_property (GObject *object,
|
||||
guint prop_id,
|
||||
GValue *value,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
CcSplitRow *self = CC_SPLIT_ROW (object);
|
||||
|
||||
switch (prop_id)
|
||||
{
|
||||
case PROP_USE_DEFAULT:
|
||||
g_value_set_boolean (value, gtk_check_button_get_active (self->default_option_checkbutton));
|
||||
break;
|
||||
case PROP_ALTERNATIVE_ILLUSTRATION_RESOURCE:
|
||||
g_value_set_string (value, cc_split_row_get_alternative_illustration_resource (self));
|
||||
break;
|
||||
case PROP_ALTERNATIVE_OPTION_TITLE:
|
||||
g_value_set_string (value, cc_split_row_get_alternative_option_title (self));
|
||||
break;
|
||||
case PROP_ALTERNATIVE_OPTION_SUBTITLE:
|
||||
g_value_set_string (value, cc_split_row_get_alternative_option_subtitle (self));
|
||||
break;
|
||||
case PROP_DEFAULT_ILLUSTRATION_RESOURCE:
|
||||
g_value_set_string (value, cc_split_row_get_default_illustration_resource (self));
|
||||
break;
|
||||
case PROP_DEFAULT_OPTION_TITLE:
|
||||
g_value_set_string (value, cc_split_row_get_default_option_title (self));
|
||||
break;
|
||||
case PROP_DEFAULT_OPTION_SUBTITLE:
|
||||
g_value_set_string (value, cc_split_row_get_default_option_subtitle (self));
|
||||
break;
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
cc_split_row_set_property (GObject *object,
|
||||
guint prop_id,
|
||||
const GValue *value,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
CcSplitRow *self = CC_SPLIT_ROW (object);
|
||||
|
||||
switch (prop_id)
|
||||
{
|
||||
case PROP_USE_DEFAULT:
|
||||
cc_split_row_set_use_default (self, g_value_get_boolean (value));
|
||||
break;
|
||||
case PROP_ALTERNATIVE_ILLUSTRATION_RESOURCE:
|
||||
cc_split_row_set_alternative_illustration_resource (self, g_value_get_string (value));
|
||||
break;
|
||||
case PROP_ALTERNATIVE_OPTION_TITLE:
|
||||
cc_split_row_set_alternative_option_title (self, g_value_get_string (value));
|
||||
break;
|
||||
case PROP_ALTERNATIVE_OPTION_SUBTITLE:
|
||||
cc_split_row_set_alternative_option_subtitle (self, g_value_get_string (value));
|
||||
break;
|
||||
case PROP_DEFAULT_ILLUSTRATION_RESOURCE:
|
||||
cc_split_row_set_default_illustration_resource (self, g_value_get_string (value));
|
||||
break;
|
||||
case PROP_DEFAULT_OPTION_TITLE:
|
||||
cc_split_row_set_default_option_title (self, g_value_get_string (value));
|
||||
break;
|
||||
case PROP_DEFAULT_OPTION_SUBTITLE:
|
||||
cc_split_row_set_default_option_subtitle (self, g_value_get_string (value));
|
||||
break;
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
cc_split_row_class_init (CcSplitRowClass *klass)
|
||||
{
|
||||
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
||||
GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
|
||||
|
||||
object_class->dispose = cc_split_row_dispose;
|
||||
object_class->get_property = cc_split_row_get_property;
|
||||
object_class->set_property = cc_split_row_set_property;
|
||||
|
||||
props[PROP_USE_DEFAULT] =
|
||||
g_param_spec_boolean ("use-default",
|
||||
"Use Default",
|
||||
"Use Default",
|
||||
TRUE,
|
||||
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_EXPLICIT_NOTIFY);
|
||||
|
||||
props[PROP_ALTERNATIVE_ILLUSTRATION_RESOURCE] =
|
||||
g_param_spec_string ("alternative-illustration-resource",
|
||||
"Alternative illustration resource",
|
||||
"Alternative illustration resource",
|
||||
"",
|
||||
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_EXPLICIT_NOTIFY);
|
||||
props[PROP_ALTERNATIVE_OPTION_TITLE] =
|
||||
g_param_spec_string ("alternative-option-title",
|
||||
"Alternative option title",
|
||||
"Alternative option title",
|
||||
"",
|
||||
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_EXPLICIT_NOTIFY);
|
||||
props[PROP_ALTERNATIVE_OPTION_SUBTITLE] =
|
||||
g_param_spec_string ("alternative-option-subtitle",
|
||||
"Alternative option subtitle",
|
||||
"Alternative option subtitle",
|
||||
"",
|
||||
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_EXPLICIT_NOTIFY);
|
||||
props[PROP_DEFAULT_ILLUSTRATION_RESOURCE] =
|
||||
g_param_spec_string ("default-illustration-resource",
|
||||
"Default illustration resource",
|
||||
"Default illustration resource",
|
||||
"",
|
||||
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_EXPLICIT_NOTIFY);
|
||||
props[PROP_DEFAULT_OPTION_TITLE] =
|
||||
g_param_spec_string ("default-option-title",
|
||||
"Default option title",
|
||||
"Default option title",
|
||||
"",
|
||||
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_EXPLICIT_NOTIFY);
|
||||
props[PROP_DEFAULT_OPTION_SUBTITLE] =
|
||||
g_param_spec_string ("default-option-subtitle",
|
||||
"Default option subtitle",
|
||||
"Default option subtitle",
|
||||
"",
|
||||
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_EXPLICIT_NOTIFY);
|
||||
|
||||
g_object_class_install_properties (object_class, N_PROPS, props);
|
||||
|
||||
gtk_widget_class_set_template_from_resource (widget_class, "/org/gnome/control-center/common/cc-split-row.ui");
|
||||
|
||||
gtk_widget_class_bind_template_child (widget_class, CcSplitRow, alternative_option_checkbutton);
|
||||
gtk_widget_class_bind_template_child (widget_class, CcSplitRow, alternative_option_picture);
|
||||
gtk_widget_class_bind_template_child (widget_class, CcSplitRow, default_option_checkbutton);
|
||||
gtk_widget_class_bind_template_child (widget_class, CcSplitRow, default_option_picture);
|
||||
|
||||
gtk_widget_class_bind_template_callback (widget_class, on_checkbutton_toggled_cb);
|
||||
gtk_widget_class_bind_template_callback (widget_class, on_option_click_released_cb);
|
||||
gtk_widget_class_bind_template_callback (widget_class, on_option_focus_enter_cb);
|
||||
gtk_widget_class_bind_template_callback (widget_class, on_option_focus_leave_cb);
|
||||
}
|
||||
|
||||
static void
|
||||
cc_split_row_init (CcSplitRow *self)
|
||||
{
|
||||
gtk_widget_init_template (GTK_WIDGET (self));
|
||||
gtk_widget_set_name (GTK_WIDGET (self), "split-row");
|
||||
gtk_widget_add_css_class (GTK_WIDGET (self), "split-row");
|
||||
}
|
||||
|
||||
const gchar *
|
||||
cc_split_row_get_default_illustration_resource (CcSplitRow *self)
|
||||
{
|
||||
return self->default_resource_path;
|
||||
}
|
||||
|
||||
void
|
||||
cc_split_row_set_default_illustration_resource (CcSplitRow *self,
|
||||
const gchar *resource_path)
|
||||
{
|
||||
g_autoptr(GtkMediaStream) media_file = NULL;
|
||||
|
||||
g_return_if_fail (CC_IS_SPLIT_ROW (self));
|
||||
|
||||
self->default_resource_path = resource_path;
|
||||
media_file = gtk_media_file_new_for_resource (resource_path);
|
||||
|
||||
gtk_picture_set_paintable (self->default_option_picture, GDK_PAINTABLE (media_file));
|
||||
gtk_widget_set_visible (GTK_WIDGET (self->default_option_picture),
|
||||
resource_path != NULL && g_strcmp0 (resource_path, "") != 0);
|
||||
|
||||
g_object_notify_by_pspec (G_OBJECT (self), props[PROP_DEFAULT_ILLUSTRATION_RESOURCE]);
|
||||
}
|
||||
|
||||
const gchar *
|
||||
cc_split_row_get_alternative_illustration_resource (CcSplitRow *self)
|
||||
{
|
||||
return self->alternative_resource_path;
|
||||
}
|
||||
|
||||
void
|
||||
cc_split_row_set_alternative_illustration_resource (CcSplitRow *self,
|
||||
const gchar *resource_path)
|
||||
{
|
||||
g_autoptr(GtkMediaStream) media_file = NULL;
|
||||
|
||||
g_return_if_fail (CC_IS_SPLIT_ROW (self));
|
||||
|
||||
self->alternative_resource_path = resource_path;
|
||||
media_file = gtk_media_file_new_for_resource (resource_path);
|
||||
gtk_media_stream_set_loop (media_file, TRUE);
|
||||
|
||||
gtk_picture_set_paintable (self->alternative_option_picture, GDK_PAINTABLE (media_file));
|
||||
gtk_widget_set_visible (GTK_WIDGET (self->alternative_option_picture),
|
||||
resource_path != NULL && g_strcmp0 (resource_path, "") != 0);
|
||||
|
||||
g_object_notify_by_pspec (G_OBJECT (self), props[PROP_ALTERNATIVE_ILLUSTRATION_RESOURCE]);
|
||||
}
|
||||
|
||||
void
|
||||
cc_split_row_set_use_default (CcSplitRow *self,
|
||||
gboolean use_default)
|
||||
{
|
||||
g_return_if_fail (CC_IS_SPLIT_ROW (self));
|
||||
|
||||
gtk_check_button_set_active (use_default ? self->default_option_checkbutton : self->alternative_option_checkbutton, TRUE);
|
||||
|
||||
g_object_notify_by_pspec (G_OBJECT (self), props[PROP_USE_DEFAULT]);
|
||||
}
|
||||
|
||||
gboolean
|
||||
cc_split_row_get_use_default (CcSplitRow *self)
|
||||
{
|
||||
return gtk_check_button_get_active (self->default_option_checkbutton);
|
||||
}
|
||||
|
||||
const gchar *
|
||||
cc_split_row_get_default_option_title (CcSplitRow *self)
|
||||
{
|
||||
g_return_val_if_fail (CC_IS_SPLIT_ROW (self), NULL);
|
||||
|
||||
return self->default_option_title;
|
||||
}
|
||||
|
||||
void
|
||||
cc_split_row_set_default_option_title (CcSplitRow *self,
|
||||
const gchar *title)
|
||||
{
|
||||
g_return_if_fail (CC_IS_SPLIT_ROW (self));
|
||||
|
||||
if (g_set_str (&self->default_option_title, title))
|
||||
g_object_notify_by_pspec (G_OBJECT (self), props[PROP_DEFAULT_OPTION_TITLE]);
|
||||
}
|
||||
|
||||
const gchar *
|
||||
cc_split_row_get_default_option_subtitle (CcSplitRow *self)
|
||||
{
|
||||
g_return_val_if_fail (CC_IS_SPLIT_ROW (self), NULL);
|
||||
|
||||
return self->default_option_subtitle;
|
||||
}
|
||||
|
||||
void
|
||||
cc_split_row_set_default_option_subtitle (CcSplitRow *self,
|
||||
const gchar *subtitle)
|
||||
{
|
||||
g_return_if_fail (CC_IS_SPLIT_ROW (self));
|
||||
|
||||
if (g_set_str (&self->default_option_subtitle, subtitle))
|
||||
g_object_notify_by_pspec (G_OBJECT (self), props[PROP_DEFAULT_OPTION_SUBTITLE]);
|
||||
}
|
||||
|
||||
const gchar *
|
||||
cc_split_row_get_alternative_option_title (CcSplitRow *self)
|
||||
{
|
||||
g_return_val_if_fail (CC_IS_SPLIT_ROW (self), NULL);
|
||||
|
||||
return self->alternative_option_title;
|
||||
}
|
||||
|
||||
void
|
||||
cc_split_row_set_alternative_option_title (CcSplitRow *self,
|
||||
const gchar *title)
|
||||
{
|
||||
g_return_if_fail (CC_IS_SPLIT_ROW (self));
|
||||
|
||||
if (g_set_str (&self->alternative_option_title, title))
|
||||
g_object_notify_by_pspec (G_OBJECT (self), props[PROP_ALTERNATIVE_OPTION_TITLE]);
|
||||
}
|
||||
|
||||
const gchar *
|
||||
cc_split_row_get_alternative_option_subtitle (CcSplitRow *self)
|
||||
{
|
||||
g_return_val_if_fail (CC_IS_SPLIT_ROW (self), NULL);
|
||||
|
||||
return self->alternative_option_subtitle;
|
||||
}
|
||||
|
||||
void
|
||||
cc_split_row_set_alternative_option_subtitle (CcSplitRow *self,
|
||||
const gchar *subtitle)
|
||||
{
|
||||
g_return_if_fail (CC_IS_SPLIT_ROW (self));
|
||||
|
||||
if (g_set_str (&self->alternative_option_subtitle, subtitle))
|
||||
g_object_notify_by_pspec (G_OBJECT (self), props[PROP_ALTERNATIVE_OPTION_SUBTITLE]);
|
||||
}
|
||||
@@ -1,74 +0,0 @@
|
||||
/* cc-vertical-row.h
|
||||
*
|
||||
* Copyright 2018 Purism SPC
|
||||
* 2021 Georges Basile Stavracas Neto <georges.stavracas@gmail.com>
|
||||
* 2023 Red Hat, Inc
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-3.0-or-later
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <adwaita.h>
|
||||
|
||||
#include "cc-vertical-row.h"
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define CC_TYPE_SPLIT_ROW (cc_split_row_get_type())
|
||||
G_DECLARE_FINAL_TYPE (CcSplitRow, cc_split_row, CC, SPLIT_ROW, CcVerticalRow)
|
||||
|
||||
struct _CcSplitRowClass
|
||||
{
|
||||
CcVerticalRowClass parent_class;
|
||||
|
||||
/*< private >*/
|
||||
gpointer padding[4];
|
||||
};
|
||||
|
||||
void cc_split_row_set_default_illustration_resource (CcSplitRow *self,
|
||||
const gchar *resource_path);
|
||||
|
||||
const gchar *cc_split_row_get_default_illustration_resource (CcSplitRow *self);
|
||||
|
||||
void cc_split_row_set_alternative_illustration_resource (CcSplitRow *self,
|
||||
const gchar *resource_path);
|
||||
|
||||
const gchar *cc_split_row_get_alternative_illustration_resource (CcSplitRow *self);
|
||||
|
||||
void cc_split_row_set_use_default (CcSplitRow *self,
|
||||
gboolean use_default);
|
||||
|
||||
gboolean cc_split_row_get_use_default (CcSplitRow *self);
|
||||
|
||||
const gchar *cc_split_row_get_default_option_title (CcSplitRow *self);
|
||||
|
||||
void cc_split_row_set_default_option_title (CcSplitRow *self,
|
||||
const gchar *title);
|
||||
const gchar *cc_split_row_get_default_option_subtitle (CcSplitRow *self);
|
||||
|
||||
void cc_split_row_set_default_option_subtitle (CcSplitRow *self,
|
||||
const gchar *subtitle);
|
||||
const gchar *cc_split_row_get_alternative_option_title (CcSplitRow *self);
|
||||
|
||||
void cc_split_row_set_alternative_option_title (CcSplitRow *self,
|
||||
const gchar *title);
|
||||
const gchar *cc_split_row_get_alternative_option_subtitle (CcSplitRow *self);
|
||||
|
||||
void cc_split_row_set_alternative_option_subtitle (CcSplitRow *self,
|
||||
const gchar *subtitle);
|
||||
|
||||
G_END_DECLS
|
||||
@@ -1,172 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<interface>
|
||||
<template class="CcSplitRow" parent="CcVerticalRow">
|
||||
<child type="content">
|
||||
<object class="GtkBox">
|
||||
<property name="hexpand">True</property>
|
||||
<property name="homogeneous">True</property>
|
||||
<property name="spacing">24</property>
|
||||
<property name="margin-top">12</property>
|
||||
<property name="margin-bottom">12</property>
|
||||
|
||||
<!-- Default Option -->
|
||||
<child>
|
||||
<object class="GtkBox">
|
||||
<property name="spacing">12</property>
|
||||
<property name="orientation">vertical</property>
|
||||
|
||||
<child>
|
||||
<object class="GtkEventControllerMotion">
|
||||
<signal name="enter" handler="on_option_focus_enter_cb" object="default_option_picture" swapped="no" />
|
||||
<signal name="leave" handler="on_option_focus_leave_cb" object="default_option_picture" swapped="no" />
|
||||
</object>
|
||||
</child>
|
||||
|
||||
<child>
|
||||
<object class="GtkGestureClick">
|
||||
<signal name="released" handler="on_option_click_released_cb" object="default_option_checkbutton" swapped="no" />
|
||||
</object>
|
||||
</child>
|
||||
|
||||
<child>
|
||||
<object class="AdwBin">
|
||||
<style>
|
||||
<class name="background"/>
|
||||
<class name="frame"/>
|
||||
</style>
|
||||
<child>
|
||||
<object class="GtkPicture" id="default_option_picture">
|
||||
<property name="hexpand">True</property>
|
||||
<property name="halign">center</property>
|
||||
<property name="margin-top">18</property>
|
||||
<property name="margin-bottom">18</property>
|
||||
<property name="margin-start">18</property>
|
||||
<property name="margin-end">18</property>
|
||||
<property name="height-request">128</property>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
|
||||
<child>
|
||||
<object class="GtkCheckButton" id="default_option_checkbutton">
|
||||
<property name="margin-start">6</property>
|
||||
<property name="group">alternative_option_checkbutton</property>
|
||||
<signal name="toggled" handler="on_checkbutton_toggled_cb" object="CcSplitRow" swapped="yes"/>
|
||||
<property name="child">
|
||||
<object class="GtkBox">
|
||||
<property name="valign">center</property>
|
||||
<property name="margin-start">6</property>
|
||||
<property name="orientation">vertical</property>
|
||||
<child>
|
||||
<object class="GtkLabel">
|
||||
<property name="xalign">0.0</property>
|
||||
<binding name="label">
|
||||
<lookup name="default-option-title">CcSplitRow</lookup>
|
||||
</binding>
|
||||
<style>
|
||||
<class name="title" />
|
||||
</style>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel">
|
||||
<property name="xalign">0.0</property>
|
||||
<binding name="label">
|
||||
<lookup name="default-option-subtitle">CcSplitRow</lookup>
|
||||
</binding>
|
||||
<style>
|
||||
<class name="subtitle" />
|
||||
</style>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</property>
|
||||
</object>
|
||||
</child>
|
||||
|
||||
</object>
|
||||
</child>
|
||||
|
||||
<!-- Alternative Option -->
|
||||
<child>
|
||||
<object class="GtkBox">
|
||||
<property name="spacing">12</property>
|
||||
<property name="orientation">vertical</property>
|
||||
|
||||
<child>
|
||||
<object class="GtkEventControllerMotion">
|
||||
<signal name="enter" handler="on_option_focus_enter_cb" object="alternative_option_picture" swapped="no" />
|
||||
<signal name="leave" handler="on_option_focus_leave_cb" object="alternative_option_picture" swapped="no" />
|
||||
</object>
|
||||
</child>
|
||||
|
||||
<child>
|
||||
<object class="GtkGestureClick">
|
||||
<signal name="released" handler="on_option_click_released_cb" object="alternative_option_checkbutton" swapped="no" />
|
||||
</object>
|
||||
</child>
|
||||
|
||||
<child>
|
||||
<object class="AdwBin">
|
||||
<style>
|
||||
<class name="background"/>
|
||||
<class name="frame"/>
|
||||
</style>
|
||||
<child>
|
||||
<object class="GtkPicture" id="alternative_option_picture">
|
||||
<property name="hexpand">True</property>
|
||||
<property name="halign">center</property>
|
||||
<property name="margin-top">18</property>
|
||||
<property name="margin-bottom">18</property>
|
||||
<property name="margin-start">18</property>
|
||||
<property name="margin-end">18</property>
|
||||
<property name="height-request">128</property>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
|
||||
<child>
|
||||
<object class="GtkCheckButton" id="alternative_option_checkbutton">
|
||||
<property name="margin-start">6</property>
|
||||
<signal name="toggled" handler="on_checkbutton_toggled_cb" object="CcSplitRow" swapped="yes"/>
|
||||
<property name="child">
|
||||
<object class="GtkBox">
|
||||
<property name="valign">center</property>
|
||||
<property name="margin-start">6</property>
|
||||
<property name="orientation">vertical</property>
|
||||
<child>
|
||||
<object class="GtkLabel">
|
||||
<property name="xalign">0.0</property>
|
||||
<binding name="label">
|
||||
<lookup name="alternative-option-title">CcSplitRow</lookup>
|
||||
</binding>
|
||||
<style>
|
||||
<class name="title" />
|
||||
</style>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel">
|
||||
<property name="xalign">0.0</property>
|
||||
<binding name="label">
|
||||
<lookup name="alternative-option-subtitle">CcSplitRow</lookup>
|
||||
</binding>
|
||||
<style>
|
||||
<class name="subtitle" />
|
||||
</style>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</property>
|
||||
</object>
|
||||
</child>
|
||||
|
||||
</object>
|
||||
</child>
|
||||
|
||||
</object>
|
||||
</child>
|
||||
</template>
|
||||
</interface>
|
||||
@@ -108,7 +108,6 @@ time_editor_time_changed_cb (CcTimeEditor *self)
|
||||
{
|
||||
g_assert (CC_IS_TIME_EDITOR (self));
|
||||
|
||||
time_editor_clock_changed_cb (self);
|
||||
g_signal_emit (self, signals[TIME_CHANGED], 0);
|
||||
}
|
||||
|
||||
|
||||
@@ -568,8 +568,6 @@ cc_time_entry_set_time (CcTimeEntry *self,
|
||||
self->minute = CLAMP (minute, 0, 59);
|
||||
|
||||
cc_time_entry_set_am_pm (self, is_am_pm);
|
||||
|
||||
g_signal_emit (self, signals[TIME_CHANGED], 0);
|
||||
time_entry_fill_time (self);
|
||||
}
|
||||
|
||||
|
||||
@@ -145,23 +145,6 @@ cc_util_get_smart_date (GDateTime *date)
|
||||
}
|
||||
}
|
||||
|
||||
char *
|
||||
cc_util_get_smart_date_time (GDateTime *date)
|
||||
{
|
||||
g_autofree gchar *date_str = NULL;
|
||||
g_autofree gchar *smart_date = NULL;
|
||||
|
||||
if (date == NULL)
|
||||
return NULL;
|
||||
|
||||
smart_date = cc_util_get_smart_date (date);
|
||||
date_str = g_date_time_format (date, "\%X");
|
||||
/* TRANSLATORS: This is the datetime format in the style of
|
||||
"Aug 1, 10:10:10 PM", "Feb 24, 2013, 10:10:10 PM", "Today, 10:10:10 AM",
|
||||
and "Yesterday, 10:10:10 AM" */
|
||||
return g_strdup_printf (_("%1$s, %2$s"), smart_date, date_str);
|
||||
}
|
||||
|
||||
/* Copied from src/plugins/properties/bacon-video-widget-properties.c
|
||||
* in totem */
|
||||
char *
|
||||
|
||||
@@ -24,5 +24,4 @@
|
||||
|
||||
char * cc_util_normalize_casefold_and_unaccent (const char *str);
|
||||
char * cc_util_get_smart_date (GDateTime *date);
|
||||
char * cc_util_get_smart_date_time (GDateTime *date);
|
||||
char * cc_util_time_to_string_text (gint64 msecs);
|
||||
|
||||
@@ -1,606 +0,0 @@
|
||||
/* cc-vertical-row.c
|
||||
*
|
||||
* Copyright 2018 Purism SPC
|
||||
* 2021 Georges Basile Stavracas Neto <georges.stavracas@gmail.com>
|
||||
* 2023 Red Hat, Inc
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-3.0-or-later
|
||||
*/
|
||||
|
||||
#include "cc-vertical-row.h"
|
||||
|
||||
typedef struct
|
||||
{
|
||||
AdwPreferencesRow parent;
|
||||
|
||||
GtkBox *content_box;
|
||||
GtkBox *header;
|
||||
GtkImage *image;
|
||||
GtkBox *prefixes;
|
||||
GtkLabel *subtitle;
|
||||
GtkBox *suffixes;
|
||||
GtkLabel *title;
|
||||
GtkBox *title_box;
|
||||
|
||||
GtkWidget *previous_parent;
|
||||
|
||||
gboolean use_underline;
|
||||
gint title_lines;
|
||||
gint subtitle_lines;
|
||||
GtkWidget *activatable_widget;
|
||||
} CcVerticalRowPrivate;
|
||||
|
||||
static GtkBuildableIface *parent_buildable_iface;
|
||||
|
||||
static void cc_vertical_row_buildable_init (GtkBuildableIface *iface);
|
||||
|
||||
G_DEFINE_TYPE_WITH_CODE (CcVerticalRow, cc_vertical_row, ADW_TYPE_PREFERENCES_ROW,
|
||||
G_ADD_PRIVATE (CcVerticalRow) G_IMPLEMENT_INTERFACE (GTK_TYPE_BUILDABLE, cc_vertical_row_buildable_init))
|
||||
|
||||
enum
|
||||
{
|
||||
PROP_0,
|
||||
PROP_ICON_NAME,
|
||||
PROP_ACTIVATABLE_WIDGET,
|
||||
PROP_SUBTITLE,
|
||||
PROP_USE_UNDERLINE,
|
||||
PROP_TITLE_LINES,
|
||||
PROP_SUBTITLE_LINES,
|
||||
N_PROPS,
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
SIGNAL_ACTIVATED,
|
||||
SIGNAL_LAST_SIGNAL,
|
||||
};
|
||||
|
||||
static GParamSpec *props[N_PROPS] = { NULL, };
|
||||
static guint signals[SIGNAL_LAST_SIGNAL] = { 0, };
|
||||
|
||||
static void
|
||||
row_activated_cb (CcVerticalRow *self,
|
||||
GtkListBoxRow *row)
|
||||
{
|
||||
/* No need to use GTK_LIST_BOX_ROW() for a pointer comparison. */
|
||||
if ((GtkListBoxRow *) self == row)
|
||||
cc_vertical_row_activate (self);
|
||||
}
|
||||
|
||||
static void
|
||||
parent_cb (CcVerticalRow *self)
|
||||
{
|
||||
GtkWidget *parent = gtk_widget_get_parent (GTK_WIDGET (self));
|
||||
CcVerticalRowPrivate *priv = cc_vertical_row_get_instance_private (self);
|
||||
|
||||
if (priv->previous_parent != NULL)
|
||||
{
|
||||
g_signal_handlers_disconnect_by_func (priv->previous_parent,
|
||||
G_CALLBACK (row_activated_cb),
|
||||
self);
|
||||
priv->previous_parent = NULL;
|
||||
}
|
||||
|
||||
if (parent == NULL || !GTK_IS_LIST_BOX (parent))
|
||||
return;
|
||||
|
||||
priv->previous_parent = parent;
|
||||
g_signal_connect_swapped (parent, "row-activated", G_CALLBACK (row_activated_cb), self);
|
||||
}
|
||||
|
||||
static void
|
||||
update_subtitle_visibility (CcVerticalRow *self)
|
||||
{
|
||||
CcVerticalRowPrivate *priv = cc_vertical_row_get_instance_private (self);
|
||||
|
||||
gtk_widget_set_visible (GTK_WIDGET (priv->subtitle),
|
||||
gtk_label_get_text (priv->subtitle) != NULL &&
|
||||
g_strcmp0 (gtk_label_get_text (priv->subtitle), "") != 0);
|
||||
}
|
||||
|
||||
static void
|
||||
cc_vertical_row_get_property (GObject *object,
|
||||
guint prop_id,
|
||||
GValue *value,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
CcVerticalRow *self = CC_VERTICAL_ROW (object);
|
||||
|
||||
switch (prop_id)
|
||||
{
|
||||
case PROP_ICON_NAME:
|
||||
g_value_set_string (value, cc_vertical_row_get_icon_name (self));
|
||||
break;
|
||||
case PROP_ACTIVATABLE_WIDGET:
|
||||
g_value_set_object (value, (GObject *) cc_vertical_row_get_activatable_widget (self));
|
||||
break;
|
||||
case PROP_SUBTITLE:
|
||||
g_value_set_string (value, cc_vertical_row_get_subtitle (self));
|
||||
break;
|
||||
case PROP_SUBTITLE_LINES:
|
||||
g_value_set_int (value, cc_vertical_row_get_subtitle_lines (self));
|
||||
break;
|
||||
case PROP_TITLE_LINES:
|
||||
g_value_set_int (value, cc_vertical_row_get_title_lines (self));
|
||||
break;
|
||||
case PROP_USE_UNDERLINE:
|
||||
g_value_set_boolean (value, cc_vertical_row_get_use_underline (self));
|
||||
break;
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
cc_vertical_row_set_property (GObject *object,
|
||||
guint prop_id,
|
||||
const GValue *value,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
CcVerticalRow *self = CC_VERTICAL_ROW (object);
|
||||
|
||||
switch (prop_id)
|
||||
{
|
||||
case PROP_ICON_NAME:
|
||||
cc_vertical_row_set_icon_name (self, g_value_get_string (value));
|
||||
break;
|
||||
case PROP_ACTIVATABLE_WIDGET:
|
||||
cc_vertical_row_set_activatable_widget (self, (GtkWidget*) g_value_get_object (value));
|
||||
break;
|
||||
case PROP_SUBTITLE:
|
||||
cc_vertical_row_set_subtitle (self, g_value_get_string (value));
|
||||
break;
|
||||
case PROP_SUBTITLE_LINES:
|
||||
cc_vertical_row_set_subtitle_lines (self, g_value_get_int (value));
|
||||
break;
|
||||
case PROP_TITLE_LINES:
|
||||
cc_vertical_row_set_title_lines (self, g_value_get_int (value));
|
||||
break;
|
||||
case PROP_USE_UNDERLINE:
|
||||
cc_vertical_row_set_use_underline (self, g_value_get_boolean (value));
|
||||
break;
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
cc_vertical_row_dispose (GObject *object)
|
||||
{
|
||||
CcVerticalRow *self = CC_VERTICAL_ROW (object);
|
||||
CcVerticalRowPrivate *priv = cc_vertical_row_get_instance_private (self);
|
||||
|
||||
if (priv->previous_parent != NULL) {
|
||||
g_signal_handlers_disconnect_by_func (priv->previous_parent, G_CALLBACK (row_activated_cb), self);
|
||||
priv->previous_parent = NULL;
|
||||
}
|
||||
|
||||
cc_vertical_row_set_activatable_widget (self, NULL);
|
||||
g_clear_pointer ((GtkWidget**)&priv->header, gtk_widget_unparent);
|
||||
|
||||
G_OBJECT_CLASS (cc_vertical_row_parent_class)->dispose (object);
|
||||
}
|
||||
|
||||
static void
|
||||
cc_vertical_row_class_init (CcVerticalRowClass *klass)
|
||||
{
|
||||
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
||||
GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
|
||||
|
||||
object_class->get_property = cc_vertical_row_get_property;
|
||||
object_class->set_property = cc_vertical_row_set_property;
|
||||
object_class->dispose = cc_vertical_row_dispose;
|
||||
|
||||
props[PROP_ICON_NAME] =
|
||||
g_param_spec_string ("icon-name",
|
||||
"Icon name",
|
||||
"Icon name",
|
||||
"",
|
||||
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_EXPLICIT_NOTIFY);
|
||||
|
||||
props[PROP_ACTIVATABLE_WIDGET] =
|
||||
g_param_spec_object ("activatable-widget",
|
||||
"Activatable widget",
|
||||
"The widget to be activated when the row is activated",
|
||||
GTK_TYPE_WIDGET,
|
||||
G_PARAM_READWRITE);
|
||||
|
||||
props[PROP_SUBTITLE] =
|
||||
g_param_spec_string ("subtitle",
|
||||
"Subtitle",
|
||||
"Subtitle",
|
||||
"",
|
||||
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_EXPLICIT_NOTIFY);
|
||||
|
||||
props[PROP_USE_UNDERLINE] =
|
||||
g_param_spec_boolean ("use-underline",
|
||||
"Use underline",
|
||||
"If set, an underline in the text indicates the next character should be used for the mnemonic accelerator key",
|
||||
FALSE,
|
||||
G_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY);
|
||||
|
||||
props[PROP_TITLE_LINES] =
|
||||
g_param_spec_int ("title-lines",
|
||||
"Number of title lines",
|
||||
"The desired number of title lines",
|
||||
0, G_MAXINT,
|
||||
1,
|
||||
G_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY);
|
||||
|
||||
props[PROP_SUBTITLE_LINES] =
|
||||
g_param_spec_int ("subtitle-lines",
|
||||
"Number of subtitle lines",
|
||||
"The desired number of subtitle lines",
|
||||
0, G_MAXINT,
|
||||
1,
|
||||
G_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY);
|
||||
|
||||
g_object_class_install_properties (object_class, N_PROPS, props);
|
||||
|
||||
signals[SIGNAL_ACTIVATED] =
|
||||
g_signal_new ("activated",
|
||||
G_TYPE_FROM_CLASS (klass),
|
||||
G_SIGNAL_RUN_LAST,
|
||||
0,
|
||||
NULL, NULL, NULL,
|
||||
G_TYPE_NONE,
|
||||
0);
|
||||
|
||||
gtk_widget_class_set_template_from_resource (widget_class, "/org/gnome/control-center/common/cc-vertical-row.ui");
|
||||
|
||||
gtk_widget_class_bind_template_child_private (widget_class, CcVerticalRow, content_box);
|
||||
gtk_widget_class_bind_template_child_private (widget_class, CcVerticalRow, header);
|
||||
gtk_widget_class_bind_template_child_private (widget_class, CcVerticalRow, image);
|
||||
gtk_widget_class_bind_template_child_private (widget_class, CcVerticalRow, prefixes);
|
||||
gtk_widget_class_bind_template_child_private (widget_class, CcVerticalRow, subtitle);
|
||||
gtk_widget_class_bind_template_child_private (widget_class, CcVerticalRow, suffixes);
|
||||
gtk_widget_class_bind_template_child_private (widget_class, CcVerticalRow, title);
|
||||
gtk_widget_class_bind_template_child_private (widget_class, CcVerticalRow, title_box);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
string_is_not_empty (GBinding *binding,
|
||||
const GValue *from_value,
|
||||
GValue *to_value,
|
||||
gpointer user_data)
|
||||
{
|
||||
const gchar *string = g_value_get_string (from_value);
|
||||
|
||||
g_value_set_boolean (to_value, string != NULL && g_strcmp0 (string, "") != 0);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
cc_vertical_row_init (CcVerticalRow *self)
|
||||
{
|
||||
CcVerticalRowPrivate *priv = cc_vertical_row_get_instance_private (self);
|
||||
|
||||
priv->title_lines = 1;
|
||||
priv->subtitle_lines = 1;
|
||||
|
||||
gtk_widget_init_template (GTK_WIDGET (self));
|
||||
|
||||
g_object_bind_property_full (self, "title",
|
||||
priv->title, "visible",
|
||||
G_BINDING_SYNC_CREATE,
|
||||
string_is_not_empty,
|
||||
NULL, NULL, NULL);
|
||||
|
||||
update_subtitle_visibility (self);
|
||||
|
||||
g_signal_connect (self, "notify::parent", G_CALLBACK (parent_cb), NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
cc_vertical_row_buildable_add_child (GtkBuildable *buildable,
|
||||
GtkBuilder *builder,
|
||||
GObject *child,
|
||||
const gchar *type)
|
||||
{
|
||||
CcVerticalRow *self = CC_VERTICAL_ROW (buildable);
|
||||
CcVerticalRowPrivate *priv = cc_vertical_row_get_instance_private (self);
|
||||
|
||||
if (!priv->header)
|
||||
parent_buildable_iface->add_child (buildable, builder, child, type);
|
||||
else if (type && strcmp (type, "prefix") == 0)
|
||||
cc_vertical_row_add_prefix (self, GTK_WIDGET (child));
|
||||
else if (type && strcmp (type, "content") == 0)
|
||||
cc_vertical_row_add_content (self, GTK_WIDGET (child));
|
||||
else if (!type && GTK_IS_WIDGET (child))
|
||||
{
|
||||
gtk_box_append (priv->suffixes, GTK_WIDGET (child));
|
||||
gtk_widget_show (GTK_WIDGET (priv->suffixes));
|
||||
}
|
||||
else
|
||||
parent_buildable_iface->add_child (buildable, builder, child, type);
|
||||
}
|
||||
|
||||
static void
|
||||
cc_vertical_row_buildable_init (GtkBuildableIface *iface)
|
||||
{
|
||||
parent_buildable_iface = g_type_interface_peek_parent (iface);
|
||||
iface->add_child = cc_vertical_row_buildable_add_child;
|
||||
}
|
||||
|
||||
const gchar *
|
||||
cc_vertical_row_get_subtitle (CcVerticalRow *self)
|
||||
{
|
||||
CcVerticalRowPrivate *priv = cc_vertical_row_get_instance_private (self);
|
||||
g_return_val_if_fail (CC_IS_VERTICAL_ROW (self), NULL);
|
||||
|
||||
return gtk_label_get_text (priv->subtitle);
|
||||
}
|
||||
|
||||
void
|
||||
cc_vertical_row_set_subtitle (CcVerticalRow *self,
|
||||
const gchar *subtitle)
|
||||
{
|
||||
CcVerticalRowPrivate *priv = cc_vertical_row_get_instance_private (self);
|
||||
g_return_if_fail (CC_IS_VERTICAL_ROW (self));
|
||||
|
||||
if (g_strcmp0 (gtk_label_get_text (priv->subtitle), subtitle) == 0)
|
||||
return;
|
||||
|
||||
gtk_label_set_text (priv->subtitle, subtitle);
|
||||
gtk_widget_set_visible (GTK_WIDGET (priv->subtitle),
|
||||
subtitle != NULL && g_strcmp0 (subtitle, "") != 0);
|
||||
|
||||
g_object_notify_by_pspec (G_OBJECT (self), props[PROP_SUBTITLE]);
|
||||
}
|
||||
|
||||
const gchar *
|
||||
cc_vertical_row_get_icon_name (CcVerticalRow *self)
|
||||
{
|
||||
CcVerticalRowPrivate *priv = cc_vertical_row_get_instance_private (self);
|
||||
g_return_val_if_fail (CC_IS_VERTICAL_ROW (self), NULL);
|
||||
|
||||
return gtk_image_get_icon_name (priv->image);
|
||||
}
|
||||
|
||||
void
|
||||
cc_vertical_row_set_icon_name (CcVerticalRow *self,
|
||||
const gchar *icon_name)
|
||||
{
|
||||
CcVerticalRowPrivate *priv = cc_vertical_row_get_instance_private (self);
|
||||
const gchar *old_icon_name;
|
||||
|
||||
g_return_if_fail (CC_IS_VERTICAL_ROW (self));
|
||||
|
||||
old_icon_name = gtk_image_get_icon_name (priv->image);
|
||||
if (g_strcmp0 (old_icon_name, icon_name) == 0)
|
||||
return;
|
||||
|
||||
gtk_image_set_from_icon_name (priv->image, icon_name);
|
||||
gtk_widget_set_visible (GTK_WIDGET (priv->image),
|
||||
icon_name != NULL && g_strcmp0 (icon_name, "") != 0);
|
||||
|
||||
g_object_notify_by_pspec (G_OBJECT (self), props[PROP_ICON_NAME]);
|
||||
}
|
||||
|
||||
GtkWidget *
|
||||
cc_vertical_row_get_activatable_widget (CcVerticalRow *self)
|
||||
{
|
||||
CcVerticalRowPrivate *priv = cc_vertical_row_get_instance_private (self);
|
||||
g_return_val_if_fail (CC_IS_VERTICAL_ROW (self), NULL);
|
||||
|
||||
return priv->activatable_widget;
|
||||
}
|
||||
|
||||
static void
|
||||
activatable_widget_weak_notify (gpointer data,
|
||||
GObject *where_the_object_was)
|
||||
{
|
||||
CcVerticalRow *self = CC_VERTICAL_ROW (data);
|
||||
CcVerticalRowPrivate *priv = cc_vertical_row_get_instance_private (self);
|
||||
|
||||
priv->activatable_widget = NULL;
|
||||
|
||||
g_object_notify_by_pspec (G_OBJECT (self), props[PROP_ACTIVATABLE_WIDGET]);
|
||||
}
|
||||
|
||||
void
|
||||
cc_vertical_row_set_activatable_widget (CcVerticalRow *self,
|
||||
GtkWidget *widget)
|
||||
{
|
||||
CcVerticalRowPrivate *priv = cc_vertical_row_get_instance_private (self);
|
||||
|
||||
g_return_if_fail (CC_IS_VERTICAL_ROW (self));
|
||||
g_return_if_fail (widget == NULL || GTK_IS_WIDGET (widget));
|
||||
|
||||
if (priv->activatable_widget == widget)
|
||||
return;
|
||||
|
||||
if (priv->activatable_widget)
|
||||
g_object_weak_unref (G_OBJECT (priv->activatable_widget),
|
||||
activatable_widget_weak_notify,
|
||||
self);
|
||||
|
||||
priv->activatable_widget = widget;
|
||||
|
||||
if (priv->activatable_widget != NULL) {
|
||||
g_object_weak_ref (G_OBJECT (priv->activatable_widget),
|
||||
activatable_widget_weak_notify,
|
||||
self);
|
||||
gtk_list_box_row_set_activatable (GTK_LIST_BOX_ROW (self), TRUE);
|
||||
gtk_accessible_update_relation (GTK_ACCESSIBLE (priv->activatable_widget),
|
||||
GTK_ACCESSIBLE_RELATION_LABELLED_BY, priv->title, NULL,
|
||||
GTK_ACCESSIBLE_RELATION_DESCRIBED_BY, priv->subtitle, NULL,
|
||||
-1);
|
||||
|
||||
}
|
||||
|
||||
g_object_notify_by_pspec (G_OBJECT (self), props[PROP_ACTIVATABLE_WIDGET]);
|
||||
}
|
||||
|
||||
gboolean
|
||||
cc_vertical_row_get_use_underline (CcVerticalRow *self)
|
||||
{
|
||||
CcVerticalRowPrivate *priv = cc_vertical_row_get_instance_private (self);
|
||||
|
||||
g_return_val_if_fail (CC_IS_VERTICAL_ROW (self), FALSE);
|
||||
|
||||
return priv->use_underline;
|
||||
}
|
||||
|
||||
void
|
||||
cc_vertical_row_set_use_underline (CcVerticalRow *self,
|
||||
gboolean use_underline)
|
||||
{
|
||||
CcVerticalRowPrivate *priv = cc_vertical_row_get_instance_private (self);
|
||||
|
||||
g_return_if_fail (CC_IS_VERTICAL_ROW (self));
|
||||
|
||||
use_underline = !!use_underline;
|
||||
|
||||
if (priv->use_underline == use_underline)
|
||||
return;
|
||||
|
||||
priv->use_underline = use_underline;
|
||||
adw_preferences_row_set_use_underline (ADW_PREFERENCES_ROW (self), priv->use_underline);
|
||||
gtk_label_set_use_underline (priv->title, priv->use_underline);
|
||||
gtk_label_set_use_underline (priv->subtitle, priv->use_underline);
|
||||
gtk_label_set_mnemonic_widget (priv->title, GTK_WIDGET (self));
|
||||
gtk_label_set_mnemonic_widget (priv->subtitle, GTK_WIDGET (self));
|
||||
|
||||
g_object_notify_by_pspec (G_OBJECT (self), props[PROP_USE_UNDERLINE]);
|
||||
}
|
||||
|
||||
gint
|
||||
cc_vertical_row_get_title_lines (CcVerticalRow *self)
|
||||
{
|
||||
CcVerticalRowPrivate *priv = cc_vertical_row_get_instance_private (self);
|
||||
|
||||
g_return_val_if_fail (CC_IS_VERTICAL_ROW (self), 0);
|
||||
|
||||
return priv->title_lines;
|
||||
}
|
||||
|
||||
void
|
||||
cc_vertical_row_set_title_lines (CcVerticalRow *self,
|
||||
gint title_lines)
|
||||
{
|
||||
CcVerticalRowPrivate *priv = cc_vertical_row_get_instance_private (self);
|
||||
|
||||
g_return_if_fail (CC_IS_VERTICAL_ROW (self));
|
||||
g_return_if_fail (title_lines >= 0);
|
||||
|
||||
if (priv->title_lines == title_lines)
|
||||
return;
|
||||
|
||||
priv->title_lines = title_lines;
|
||||
|
||||
gtk_label_set_lines (priv->title, title_lines);
|
||||
gtk_label_set_ellipsize (priv->title, title_lines == 0 ? PANGO_ELLIPSIZE_NONE : PANGO_ELLIPSIZE_END);
|
||||
|
||||
g_object_notify_by_pspec (G_OBJECT (self), props[PROP_TITLE_LINES]);
|
||||
}
|
||||
|
||||
gint
|
||||
cc_vertical_row_get_subtitle_lines (CcVerticalRow *self)
|
||||
{
|
||||
CcVerticalRowPrivate *priv = cc_vertical_row_get_instance_private (self);
|
||||
|
||||
g_return_val_if_fail (CC_IS_VERTICAL_ROW (self), 0);
|
||||
|
||||
return priv->subtitle_lines;
|
||||
}
|
||||
|
||||
void
|
||||
cc_vertical_row_set_subtitle_lines (CcVerticalRow *self,
|
||||
gint subtitle_lines)
|
||||
{
|
||||
CcVerticalRowPrivate *priv = cc_vertical_row_get_instance_private (self);
|
||||
|
||||
g_return_if_fail (CC_IS_VERTICAL_ROW (self));
|
||||
g_return_if_fail (subtitle_lines >= 0);
|
||||
|
||||
if (priv->subtitle_lines == subtitle_lines)
|
||||
return;
|
||||
|
||||
priv->subtitle_lines = subtitle_lines;
|
||||
|
||||
gtk_label_set_lines (priv->subtitle, subtitle_lines);
|
||||
gtk_label_set_ellipsize (priv->subtitle, subtitle_lines == 0 ? PANGO_ELLIPSIZE_NONE : PANGO_ELLIPSIZE_END);
|
||||
|
||||
g_object_notify_by_pspec (G_OBJECT (self), props[PROP_SUBTITLE_LINES]);
|
||||
}
|
||||
|
||||
void
|
||||
cc_vertical_row_add_prefix (CcVerticalRow *self,
|
||||
GtkWidget *widget)
|
||||
{
|
||||
CcVerticalRowPrivate *priv = cc_vertical_row_get_instance_private (self);
|
||||
|
||||
g_return_if_fail (CC_IS_VERTICAL_ROW (self));
|
||||
g_return_if_fail (GTK_IS_WIDGET (self));
|
||||
|
||||
gtk_box_append (priv->prefixes, widget);
|
||||
gtk_widget_show (GTK_WIDGET (priv->prefixes));
|
||||
}
|
||||
|
||||
void
|
||||
cc_vertical_row_add_content (CcVerticalRow *self,
|
||||
GtkWidget *widget)
|
||||
{
|
||||
CcVerticalRowPrivate *priv = cc_vertical_row_get_instance_private (self);
|
||||
|
||||
g_return_if_fail (CC_IS_VERTICAL_ROW (self));
|
||||
g_return_if_fail (GTK_IS_WIDGET (self));
|
||||
|
||||
/* HACK: the content box pushes the title too much to the top, so we
|
||||
* need to compensate this here.
|
||||
*/
|
||||
gtk_widget_set_margin_top (GTK_WIDGET (priv->header), 12);
|
||||
|
||||
gtk_box_append (priv->content_box, widget);
|
||||
gtk_widget_set_visible (GTK_WIDGET (priv->content_box), TRUE);
|
||||
}
|
||||
|
||||
void
|
||||
cc_vertical_row_activate (CcVerticalRow *self)
|
||||
{
|
||||
CcVerticalRowPrivate *priv = cc_vertical_row_get_instance_private (self);
|
||||
g_return_if_fail (CC_IS_VERTICAL_ROW (self));
|
||||
|
||||
if (priv->activatable_widget)
|
||||
gtk_widget_mnemonic_activate (priv->activatable_widget, FALSE);
|
||||
|
||||
g_signal_emit (self, signals[SIGNAL_ACTIVATED], 0);
|
||||
}
|
||||
|
||||
void
|
||||
cc_vertical_row_remove (CcVerticalRow *self,
|
||||
GtkWidget *child)
|
||||
{
|
||||
CcVerticalRowPrivate *priv = cc_vertical_row_get_instance_private (self);
|
||||
GtkWidget *parent;
|
||||
|
||||
g_return_if_fail (CC_IS_VERTICAL_ROW (self));
|
||||
g_return_if_fail (GTK_IS_WIDGET (child));
|
||||
|
||||
parent = gtk_widget_get_parent (child);
|
||||
|
||||
if (parent == GTK_WIDGET (priv->prefixes))
|
||||
gtk_box_remove (priv->prefixes, child);
|
||||
else if (parent == GTK_WIDGET (priv->suffixes))
|
||||
gtk_box_remove (priv->suffixes, child);
|
||||
else if (parent == GTK_WIDGET (priv->content_box))
|
||||
gtk_box_remove (priv->content_box, child);
|
||||
else
|
||||
g_warning ("%p is not a child of %p", child, self);
|
||||
}
|
||||
|
||||
@@ -1,75 +0,0 @@
|
||||
/* cc-vertical-row.h
|
||||
*
|
||||
* Copyright 2018 Purism SPC
|
||||
* 2021 Georges Basile Stavracas Neto <georges.stavracas@gmail.com>
|
||||
* 2023 Red Hat, Inc
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-3.0-or-later
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <adwaita.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define CC_TYPE_VERTICAL_ROW (cc_vertical_row_get_type())
|
||||
G_DECLARE_DERIVABLE_TYPE (CcVerticalRow, cc_vertical_row, CC, VERTICAL_ROW, AdwPreferencesRow)
|
||||
|
||||
struct _CcVerticalRowClass
|
||||
{
|
||||
AdwPreferencesRowClass parent_class;
|
||||
|
||||
/*< private >*/
|
||||
gpointer padding[4];
|
||||
};
|
||||
|
||||
const gchar *cc_vertical_row_get_subtitle (CcVerticalRow *self);
|
||||
void cc_vertical_row_set_subtitle (CcVerticalRow *self,
|
||||
const gchar *subtitle);
|
||||
|
||||
const gchar *cc_vertical_row_get_icon_name (CcVerticalRow *self);
|
||||
void cc_vertical_row_set_icon_name (CcVerticalRow *self,
|
||||
const gchar *icon_name);
|
||||
|
||||
GtkWidget *cc_vertical_row_get_activatable_widget (CcVerticalRow *self);
|
||||
void cc_vertical_row_set_activatable_widget (CcVerticalRow *self,
|
||||
GtkWidget *widget);
|
||||
|
||||
gboolean cc_vertical_row_get_use_underline (CcVerticalRow *self);
|
||||
void cc_vertical_row_set_use_underline (CcVerticalRow *self,
|
||||
gboolean use_underline);
|
||||
|
||||
gint cc_vertical_row_get_title_lines (CcVerticalRow *self);
|
||||
void cc_vertical_row_set_title_lines (CcVerticalRow *self,
|
||||
gint title_lines);
|
||||
|
||||
gint cc_vertical_row_get_subtitle_lines (CcVerticalRow *self);
|
||||
void cc_vertical_row_set_subtitle_lines (CcVerticalRow *self,
|
||||
gint subtitle_lines);
|
||||
|
||||
void cc_vertical_row_add_prefix (CcVerticalRow *self,
|
||||
GtkWidget *widget);
|
||||
|
||||
void cc_vertical_row_add_content (CcVerticalRow *self,
|
||||
GtkWidget *widget);
|
||||
|
||||
void cc_vertical_row_activate (CcVerticalRow *self);
|
||||
|
||||
void cc_vertical_row_remove (CcVerticalRow *self,
|
||||
GtkWidget *child);
|
||||
|
||||
G_END_DECLS
|
||||
@@ -1,13 +1,10 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<gresources>
|
||||
<gresource prefix="/org/gnome/control-center/common">
|
||||
<file preprocess="xml-stripblanks">cc-illustrated-row.ui</file>
|
||||
<file preprocess="xml-stripblanks">cc-language-chooser.ui</file>
|
||||
<file preprocess="xml-stripblanks">cc-language-row.ui</file>
|
||||
<file preprocess="xml-stripblanks">cc-list-row.ui</file>
|
||||
<file preprocess="xml-stripblanks">cc-time-editor.ui</file>
|
||||
<file preprocess="xml-stripblanks">cc-permission-infobar.ui</file>
|
||||
<file preprocess="xml-stripblanks">cc-split-row.ui</file>
|
||||
<file preprocess="xml-stripblanks">cc-vertical-row.ui</file>
|
||||
</gresource>
|
||||
</gresources>
|
||||
|
||||
@@ -25,14 +25,11 @@ common_sources += gnome.mkenums(
|
||||
)
|
||||
|
||||
resource_data = files(
|
||||
'cc-illustrated-row.ui',
|
||||
'cc-language-chooser.ui',
|
||||
'cc-language-row.ui',
|
||||
'cc-list-row.ui',
|
||||
'cc-time-editor.ui',
|
||||
'cc-permission-infobar.ui',
|
||||
'cc-split-row.ui',
|
||||
'cc-vertical-row.ui',
|
||||
)
|
||||
|
||||
common_sources += gnome.compile_resources(
|
||||
@@ -66,14 +63,11 @@ libwidgets_dep = declare_dependency(
|
||||
|
||||
sources = common_sources + files(
|
||||
'cc-common-language.c',
|
||||
'cc-illustrated-row.c',
|
||||
'cc-language-chooser.c',
|
||||
'cc-language-row.c',
|
||||
'cc-list-row.c',
|
||||
'cc-time-editor.c',
|
||||
'cc-permission-infobar.c',
|
||||
'cc-split-row.c',
|
||||
'cc-vertical-row.c',
|
||||
'cc-util.c'
|
||||
)
|
||||
|
||||
|
||||
@@ -20,20 +20,18 @@
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
#include "cc-list-row.h"
|
||||
#include "cc-time-editor.h"
|
||||
#include "cc-datetime-panel.h"
|
||||
#include "cc-datetime-resources.h"
|
||||
|
||||
#include <langinfo.h>
|
||||
#include <sys/time.h>
|
||||
#include "cc-tz-dialog.h"
|
||||
#include "cc-timezone-map.h"
|
||||
#include "timedated.h"
|
||||
#include "date-endian.h"
|
||||
#define GNOME_DESKTOP_USE_UNSTABLE_API
|
||||
|
||||
#include <gdesktop-enums.h>
|
||||
#include "gdesktop-enums-types.h"
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <libintl.h>
|
||||
@@ -47,6 +45,12 @@
|
||||
#define DEFAULT_TZ "Europe/London"
|
||||
#define GETTEXT_PACKAGE_TIMEZONES GETTEXT_PACKAGE "-timezones"
|
||||
|
||||
enum {
|
||||
CITY_COL_CITY_HUMAN_READABLE,
|
||||
CITY_COL_ZONE,
|
||||
CITY_NUM_COLS
|
||||
};
|
||||
|
||||
#define DATETIME_PERMISSION "org.gnome.controlcenter.datetime.configure"
|
||||
#define DATETIME_TZ_PERMISSION "org.freedesktop.timedate1.set-timezone"
|
||||
#define LOCATION_SETTINGS "org.gnome.system.location"
|
||||
@@ -64,6 +68,8 @@ struct _CcDateTimePanel
|
||||
{
|
||||
CcPanel parent_instance;
|
||||
|
||||
GtkWidget *map;
|
||||
|
||||
GList *toplevels;
|
||||
|
||||
TzLocation *current_location;
|
||||
@@ -76,9 +82,12 @@ struct _CcDateTimePanel
|
||||
GSettings *datetime_settings;
|
||||
GSettings *filechooser_settings;
|
||||
GDesktopClockFormat clock_format;
|
||||
GtkFrame *aspectmap;
|
||||
GtkWidget *auto_datetime_row;
|
||||
GtkWidget *auto_timezone_row;
|
||||
GtkWidget *auto_timezone_switch;
|
||||
GtkListStore *city_liststore;
|
||||
GtkTreeModelSort *city_modelsort;
|
||||
GtkWidget *date_grid;
|
||||
GtkWidget *datetime_button;
|
||||
GtkWidget *datetime_dialog;
|
||||
@@ -89,15 +98,14 @@ struct _CcDateTimePanel
|
||||
GtkLockButton *lock_button;
|
||||
GtkListBox *date_box;
|
||||
GtkListBoxRow *day_row;
|
||||
GtkSingleSelection *month_model;
|
||||
GtkPopover *month_popover;
|
||||
GtkListBoxRow *month_row;
|
||||
AdwComboRow *month_row;
|
||||
GtkListBoxRow *year_row;
|
||||
GtkWidget *network_time_switch;
|
||||
GtkWidget *time_editor;
|
||||
GtkWidget *timezone_button;
|
||||
GtkWidget *timezone_dialog;
|
||||
GtkWidget *timezone_label;
|
||||
GtkWidget *timezone_searchentry;
|
||||
GtkWidget *year_spinbutton;
|
||||
|
||||
GnomeWallClock *clock_tracker;
|
||||
@@ -105,8 +113,6 @@ struct _CcDateTimePanel
|
||||
Timedate1 *dtm;
|
||||
GCancellable *cancellable;
|
||||
|
||||
gboolean pending_ntp_state;
|
||||
|
||||
GPermission *permission;
|
||||
GPermission *tz_permission;
|
||||
GSettings *location_settings;
|
||||
@@ -248,7 +254,7 @@ update_time (CcDateTimePanel *self)
|
||||
}
|
||||
|
||||
self->month = g_date_time_get_month (self->date);
|
||||
gtk_single_selection_set_selected (self->month_model, self->month - 1);
|
||||
adw_combo_row_set_selected (self->month_row, self->month - 1);
|
||||
gtk_label_set_text (GTK_LABEL (self->datetime_label), label);
|
||||
}
|
||||
|
||||
@@ -305,10 +311,6 @@ set_using_ntp_cb (GObject *source,
|
||||
/* TODO: display any error in a user friendly way */
|
||||
g_warning ("Could not set system to use NTP: %s", error->message);
|
||||
}
|
||||
else
|
||||
{
|
||||
gtk_switch_set_state (GTK_SWITCH (self->network_time_switch), self->pending_ntp_state);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -329,10 +331,12 @@ queue_set_datetime (CcDateTimePanel *self)
|
||||
}
|
||||
|
||||
static void
|
||||
queue_set_ntp (CcDateTimePanel *self,
|
||||
gboolean using_ntp)
|
||||
queue_set_ntp (CcDateTimePanel *self)
|
||||
{
|
||||
self->pending_ntp_state = using_ntp;
|
||||
gboolean using_ntp;
|
||||
/* for now just do it */
|
||||
using_ntp = gtk_switch_get_active (GTK_SWITCH (self->network_time_switch));
|
||||
|
||||
timedate1_call_set_ntp (self->dtm,
|
||||
using_ntp,
|
||||
TRUE,
|
||||
@@ -377,6 +381,25 @@ change_date (CcDateTimePanel *self)
|
||||
queue_set_datetime (self);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
city_changed_cb (CcDateTimePanel *self,
|
||||
GtkTreeModel *model,
|
||||
GtkTreeIter *iter,
|
||||
GtkEntryCompletion *completion)
|
||||
{
|
||||
GtkWidget *entry;
|
||||
g_autofree gchar *zone = NULL;
|
||||
|
||||
gtk_tree_model_get (model, iter,
|
||||
CITY_COL_ZONE, &zone, -1);
|
||||
cc_timezone_map_set_timezone (CC_TIMEZONE_MAP (self->map), zone);
|
||||
|
||||
entry = gtk_entry_completion_get_entry (completion);
|
||||
gtk_editable_set_text (GTK_EDITABLE (entry), "");
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static char *
|
||||
translated_city_name (TzLocation *loc)
|
||||
{
|
||||
@@ -407,8 +430,18 @@ translated_city_name (TzLocation *loc)
|
||||
static void
|
||||
update_timezone (CcDateTimePanel *self)
|
||||
{
|
||||
g_autofree gchar *bubble_text = NULL;
|
||||
g_autofree gchar *city_country = NULL;
|
||||
g_autofree gchar *label = NULL;
|
||||
g_autofree gchar *time_label = NULL;
|
||||
g_autofree gchar *utc_label = NULL;
|
||||
g_autofree gchar *tz_desc = NULL;
|
||||
gboolean use_ampm;
|
||||
|
||||
if (self->clock_format == G_DESKTOP_CLOCK_FORMAT_12H)
|
||||
use_ampm = TRUE;
|
||||
else
|
||||
use_ampm = FALSE;
|
||||
|
||||
city_country = translated_city_name (self->current_location);
|
||||
|
||||
@@ -418,6 +451,62 @@ update_timezone (CcDateTimePanel *self)
|
||||
g_date_time_get_timezone_abbreviation (self->date),
|
||||
city_country);
|
||||
gtk_label_set_text (GTK_LABEL (self->timezone_label), label);
|
||||
|
||||
/* Translators: UTC here means the Coordinated Universal Time.
|
||||
* %:::z will be replaced by the offset from UTC e.g. UTC+02 */
|
||||
utc_label = g_date_time_format (self->date, _("UTC%:::z"));
|
||||
|
||||
if (use_ampm)
|
||||
{
|
||||
/* Translators: This is the time format used in 12-hour mode. */
|
||||
time_label = g_date_time_format (self->date, _("%l:%M %p"));
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Translators: This is the time format used in 24-hour mode. */
|
||||
time_label = g_date_time_format (self->date, _("%R"));
|
||||
}
|
||||
|
||||
/* Update the text bubble in the timezone map */
|
||||
/* Translators: "timezone (utc shift)" */
|
||||
tz_desc = g_strdup_printf (C_("timezone map", "%s (%s)"),
|
||||
g_date_time_get_timezone_abbreviation (self->date),
|
||||
utc_label);
|
||||
bubble_text = g_strdup_printf ("<b>%s</b>\n"
|
||||
"<small>%s</small>\n"
|
||||
"<b>%s</b>",
|
||||
tz_desc,
|
||||
city_country,
|
||||
time_label);
|
||||
cc_timezone_map_set_bubble_text (CC_TIMEZONE_MAP (self->map), bubble_text);
|
||||
}
|
||||
|
||||
static void
|
||||
location_changed_cb (CcDateTimePanel *self,
|
||||
TzLocation *location)
|
||||
{
|
||||
g_autoptr(GDateTime) old_date = NULL;
|
||||
g_autoptr(GTimeZone) timezone = NULL;
|
||||
|
||||
g_debug ("location changed to %s/%s", location->country, location->zone);
|
||||
|
||||
self->current_location = location;
|
||||
|
||||
timezone = g_time_zone_new_identifier (location->zone);
|
||||
if (!timezone)
|
||||
{
|
||||
g_warning ("Could not find timezone \"%s\", using UTC instead", location->zone);
|
||||
timezone = g_time_zone_new_utc ();
|
||||
}
|
||||
|
||||
old_date = self->date;
|
||||
self->date = g_date_time_to_timezone (old_date, timezone);
|
||||
cc_time_editor_set_time (CC_TIME_EDITOR (self->time_editor),
|
||||
g_date_time_get_hour (self->date),
|
||||
g_date_time_get_minute (self->date));
|
||||
|
||||
update_timezone (self);
|
||||
queue_set_timezone (self);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -428,16 +517,37 @@ get_initial_timezone (CcDateTimePanel *self)
|
||||
timezone = timedate1_get_timezone (self->dtm);
|
||||
|
||||
if (timezone == NULL ||
|
||||
!cc_tz_dialog_set_tz (CC_TZ_DIALOG (self->timezone_dialog), timezone))
|
||||
!cc_timezone_map_set_timezone (CC_TIMEZONE_MAP (self->map), timezone))
|
||||
{
|
||||
g_warning ("Timezone '%s' is unhandled, setting %s as default", timezone ? timezone : "(null)", DEFAULT_TZ);
|
||||
cc_tz_dialog_set_tz (CC_TZ_DIALOG (self->timezone_dialog), DEFAULT_TZ);
|
||||
cc_timezone_map_set_timezone (CC_TIMEZONE_MAP (self->map), DEFAULT_TZ);
|
||||
}
|
||||
|
||||
self->current_location = cc_tz_dialog_get_selected_location (CC_TZ_DIALOG (self->timezone_dialog));
|
||||
self->current_location = cc_timezone_map_get_location (CC_TIMEZONE_MAP (self->map));
|
||||
update_timezone (self);
|
||||
}
|
||||
|
||||
static void
|
||||
load_cities (TzLocation *loc,
|
||||
GtkListStore *city_store)
|
||||
{
|
||||
g_autofree gchar *human_readable = NULL;
|
||||
|
||||
human_readable = translated_city_name (loc);
|
||||
gtk_list_store_insert_with_values (city_store, NULL, 0,
|
||||
CITY_COL_CITY_HUMAN_READABLE, human_readable,
|
||||
CITY_COL_ZONE, loc->zone,
|
||||
-1);
|
||||
}
|
||||
|
||||
static void
|
||||
load_regions_model (GtkListStore *cities)
|
||||
{
|
||||
g_autoptr(TzDB) db = NULL;
|
||||
|
||||
db = tz_load_db ();
|
||||
g_ptr_array_foreach (db->locations, (GFunc) load_cities, cities);
|
||||
}
|
||||
|
||||
static void
|
||||
day_changed (CcDateTimePanel *panel)
|
||||
{
|
||||
@@ -468,29 +578,20 @@ month_year_changed (CcDateTimePanel *self)
|
||||
}
|
||||
|
||||
static void
|
||||
on_date_box_row_activated_cb (CcDateTimePanel *self,
|
||||
GtkListBoxRow *row)
|
||||
on_month_row_selected_changed_cb (AdwComboRow *month_row,
|
||||
GParamSpec *pspec,
|
||||
CcDateTimePanel *self)
|
||||
{
|
||||
g_assert (CC_IS_DATE_TIME_PANEL (self));
|
||||
|
||||
if (row == self->month_row)
|
||||
gtk_popover_popup (self->month_popover);
|
||||
}
|
||||
|
||||
static void
|
||||
on_month_selection_changed_cb (CcDateTimePanel *self)
|
||||
{
|
||||
guint i;
|
||||
unsigned int i;
|
||||
|
||||
g_assert (CC_IS_DATE_TIME_PANEL (self));
|
||||
g_assert (ADW_IS_COMBO_ROW (month_row));
|
||||
|
||||
i = gtk_single_selection_get_selected (self->month_model);
|
||||
i = adw_combo_row_get_selected (month_row);
|
||||
g_assert (i >= 0 && i < 12);
|
||||
|
||||
self->month = i + 1;
|
||||
month_year_changed (self);
|
||||
|
||||
gtk_popover_popdown (self->month_popover);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -504,10 +605,9 @@ on_clock_changed (CcDateTimePanel *panel,
|
||||
}
|
||||
|
||||
static gboolean
|
||||
change_ntp (CcDateTimePanel *self,
|
||||
gboolean state)
|
||||
change_ntp (CcDateTimePanel *self)
|
||||
{
|
||||
queue_set_ntp (self, state);
|
||||
queue_set_ntp (self);
|
||||
|
||||
/* The new state will be visible once we see the reply. */
|
||||
return TRUE;
|
||||
@@ -523,7 +623,7 @@ on_ntp_changed (CcDateTimePanel *self)
|
||||
g_signal_handlers_block_by_func (self->network_time_switch, change_ntp, self);
|
||||
|
||||
g_object_set (self->network_time_switch,
|
||||
"active", ntp_on,
|
||||
"state", ntp_on,
|
||||
NULL);
|
||||
|
||||
g_signal_handlers_unblock_by_func (self->network_time_switch, change_ntp, self);
|
||||
@@ -587,7 +687,9 @@ on_can_ntp_changed (CcDateTimePanel *self)
|
||||
static void
|
||||
on_timezone_changed (CcDateTimePanel *self)
|
||||
{
|
||||
g_signal_handlers_block_by_func (self->map, location_changed_cb, self);
|
||||
get_initial_timezone (self);
|
||||
g_signal_handlers_unblock_by_func (self->map, location_changed_cb, self);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -682,15 +784,6 @@ bind_switch_to_row (CcDateTimePanel *self,
|
||||
NULL, self, NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
panel_tz_selection_changed_cb (CcDateTimePanel *self)
|
||||
{
|
||||
g_assert (CC_IS_DATE_TIME_PANEL (self));
|
||||
|
||||
self->current_location = cc_tz_dialog_get_selected_location (CC_TZ_DIALOG (self->timezone_dialog));
|
||||
queue_set_timezone (self);
|
||||
}
|
||||
|
||||
static void
|
||||
list_box_row_activated (CcDateTimePanel *self,
|
||||
GtkListBoxRow *row)
|
||||
@@ -727,6 +820,24 @@ time_changed_cb (CcDateTimePanel *self,
|
||||
queue_set_datetime (self);
|
||||
}
|
||||
|
||||
static void
|
||||
setup_timezone_dialog (CcDateTimePanel *self)
|
||||
{
|
||||
g_autoptr(GtkEntryCompletion) completion = NULL;
|
||||
|
||||
/* set up timezone map */
|
||||
self->map = (GtkWidget *) cc_timezone_map_new ();
|
||||
gtk_frame_set_child (self->aspectmap, self->map);
|
||||
|
||||
/* Create the completion object */
|
||||
completion = gtk_entry_completion_new ();
|
||||
gtk_entry_set_completion (GTK_ENTRY (self->timezone_searchentry), completion);
|
||||
|
||||
gtk_entry_completion_set_model (completion, GTK_TREE_MODEL (self->city_modelsort));
|
||||
|
||||
gtk_entry_completion_set_text_column (completion, CITY_COL_CITY_HUMAN_READABLE);
|
||||
}
|
||||
|
||||
static void
|
||||
setup_datetime_dialog (CcDateTimePanel *self)
|
||||
{
|
||||
@@ -742,9 +853,6 @@ setup_datetime_dialog (CcDateTimePanel *self)
|
||||
".gnome-control-center-datetime-setup-time>label {\n"
|
||||
" font-size: 250%;\n"
|
||||
"}\n"
|
||||
"gridview.month-grid > child {\n"
|
||||
" background: transparent;\n"
|
||||
"}\n"
|
||||
".gnome-control-center-datetime-setup-time>spinbutton>entry {\n"
|
||||
" padding: 8px 13px;\n"
|
||||
"}", -1);
|
||||
@@ -774,7 +882,7 @@ setup_datetime_dialog (CcDateTimePanel *self)
|
||||
|
||||
/* Month */
|
||||
self->month = g_date_time_get_month (self->date);
|
||||
gtk_single_selection_set_selected (self->month_model, self->month - 1);
|
||||
adw_combo_row_set_selected (self->month_row, self->month - 1);
|
||||
}
|
||||
|
||||
static int
|
||||
@@ -832,15 +940,14 @@ cc_date_time_panel_class_init (CcDateTimePanelClass *klass)
|
||||
|
||||
panel_class->get_help_uri = cc_date_time_panel_get_help_uri;
|
||||
|
||||
g_type_ensure (CC_TYPE_LIST_ROW);
|
||||
g_type_ensure (CC_TYPE_TZ_DIALOG);
|
||||
g_type_ensure (G_DESKTOP_TYPE_DESKTOP_CLOCK_FORMAT);
|
||||
|
||||
gtk_widget_class_set_template_from_resource (widget_class, "/org/gnome/control-center/datetime/cc-datetime-panel.ui");
|
||||
|
||||
gtk_widget_class_bind_template_child (widget_class, CcDateTimePanel, aspectmap);
|
||||
gtk_widget_class_bind_template_child (widget_class, CcDateTimePanel, auto_datetime_row);
|
||||
gtk_widget_class_bind_template_child (widget_class, CcDateTimePanel, auto_timezone_row);
|
||||
gtk_widget_class_bind_template_child (widget_class, CcDateTimePanel, auto_timezone_switch);
|
||||
gtk_widget_class_bind_template_child (widget_class, CcDateTimePanel, city_liststore);
|
||||
gtk_widget_class_bind_template_child (widget_class, CcDateTimePanel, city_modelsort);
|
||||
gtk_widget_class_bind_template_child (widget_class, CcDateTimePanel, date_box);
|
||||
gtk_widget_class_bind_template_child (widget_class, CcDateTimePanel, datetime_button);
|
||||
gtk_widget_class_bind_template_child (widget_class, CcDateTimePanel, datetime_dialog);
|
||||
@@ -849,24 +956,21 @@ cc_date_time_panel_class_init (CcDateTimePanelClass *klass)
|
||||
gtk_widget_class_bind_template_child (widget_class, CcDateTimePanel, day_spinbutton);
|
||||
gtk_widget_class_bind_template_child (widget_class, CcDateTimePanel, timeformat_row);
|
||||
gtk_widget_class_bind_template_child (widget_class, CcDateTimePanel, lock_button);
|
||||
gtk_widget_class_bind_template_child (widget_class, CcDateTimePanel, month_model);
|
||||
gtk_widget_class_bind_template_child (widget_class, CcDateTimePanel, month_popover);
|
||||
gtk_widget_class_bind_template_child (widget_class, CcDateTimePanel, month_row);
|
||||
gtk_widget_class_bind_template_child (widget_class, CcDateTimePanel, network_time_switch);
|
||||
gtk_widget_class_bind_template_child (widget_class, CcDateTimePanel, time_editor);
|
||||
gtk_widget_class_bind_template_child (widget_class, CcDateTimePanel, timezone_button);
|
||||
gtk_widget_class_bind_template_child (widget_class, CcDateTimePanel, timezone_dialog);
|
||||
gtk_widget_class_bind_template_child (widget_class, CcDateTimePanel, timezone_label);
|
||||
gtk_widget_class_bind_template_child (widget_class, CcDateTimePanel, timezone_searchentry);
|
||||
gtk_widget_class_bind_template_child (widget_class, CcDateTimePanel, year_row);
|
||||
gtk_widget_class_bind_template_child (widget_class, CcDateTimePanel, year_spinbutton);
|
||||
|
||||
gtk_widget_class_bind_template_callback (widget_class, panel_tz_selection_changed_cb);
|
||||
gtk_widget_class_bind_template_callback (widget_class, list_box_row_activated);
|
||||
gtk_widget_class_bind_template_callback (widget_class, time_changed_cb);
|
||||
gtk_widget_class_bind_template_callback (widget_class, change_clock_settings);
|
||||
gtk_widget_class_bind_template_callback (widget_class, format_clock_name_cb);
|
||||
gtk_widget_class_bind_template_callback (widget_class, on_date_box_row_activated_cb);
|
||||
gtk_widget_class_bind_template_callback (widget_class, on_month_selection_changed_cb);
|
||||
gtk_widget_class_bind_template_callback (widget_class, on_month_row_selected_changed_cb);
|
||||
|
||||
bind_textdomain_codeset (GETTEXT_PACKAGE_TIMEZONES, "UTF-8");
|
||||
|
||||
@@ -926,7 +1030,7 @@ cc_date_time_panel_init (CcDateTimePanel *self)
|
||||
self->toplevels = g_list_append (self->toplevels, self->datetime_dialog);
|
||||
self->toplevels = g_list_append (self->toplevels, self->timezone_dialog);
|
||||
|
||||
/* setup_timezone_dialog (self); */
|
||||
setup_timezone_dialog (self);
|
||||
setup_datetime_dialog (self);
|
||||
|
||||
/* set up network time switch */
|
||||
@@ -966,10 +1070,21 @@ cc_date_time_panel_init (CcDateTimePanel *self)
|
||||
|
||||
update_time (self);
|
||||
|
||||
load_regions_model (GTK_LIST_STORE (self->city_liststore));
|
||||
|
||||
gtk_tree_sortable_set_sort_column_id (GTK_TREE_SORTABLE (self->city_modelsort), CITY_COL_CITY_HUMAN_READABLE,
|
||||
GTK_SORT_ASCENDING);
|
||||
|
||||
/* After the initial setup, so we can be sure that
|
||||
* the model is filled up */
|
||||
get_initial_timezone (self);
|
||||
|
||||
g_signal_connect_object (gtk_entry_get_completion (GTK_ENTRY (self->timezone_searchentry)),
|
||||
"match-selected", G_CALLBACK (city_changed_cb), self, G_CONNECT_SWAPPED);
|
||||
|
||||
g_signal_connect_object (self->map, "location-changed",
|
||||
G_CALLBACK (location_changed_cb), self, G_CONNECT_SWAPPED);
|
||||
|
||||
/* Watch changes of timedated remote service properties */
|
||||
g_signal_connect_object (self->dtm, "g-properties-changed",
|
||||
G_CALLBACK (on_timedated_properties_changed), self, G_CONNECT_SWAPPED);
|
||||
|
||||
@@ -1,10 +1,16 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<interface>
|
||||
|
||||
<object class="CcTzDialog" id="timezone_dialog">
|
||||
<signal name="tz-selected" handler="panel_tz_selection_changed_cb" swapped="yes"/>
|
||||
<object class="GtkListStore" id="city_liststore">
|
||||
<columns>
|
||||
<!-- column-name city-human-readable -->
|
||||
<column type="gchararray"/>
|
||||
<!-- column-name zone -->
|
||||
<column type="gchararray"/>
|
||||
</columns>
|
||||
</object>
|
||||
<object class="GtkTreeModelSort" id="city_modelsort">
|
||||
<property name="model">city_liststore</property>
|
||||
</object>
|
||||
|
||||
<object class="GtkDialog" id="datetime_dialog">
|
||||
<property name="title" translatable="yes">Date & Time</property>
|
||||
<property name="modal">True</property>
|
||||
@@ -34,7 +40,6 @@
|
||||
<object class="GtkListBox" id="date_box">
|
||||
<property name="width-request">320</property>
|
||||
<property name="selection-mode">none</property>
|
||||
<signal name="row-activated" handler="on_date_box_row_activated_cb" swapped="yes"/>
|
||||
<style>
|
||||
<class name="boxed-list"/>
|
||||
</style>
|
||||
@@ -57,28 +62,27 @@
|
||||
|
||||
<!-- Month row -->
|
||||
<child>
|
||||
<object class="CcListRow" id="month_row">
|
||||
<object class="AdwComboRow" id="month_row">
|
||||
<property name="title" translatable="yes">Month</property>
|
||||
<binding name="secondary-label">
|
||||
<lookup name="string" type="GtkStringObject">
|
||||
<lookup name="selected-item">month_model</lookup>
|
||||
</lookup>
|
||||
</binding>
|
||||
<child type="suffix">
|
||||
<object class="GtkBox">
|
||||
<property name="valign">center</property>
|
||||
<child>
|
||||
<object class="GtkImage">
|
||||
<property name="icon-name">pan-down-symbolic</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkPopover" id="month_popover">
|
||||
<property name="child">month_grid</property>
|
||||
</object>
|
||||
</child>
|
||||
<signal name="notify::selected" handler="on_month_row_selected_changed_cb" object="CcDateTimePanel" swapped="no" />
|
||||
<property name="model">
|
||||
<object class="GtkStringList">
|
||||
<items>
|
||||
<item translatable="yes">January</item>
|
||||
<item translatable="yes">February</item>
|
||||
<item translatable="yes">March</item>
|
||||
<item translatable="yes">April</item>
|
||||
<item translatable="yes">May</item>
|
||||
<item translatable="yes">June</item>
|
||||
<item translatable="yes">July</item>
|
||||
<item translatable="yes">August</item>
|
||||
<item translatable="yes">September</item>
|
||||
<item translatable="yes">October</item>
|
||||
<item translatable="yes">November</item>
|
||||
<item translatable="yes">December</item>
|
||||
</items>
|
||||
</object>
|
||||
</child>
|
||||
</property>
|
||||
</object>
|
||||
</child>
|
||||
|
||||
@@ -105,6 +109,44 @@
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
<object class="GtkDialog" id="timezone_dialog">
|
||||
<property name="title" translatable="yes">Time Zone</property>
|
||||
<property name="resizable">False</property>
|
||||
<property name="modal">True</property>
|
||||
<property name="use_header_bar">1</property>
|
||||
<property name="hide-on-close">True</property>
|
||||
<child internal-child="headerbar">
|
||||
<object class="GtkHeaderBar" id="dialog_header_bar">
|
||||
<property name="show-title-buttons">True</property>
|
||||
<child type="title">
|
||||
<object class="GtkEntry" id="timezone_searchentry">
|
||||
<property name="halign">center</property>
|
||||
<property name="margin_start">5</property>
|
||||
<property name="margin_end">5</property>
|
||||
<property name="width_chars">40</property>
|
||||
<property name="primary_icon_name">edit-find-symbolic</property>
|
||||
<property name="primary_icon_activatable">False</property>
|
||||
<property name="primary_icon_sensitive">False</property>
|
||||
<property name="placeholder_text" translatable="yes">Search for a city</property>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkBox" id="dialog_vbox7">
|
||||
<property name="orientation">vertical</property>
|
||||
<property name="spacing">2</property>
|
||||
<child>
|
||||
<object class="GtkFrame" id="aspectmap">
|
||||
<property name="margin_start">5</property>
|
||||
<property name="margin_end">5</property>
|
||||
<property name="margin_top">5</property>
|
||||
<property name="margin_bottom">5</property>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
<template class="CcDateTimePanel" parent="CcPanel">
|
||||
|
||||
<child type="titlebar-end">
|
||||
@@ -205,7 +247,7 @@
|
||||
<signal name="notify::selected-item" handler="change_clock_settings" object="CcDateTimePanel" swapped="no"/>
|
||||
<property name="model">
|
||||
<object class="AdwEnumListModel">
|
||||
<property name="enum-type">GDesktopClockFormat</property>
|
||||
<property name="enum_type">GDesktopClockFormat</property>
|
||||
</object>
|
||||
</property>
|
||||
<property name="expression">
|
||||
@@ -218,49 +260,4 @@
|
||||
</object>
|
||||
</child>
|
||||
</template>
|
||||
|
||||
<object class="GtkGridView" id="month_grid">
|
||||
<property name="halign">start</property>
|
||||
<property name="margin-start">3</property>
|
||||
<property name="margin-end">3</property>
|
||||
<property name="margin-top">3</property>
|
||||
<property name="margin-bottom">3</property>
|
||||
<property name="orientation">horizontal</property>
|
||||
<property name="max-columns">6</property>
|
||||
<property name="min-columns">6</property>
|
||||
<property name="enable-rubberband">False</property>
|
||||
<style>
|
||||
<class name="month-grid"/>
|
||||
</style>
|
||||
<property name="factory">
|
||||
<object class="GtkBuilderListItemFactory">
|
||||
<property name="resource">/org/gnome/control-center/datetime/cc-month-row.ui</property>
|
||||
</object>
|
||||
</property>
|
||||
<property name="model">
|
||||
<object class="GtkSingleSelection" id="month_model">
|
||||
<property name="autoselect">False</property>
|
||||
<signal name="selection-changed" handler="on_month_selection_changed_cb" swapped="yes"/>
|
||||
<property name="model">
|
||||
<object class="GtkStringList">
|
||||
<items>
|
||||
<item translatable="yes">January</item>
|
||||
<item translatable="yes">February</item>
|
||||
<item translatable="yes">March</item>
|
||||
<item translatable="yes">April</item>
|
||||
<item translatable="yes">May</item>
|
||||
<item translatable="yes">June</item>
|
||||
<item translatable="yes">July</item>
|
||||
<item translatable="yes">August</item>
|
||||
<item translatable="yes">September</item>
|
||||
<item translatable="yes">October</item>
|
||||
<item translatable="yes">November</item>
|
||||
<item translatable="yes">December</item>
|
||||
</items>
|
||||
</object>
|
||||
</property>
|
||||
</object>
|
||||
</property>
|
||||
</object>
|
||||
|
||||
</interface>
|
||||
|
||||
@@ -1,55 +0,0 @@
|
||||
<interface>
|
||||
<template class="GtkListItem">
|
||||
<property name="activatable">False</property>
|
||||
<property name="child">
|
||||
<object class="GtkBox">
|
||||
<property name="margin-start">6</property>
|
||||
<property name="margin-end">6</property>
|
||||
<property name="margin-top">6</property>
|
||||
<property name="margin-bottom">6</property>
|
||||
|
||||
<!-- Month name -->
|
||||
<child>
|
||||
<object class="GtkLabel">
|
||||
<property name="ellipsize">end</property>
|
||||
<property name="xalign">0</property>
|
||||
<property name="width-request">96</property>
|
||||
<style>
|
||||
<class name="title"/>
|
||||
</style>
|
||||
<binding name="label">
|
||||
<lookup name="string" type="GtkStringObject">
|
||||
<lookup name="item">GtkListItem</lookup>
|
||||
</lookup>
|
||||
</binding>
|
||||
</object>
|
||||
</child>
|
||||
|
||||
<!-- Check Image -->
|
||||
<child>
|
||||
<object class="GtkImage" id="select_image">
|
||||
<property name="visible" bind-source="GtkListItem" bind-property="selected" bind-flags="sync-create" />
|
||||
<property name="icon-name">object-select-symbolic</property>
|
||||
</object>
|
||||
</child>
|
||||
|
||||
<!-- Placeholder too keep check image space intact -->
|
||||
<child>
|
||||
<object class="AdwBin" id="image_placeholder">
|
||||
<property name="visible" bind-source="select_image" bind-flags="sync-create|invert-boolean" />
|
||||
</object>
|
||||
</child>
|
||||
|
||||
</object>
|
||||
</property>
|
||||
</template>
|
||||
|
||||
<object class="GtkSizeGroup">
|
||||
<property name="mode">both</property>
|
||||
<widgets>
|
||||
<widget name="select_image"/>
|
||||
<widget name="image_placeholder"/>
|
||||
</widgets>
|
||||
</object>
|
||||
|
||||
</interface>
|
||||
577
panels/datetime/cc-timezone-map.c
Normal file
@@ -0,0 +1,577 @@
|
||||
/*
|
||||
* Copyright (C) 2010 Intel, Inc
|
||||
*
|
||||
* Portions from Ubiquity, Copyright (C) 2009 Canonical Ltd.
|
||||
* Written by Evan Dandrea <evand@ubuntu.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* Author: Thomas Wood <thomas.wood@intel.com>
|
||||
*
|
||||
*/
|
||||
|
||||
#include "cc-timezone-map.h"
|
||||
#include <math.h>
|
||||
#include <string.h>
|
||||
#include "tz.h"
|
||||
|
||||
#define PIN_HOT_POINT_X 8
|
||||
#define PIN_HOT_POINT_Y 15
|
||||
|
||||
#define DATETIME_RESOURCE_PATH "/org/gnome/control-center/datetime"
|
||||
|
||||
typedef struct
|
||||
{
|
||||
gdouble offset;
|
||||
guchar red;
|
||||
guchar green;
|
||||
guchar blue;
|
||||
guchar alpha;
|
||||
} CcTimezoneMapOffset;
|
||||
|
||||
struct _CcTimezoneMap
|
||||
{
|
||||
GtkWidget parent_instance;
|
||||
|
||||
GdkTexture *orig_background;
|
||||
GdkTexture *orig_background_dim;
|
||||
|
||||
GdkTexture *background;
|
||||
GdkTexture *color_map;
|
||||
GdkTexture *pin;
|
||||
|
||||
gdouble selected_offset;
|
||||
|
||||
TzDB *tzdb;
|
||||
TzLocation *location;
|
||||
|
||||
gchar *bubble_text;
|
||||
};
|
||||
|
||||
G_DEFINE_TYPE (CcTimezoneMap, cc_timezone_map, GTK_TYPE_WIDGET)
|
||||
|
||||
enum
|
||||
{
|
||||
LOCATION_CHANGED,
|
||||
LAST_SIGNAL
|
||||
};
|
||||
|
||||
static guint signals[LAST_SIGNAL];
|
||||
|
||||
static GdkTexture *
|
||||
texture_from_resource (const gchar *resource_path,
|
||||
GError **error)
|
||||
{
|
||||
g_autofree gchar *full_path = g_strdup_printf ("resource://%s", resource_path);
|
||||
g_autoptr(GFile) file = g_file_new_for_uri (full_path);
|
||||
g_autoptr(GdkTexture) texture = gdk_texture_new_from_file (file, error);
|
||||
|
||||
return g_steal_pointer (&texture);
|
||||
}
|
||||
|
||||
static void
|
||||
cc_timezone_map_dispose (GObject *object)
|
||||
{
|
||||
CcTimezoneMap *self = CC_TIMEZONE_MAP (object);
|
||||
|
||||
g_clear_object (&self->color_map);
|
||||
g_clear_object (&self->orig_background);
|
||||
g_clear_object (&self->orig_background_dim);
|
||||
g_clear_object (&self->background);
|
||||
g_clear_object (&self->pin);
|
||||
g_clear_pointer (&self->bubble_text, g_free);
|
||||
|
||||
G_OBJECT_CLASS (cc_timezone_map_parent_class)->dispose (object);
|
||||
}
|
||||
|
||||
static void
|
||||
cc_timezone_map_finalize (GObject *object)
|
||||
{
|
||||
CcTimezoneMap *self = CC_TIMEZONE_MAP (object);
|
||||
|
||||
g_clear_pointer (&self->tzdb, tz_db_free);
|
||||
|
||||
G_OBJECT_CLASS (cc_timezone_map_parent_class)->finalize (object);
|
||||
}
|
||||
|
||||
/* GtkWidget functions */
|
||||
static void
|
||||
cc_timezone_map_measure (GtkWidget *widget,
|
||||
GtkOrientation orientation,
|
||||
gint for_size,
|
||||
gint *minimum,
|
||||
gint *natural,
|
||||
gint *minimum_baseline,
|
||||
gint *natural_baseline)
|
||||
{
|
||||
CcTimezoneMap *map = CC_TIMEZONE_MAP (widget);
|
||||
gint size;
|
||||
|
||||
switch (orientation)
|
||||
{
|
||||
case GTK_ORIENTATION_HORIZONTAL:
|
||||
size = gdk_texture_get_width (map->orig_background);
|
||||
break;
|
||||
|
||||
case GTK_ORIENTATION_VERTICAL:
|
||||
size = gdk_texture_get_height (map->orig_background);
|
||||
break;
|
||||
}
|
||||
|
||||
if (minimum != NULL)
|
||||
*minimum = size;
|
||||
if (natural != NULL)
|
||||
*natural = size;
|
||||
}
|
||||
|
||||
static void
|
||||
cc_timezone_map_size_allocate (GtkWidget *widget,
|
||||
gint width,
|
||||
gint height,
|
||||
gint baseline)
|
||||
{
|
||||
CcTimezoneMap *map = CC_TIMEZONE_MAP (widget);
|
||||
GdkTexture *texture;
|
||||
|
||||
if (!gtk_widget_is_sensitive (widget))
|
||||
texture = map->orig_background_dim;
|
||||
else
|
||||
texture = map->orig_background;
|
||||
|
||||
g_clear_object (&map->background);
|
||||
map->background = g_object_ref (texture);
|
||||
|
||||
GTK_WIDGET_CLASS (cc_timezone_map_parent_class)->size_allocate (widget,
|
||||
width,
|
||||
height,
|
||||
baseline);
|
||||
}
|
||||
|
||||
static gdouble
|
||||
convert_longitude_to_x (gdouble longitude, gint map_width)
|
||||
{
|
||||
const gdouble xdeg_offset = -6;
|
||||
gdouble x;
|
||||
|
||||
x = (map_width * (180.0 + longitude) / 360.0)
|
||||
+ (map_width * xdeg_offset / 180.0);
|
||||
|
||||
return x;
|
||||
}
|
||||
|
||||
static gdouble
|
||||
radians (gdouble degrees)
|
||||
{
|
||||
return (degrees / 360.0) * G_PI * 2;
|
||||
}
|
||||
|
||||
static gdouble
|
||||
convert_latitude_to_y (gdouble latitude, gdouble map_height)
|
||||
{
|
||||
gdouble bottom_lat = -59;
|
||||
gdouble top_lat = 81;
|
||||
gdouble top_per, y, full_range, top_offset, map_range;
|
||||
|
||||
top_per = top_lat / 180.0;
|
||||
y = 1.25 * log (tan (G_PI_4 + 0.4 * radians (latitude)));
|
||||
full_range = 4.6068250867599998;
|
||||
top_offset = full_range * top_per;
|
||||
map_range = fabs (1.25 * log (tan (G_PI_4 + 0.4 * radians (bottom_lat))) - top_offset);
|
||||
y = fabs (y - top_offset);
|
||||
y = y / map_range;
|
||||
y = y * map_height;
|
||||
return y;
|
||||
}
|
||||
|
||||
static void
|
||||
draw_text_bubble (CcTimezoneMap *map,
|
||||
GtkSnapshot *snapshot,
|
||||
gint width,
|
||||
gint height,
|
||||
gdouble pointx,
|
||||
gdouble pointy)
|
||||
{
|
||||
static const double corner_radius = 9.0;
|
||||
static const double margin_top = 12.0;
|
||||
static const double margin_bottom = 12.0;
|
||||
static const double margin_left = 24.0;
|
||||
static const double margin_right = 24.0;
|
||||
|
||||
GskRoundedRect rounded_rect;
|
||||
PangoRectangle text_rect;
|
||||
PangoLayout *layout;
|
||||
GdkRGBA rgba;
|
||||
double x;
|
||||
double y;
|
||||
double bubble_width;
|
||||
double bubble_height;
|
||||
|
||||
if (!map->bubble_text)
|
||||
return;
|
||||
|
||||
layout = gtk_widget_create_pango_layout (GTK_WIDGET (map), NULL);
|
||||
|
||||
/* Layout the text */
|
||||
pango_layout_set_alignment (layout, PANGO_ALIGN_CENTER);
|
||||
pango_layout_set_spacing (layout, 3);
|
||||
pango_layout_set_markup (layout, map->bubble_text, -1);
|
||||
|
||||
pango_layout_get_pixel_extents (layout, NULL, &text_rect);
|
||||
|
||||
/* Calculate the bubble size based on the text layout size */
|
||||
bubble_width = text_rect.width + margin_left + margin_right;
|
||||
bubble_height = text_rect.height + margin_top + margin_bottom;
|
||||
|
||||
if (pointx < width / 2)
|
||||
x = pointx + 25;
|
||||
else
|
||||
x = pointx - bubble_width - 25;
|
||||
|
||||
y = pointy - bubble_height / 2;
|
||||
|
||||
/* Make sure it fits in the visible area */
|
||||
x = CLAMP (x, 0, width - bubble_width);
|
||||
y = CLAMP (y, 0, height - bubble_height);
|
||||
|
||||
gtk_snapshot_save (snapshot);
|
||||
|
||||
gsk_rounded_rect_init (&rounded_rect,
|
||||
&GRAPHENE_RECT_INIT (x, y, bubble_width, bubble_height),
|
||||
&GRAPHENE_SIZE_INIT (corner_radius, corner_radius),
|
||||
&GRAPHENE_SIZE_INIT (corner_radius, corner_radius),
|
||||
&GRAPHENE_SIZE_INIT (corner_radius, corner_radius),
|
||||
&GRAPHENE_SIZE_INIT (corner_radius, corner_radius));
|
||||
|
||||
gtk_snapshot_push_rounded_clip (snapshot, &rounded_rect);
|
||||
|
||||
rgba = (GdkRGBA) {
|
||||
.red = 0.2,
|
||||
.green = 0.2,
|
||||
.blue = 0.2,
|
||||
.alpha = 0.7,
|
||||
};
|
||||
gtk_snapshot_append_color (snapshot,
|
||||
&rgba,
|
||||
&GRAPHENE_RECT_INIT (x, y, bubble_width, bubble_height));
|
||||
|
||||
|
||||
rgba = (GdkRGBA) {
|
||||
.red = 1.0,
|
||||
.green = 1.0,
|
||||
.blue = 1.0,
|
||||
.alpha = 1.0,
|
||||
};
|
||||
gtk_snapshot_translate (snapshot, &GRAPHENE_POINT_INIT (x + margin_left, y + margin_top));
|
||||
gtk_snapshot_append_layout (snapshot, layout, &rgba);
|
||||
|
||||
gtk_snapshot_pop (snapshot);
|
||||
gtk_snapshot_restore (snapshot);
|
||||
|
||||
g_object_unref (layout);
|
||||
}
|
||||
|
||||
static void
|
||||
cc_timezone_map_snapshot (GtkWidget *widget,
|
||||
GtkSnapshot *snapshot)
|
||||
{
|
||||
CcTimezoneMap *map = CC_TIMEZONE_MAP (widget);
|
||||
g_autoptr(GdkTexture) orig_highlight = NULL;
|
||||
g_autofree gchar *file = NULL;
|
||||
g_autoptr(GError) err = NULL;
|
||||
gdouble pointx, pointy;
|
||||
gint width, height;
|
||||
char buf[16];
|
||||
|
||||
width = gtk_widget_get_width (widget);
|
||||
height = gtk_widget_get_height (widget);
|
||||
|
||||
/* paint background */
|
||||
gtk_snapshot_append_texture (snapshot,
|
||||
map->background,
|
||||
&GRAPHENE_RECT_INIT (0, 0, width, height));
|
||||
|
||||
/* paint highlight */
|
||||
if (gtk_widget_is_sensitive (widget))
|
||||
{
|
||||
file = g_strdup_printf (DATETIME_RESOURCE_PATH "/timezone_%s.png",
|
||||
g_ascii_formatd (buf, sizeof (buf),
|
||||
"%g", map->selected_offset));
|
||||
}
|
||||
else
|
||||
{
|
||||
file = g_strdup_printf (DATETIME_RESOURCE_PATH "/timezone_%s_dim.png",
|
||||
g_ascii_formatd (buf, sizeof (buf),
|
||||
"%g", map->selected_offset));
|
||||
|
||||
}
|
||||
|
||||
orig_highlight = texture_from_resource (file, &err);
|
||||
|
||||
if (!orig_highlight)
|
||||
{
|
||||
g_warning ("Could not load highlight: %s",
|
||||
(err) ? err->message : "Unknown Error");
|
||||
}
|
||||
else
|
||||
{
|
||||
gtk_snapshot_append_texture (snapshot,
|
||||
orig_highlight,
|
||||
&GRAPHENE_RECT_INIT (0, 0, width, height));
|
||||
}
|
||||
|
||||
if (map->location)
|
||||
{
|
||||
pointx = convert_longitude_to_x (map->location->longitude, width);
|
||||
pointy = convert_latitude_to_y (map->location->latitude, height);
|
||||
|
||||
pointx = CLAMP (floor (pointx), 0, width);
|
||||
pointy = CLAMP (floor (pointy), 0, height);
|
||||
|
||||
draw_text_bubble (map, snapshot, width, height, pointx, pointy);
|
||||
|
||||
if (map->pin)
|
||||
{
|
||||
gtk_snapshot_append_texture (snapshot,
|
||||
map->pin,
|
||||
&GRAPHENE_RECT_INIT (pointx - PIN_HOT_POINT_X,
|
||||
pointy - PIN_HOT_POINT_Y,
|
||||
gdk_texture_get_width (map->pin),
|
||||
gdk_texture_get_height (map->pin)));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
update_cursor (GtkWidget *widget)
|
||||
{
|
||||
const gchar *cursor_name = NULL;
|
||||
|
||||
if (!gtk_widget_get_realized (widget))
|
||||
return;
|
||||
|
||||
if (gtk_widget_is_sensitive (widget))
|
||||
cursor_name = "pointer";
|
||||
|
||||
gtk_widget_set_cursor_from_name (widget, cursor_name);
|
||||
}
|
||||
|
||||
static void
|
||||
cc_timezone_map_state_flags_changed (GtkWidget *widget,
|
||||
GtkStateFlags prev_state)
|
||||
{
|
||||
update_cursor (widget);
|
||||
|
||||
if (GTK_WIDGET_CLASS (cc_timezone_map_parent_class)->state_flags_changed)
|
||||
GTK_WIDGET_CLASS (cc_timezone_map_parent_class)->state_flags_changed (widget, prev_state);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
cc_timezone_map_class_init (CcTimezoneMapClass *klass)
|
||||
{
|
||||
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
||||
GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
|
||||
|
||||
object_class->dispose = cc_timezone_map_dispose;
|
||||
object_class->finalize = cc_timezone_map_finalize;
|
||||
|
||||
widget_class->measure = cc_timezone_map_measure;
|
||||
widget_class->size_allocate = cc_timezone_map_size_allocate;
|
||||
widget_class->snapshot = cc_timezone_map_snapshot;
|
||||
widget_class->state_flags_changed = cc_timezone_map_state_flags_changed;
|
||||
|
||||
signals[LOCATION_CHANGED] = g_signal_new ("location-changed",
|
||||
CC_TYPE_TIMEZONE_MAP,
|
||||
G_SIGNAL_RUN_FIRST,
|
||||
0,
|
||||
NULL,
|
||||
NULL,
|
||||
g_cclosure_marshal_VOID__POINTER,
|
||||
G_TYPE_NONE, 1,
|
||||
G_TYPE_POINTER);
|
||||
}
|
||||
|
||||
|
||||
static gint
|
||||
sort_locations (TzLocation *a,
|
||||
TzLocation *b)
|
||||
{
|
||||
if (a->dist > b->dist)
|
||||
return 1;
|
||||
|
||||
if (a->dist < b->dist)
|
||||
return -1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
set_location (CcTimezoneMap *map,
|
||||
TzLocation *location)
|
||||
{
|
||||
g_autoptr(TzInfo) info = NULL;
|
||||
|
||||
map->location = location;
|
||||
|
||||
info = tz_info_from_location (map->location);
|
||||
|
||||
map->selected_offset = tz_location_get_base_utc_offset (map->location)
|
||||
/ (60.0*60.0);
|
||||
gtk_widget_queue_draw (GTK_WIDGET (map));
|
||||
|
||||
g_signal_emit (map, signals[LOCATION_CHANGED], 0, map->location);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
map_clicked_cb (GtkGestureClick *self,
|
||||
gint n_press,
|
||||
gdouble x,
|
||||
gdouble y,
|
||||
CcTimezoneMap *map)
|
||||
{
|
||||
const GPtrArray *array;
|
||||
gint width, height;
|
||||
GList *distances = NULL;
|
||||
gint i;
|
||||
|
||||
/* work out the coordinates */
|
||||
|
||||
array = tz_get_locations (map->tzdb);
|
||||
|
||||
width = gtk_widget_get_width (GTK_WIDGET (map));
|
||||
height = gtk_widget_get_height (GTK_WIDGET (map));
|
||||
|
||||
for (i = 0; i < array->len; i++)
|
||||
{
|
||||
gdouble pointx, pointy, dx, dy;
|
||||
TzLocation *loc = array->pdata[i];
|
||||
|
||||
pointx = convert_longitude_to_x (loc->longitude, width);
|
||||
pointy = convert_latitude_to_y (loc->latitude, height);
|
||||
|
||||
dx = pointx - x;
|
||||
dy = pointy - y;
|
||||
|
||||
loc->dist = dx * dx + dy * dy;
|
||||
distances = g_list_prepend (distances, loc);
|
||||
|
||||
}
|
||||
distances = g_list_sort (distances, (GCompareFunc) sort_locations);
|
||||
|
||||
|
||||
set_location (map, (TzLocation*) distances->data);
|
||||
|
||||
g_list_free (distances);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
cc_timezone_map_init (CcTimezoneMap *map)
|
||||
{
|
||||
GtkGesture *click_gesture;
|
||||
GError *err = NULL;
|
||||
|
||||
map->orig_background = texture_from_resource (DATETIME_RESOURCE_PATH "/bg.png", &err);
|
||||
if (!map->orig_background)
|
||||
{
|
||||
g_warning ("Could not load background image: %s",
|
||||
(err) ? err->message : "Unknown error");
|
||||
g_clear_error (&err);
|
||||
}
|
||||
|
||||
map->orig_background_dim = texture_from_resource (DATETIME_RESOURCE_PATH "/bg_dim.png", &err);
|
||||
if (!map->orig_background_dim)
|
||||
{
|
||||
g_warning ("Could not load background image: %s",
|
||||
(err) ? err->message : "Unknown error");
|
||||
g_clear_error (&err);
|
||||
}
|
||||
|
||||
map->color_map = texture_from_resource (DATETIME_RESOURCE_PATH "/cc.png", &err);
|
||||
if (!map->color_map)
|
||||
{
|
||||
g_warning ("Could not load background image: %s",
|
||||
(err) ? err->message : "Unknown error");
|
||||
g_clear_error (&err);
|
||||
}
|
||||
|
||||
map->pin = texture_from_resource (DATETIME_RESOURCE_PATH "/pin.png", &err);
|
||||
if (!map->pin)
|
||||
{
|
||||
g_warning ("Could not load pin icon: %s",
|
||||
(err) ? err->message : "Unknown error");
|
||||
g_clear_error (&err);
|
||||
}
|
||||
|
||||
map->tzdb = tz_load_db ();
|
||||
|
||||
click_gesture = gtk_gesture_click_new ();
|
||||
g_signal_connect (click_gesture, "pressed", G_CALLBACK (map_clicked_cb), map);
|
||||
gtk_widget_add_controller (GTK_WIDGET (map), GTK_EVENT_CONTROLLER (click_gesture));
|
||||
}
|
||||
|
||||
CcTimezoneMap *
|
||||
cc_timezone_map_new (void)
|
||||
{
|
||||
return g_object_new (CC_TYPE_TIMEZONE_MAP, NULL);
|
||||
}
|
||||
|
||||
gboolean
|
||||
cc_timezone_map_set_timezone (CcTimezoneMap *map,
|
||||
const gchar *timezone)
|
||||
{
|
||||
GPtrArray *locations;
|
||||
guint i;
|
||||
g_autofree gchar *real_tz = NULL;
|
||||
gboolean ret;
|
||||
|
||||
real_tz = tz_info_get_clean_name (map->tzdb, timezone);
|
||||
|
||||
locations = tz_get_locations (map->tzdb);
|
||||
ret = FALSE;
|
||||
|
||||
for (i = 0; i < locations->len; i++)
|
||||
{
|
||||
TzLocation *loc = locations->pdata[i];
|
||||
|
||||
if (!g_strcmp0 (loc->zone, real_tz ? real_tz : timezone))
|
||||
{
|
||||
set_location (map, loc);
|
||||
ret = TRUE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (ret)
|
||||
gtk_widget_queue_draw (GTK_WIDGET (map));
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
void
|
||||
cc_timezone_map_set_bubble_text (CcTimezoneMap *map,
|
||||
const gchar *text)
|
||||
{
|
||||
g_free (map->bubble_text);
|
||||
map->bubble_text = g_strdup (text);
|
||||
|
||||
gtk_widget_queue_draw (GTK_WIDGET (map));
|
||||
}
|
||||
|
||||
TzLocation *
|
||||
cc_timezone_map_get_location (CcTimezoneMap *map)
|
||||
{
|
||||
return map->location;
|
||||
}
|
||||
@@ -1,6 +1,5 @@
|
||||
/* cc-firmware-security-boot-dialog.h
|
||||
*
|
||||
* Copyright (C) 2021 Red Hat, Inc
|
||||
/*
|
||||
* Copyright (C) 2010 Intel, Inc
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
@@ -15,23 +14,26 @@
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* Author: Kate Hsuan <hpa@redhat.com>
|
||||
* Author: Thomas Wood <thomas.wood@intel.com>
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0-or-later
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <gtk/gtk.h>
|
||||
|
||||
#include "cc-firmware-security-utils.h"
|
||||
#include "tz.h"
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define CC_TYPE_FIRMWARE_SECURITY_BOOT_DIALOG (cc_firmware_security_boot_dialog_get_type ())
|
||||
G_DECLARE_FINAL_TYPE (CcFirmwareSecurityBootDialog, cc_firmware_security_boot_dialog,
|
||||
CC, FIRMWARE_SECURITY_BOOT_DIALOG, GtkDialog)
|
||||
#define CC_TYPE_TIMEZONE_MAP (cc_timezone_map_get_type ())
|
||||
G_DECLARE_FINAL_TYPE (CcTimezoneMap, cc_timezone_map, CC, TIMEZONE_MAP, GtkWidget)
|
||||
|
||||
GtkWidget *cc_firmware_security_boot_dialog_new (SecureBootState secure_boot_state);
|
||||
CcTimezoneMap *cc_timezone_map_new (void);
|
||||
|
||||
gboolean cc_timezone_map_set_timezone (CcTimezoneMap *map,
|
||||
const gchar *timezone);
|
||||
void cc_timezone_map_set_bubble_text (CcTimezoneMap *map,
|
||||
const gchar *text);
|
||||
TzLocation * cc_timezone_map_get_location (CcTimezoneMap *map);
|
||||
|
||||
G_END_DECLS
|
||||
@@ -1,327 +0,0 @@
|
||||
/* -*- mode: c; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* cc-tz-dialog.c
|
||||
*
|
||||
* Copyright 2022 Purism SPC
|
||||
* Copyright 2022 Mohammed Sadiq <sadiq@sadiqpk.org>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* Author(s):
|
||||
* Mohammed Sadiq <sadiq@sadiqpk.org>
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-3.0-or-later
|
||||
*/
|
||||
|
||||
#undef G_LOG_DOMAIN
|
||||
#define G_LOG_DOMAIN "cc-tz-dialog"
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include "config.h"
|
||||
#endif
|
||||
|
||||
#define _GNU_SOURCE
|
||||
#include <string.h>
|
||||
#include <glib/gi18n.h>
|
||||
|
||||
#include "cc-tz-dialog.h"
|
||||
#include "tz.h"
|
||||
|
||||
struct _CcTzDialog
|
||||
{
|
||||
AdwWindow parent_instance;
|
||||
|
||||
GtkSearchEntry *location_entry;
|
||||
|
||||
GtkStack *main_stack;
|
||||
AdwStatusPage *empty_page;
|
||||
GtkScrolledWindow *tz_page;
|
||||
GtkListView *tz_view;
|
||||
|
||||
TzDB *tz_db;
|
||||
GListStore *tz_store;
|
||||
GtkFilterListModel *tz_filtered_model;
|
||||
GtkNoSelection *tz_selection_model;
|
||||
|
||||
CcTzItem *selected_item;
|
||||
};
|
||||
|
||||
G_DEFINE_TYPE (CcTzDialog, cc_tz_dialog, ADW_TYPE_WINDOW)
|
||||
|
||||
enum {
|
||||
TZ_SELECTED,
|
||||
N_SIGNALS
|
||||
};
|
||||
|
||||
static guint signals[N_SIGNALS];
|
||||
|
||||
static gboolean
|
||||
match_tz_item (CcTzItem *item,
|
||||
CcTzDialog *self)
|
||||
{
|
||||
g_auto(GStrv) strv = NULL;
|
||||
g_autofree char *country = NULL;
|
||||
g_autofree char *name = NULL;
|
||||
g_autofree char *zone = NULL;
|
||||
const char *search_terms;
|
||||
|
||||
g_assert (CC_IS_TZ_ITEM (item));
|
||||
g_assert (CC_IS_TZ_DIALOG (self));
|
||||
|
||||
search_terms = gtk_editable_get_text (GTK_EDITABLE (self->location_entry));
|
||||
|
||||
if (!search_terms || !*search_terms)
|
||||
return TRUE;
|
||||
|
||||
g_object_get (item,
|
||||
"country", &country,
|
||||
"name", &name,
|
||||
"zone", &zone,
|
||||
NULL);
|
||||
|
||||
if (!name || !zone || !country)
|
||||
return FALSE;
|
||||
|
||||
/* Search for each word separated by spaces */
|
||||
strv = g_strsplit (search_terms, " ", 0);
|
||||
|
||||
/*
|
||||
* List the item only if the value contain each word.
|
||||
* ie, for a search "as kol" it will match "Asia/Kolkata"
|
||||
* not "Asia/Karachi"
|
||||
*/
|
||||
for (guint i = 0; strv[i]; i++)
|
||||
{
|
||||
const char *str = strv[i];
|
||||
|
||||
if (!str || !*str)
|
||||
continue;
|
||||
|
||||
if (!strcasestr (name, str) &&
|
||||
!strcasestr (zone, str) &&
|
||||
!strcasestr (country, str))
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
load_tz (CcTzDialog *self)
|
||||
{
|
||||
GPtrArray *locations;
|
||||
|
||||
g_assert (CC_IS_TZ_DIALOG (self));
|
||||
|
||||
self->tz_db = tz_load_db ();
|
||||
g_assert (self->tz_db);
|
||||
|
||||
locations = tz_get_locations (self->tz_db);
|
||||
g_assert (locations);
|
||||
|
||||
for (guint i = 0; i < locations->len; i++)
|
||||
{
|
||||
g_autoptr(CcTzItem) item = NULL;
|
||||
TzLocation *location;
|
||||
|
||||
location = locations->pdata[i];
|
||||
item = cc_tz_item_new (location);
|
||||
|
||||
g_list_store_append (self->tz_store, item);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
tz_selection_model_changed_cb (CcTzDialog *self)
|
||||
{
|
||||
guint n_items;
|
||||
|
||||
g_assert (CC_IS_TZ_DIALOG (self));
|
||||
|
||||
n_items = g_list_model_get_n_items (G_LIST_MODEL (self->tz_selection_model));
|
||||
|
||||
if (n_items)
|
||||
gtk_stack_set_visible_child (self->main_stack, GTK_WIDGET (self->tz_page));
|
||||
else
|
||||
gtk_stack_set_visible_child (self->main_stack, GTK_WIDGET (self->empty_page));
|
||||
}
|
||||
|
||||
static void
|
||||
tz_dialog_search_changed_cb (CcTzDialog *self)
|
||||
{
|
||||
GtkFilter *filter;
|
||||
|
||||
g_assert (CC_IS_TZ_DIALOG (self));
|
||||
|
||||
filter = gtk_filter_list_model_get_filter (self->tz_filtered_model);
|
||||
|
||||
gtk_filter_changed (filter, GTK_FILTER_CHANGE_DIFFERENT);
|
||||
}
|
||||
|
||||
static void
|
||||
tz_dialog_row_activated_cb (CcTzDialog *self,
|
||||
guint position)
|
||||
{
|
||||
GListModel *model;
|
||||
|
||||
g_assert (CC_IS_TZ_DIALOG (self));
|
||||
|
||||
g_clear_object (&self->selected_item);
|
||||
|
||||
model = G_LIST_MODEL (self->tz_selection_model);
|
||||
self->selected_item = g_list_model_get_item (model, position);
|
||||
|
||||
gtk_window_close (GTK_WINDOW (self));
|
||||
g_signal_emit (self, signals[TZ_SELECTED], 0);
|
||||
}
|
||||
|
||||
static void
|
||||
cc_tz_dialog_map (GtkWidget *widget)
|
||||
{
|
||||
CcTzDialog *self = (CcTzDialog *)widget;
|
||||
|
||||
gtk_editable_set_text (GTK_EDITABLE (self->location_entry), "");
|
||||
gtk_widget_grab_focus (GTK_WIDGET (self->location_entry));
|
||||
|
||||
GTK_WIDGET_CLASS (cc_tz_dialog_parent_class)->map (widget);
|
||||
}
|
||||
|
||||
static void
|
||||
cc_tz_dialog_finalize (GObject *object)
|
||||
{
|
||||
CcTzDialog *self = (CcTzDialog *)object;
|
||||
|
||||
g_clear_object (&self->tz_store);
|
||||
g_clear_pointer (&self->tz_db, tz_db_free);
|
||||
|
||||
G_OBJECT_CLASS (cc_tz_dialog_parent_class)->finalize (object);
|
||||
}
|
||||
|
||||
static void
|
||||
cc_tz_dialog_class_init (CcTzDialogClass *klass)
|
||||
{
|
||||
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
||||
GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
|
||||
|
||||
object_class->finalize = cc_tz_dialog_finalize;
|
||||
|
||||
widget_class->map = cc_tz_dialog_map;
|
||||
|
||||
signals[TZ_SELECTED] =
|
||||
g_signal_new ("tz-selected",
|
||||
G_TYPE_FROM_CLASS (klass),
|
||||
G_SIGNAL_RUN_LAST,
|
||||
0, NULL, NULL, NULL,
|
||||
G_TYPE_NONE, 0);
|
||||
|
||||
gtk_widget_class_set_template_from_resource (widget_class,
|
||||
"/org/gnome/control-center/"
|
||||
"datetime/cc-tz-dialog.ui");
|
||||
|
||||
gtk_widget_class_bind_template_child (widget_class, CcTzDialog, location_entry);
|
||||
|
||||
gtk_widget_class_bind_template_child (widget_class, CcTzDialog, main_stack);
|
||||
gtk_widget_class_bind_template_child (widget_class, CcTzDialog, empty_page);
|
||||
gtk_widget_class_bind_template_child (widget_class, CcTzDialog, tz_page);
|
||||
gtk_widget_class_bind_template_child (widget_class, CcTzDialog, tz_view);
|
||||
|
||||
gtk_widget_class_bind_template_callback (widget_class, tz_dialog_search_changed_cb);
|
||||
gtk_widget_class_bind_template_callback (widget_class, tz_dialog_row_activated_cb);
|
||||
}
|
||||
|
||||
static void
|
||||
cc_tz_dialog_init (CcTzDialog *self)
|
||||
{
|
||||
GtkSortListModel *tz_sorted_model;
|
||||
GtkExpression *expression;
|
||||
GtkSorter *sorter;
|
||||
GtkFilter *filter;
|
||||
|
||||
gtk_widget_init_template (GTK_WIDGET (self));
|
||||
|
||||
self->tz_store = g_list_store_new (CC_TYPE_TZ_ITEM);
|
||||
load_tz (self);
|
||||
|
||||
/* Sort items by name */
|
||||
expression = gtk_property_expression_new (CC_TYPE_TZ_ITEM, NULL, "name");
|
||||
sorter = GTK_SORTER (gtk_string_sorter_new (expression));
|
||||
tz_sorted_model = gtk_sort_list_model_new (G_LIST_MODEL (self->tz_store), sorter);
|
||||
|
||||
filter = (GtkFilter *)gtk_custom_filter_new ((GtkCustomFilterFunc) match_tz_item, self, NULL);
|
||||
self->tz_filtered_model = gtk_filter_list_model_new (G_LIST_MODEL (tz_sorted_model), filter);
|
||||
self->tz_selection_model = gtk_no_selection_new (G_LIST_MODEL (self->tz_filtered_model));
|
||||
|
||||
g_signal_connect_object (self->tz_selection_model, "items-changed",
|
||||
G_CALLBACK (tz_selection_model_changed_cb),
|
||||
self, G_CONNECT_SWAPPED);
|
||||
tz_selection_model_changed_cb (self);
|
||||
|
||||
gtk_list_view_set_model (self->tz_view, GTK_SELECTION_MODEL (self->tz_selection_model));
|
||||
}
|
||||
|
||||
GtkWidget *
|
||||
cc_tz_dialog_new (void)
|
||||
{
|
||||
return g_object_new (CC_TYPE_TZ_DIALOG, NULL);
|
||||
}
|
||||
|
||||
gboolean
|
||||
cc_tz_dialog_set_tz (CcTzDialog *self,
|
||||
const char *timezone)
|
||||
{
|
||||
g_autofree gchar *tz = NULL;
|
||||
guint n_items;
|
||||
|
||||
g_return_val_if_fail (CC_IS_TZ_DIALOG (self), FALSE);
|
||||
g_return_val_if_fail (timezone && *timezone, FALSE);
|
||||
|
||||
n_items = g_list_model_get_n_items (G_LIST_MODEL (self->tz_store));
|
||||
tz = tz_info_get_clean_name (self->tz_db, timezone);
|
||||
|
||||
for (guint i = 0; i < n_items; i++)
|
||||
{
|
||||
g_autoptr(CcTzItem) item = NULL;
|
||||
TzLocation *loc;
|
||||
|
||||
item = g_list_model_get_item (G_LIST_MODEL (self->tz_store), i);
|
||||
loc = cc_tz_item_get_location (item);
|
||||
|
||||
if (g_strcmp0 (loc->zone, tz ? tz : timezone) == 0)
|
||||
{
|
||||
g_set_object (&self->selected_item, item);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
CcTzItem *
|
||||
cc_tz_dialog_get_selected_tz (CcTzDialog *self)
|
||||
{
|
||||
g_return_val_if_fail (CC_IS_TZ_DIALOG (self), NULL);
|
||||
|
||||
return self->selected_item;
|
||||
}
|
||||
|
||||
TzLocation *
|
||||
cc_tz_dialog_get_selected_location (CcTzDialog *self)
|
||||
{
|
||||
g_return_val_if_fail (CC_IS_TZ_DIALOG (self), NULL);
|
||||
|
||||
if (!self->selected_item)
|
||||
return NULL;
|
||||
|
||||
return cc_tz_item_get_location (self->selected_item);
|
||||
}
|
||||
@@ -1,19 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include <adwaita.h>
|
||||
|
||||
#include "cc-tz-item.h"
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define CC_TYPE_TZ_DIALOG (cc_tz_dialog_get_type ())
|
||||
|
||||
G_DECLARE_FINAL_TYPE (CcTzDialog, cc_tz_dialog, CC, TZ_DIALOG, AdwWindow)
|
||||
|
||||
GtkWidget *cc_tz_dialog_new (void);
|
||||
gboolean cc_tz_dialog_set_tz (CcTzDialog *self,
|
||||
const char *timezone);
|
||||
CcTzItem *cc_tz_dialog_get_selected_tz (CcTzDialog *self);
|
||||
TzLocation *cc_tz_dialog_get_selected_location (CcTzDialog *self);
|
||||
|
||||
G_END_DECLS
|
||||
@@ -1,79 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<interface>
|
||||
<template class="CcTzDialog" parent="AdwWindow">
|
||||
<property name="modal">True</property>
|
||||
<property name="hide-on-close">True</property>
|
||||
<property name="title" translatable="yes">Select Time Zone</property>
|
||||
<property name="width-request">360</property>
|
||||
<property name="height-request">300</property>
|
||||
<property name="default-height">540</property>
|
||||
|
||||
<property name="content">
|
||||
<object class="GtkBox">
|
||||
<property name="orientation">vertical</property>
|
||||
|
||||
<child>
|
||||
<object class="AdwHeaderBar">
|
||||
<property name="show-start-title-buttons">True</property>
|
||||
<property name="show-end-title-buttons">True</property>
|
||||
</object>
|
||||
</child>
|
||||
|
||||
<!-- SearchBar -->
|
||||
<child>
|
||||
<object class="GtkSearchEntry" id="location_entry">
|
||||
<property name="halign">center</property>
|
||||
<property name="margin-top">6</property>
|
||||
<property name="margin-bottom">6</property>
|
||||
<property name="width-chars">24</property>
|
||||
<signal name="search-changed" handler="tz_dialog_search_changed_cb" swapped="yes"/>
|
||||
</object>
|
||||
</child>
|
||||
|
||||
<child>
|
||||
<object class="GtkStack" id="main_stack">
|
||||
<property name="vexpand">True</property>
|
||||
|
||||
<child>
|
||||
<object class="AdwStatusPage" id="empty_page">
|
||||
<property name="margin-top">18</property>
|
||||
<property name="title" translatable="yes">No Results</property>
|
||||
<property name="icon-name">system-search-symbolic</property>
|
||||
</object>
|
||||
</child>
|
||||
|
||||
<child>
|
||||
<object class="GtkScrolledWindow" id="tz_page">
|
||||
<property name="hscrollbar-policy">never</property>
|
||||
<property name="vexpand">True</property>
|
||||
<child>
|
||||
<object class="AdwClampScrollable">
|
||||
<child>
|
||||
<object class="GtkListView" id="tz_view">
|
||||
<property name="show-separators">True</property>
|
||||
<property name="single-click-activate">True</property>
|
||||
<signal name="activate" handler="tz_dialog_row_activated_cb" swapped="yes"/>
|
||||
<style>
|
||||
/* fixme: 'boxed-list' gives nice rounded borders, but we can't use
|
||||
* it here as it works only with GtkListBox, not with GtkListView */
|
||||
<class name="frame"/>
|
||||
</style>
|
||||
<property name="factory">
|
||||
<object class="GtkBuilderListItemFactory">
|
||||
<property name="resource">/org/gnome/control-center/datetime/cc-tz-row.ui</property>
|
||||
</object>
|
||||
</property>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
|
||||
</object>
|
||||
</child>
|
||||
|
||||
</object>
|
||||
</property>
|
||||
</template>
|
||||
</interface>
|
||||
@@ -1,285 +0,0 @@
|
||||
/* -*- mode: c; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/*
|
||||
* Copyright 2022 Purism SPC
|
||||
* Copyright 2022 Mohammed Sadiq <sadiq@sadiqpk.org>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* Author(s):
|
||||
* Mohammed Sadiq <sadiq@sadiqpk.org>
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-3.0-or-later
|
||||
*/
|
||||
|
||||
#undef G_LOG_DOMAIN
|
||||
#define G_LOG_DOMAIN "cc-tz-item"
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include "config.h"
|
||||
#endif
|
||||
|
||||
#include <glib/gi18n.h>
|
||||
#define GNOME_DESKTOP_USE_UNSTABLE_API
|
||||
#include <libgnome-desktop/gnome-languages.h>
|
||||
#include <libgnome-desktop/gnome-wall-clock.h>
|
||||
|
||||
#include "cc-tz-item.h"
|
||||
|
||||
#define DEFAULT_TZ "Europe/London"
|
||||
#define GETTEXT_PACKAGE_TIMEZONES GETTEXT_PACKAGE "-timezones"
|
||||
|
||||
struct _CcTzItem
|
||||
{
|
||||
GObject parent_instance;
|
||||
|
||||
GSettings *desktop_settings;
|
||||
GTimeZone *tz;
|
||||
GnomeWallClock *wall_clock;
|
||||
|
||||
TzLocation *tz_location;
|
||||
TzInfo *tz_info;
|
||||
|
||||
char *name;
|
||||
char *country;
|
||||
char *time;
|
||||
char *offset; /* eg: UTC+530 */
|
||||
char *zone;
|
||||
};
|
||||
|
||||
G_DEFINE_TYPE (CcTzItem, cc_tz_item, G_TYPE_OBJECT)
|
||||
|
||||
enum {
|
||||
PROP_0,
|
||||
PROP_COUNTRY,
|
||||
PROP_NAME,
|
||||
PROP_OFFSET,
|
||||
PROP_TIME,
|
||||
PROP_ZONE,
|
||||
N_PROPS
|
||||
};
|
||||
|
||||
static GParamSpec *properties[N_PROPS];
|
||||
|
||||
/* Adapted from cc-datetime-panel.c */
|
||||
static void
|
||||
generate_city_name (CcTzItem *self,
|
||||
TzLocation *loc)
|
||||
{
|
||||
g_auto(GStrv) split_translated = NULL;
|
||||
gint length;
|
||||
|
||||
/* Load the translation for it */
|
||||
self->zone = g_strdup (dgettext (GETTEXT_PACKAGE_TIMEZONES, loc->zone));
|
||||
g_strdelimit (self->zone, "_", ' ');
|
||||
split_translated = g_regex_split_simple ("[\\x{2044}\\x{2215}\\x{29f8}\\x{ff0f}/]",
|
||||
self->zone,
|
||||
0, 0);
|
||||
|
||||
length = g_strv_length (split_translated);
|
||||
self->country = gnome_get_country_from_code (loc->country, NULL);
|
||||
self->name = g_strdup (split_translated[length-1]);
|
||||
}
|
||||
|
||||
static const char *
|
||||
tz_item_get_time (CcTzItem *self)
|
||||
{
|
||||
g_autoptr(GDateTime) now = NULL;
|
||||
GDesktopClockFormat format;
|
||||
|
||||
g_assert (CC_IS_TZ_ITEM (self));
|
||||
|
||||
if (self->time)
|
||||
return self->time;
|
||||
|
||||
now = g_date_time_new_now (self->tz);
|
||||
format = g_settings_get_enum (self->desktop_settings, "clock-format");
|
||||
|
||||
self->time = gnome_wall_clock_string_for_datetime (self->wall_clock, now, format, TRUE, FALSE, FALSE);
|
||||
|
||||
return self->time;
|
||||
}
|
||||
|
||||
static void
|
||||
tz_item_clock_changed_cb (CcTzItem *self)
|
||||
{
|
||||
gboolean had_time;
|
||||
|
||||
g_assert (CC_IS_TZ_ITEM (self));
|
||||
|
||||
had_time = !!self->time;
|
||||
|
||||
/* Clear the time, so that it'll be re-created when asked for one */
|
||||
g_clear_pointer (&self->time, g_free);
|
||||
|
||||
if (had_time)
|
||||
g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_TIME]);
|
||||
}
|
||||
|
||||
static void
|
||||
cc_tz_item_get_property (GObject *object,
|
||||
guint prop_id,
|
||||
GValue *value,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
CcTzItem *self = (CcTzItem *)object;
|
||||
|
||||
switch (prop_id)
|
||||
{
|
||||
case PROP_COUNTRY:
|
||||
g_value_set_string (value, self->country);
|
||||
break;
|
||||
|
||||
case PROP_NAME:
|
||||
g_value_set_string (value, self->name);
|
||||
break;
|
||||
|
||||
case PROP_OFFSET:
|
||||
g_value_set_string (value, self->offset);
|
||||
break;
|
||||
|
||||
case PROP_TIME:
|
||||
g_value_set_string (value, tz_item_get_time (self));
|
||||
break;
|
||||
|
||||
case PROP_ZONE:
|
||||
g_value_set_string (value, self->zone);
|
||||
break;
|
||||
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
cc_tz_item_finalize (GObject *object)
|
||||
{
|
||||
CcTzItem *self = (CcTzItem *)object;
|
||||
|
||||
g_clear_object (&self->desktop_settings);
|
||||
g_clear_object (&self->wall_clock);
|
||||
|
||||
g_clear_pointer (&self->tz, g_time_zone_unref);
|
||||
g_clear_pointer (&self->tz_info, tz_info_free);
|
||||
|
||||
g_clear_pointer (&self->name, g_free);
|
||||
g_clear_pointer (&self->country, g_free);
|
||||
g_clear_pointer (&self->time, g_free);
|
||||
g_clear_pointer (&self->offset, g_free);
|
||||
g_clear_pointer (&self->zone, g_free);
|
||||
|
||||
G_OBJECT_CLASS (cc_tz_item_parent_class)->finalize (object);
|
||||
}
|
||||
|
||||
static void
|
||||
cc_tz_item_class_init (CcTzItemClass *klass)
|
||||
{
|
||||
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
||||
|
||||
object_class->get_property = cc_tz_item_get_property;
|
||||
object_class->finalize = cc_tz_item_finalize;
|
||||
|
||||
properties[PROP_COUNTRY] =
|
||||
g_param_spec_string ("country",
|
||||
"Timezone Country",
|
||||
"Timezone Country",
|
||||
NULL,
|
||||
G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
|
||||
|
||||
properties[PROP_NAME] =
|
||||
g_param_spec_string ("name",
|
||||
"Timezone Name",
|
||||
"Timezone Name",
|
||||
NULL,
|
||||
G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
|
||||
|
||||
properties[PROP_OFFSET] =
|
||||
g_param_spec_string ("offset",
|
||||
"Timezone offset",
|
||||
"Timezone offset",
|
||||
NULL,
|
||||
G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
|
||||
|
||||
properties[PROP_TIME] =
|
||||
g_param_spec_string ("time",
|
||||
"Timezone time",
|
||||
"Timezone time",
|
||||
NULL,
|
||||
G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
|
||||
|
||||
properties[PROP_ZONE] =
|
||||
g_param_spec_string ("zone",
|
||||
"Timezone zone",
|
||||
"Timezone zone",
|
||||
NULL,
|
||||
G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
|
||||
|
||||
g_object_class_install_properties (object_class, N_PROPS, properties);
|
||||
}
|
||||
|
||||
static void
|
||||
cc_tz_item_init (CcTzItem *self)
|
||||
{
|
||||
self->desktop_settings = g_settings_new ("org.gnome.desktop.interface");
|
||||
self->wall_clock = gnome_wall_clock_new ();
|
||||
|
||||
g_signal_connect_object (self->wall_clock, "notify::clock",
|
||||
G_CALLBACK (tz_item_clock_changed_cb),
|
||||
self,
|
||||
G_CONNECT_SWAPPED);
|
||||
g_signal_connect_object (self->desktop_settings, "changed::clock-format",
|
||||
G_CALLBACK (tz_item_clock_changed_cb),
|
||||
self,
|
||||
G_CONNECT_SWAPPED);
|
||||
}
|
||||
|
||||
CcTzItem *
|
||||
cc_tz_item_new (TzLocation *location)
|
||||
{
|
||||
CcTzItem *self;
|
||||
GString *offset;
|
||||
|
||||
g_return_val_if_fail (location, NULL);
|
||||
|
||||
self = g_object_new (CC_TYPE_TZ_ITEM, NULL);
|
||||
self->tz_location = location;
|
||||
self->tz_info = tz_info_from_location (location);
|
||||
generate_city_name (self, location);
|
||||
|
||||
self->tz = g_time_zone_new_offset (self->tz_info->utc_offset);
|
||||
|
||||
offset = g_string_new (g_time_zone_get_identifier (self->tz));
|
||||
/* Strip the seconds, eg: +05:30:00 -> +05:30 */
|
||||
g_string_set_size (offset, offset->len - 3);
|
||||
/* eg: +05:30 -> +0530*/
|
||||
g_string_replace (offset, ":", "", 0);
|
||||
|
||||
/* If the timezone is UTC remove the time, which will always be [+]0000 */
|
||||
if (g_str_has_suffix (offset->str, "0000"))
|
||||
g_string_set_size (offset, 0);
|
||||
|
||||
/* eg: +0530 -> UTC+0530 */
|
||||
g_string_prepend (offset, "UTC");
|
||||
|
||||
self->offset = g_string_free (offset, FALSE);
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
TzLocation *
|
||||
cc_tz_item_get_location (CcTzItem *self)
|
||||
{
|
||||
g_return_val_if_fail (CC_IS_TZ_ITEM (self), NULL);
|
||||
|
||||
return self->tz_location;
|
||||
}
|
||||
@@ -1,40 +0,0 @@
|
||||
/* -*- mode: c; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/*
|
||||
* Copyright 2022 Purism SPC
|
||||
* Copyright 2022 Mohammed Sadiq <sadiq@sadiqpk.org>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* Author(s):
|
||||
* Mohammed Sadiq <sadiq@sadiqpk.org>
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-3.0-or-later
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <glib-object.h>
|
||||
|
||||
#include "tz.h"
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define CC_TYPE_TZ_ITEM (cc_tz_item_get_type ())
|
||||
|
||||
G_DECLARE_FINAL_TYPE (CcTzItem, cc_tz_item, CC, TZ_ITEM, GObject)
|
||||
|
||||
CcTzItem *cc_tz_item_new (TzLocation *location);
|
||||
TzLocation *cc_tz_item_get_location (CcTzItem *self);
|
||||
|
||||
G_END_DECLS
|
||||
@@ -1,129 +0,0 @@
|
||||
<interface>
|
||||
<template class="GtkListItem">
|
||||
<property name="child">
|
||||
<object class="GtkGrid">
|
||||
<property name="margin-start">12</property>
|
||||
<property name="margin-end">12</property>
|
||||
<property name="margin-top">12</property>
|
||||
<property name="margin-bottom">12</property>
|
||||
<property name="row-spacing">6</property>
|
||||
<property name="column-spacing">6</property>
|
||||
|
||||
<!-- Location -->
|
||||
<child>
|
||||
<object class="GtkLabel">
|
||||
<property name="ellipsize">end</property>
|
||||
<property name="xalign">0</property>
|
||||
<style>
|
||||
<class name="title"/>
|
||||
</style>
|
||||
<binding name="label">
|
||||
<lookup name="name" type="CcTzItem">
|
||||
<lookup name="item">GtkListItem</lookup>
|
||||
</lookup>
|
||||
</binding>
|
||||
<layout>
|
||||
<property name="column">0</property>
|
||||
<property name="row">0</property>
|
||||
</layout>
|
||||
</object>
|
||||
</child>
|
||||
|
||||
<!-- Country -->
|
||||
<child>
|
||||
<object class="GtkLabel">
|
||||
<property name="hexpand">True</property>
|
||||
<property name="ellipsize">end</property>
|
||||
<property name="xalign">0</property>
|
||||
<style>
|
||||
<class name="heading"/>
|
||||
</style>
|
||||
<binding name="label">
|
||||
<lookup name="country" type="CcTzItem">
|
||||
<lookup name="item">GtkListItem</lookup>
|
||||
</lookup>
|
||||
</binding>
|
||||
<layout>
|
||||
<property name="column">1</property>
|
||||
<property name="row">0</property>
|
||||
</layout>
|
||||
</object>
|
||||
</child>
|
||||
|
||||
<child>
|
||||
<object class="GtkBox">
|
||||
<property name="spacing">3</property>
|
||||
<style>
|
||||
<class name="caption"/>
|
||||
<class name="dim-label"/>
|
||||
</style>
|
||||
<layout>
|
||||
<property name="column">0</property>
|
||||
<property name="row">1</property>
|
||||
<property name="column-span">2</property>
|
||||
</layout>
|
||||
|
||||
<!-- Zone Name -->
|
||||
<child>
|
||||
<object class="GtkLabel">
|
||||
<property name="xalign">0</property>
|
||||
<binding name="label">
|
||||
<lookup name="zone" type="CcTzItem">
|
||||
<lookup name="item">GtkListItem</lookup>
|
||||
</lookup>
|
||||
</binding>
|
||||
</object>
|
||||
</child>
|
||||
|
||||
<!-- Zone Name -->
|
||||
<child>
|
||||
<object class="GtkLabel">
|
||||
<property name="margin-start">3</property>
|
||||
<property name="margin-end">3</property>
|
||||
<property name="label">•</property>
|
||||
</object>
|
||||
</child>
|
||||
|
||||
<!-- Offset from GMT -->
|
||||
<child>
|
||||
<object class="GtkLabel">
|
||||
<property name="xalign">0</property>
|
||||
<binding name="label">
|
||||
<lookup name="offset" type="CcTzItem">
|
||||
<lookup name="item">GtkListItem</lookup>
|
||||
</lookup>
|
||||
</binding>
|
||||
</object>
|
||||
</child>
|
||||
|
||||
</object>
|
||||
</child>
|
||||
|
||||
<!-- Current time for the given timezone -->
|
||||
<child>
|
||||
<object class="GtkLabel">
|
||||
<property name="xalign">0</property>
|
||||
<property name="halign">end</property>
|
||||
<attributes>
|
||||
<attribute name="font-features" value="tnum"/>
|
||||
</attributes>
|
||||
<style>
|
||||
<class name="dim-label"/>
|
||||
</style>
|
||||
<binding name="label">
|
||||
<lookup name="time" type="CcTzItem">
|
||||
<lookup name="item">GtkListItem</lookup>
|
||||
</lookup>
|
||||
</binding>
|
||||
<layout>
|
||||
<property name="column">2</property>
|
||||
<property name="row">0</property>
|
||||
<property name="row-span">2</property>
|
||||
</layout>
|
||||
</object>
|
||||
</child>
|
||||
|
||||
</object>
|
||||
</property>
|
||||
</template>
|
||||
</interface>
|
||||
BIN
panels/datetime/data/bg.png
Normal file
|
After Width: | Height: | Size: 208 KiB |
BIN
panels/datetime/data/bg_dim.png
Normal file
|
After Width: | Height: | Size: 94 KiB |
BIN
panels/datetime/data/cc.png
Normal file
|
After Width: | Height: | Size: 50 KiB |
BIN
panels/datetime/data/pin.png
Normal file
|
After Width: | Height: | Size: 666 B |
BIN
panels/datetime/data/timezone_-1.png
Normal file
|
After Width: | Height: | Size: 7.8 KiB |
BIN
panels/datetime/data/timezone_-10.png
Normal file
|
After Width: | Height: | Size: 7.6 KiB |
BIN
panels/datetime/data/timezone_-10_dim.png
Normal file
|
After Width: | Height: | Size: 5.0 KiB |
BIN
panels/datetime/data/timezone_-11.png
Normal file
|
After Width: | Height: | Size: 8.2 KiB |
BIN
panels/datetime/data/timezone_-11_dim.png
Normal file
|
After Width: | Height: | Size: 4.7 KiB |
BIN
panels/datetime/data/timezone_-1_dim.png
Normal file
|
After Width: | Height: | Size: 4.8 KiB |
BIN
panels/datetime/data/timezone_-2.png
Normal file
|
After Width: | Height: | Size: 4.2 KiB |
BIN
panels/datetime/data/timezone_-2_dim.png
Normal file
|
After Width: | Height: | Size: 2.6 KiB |
BIN
panels/datetime/data/timezone_-3.5.png
Normal file
|
After Width: | Height: | Size: 740 B |
BIN
panels/datetime/data/timezone_-3.5_dim.png
Normal file
|
After Width: | Height: | Size: 995 B |
BIN
panels/datetime/data/timezone_-3.png
Normal file
|
After Width: | Height: | Size: 13 KiB |
BIN
panels/datetime/data/timezone_-3_dim.png
Normal file
|
After Width: | Height: | Size: 8.6 KiB |
BIN
panels/datetime/data/timezone_-4.png
Normal file
|
After Width: | Height: | Size: 16 KiB |
BIN
panels/datetime/data/timezone_-4_dim.png
Normal file
|
After Width: | Height: | Size: 9.6 KiB |
BIN
panels/datetime/data/timezone_-5.5.png
Normal file
|
After Width: | Height: | Size: 437 B |
BIN
panels/datetime/data/timezone_-5.5_dim.png
Normal file
|
After Width: | Height: | Size: 859 B |
BIN
panels/datetime/data/timezone_-5.png
Normal file
|
After Width: | Height: | Size: 19 KiB |
BIN
panels/datetime/data/timezone_-5_dim.png
Normal file
|
After Width: | Height: | Size: 12 KiB |
BIN
panels/datetime/data/timezone_-6.png
Normal file
|
After Width: | Height: | Size: 13 KiB |
BIN
panels/datetime/data/timezone_-6_dim.png
Normal file
|
After Width: | Height: | Size: 8.6 KiB |
BIN
panels/datetime/data/timezone_-7.png
Normal file
|
After Width: | Height: | Size: 12 KiB |
BIN
panels/datetime/data/timezone_-7_dim.png
Normal file
|
After Width: | Height: | Size: 7.7 KiB |
BIN
panels/datetime/data/timezone_-8.png
Normal file
|
After Width: | Height: | Size: 6.6 KiB |
BIN
panels/datetime/data/timezone_-8_dim.png
Normal file
|
After Width: | Height: | Size: 4.2 KiB |
BIN
panels/datetime/data/timezone_-9.5.png
Normal file
|
After Width: | Height: | Size: 437 B |