diff options
author | Mike Gabriel <mike.gabriel@das-netzwerkteam.de> | 2024-08-27 15:50:10 +0200 |
---|---|---|
committer | Mike Gabriel <mike.gabriel@das-netzwerkteam.de> | 2024-08-27 15:50:10 +0200 |
commit | 79853595a8e4adacddaeffd42f8e4cfdf5f9a5c5 (patch) | |
tree | 1a1e7ab8a8a4b703f3237d2ed77ed9f60a2d42fd /src | |
parent | 4bfbd579171d9194956376c7153f378ff6eb9d4e (diff) | |
parent | 1398450b47460ae951f69e410311677cb8fc14a7 (diff) | |
download | ayatana-settings-79853595a8e4adacddaeffd42f8e4cfdf5f9a5c5.tar.gz ayatana-settings-79853595a8e4adacddaeffd42f8e4cfdf5f9a5c5.tar.bz2 ayatana-settings-79853595a8e4adacddaeffd42f8e4cfdf5f9a5c5.zip |
Merge branch 'pr/full-rewrite'
Attributes GH PR #25: https://github.com/AyatanaIndicators/ayatana-settings/pull/25
Diffstat (limited to 'src')
-rw-r--r-- | src/CMakeLists.txt | 9 | ||||
-rw-r--r-- | src/glib.h | 61 | ||||
-rw-r--r-- | src/gtk.h | 210 | ||||
-rwxr-xr-x | src/main.c | 493 |
4 files changed, 773 insertions, 0 deletions
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt new file mode 100644 index 0000000..cb68f96 --- /dev/null +++ b/src/CMakeLists.txt @@ -0,0 +1,9 @@ +# ayatana-settings + +set_source_files_properties ("${CMAKE_BINARY_DIR}/data/${CMAKE_PROJECT_NAME}-gresource.c" PROPERTIES GENERATED TRUE) +add_executable ("ayatana-settings" "main.c" "${CMAKE_BINARY_DIR}/data/${CMAKE_PROJECT_NAME}-gresource.c") +add_dependencies ("ayatana-settings" "data") +target_compile_definitions ("ayatana-settings" PUBLIC G_LOG_DOMAIN="${CMAKE_PROJECT_NAME}" LOCALEDIR="${CMAKE_INSTALL_FULL_LOCALEDIR}" GETTEXT_PACKAGE="${CMAKE_PROJECT_NAME}") +target_link_libraries ("ayatana-settings" ${DEPS_LIBRARIES}) +target_include_directories ("ayatana-settings" PUBLIC ${DEPS_INCLUDE_DIRS}) +install (TARGETS "ayatana-settings" RUNTIME DESTINATION ${CMAKE_INSTALL_FULL_BINDIR}) diff --git a/src/glib.h b/src/glib.h new file mode 100644 index 0000000..be9cb06 --- /dev/null +++ b/src/glib.h @@ -0,0 +1,61 @@ +#ifndef __GLIB__ +#define __GLIB__ + +#include <glib.h> +#include <gio/gio.h> + +G_BEGIN_DECLS + +static inline void file_Copy (gchar *sPathIn, gchar *sPathOut) +{ + GError *pError = NULL; + GFile *pFileIn = g_file_new_for_path (sPathIn); + GFile *pFileOut = g_file_new_for_path (sPathOut); + g_file_copy (pFileIn, pFileOut, G_FILE_COPY_NONE, NULL, NULL, NULL, &pError); + g_object_unref (pFileIn); + g_object_unref (pFileOut); + + if (pError) + { + g_error ("Panic: Failed copying file from %s to %s: %s", sPathIn, sPathOut, pError->message); + g_clear_error (&pError); + + return; + } +} + +static inline gboolean string_Equal (gchar *sText, gchar *sText2) +{ + gint nEquality = g_strcmp0 (sText, sText2); + + return (nEquality == 0); +} + +static inline guint string_Length (gchar *sText) +{ + glong nLength = g_utf8_strlen (sText, -1); + + return nLength; +} + +static inline gchar* string_Replace (gchar *sText, gchar *sFind, gchar *sReplace) +{ + GString *sString = g_string_new (sText); + g_string_replace (sString, sFind, sReplace, 0); + gchar *sNewText = g_string_free_and_steal (sString); + + return sNewText; +} + +static inline gchar* string_Remove (gchar *sText, gchar *sRemove) +{ + gchar *sNewText = string_Replace (sText, sRemove, ""); + + return sNewText; +} + +#define string_ToInt atoi + +G_END_DECLS + +#endif diff --git a/src/gtk.h b/src/gtk.h new file mode 100644 index 0000000..fc01b3c --- /dev/null +++ b/src/gtk.h @@ -0,0 +1,210 @@ +#ifndef __GTK__ +#define __GTK__ + +#include <glib/gi18n.h> +#include <locale.h> +#include <gtk/gtk.h> + +G_BEGIN_DECLS + +typedef struct +{ + gchar *sId; + GCallback pCallback; +} ApplicationCallbackSymbol; + +typedef struct +{ + gchar *sUi; + GCallback pCallback; + ApplicationCallbackSymbol *lSymbols; +} ApplicationStartup; + +static GtkBuilder *m_pBuilder = NULL; +static GSettings *m_pDesktopSettings = NULL; +static GSettings *m_pA11ySettings = NULL; + +static inline void application_OnShutdown (GApplication *pApplication, gpointer pData) +{ + if (pData) + { + GCallback pCallback = (GCallback) pData; + pCallback (); + } + + g_object_unref (m_pBuilder); + g_clear_object (&m_pDesktopSettings); + g_clear_object (&m_pA11ySettings); +} + +static inline GObject* application_GetObject (gchar *sId) +{ + GObject *pObject = gtk_builder_get_object (m_pBuilder, sId); + + return pObject; +} + +static inline void application_OnActivate (GApplication *pApplication, gpointer pData) +{ + GList *lWindows = gtk_application_get_windows (GTK_APPLICATION (pApplication)); + + if (lWindows) + { + return; + } + + GObject *pWindow = gtk_builder_get_object (m_pBuilder, "window"); + gtk_window_present (GTK_WINDOW (pWindow)); + gtk_application_add_window (GTK_APPLICATION (pApplication), GTK_WINDOW (pWindow)); + GCallback pCallback = (GCallback) pData; + + if (pCallback) + { + pCallback (); + } +} + +static inline void application_onThemeChanged (GSettings *pSettings, const gchar *sKey, gpointer pData) +{ + gchar *sColorScheme = g_settings_get_string (m_pDesktopSettings, "color-scheme"); + gboolean bDark = string_Equal (sColorScheme, "prefer-dark"); + g_free (sColorScheme); + gboolean bHighContrast = g_settings_get_boolean (m_pA11ySettings, "high-contrast"); + GtkSettings *pGtkSettings = gtk_settings_get_default (); + + if (bHighContrast && bDark) + { + g_object_set (pGtkSettings, "gtk-theme-name", "Default-hc-dark", NULL); + } + else if (bHighContrast) + { + g_object_set (pGtkSettings, "gtk-theme-name", "Default-hc", NULL); + } + else if (bDark) + { + gtk_settings_reset_property (pGtkSettings, "gtk-theme-name"); + } + else + { + gtk_settings_reset_property (pGtkSettings, "gtk-theme-name"); + } + + g_object_set (pGtkSettings, "gtk-application-prefer-dark-theme", bDark, NULL); +} + +static inline void application_OnStartup (GApplication *pApplication, gpointer pData) +{ + ApplicationStartup *pStartup = (ApplicationStartup*) pData; + m_pBuilder = gtk_builder_new (); + GtkBuilderScope *pScope = gtk_builder_get_scope (m_pBuilder); + guint nId = 0; + + while (pStartup->lSymbols[nId].pCallback != NULL) + { + gtk_builder_cscope_add_callback_symbol (GTK_BUILDER_CSCOPE (pScope), pStartup->lSymbols[nId].sId, pStartup->lSymbols[nId].pCallback); + nId++; + } + + gtk_builder_add_from_resource (m_pBuilder, pStartup->sUi, NULL); + g_free (pStartup->sUi); + gtk_builder_set_translation_domain (m_pBuilder, GETTEXT_PACKAGE); + GSettingsSchemaSource *pSource = g_settings_schema_source_get_default (); + GSettingsSchema *pSchema = g_settings_schema_source_lookup (pSource, "org.gnome.desktop.interface", FALSE); + + if (pSchema) + { + gboolean bKey = g_settings_schema_has_key (pSchema, "color-scheme"); + g_settings_schema_unref (pSchema); + + if (bKey) + { + m_pDesktopSettings = g_settings_new ("org.gnome.desktop.interface"); + g_signal_connect (m_pDesktopSettings, "changed::color-scheme", G_CALLBACK (application_onThemeChanged), NULL); + } + } + + pSchema = g_settings_schema_source_lookup (pSource, "org.gnome.desktop.a11y.interface", FALSE); + + if (pSchema) + { + gboolean bKey = g_settings_schema_has_key (pSchema, "high-contrast"); + g_settings_schema_unref (pSchema); + + if (bKey) + { + m_pA11ySettings = g_settings_new ("org.gnome.desktop.a11y.interface"); + g_signal_connect (m_pA11ySettings, "changed::high-contrast", G_CALLBACK (application_onThemeChanged), NULL); + } + } + + if (m_pDesktopSettings && m_pA11ySettings) + { + application_onThemeChanged (NULL, NULL, NULL); + } + + if (pStartup->pCallback) + { + pStartup->pCallback (); + } +} + +static inline gint application_Init (ApplicationCallbackSymbol *lSymbols, gchar *sId, GCallback pOnStartup, GCallback pOnActivate, GCallback pOnShutdown, gint argc, gchar *argv[]) +{ + setlocale (LC_ALL, ""); + bindtextdomain (GETTEXT_PACKAGE, LOCALEDIR); + textdomain (GETTEXT_PACKAGE); + bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8"); + GtkApplication *pApplication = gtk_application_new (sId, G_APPLICATION_DEFAULT_FLAGS); + gchar *sReplaced = string_Replace (sId, ".", "/"); + gchar *sConcatenated = g_strconcat ("/", sReplaced, "/", GETTEXT_PACKAGE, ".ui", NULL); + g_free (sReplaced); + ApplicationStartup cApplicationStartup = {sConcatenated, pOnStartup, lSymbols}; + g_signal_connect (pApplication, "startup", G_CALLBACK (application_OnStartup), &cApplicationStartup); + g_signal_connect (pApplication, "activate", G_CALLBACK (application_OnActivate), pOnActivate); + g_signal_connect (pApplication, "shutdown", G_CALLBACK (application_OnShutdown), pOnShutdown); + gint nStatus = g_application_run (G_APPLICATION (pApplication), argc, argv); + g_object_unref (pApplication); + + return nStatus; +} + +static inline void listview_SetStringListFactory (gchar *sListView) +{ + const char *sFactory = + "<?xml version='1.0' encoding='UTF-8'?>\n" + "<interface>\n" + " <template class='GtkListItem'>\n" + " <property name='child'>\n" + " <object class='GtkInscription'>\n" + " <property name='xalign'>0</property>\n" + " <binding name='text'>\n" + " <lookup name='string' type='GtkStringObject'>\n" + " <lookup name='item'>GtkListItem</lookup>\n" + " </lookup>\n" + " </binding>\n" + " </object>\n" + " </property>\n" + " </template>\n" + "</interface>\n"; + + gsize nSize = strlen (sFactory); + GBytes *pBytes = g_bytes_new_static (sFactory, nSize); + GtkListItemFactory *pFactory = gtk_builder_list_item_factory_new_from_bytes (NULL, pBytes); + GtkListView *pListView = GTK_LIST_VIEW (application_GetObject (sListView)); + gtk_list_view_set_factory (pListView, pFactory); +} + +static inline void notebook_DisablePage (gchar *sPage) +{ + GtkNotebookPage *pPage = GTK_NOTEBOOK_PAGE (application_GetObject (sPage)); + GtkWidget *pChild = gtk_notebook_page_get_child (pPage); + gtk_widget_set_sensitive (pChild, FALSE); + GtkWidget *pTab = NULL; + g_object_get (pPage, "tab", &pTab, NULL); + gtk_widget_set_sensitive (pTab, FALSE); + g_object_unref (pTab); +} + +G_END_DECLS + +#endif diff --git a/src/main.c b/src/main.c new file mode 100755 index 0000000..028c78a --- /dev/null +++ b/src/main.c @@ -0,0 +1,493 @@ +/* + Copyright 2020-2024 Robert Tari <robert@tari.in> + + This file is part of Ayatana Settings. + + Ayatana Settings 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. + + Ayatana Settings 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 Ayatana Settings. If not, see <http://www.gnu.org/licenses/gpl-3.0.txt>. +*/ + +#include "glib.h" +#include "gtk.h" + +static gboolean m_bInit = FALSE; +static gboolean m_bMate = FALSE; +static GSettings *m_pSettingsSession = NULL; +static GSettings *m_pSettingsDateTime = NULL; +static GSettings *m_pSettingsSound = NULL; +static GSettings *m_pSettingsPower = NULL; +static GSettings *m_pSettingsNotifications = NULL; + +static gboolean isEnabled (gchar *sIndicator) +{ + gboolean bEnabled = TRUE; + const gchar *sHome = g_get_home_dir (); + gchar *sDesktop = g_strdup_printf (".config/autostart/ayatana-indicator-%s.desktop", sIndicator); + gchar *sPath = g_build_filename (sHome, sDesktop, NULL); + g_free (sDesktop); + gboolean bExists = g_file_test (sPath, G_FILE_TEST_EXISTS); + + if (bExists) + { + GKeyFile *pKeyFile = g_key_file_new (); + GError *pError = NULL; + g_key_file_load_from_file (pKeyFile, sPath, G_KEY_FILE_NONE, &pError); + + if (pError) + { + g_key_file_free (pKeyFile); + g_free (sPath); + g_error ("Panic: Failed loading key file: %s", pError->message); + g_clear_error (&pError); + + return FALSE; + } + + gboolean bKey = g_key_file_has_key (pKeyFile, "Desktop Entry", "X-MATE-Autostart-enabled", &pError); + + if (pError) + { + g_key_file_free (pKeyFile); + g_free (sPath); + g_error ("Panic: Failed parsing key file for X-MATE-Autostart-enabled: %s", pError->message); + g_clear_error (&pError); + + return FALSE; + } + + if (bKey) + { + bEnabled = g_key_file_get_boolean (pKeyFile, "Desktop Entry", "X-MATE-Autostart-enabled", &pError); + + if (pError) + { + g_key_file_free (pKeyFile); + g_free (sPath); + g_error ("Panic: Failed getting the value of X-MATE-Autostart-enabled from the key file: %s", pError->message); + g_clear_error (&pError); + + return FALSE; + } + } + else + { + gboolean bKey = g_key_file_has_key (pKeyFile, "Desktop Entry", "X-GNOME-Autostart-enabled", &pError); + + if (pError) + { + g_key_file_free (pKeyFile); + g_free (sPath); + g_error ("Panic: Failed parsing key file for X-GNOME-Autostart-enabled: %s", pError->message); + g_clear_error (&pError); + + return FALSE; + } + + if (bKey) + { + bEnabled = g_key_file_get_boolean (pKeyFile, "Desktop Entry", "X-GNOME-Autostart-enabled", &pError); + + if (pError) + { + g_key_file_free (pKeyFile); + g_free (sPath); + g_error ("Panic: Failed getting the value of X-GNOME-Autostart-enabled from the key file: %s", pError->message); + g_clear_error (&pError); + + return FALSE; + } + } + } + + g_key_file_free (pKeyFile); + } + + g_free (sPath); + + return bEnabled; +} + +static void onToggleButtonEnableToggled (GtkToggleButton *pButton, gpointer pData) +{ + if (!m_bInit) + { + return; + } + + const gchar *sHome = g_get_home_dir (); + gchar *sAutostartFolder = g_build_filename (sHome, ".config/autostart", NULL); + gboolean bExists = g_file_test (sAutostartFolder, G_FILE_TEST_IS_DIR); + + if (!bExists) + { + g_mkdir_with_parents (sAutostartFolder, 755); + } + + g_free (sAutostartFolder); + const gchar *sIndicator = gtk_widget_get_name (GTK_WIDGET (pButton)); + gchar *sDesktop = g_strdup_printf (".config/autostart/ayatana-indicator-%s.desktop", sIndicator); + gchar *sPath = g_build_filename (sHome, sDesktop, NULL); + g_free (sDesktop); + bExists = g_file_test (sPath, G_FILE_TEST_EXISTS); + + if (!bExists) + { + gchar *sPathIn = g_strdup_printf ("/etc/xdg/autostart/ayatana-indicator-%s.desktop", sIndicator); + file_Copy (sPathIn, sPath); + g_free (sPathIn); + } + + GKeyFile *pKeyFile = g_key_file_new (); + GError *pError = NULL; + g_key_file_load_from_file (pKeyFile, sPath, G_KEY_FILE_NONE, &pError); + + if (pError) + { + g_key_file_free (pKeyFile); + g_free (sPath); + g_error ("Panic: Failed loading key file: %s", pError->message); + g_clear_error (&pError); + + return; + } + + gboolean bEnabled = gtk_toggle_button_get_active (pButton); + + if (m_bMate) + { + g_key_file_set_boolean (pKeyFile, "Desktop Entry", "X-MATE-Autostart-enabled", bEnabled); + } + else + { + g_key_file_set_boolean (pKeyFile, "Desktop Entry", "X-GNOME-Autostart-enabled", bEnabled); + } + + g_key_file_save_to_file (pKeyFile, sPath, &pError); + + if (pError) + { + g_key_file_free (pKeyFile); + g_free (sPath); + g_error ("Panic: Failed saving key file: %s", pError->message); + g_clear_error (&pError); + + return; + } + + g_key_file_free (pKeyFile); + g_free (sPath); +} + +static void onSpinButtonNotificationsValueChanged (GtkSpinButton *pSpinButton, gpointer pData) +{ + gint nValue = gtk_spin_button_get_value_as_int (pSpinButton); + g_settings_set_int (m_pSettingsNotifications, "max-items", nValue); +} + +static void saveFilterList () +{ + GStrvBuilder *pBuilder = g_strv_builder_new (); + GtkStringList *pStringList = GTK_STRING_LIST (application_GetObject ("StringListNotificationsFilters")); + guint nItems = g_list_model_get_n_items (G_LIST_MODEL (pStringList)); + + for (guint nItem = 0; nItem < nItems; nItem++) + { + const gchar *sModelText = gtk_string_list_get_string (pStringList, nItem); + g_strv_builder_add (pBuilder, (gchar*) sModelText); + } + + GStrv lItems = g_strv_builder_end (pBuilder); + g_strv_builder_unref (pBuilder); + g_settings_set_strv (m_pSettingsNotifications, "filter-list", (const char* const*) lItems); + g_strfreev (lItems); +} + +static void onButtonNotificationsAddClicked (GtkButton *pButton, gpointer pData) +{ + GObject *pEntryNotifications = application_GetObject ("EntryNotifications"); + const gchar *sText = gtk_editable_get_text (GTK_EDITABLE (pEntryNotifications)); + gchar *sTextDup = g_strdup (sText); + g_strstrip (sTextDup); + guint nLength = string_Length (sTextDup); + + if (nLength) + { + gboolean bDuplicate = FALSE; + GtkStringList *pStringList = GTK_STRING_LIST (application_GetObject ("StringListNotificationsFilters")); + guint nItems = g_list_model_get_n_items (G_LIST_MODEL (pStringList)); + + for (guint nItem = 0; nItem < nItems; nItem++) + { + const gchar *sModelText = gtk_string_list_get_string (pStringList, nItem); + gboolean bEqual = string_Equal ((gchar*) sModelText, (gchar*) sText); + + if (bEqual) + { + bDuplicate = TRUE; + + break; + } + } + + if (!bDuplicate) + { + gtk_string_list_append (pStringList, sTextDup); + saveFilterList (); + } + } + + g_free (sTextDup); + gtk_editable_set_text (GTK_EDITABLE (pEntryNotifications), ""); +} + +static void onButtonNotificationsRemoveClicked (GtkButton *pButton, gpointer pData) +{ + GtkSingleSelection *pSelection = GTK_SINGLE_SELECTION (application_GetObject ("SingleSelectionNotifications")); + guint nSelected = gtk_single_selection_get_selected (pSelection); + GtkStringList *pStringList = GTK_STRING_LIST (application_GetObject ("StringListNotificationsFilters")); + + if (nSelected != GTK_INVALID_LIST_POSITION) + { + gtk_string_list_remove (pStringList, nSelected); + saveFilterList (); + } +} + +static void onActivate () +{ + GSettingsSchemaSource *pSource = g_settings_schema_source_get_default (); + GSettingsSchema *pSchema = NULL; + GObject *pSwitch = NULL; + + // Session + pSchema = g_settings_schema_source_lookup (pSource, "org.ayatana.indicator.session", FALSE); + + if (pSchema) + { + g_settings_schema_unref (pSchema); + m_pSettingsSession = g_settings_new ("org.ayatana.indicator.session"); + pSwitch = application_GetObject ("SwitchSessionShowName"); + g_settings_bind (m_pSettingsSession, "show-real-name-on-panel", pSwitch, "active", G_SETTINGS_BIND_DEFAULT); + pSwitch = application_GetObject ("SwitchSessionRemoveLogOut"); + g_settings_bind (m_pSettingsSession, "suppress-logout-menuitem", pSwitch, "active", G_SETTINGS_BIND_DEFAULT); + pSwitch = application_GetObject ("SwitchSessionSuppressConfirmation"); + g_settings_bind (m_pSettingsSession, "suppress-logout-restart-shutdown", pSwitch, "active", G_SETTINGS_BIND_DEFAULT); + pSwitch = application_GetObject ("SwitchSessionRemoveRestart"); + g_settings_bind (m_pSettingsSession, "suppress-restart-menuitem", pSwitch, "active", G_SETTINGS_BIND_DEFAULT); + pSwitch = application_GetObject ("SwitchSessionRemoveShutDown"); + g_settings_bind (m_pSettingsSession, "suppress-shutdown-menuitem", pSwitch, "active", G_SETTINGS_BIND_DEFAULT); + pSwitch = application_GetObject ("SwitchSessionShowUsers"); + g_settings_bind (m_pSettingsSession, "user-show-menu", pSwitch, "active", G_SETTINGS_BIND_DEFAULT); + gboolean bEnabled = isEnabled ("session"); + GtkToggleButton *pToggleButton = GTK_TOGGLE_BUTTON (application_GetObject ("ToggleButtonSessionEnable")); + gtk_toggle_button_set_active (pToggleButton, bEnabled); + } + else + { + notebook_DisablePage ("NotebookPageSession"); + } + //~Session + + // Date/Time + pSchema = g_settings_schema_source_lookup (pSource, "org.ayatana.indicator.datetime", FALSE); + + if (pSchema) + { + g_settings_schema_unref (pSchema); + m_pSettingsDateTime = g_settings_new ("org.ayatana.indicator.datetime"); + pSwitch = application_GetObject ("SwitchDatetimeShowCalendar"); + g_settings_bind (m_pSettingsDateTime, "show-calendar", pSwitch, "active", G_SETTINGS_BIND_DEFAULT); + pSwitch = application_GetObject ("SwitchDatetimeShowDate"); + g_settings_bind (m_pSettingsDateTime, "show-date", pSwitch, "active", G_SETTINGS_BIND_DEFAULT); + pSwitch = application_GetObject ("SwitchDatetimeShowDay"); + g_settings_bind (m_pSettingsDateTime, "show-day", pSwitch, "active", G_SETTINGS_BIND_DEFAULT); + pSwitch = application_GetObject ("SwitchDatetimeShowEvents"); + g_settings_bind (m_pSettingsDateTime, "show-events", pSwitch, "active", G_SETTINGS_BIND_DEFAULT); + pSwitch = application_GetObject ("SwitchDatetimeShowSeconds"); + g_settings_bind (m_pSettingsDateTime, "show-seconds", pSwitch, "active", G_SETTINGS_BIND_DEFAULT); + pSwitch = application_GetObject ("SwitchDatetimeShowWeekNumbers"); + g_settings_bind (m_pSettingsDateTime, "show-week-numbers", pSwitch, "active", G_SETTINGS_BIND_DEFAULT); + pSwitch = application_GetObject ("SwitchDatetimeShowYear"); + g_settings_bind (m_pSettingsDateTime, "show-year", pSwitch, "active", G_SETTINGS_BIND_DEFAULT); + gboolean bEnabled = isEnabled ("datetime"); + GtkToggleButton *pToggleButton = GTK_TOGGLE_BUTTON (application_GetObject ("ToggleButtonDatetimeEnable")); + gtk_toggle_button_set_active (pToggleButton, bEnabled); + } + else + { + notebook_DisablePage ("NotebookPageDatetime"); + } + //~Date/Time + + // Sound + pSchema = g_settings_schema_source_lookup (pSource, "org.ayatana.indicator.sound", FALSE); + + if (pSchema) + { + g_settings_schema_unref (pSchema); + m_pSettingsSound = g_settings_new ("org.ayatana.indicator.sound"); + pSwitch = application_GetObject ("SwitchSoundAllowAmplified"); + g_settings_bind (m_pSettingsSound, "allow-amplified-volume", pSwitch, "active", G_SETTINGS_BIND_DEFAULT); + gboolean bEnabled = isEnabled ("sound"); + GtkToggleButton *pToggleButton = GTK_TOGGLE_BUTTON (application_GetObject ("ToggleButtonSoundEnable")); + gtk_toggle_button_set_active (pToggleButton, bEnabled); + } + else + { + notebook_DisablePage ("NotebookPageSound"); + } + //~Sound + + // Power + pSchema = g_settings_schema_source_lookup (pSource, "org.ayatana.indicator.power", FALSE); + + if (pSchema) + { + g_settings_schema_unref (pSchema); + m_pSettingsPower = g_settings_new ("org.ayatana.indicator.power"); + pSwitch = application_GetObject ("SwitchPowerShowPercentage"); + g_settings_bind (m_pSettingsPower, "show-percentage", pSwitch, "active", G_SETTINGS_BIND_DEFAULT); + pSwitch = application_GetObject ("SwitchPowerShowTime"); + g_settings_bind (m_pSettingsPower, "show-time", pSwitch, "active", G_SETTINGS_BIND_DEFAULT); + gboolean bEnabled = isEnabled ("power"); + GtkToggleButton *pToggleButton = GTK_TOGGLE_BUTTON (application_GetObject ("ToggleButtonPowerEnable")); + gtk_toggle_button_set_active (pToggleButton, bEnabled); + } + else + { + notebook_DisablePage ("NotebookPagePower"); + } + //~Power + + // Messages + pSchema = g_settings_schema_source_lookup (pSource, "org.ayatana.indicator.messages", FALSE); + + if (pSchema) + { + g_settings_schema_unref (pSchema); + gboolean bEnabled = isEnabled ("messages"); + GtkToggleButton *pToggleButton = GTK_TOGGLE_BUTTON (application_GetObject ("ToggleButtonMessagesEnable")); + gtk_toggle_button_set_active (pToggleButton, bEnabled); + } + else + { + notebook_DisablePage ("NotebookPageMessages"); + } + //~Messages + + // Bluetooth + pSchema = g_settings_schema_source_lookup (pSource, "org.ayatana.indicator.bluetooth", FALSE); + + if (pSchema) + { + g_settings_schema_unref (pSchema); + gboolean bEnabled = isEnabled ("bluetooth"); + GtkToggleButton *pToggleButton = GTK_TOGGLE_BUTTON (application_GetObject ("ToggleButtonBluetoothEnable")); + gtk_toggle_button_set_active (pToggleButton, bEnabled); + } + else + { + notebook_DisablePage ("NotebookPageBluetooth"); + } + //~Bluetooth + + // Notifications + pSchema = g_settings_schema_source_lookup (pSource, "org.ayatana.indicator.notifications", FALSE); + + if (pSchema) + { + g_settings_schema_unref (pSchema); + m_pSettingsNotifications = g_settings_new ("org.ayatana.indicator.notifications"); + gint nMaxItems = g_settings_get_int (m_pSettingsNotifications, "max-items"); + GtkSpinButton *pSpinButton = GTK_SPIN_BUTTON (application_GetObject ("SpinButtonNotifications")); + gtk_spin_button_set_value (pSpinButton, nMaxItems); + GStrv lFilters = g_settings_get_strv (m_pSettingsNotifications, "filter-list"); + guint nFilters = g_strv_length (lFilters); + listview_SetStringListFactory ("ListViewNotifications"); + GtkStringList *pStringList = GTK_STRING_LIST (application_GetObject ("StringListNotificationsFilters")); + + for (guint nFilter = 0; nFilter < nFilters; nFilter++) + { + gtk_string_list_append (pStringList, lFilters[nFilter]); + } + + g_strfreev (lFilters); + GStrv lHints = g_settings_get_strv (m_pSettingsNotifications, "filter-list-hints"); + guint nHints = g_strv_length (lHints); + pStringList = GTK_STRING_LIST (application_GetObject ("StringListNotificationsHints")); + + for (guint nHint = 0; nHint < nHints; nHint++) + { + gtk_string_list_append (pStringList, lHints[nHint]); + } + + g_strfreev (lHints); + // TODO: Entry completion replacement goes here, once available + gboolean bEnabled = isEnabled ("notifications"); + GtkToggleButton *pToggleButton = GTK_TOGGLE_BUTTON (application_GetObject ("ToggleButtonNotificationsEnable")); + gtk_toggle_button_set_active (pToggleButton, bEnabled); + } + else + { + notebook_DisablePage ("NotebookPageNotifications"); + } + //~Notifications + + // Keyboard + pSchema = g_settings_schema_source_lookup (pSource, "org.ayatana.indicator.keyboard", FALSE); + + if (pSchema) + { + gboolean bEnabled = isEnabled ("keyboard"); + GtkToggleButton *pToggleButton = GTK_TOGGLE_BUTTON (application_GetObject ("ToggleButtonKeyboardEnable")); + gtk_toggle_button_set_active (pToggleButton, bEnabled); + } + else + { + notebook_DisablePage ("NotebookPageKeyboard"); + } + //~Keyboard + + m_bInit = TRUE; +} + +static void onShutdown () +{ + g_clear_object (&m_pSettingsSession); + g_clear_object (&m_pSettingsDateTime); + g_clear_object (&m_pSettingsSound); + g_clear_object (&m_pSettingsPower); + g_clear_object (&m_pSettingsNotifications); +} + +static void onStartup () +{ + const gchar *sDesktop = g_getenv ("XDG_CURRENT_DESKTOP"); + m_bMate = string_Equal ((gchar*) sDesktop, "MATE"); +} + +gint main (gint argc, gchar *argv[]) +{ + ApplicationCallbackSymbol lSymbols[] = + { + {"onToggleButtonEnableToggled", G_CALLBACK (onToggleButtonEnableToggled)}, + {"onButtonNotificationsRemoveClicked", G_CALLBACK (onButtonNotificationsRemoveClicked)}, + {"onButtonNotificationsAddClicked", G_CALLBACK (onButtonNotificationsAddClicked)}, + {"onSpinButtonNotificationsValueChanged", G_CALLBACK (onSpinButtonNotificationsValueChanged)}, + {NULL, NULL} + }; + + gint nStatus = application_Init (lSymbols, "org.ayatana.ayatana-settings", onStartup, onActivate, onShutdown, argc, argv); + + return nStatus; +} |