From 2eca12715d78423b7f7db0eb25137c42cea321df Mon Sep 17 00:00:00 2001 From: Ivan Yarcev Date: Fri, 5 May 2023 16:25:06 +0600 Subject: [PATCH 1/5] Link updated --- ubl-settings-update.glade | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ubl-settings-update.glade b/ubl-settings-update.glade index 2cfba93..6e72350 100644 --- a/ubl-settings-update.glade +++ b/ubl-settings-update.glade @@ -15,7 +15,7 @@ 1.1 Copyright © 2022 - 2023, UBSoft LLC Update confugurator - https://ublinux.ru/ + https://wiki.ublinux.ru/ru/Программное_обеспечение/Программы_и_утилиты/Все/ubl-settings-update Project Home Page Это приложение распространяется без каких-либо гарантий. Подробнее в <a href="https://www.gnu.org/licenses/old-licenses/gpl-2.0.html">GNU General Public License, версии 2 или позднее</a>. From 932e2b39aae544edf856843e12eb0cefd324b41a Mon Sep 17 00:00:00 2001 From: Ivan Yarcev Date: Fri, 19 May 2023 18:09:46 +0600 Subject: [PATCH 2/5] Design changes --- source/ubl-settings-update.c | 87 +++++++------- source/ubl-settings-update.h | 7 +- ubl-settings-update.desktop | 4 +- ubl-settings-update.glade | 214 ++++++++++++----------------------- 4 files changed, 118 insertions(+), 194 deletions(-) diff --git a/source/ubl-settings-update.c b/source/ubl-settings-update.c index 0ee60fc..02ddd8f 100644 --- a/source/ubl-settings-update.c +++ b/source/ubl-settings-update.c @@ -29,12 +29,8 @@ repo_window *setup_repo_window(){ widgets->repoTypeLabel=yon_gtk_builder_get_widget(widgets->builder, "repoTypeLabel"); widgets->repoTypeEntry=yon_gtk_builder_get_widget(widgets->builder, "repoTypeEntry"); - widgets->repoURILabel=yon_gtk_builder_get_widget(widgets->builder, "repoURILabel"); - widgets->repoURIMeanLabel=yon_gtk_builder_get_widget(widgets->builder, "repoURIMeanLabel"); widgets->repoDistributionLabel=yon_gtk_builder_get_widget(widgets->builder, "repoDistributionLabel"); - widgets->repoDistributionMeanLabel=yon_gtk_builder_get_widget(widgets->builder, "repoDistributionMeanLabel"); - widgets->repoSectionsLabel=yon_gtk_builder_get_widget(widgets->builder, "repoSectionsLabel"); - widgets->repoSectionsMeanlabel=yon_gtk_builder_get_widget(widgets->builder, "repoSectionsMeanlabel"); + widgets->repoDistributionEntry=yon_gtk_builder_get_widget(widgets->builder, "repoDistributionEntry"); widgets->repoCancelButton=yon_gtk_builder_get_widget(widgets->builder, "repoCancelButton"); widgets->repoAcceptButton=yon_gtk_builder_get_widget(widgets->builder, "repoAcceptButton"); @@ -43,18 +39,13 @@ repo_window *setup_repo_window(){ g_signal_connect(G_OBJECT(widgets->repoAcceptButton), "clicked", G_CALLBACK(on_close_subwindow), NULL); - gtk_window_set_title(GTK_WINDOW(widgets->window),_("System update")); + gtk_window_set_title(GTK_WINDOW(widgets->window),TITLE_LABEL); - gtk_label_set_text(GTK_LABEL(widgets->repoTypeLabel),_("Type: ")); - gtk_label_set_text(GTK_LABEL(widgets->repoURILabel),_("URI: ")); - gtk_label_set_text(GTK_LABEL(widgets->repoURIMeanLabel),_(" ")); - gtk_label_set_text(GTK_LABEL(widgets->repoDistributionLabel),_("Distribution: ")); - gtk_label_set_text(GTK_LABEL(widgets->repoDistributionMeanLabel),_(" ")); - gtk_label_set_text(GTK_LABEL(widgets->repoSectionsLabel),_("Sections: ")); - gtk_label_set_text(GTK_LABEL(widgets->repoSectionsMeanlabel),_(" ")); + gtk_label_set_text(GTK_LABEL(widgets->repoTypeLabel),ADRESS_LABEL); + gtk_label_set_text(GTK_LABEL(widgets->repoDistributionLabel),DISTRIBUTION_LABEL); - gtk_button_set_label(GTK_BUTTON(widgets->repoCancelButton),_("Cancel")); - gtk_button_set_label(GTK_BUTTON(widgets->repoAcceptButton),_("Save")); + gtk_button_set_label(GTK_BUTTON(widgets->repoCancelButton),CANCEL_LABEL); + gtk_button_set_label(GTK_BUTTON(widgets->repoAcceptButton),SAVE_LABEL); gtk_widget_show_all(widgets->window); } @@ -108,47 +99,47 @@ main_window *setup_window(){ widgets->mainCheckForUpdatesButton=yon_gtk_builder_get_widget(widgets->builder,"checkForUpdatesButton"); - gtk_window_set_title(GTK_WINDOW(widgets->window),_("System update")); + gtk_window_set_title(GTK_WINDOW(widgets->window),TITLE_LABEL); - gtk_label_set_text(GTK_LABEL(widgets->HeaderTopic),_("System update")); + gtk_label_set_text(GTK_LABEL(widgets->HeaderTopic),TITLE_LABEL); - gtk_label_set_text(GTK_LABEL(widgets->generalSettingsTabLabel),_("General")); - gtk_label_set_text(GTK_LABEL(widgets->repositoriesSettingsTabLabel),_("Repositories")); - gtk_label_set_text(GTK_LABEL(widgets->extraSettingsTabLabel),_("Extra")); + gtk_label_set_text(GTK_LABEL(widgets->generalSettingsTabLabel),GENERAL_LABEL); + gtk_label_set_text(GTK_LABEL(widgets->repositoriesSettingsTabLabel),REPOSITORIES_LABEL); + gtk_label_set_text(GTK_LABEL(widgets->extraSettingsTabLabel),EXTRA_LABEL); - gtk_label_set_text(GTK_LABEL(widgets->generalSettingsUpdatesCheckFreqLabel),_("Update checking frequency")); - gtk_button_set_label(GTK_BUTTON(widgets->generalSettingsHideNoUpdatesCheck),_("Hide icon of no updates found")); - gtk_button_set_label(GTK_BUTTON(widgets->generalSettingsDownloadAutoCheck),_("Download updates automatically")); - gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(widgets->generalSettingsUpdatesCheckFreqCombo),_("Every 1 hour")); - gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(widgets->generalSettingsUpdatesCheckFreqCombo),_("Every 2 hours")); - gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(widgets->generalSettingsUpdatesCheckFreqCombo),_("Every 3 hours")); + gtk_label_set_text(GTK_LABEL(widgets->generalSettingsUpdatesCheckFreqLabel),CHECK_FREQUENCY_LABEL); + gtk_button_set_label(GTK_BUTTON(widgets->generalSettingsHideNoUpdatesCheck),HIDE_NO_UPDATES_LABEL); + gtk_button_set_label(GTK_BUTTON(widgets->generalSettingsDownloadAutoCheck),AUTO_UPDATE_LABEL); + gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(widgets->generalSettingsUpdatesCheckFreqCombo),EVERY_1_HOUR_LABEL); + gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(widgets->generalSettingsUpdatesCheckFreqCombo),EVERY_2_HOURS_LABEL); + gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(widgets->generalSettingsUpdatesCheckFreqCombo),EVERY_3_HOURS_LABEL); - gtk_button_set_label(GTK_BUTTON(widgets->repositoriesSettingsActivateAURCheck),_("Activate AUR")); - gtk_button_set_label(GTK_BUTTON(widgets->repositoriesSettingsActivateUBURCheck),_("Activate UBUR")); - gtk_button_set_label(GTK_BUTTON(widgets->repositoriesSettingsCreateButton),_("Create")); - gtk_button_set_label(GTK_BUTTON(widgets->repositoriesSettingsEditButton),_("Edit")); - gtk_button_set_label(GTK_BUTTON(widgets->repositoriesSettingsDeleteButton),_("Delete")); - gtk_tree_view_column_set_title(GTK_TREE_VIEW_COLUMN(widgets->repositoriesSettingsEnabledColumn),_("Enabled")); - gtk_tree_view_column_set_title(GTK_TREE_VIEW_COLUMN(widgets->repositoriesSettingsURIColumn),_("URI")); + gtk_button_set_label(GTK_BUTTON(widgets->repositoriesSettingsActivateAURCheck),AUR_LABEL); + gtk_button_set_label(GTK_BUTTON(widgets->repositoriesSettingsActivateUBURCheck),UBUR_LABEL); + // gtk_button_set_label(GTK_BUTTON(widgets->repositoriesSettingsCreateButton),_("Create")); + // gtk_button_set_label(GTK_BUTTON(widgets->repositoriesSettingsEditButton),_("Edit")); + // gtk_button_set_label(GTK_BUTTON(widgets->repositoriesSettingsDeleteButton),_("Delete")); + gtk_tree_view_column_set_title(GTK_TREE_VIEW_COLUMN(widgets->repositoriesSettingsEnabledColumn),ENABLED_LABEL); + gtk_tree_view_column_set_title(GTK_TREE_VIEW_COLUMN(widgets->repositoriesSettingsURIColumn),URI_LABEL); - gtk_label_set_text(GTK_LABEL(widgets->extraSettingsPackageManagerLabel),_("Package manager: ")); - gtk_label_set_text(GTK_LABEL(widgets->extraSettingsUpdateCommandLabel),_("Update command: ")); - gtk_label_set_text(GTK_LABEL(widgets->extraSettingsCacheCleanlabel),_("Cache clean command: ")); - gtk_button_set_label(GTK_BUTTON(widgets->extraSettingsLaunchPackageManagerButton),_("Launch package manager")); + gtk_label_set_text(GTK_LABEL(widgets->extraSettingsPackageManagerLabel),PACKAGE_MANAGER_LABEL); + gtk_label_set_text(GTK_LABEL(widgets->extraSettingsUpdateCommandLabel),UPDATE_COMMAND_LABEL); + gtk_label_set_text(GTK_LABEL(widgets->extraSettingsCacheCleanlabel),CACHE_CLEAN_LABEL); + gtk_button_set_label(GTK_BUTTON(widgets->extraSettingsLaunchPackageManagerButton),LAUNCH_PACKAGE_MANAGER_LABEL); - gtk_label_set_text(GTK_LABEL(widgets->headerLoadConfigLabel),_("load")); - gtk_menu_item_set_label(GTK_MENU_ITEM(widgets->headerLoadGlobalConfigButton),_("Load global configuration")); - gtk_menu_item_set_label(GTK_MENU_ITEM(widgets->headerLoadLocalConfigButton),_("Load local configuration")); + gtk_label_set_text(GTK_LABEL(widgets->headerLoadConfigLabel),LOAD_LABEL); + gtk_menu_item_set_label(GTK_MENU_ITEM(widgets->headerLoadGlobalConfigButton),LOAD_GLOBAL_LABEL); + gtk_menu_item_set_label(GTK_MENU_ITEM(widgets->headerLoadLocalConfigButton),LOAD_LOCAL_LABEL); - gtk_label_set_text(GTK_LABEL(widgets->headerSaveConfigLabel),_("Save")); - gtk_menu_item_set_label(GTK_MENU_ITEM(widgets->headerSaveGlobalLocalConfigButton),_("Save to global and local configuration")); - gtk_menu_item_set_label(GTK_MENU_ITEM(widgets->headerSaveGlobalConfigButton),_("Save to global configuration")); - gtk_menu_item_set_label(GTK_MENU_ITEM(widgets->headerSaveLocalConfigButton),_("Save to local configuration")); + gtk_label_set_text(GTK_LABEL(widgets->headerSaveConfigLabel),SAVE_LABEL); + gtk_menu_item_set_label(GTK_MENU_ITEM(widgets->headerSaveGlobalLocalConfigButton),SAVE_LABEL); + gtk_menu_item_set_label(GTK_MENU_ITEM(widgets->headerSaveGlobalConfigButton),SAVE_GLOBAL_LABEL); + gtk_menu_item_set_label(GTK_MENU_ITEM(widgets->headerSaveLocalConfigButton),SAVE_LOCAL_LABEL); - gtk_menu_item_set_label(GTK_MENU_ITEM(widgets->headerDocumentationButton),_("Documentation")); - gtk_menu_item_set_label(GTK_MENU_ITEM(widgets->headerAboutButton),_("About")); + gtk_menu_item_set_label(GTK_MENU_ITEM(widgets->headerDocumentationButton),DOCUMENTATION_LABEL); + gtk_menu_item_set_label(GTK_MENU_ITEM(widgets->headerAboutButton),ABOUT_LABEL); - gtk_button_set_label(GTK_BUTTON(widgets->mainCheckForUpdatesButton),_("Check for updates")); + gtk_button_set_label(GTK_BUTTON(widgets->mainCheckForUpdatesButton),CHECK_FOR_UPDATES_LABEL); @@ -163,7 +154,7 @@ main_window *setup_window(){ yon_ubl_header_setup(Overlay,Header,Image,image_path); gtk_overlay_add_overlay(GTK_OVERLAY(UnderNoteOverlay),checkForUpdatesButton); - gtk_label_set_text(GTK_LABEL(headLabel),_("System update parameter configuration")); + gtk_label_set_text(GTK_LABEL(headLabel),TITLE_LABEL); gtk_widget_show_all(widgets->window); diff --git a/source/ubl-settings-update.h b/source/ubl-settings-update.h index e5129f0..69c7296 100644 --- a/source/ubl-settings-update.h +++ b/source/ubl-settings-update.h @@ -5,6 +5,7 @@ #include #include #include +#include "ubl-settings-update-strings.h" #define _(String) gettext(String) @@ -75,12 +76,8 @@ typedef struct { GtkWidget *repoTypeLabel; GtkWidget *repoTypeEntry; - GtkWidget *repoURILabel; - GtkWidget *repoURIMeanLabel; GtkWidget *repoDistributionLabel; - GtkWidget *repoDistributionMeanLabel; - GtkWidget *repoSectionsLabel; - GtkWidget *repoSectionsMeanlabel; + GtkWidget *repoDistributionEntry; GtkWidget *repoCancelButton; GtkWidget *repoAcceptButton; diff --git a/ubl-settings-update.desktop b/ubl-settings-update.desktop index c67c7c4..74138da 100644 --- a/ubl-settings-update.desktop +++ b/ubl-settings-update.desktop @@ -1,9 +1,9 @@ [Desktop Entry] Encoding=UTF-8 Name=ubl-settings-update -Name[ru]=Настройки обновлений +Name[ru]=Обновление системы GenericName=ubl-settings-quotas -GenericName[ru]=Настройки обновлений +GenericName[ru]=Обвноление системы Comment=ubl-settings-update Comment[ru]=Приложение для управления настройками обновлений Type=Application diff --git a/ubl-settings-update.glade b/ubl-settings-update.glade index 6e72350..d89d9df 100644 --- a/ubl-settings-update.glade +++ b/ubl-settings-update.glade @@ -66,6 +66,7 @@ + True False @@ -211,43 +212,6 @@ False vertical 5 - - - True - False - 5 - - - True - False - URI: - 0 - - - False - True - 0 - - - - - True - False - 0 - - - False - True - 1 - - - - - False - True - 0 - - True @@ -267,13 +231,12 @@ - + True - False - 0 + True - False + True True 1 @@ -285,43 +248,6 @@ 1 - - - True - False - 5 - - - True - False - Sections: - 0 - - - False - True - 0 - - - - - True - False - 0 - - - False - True - 1 - - - - - False - True - 2 - - False @@ -397,12 +323,10 @@ - + - - - + @@ -425,6 +349,21 @@ start image4 + + True + False + value-increase-symbolic + + + True + False + error-correct-symbolic + + + True + False + user-trash-symbolic + @@ -501,6 +440,8 @@ + 800 + 600 False 800 600 @@ -714,6 +655,8 @@ True False + 5 + 5 5 @@ -756,9 +699,9 @@ True False - center + start vertical - 25 + 15 True @@ -822,6 +765,54 @@ 1 + + + True + True + True + image5 + + + + False + True + 2 + + + + + True + True + True + image6 + + + + False + True + 3 + + + + + True + True + True + image7 + + + + False + True + 4 + + False @@ -836,60 +827,6 @@ 1 - - - True - False - 5 - 5 - 5 - - - Create - True - True - True - - - False - True - 0 - - - - - Edit - True - True - True - - - False - True - 1 - - - - - Delete - True - True - True - - - False - True - 2 - - - - - False - True - end - 2 - - 1 @@ -1051,7 +988,6 @@ False True - end 3 From baf70daba3484c6982d4d5bb5c7924955c3ce902 Mon Sep 17 00:00:00 2001 From: Ivan Yarcev Date: Fri, 19 May 2023 18:10:18 +0600 Subject: [PATCH 3/5] Moved translatable strings to separate header file --- source/ubl-settings-update-strings.h | 32 ++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) create mode 100644 source/ubl-settings-update-strings.h diff --git a/source/ubl-settings-update-strings.h b/source/ubl-settings-update-strings.h new file mode 100644 index 0000000..26015da --- /dev/null +++ b/source/ubl-settings-update-strings.h @@ -0,0 +1,32 @@ +#define TITLE_LABEL _("System update") +#define CHECK_FOR_UPDATES_LABEL _("Check for updates") +#define ABOUT_LABEL _("About") +#define DOCUMENTATION_LABEL _("Documentation") +#define SAVE_LOCAL_LABEL _("Save to local configuration") +#define SAVE_GLOBAL_LABEL _("Save to global configuration") +#define SAVE_CONFIGURATION_LABEL _("Save configuration") +#define SAVE_LABEL _("Save") +#define LOAD_LOCAL_LABEL _("Load local configuration") +#define LOAD_GLOBAL_LABEL _("Load global configuration") +#define LOAD_LABEL _("load") +#define LAUNCH_PACKAGE_MANAGER_LABEL _("Launch package manager") +#define CACHE_CLEAN_LABEL _("Cache clean command: ") +#define UPDATE_COMMAND_LABEL _("Update command: ") +#define PACKAGE_MANAGER_LABEL _("Package manager: ") +#define URI_LABEL _("URI") +#define ENABLED_LABEL _("Enabled") +#define UBUR_LABEL _("Activate UBUR") +#define AUR_LABEL _("Activate AUR") +#define EVERY_3_HOURS_LABEL _("Every 3 hours") +#define EVERY_2_HOURS_LABEL _("Every 2 hours") +#define EVERY_1_HOUR_LABEL _("Every 1 hour") +#define AUTO_UPDATE_LABEL _("Download updates automatically") +#define HIDE_NO_UPDATES_LABEL _("Hide icon of no updates found") +#define CHECK_FREQUENCY_LABEL _("Update checking frequency") +#define EXTRA_LABEL _("Extra") +#define REPOSITORIES_LABEL _("Repositories") +#define GENERAL_LABEL _("General") +#define ADRESS_LABEL _("Adress: ") +#define DISTRIBUTION_LABEL _("Distribution: ") +#define CANCEL_LABEL _("Cancel") +#define SAVE_LABEL _("Save") \ No newline at end of file From ea4756d3116bb065c84e66d4211187b4896f260f Mon Sep 17 00:00:00 2001 From: Ivan Yarcev Date: Mon, 22 May 2023 17:31:33 +0600 Subject: [PATCH 4/5] Version 1.0 is done --- .gitignore | 1 + Makefile | 3 + com.ublinux.ubl-settings-update.policy | 24 + com.ublinux.ubl-settings-update.svg | 931 +++++++++++++++- screenshot/screenshot.png | Bin 0 -> 51588 bytes source/CMakeLists.txt | 26 +- source/ubl-settings-update-strings.h | 19 +- source/ubl-settings-update.c | 253 ++++- source/ubl-settings-update.h | 58 +- source/ubl-settings-update.h.in | 1 + source/ubl-utils.c | 1343 ++++++++++++++++-------- source/ubl-utils.h | 225 +++- ubl-settings-update.css | 94 ++ ubl-settings-update.desktop | 4 +- ubl-settings-update.glade | 639 ++++++++--- ubl-settings-update.pot | 245 +++-- ubl-settings-update_ru.po | 319 +++--- 17 files changed, 3257 insertions(+), 928 deletions(-) create mode 100644 com.ublinux.ubl-settings-update.policy create mode 100644 screenshot/screenshot.png create mode 100644 source/ubl-settings-update.h.in diff --git a/.gitignore b/.gitignore index 57ab3b7..f3b220d 100644 --- a/.gitignore +++ b/.gitignore @@ -3,3 +3,4 @@ ubl-settings-update.glade~ ubl-settings-update ubl-settings-update_ru.po~ build/ +compile/ diff --git a/Makefile b/Makefile index aef26b5..0a510ff 100644 --- a/Makefile +++ b/Makefile @@ -88,6 +88,7 @@ uninstall: @$(RM) "${DESTDIR}${PREFIX}/share/icons/hicolor/scalable/apps/com.ublinux.${PKGNAME}.svg" @$(RM) -rd "${DESTDIR}${PREFIX}/share/${PKGNAME}/images/${PKGNAME}-banner.png" @$(RM) -rd "${DESTDIR}${PREFIX}/share/${PKGNAME}" + @$(RM) "${DESTDIR}${PREFIX}/share/polkit-1/actions/com.ublinux.${PKGNAME}.policy" @if [ -z ${DESTDIR} ]; then \ [ -d "${DESTDIR}${PREFIX}/share/icons/hicolor/" ] && gtk-update-icon-cache -fiq "${DESTDIR}${PREFIX}/share/icons/hicolor/" &>/dev/null || true; \ update-desktop-database --quiet &>/dev/null || true; \ @@ -111,6 +112,8 @@ install: check uninstall done @install -dm755 "${DESTDIR}${PREFIX}/share/icons/hicolor/scalable/apps" @install -Dm644 -t "${DESTDIR}${PREFIX}/share/icons/hicolor/scalable/apps/" "com.ublinux.${PKGNAME}.svg" + @install -dm755 "${DESTDIR}${PREFIX}/share/polkit-1/actions" + @install -Dm644 -t "${DESTDIR}${PREFIX}/share/polkit-1/actions/" "com.ublinux.${PKGNAME}.policy" @install -Dm755 -t "${DESTDIR}${PREFIX}/bin/" "${CMAKE_BUILD_DIR}/${PKGNAME}" @install -dm755 "${DESTDIR}/etc/xdg" @install -dm755 "${DESTDIR}${PREFIX}/share/applications" diff --git a/com.ublinux.ubl-settings-update.policy b/com.ublinux.ubl-settings-update.policy new file mode 100644 index 0000000..4eaf3e9 --- /dev/null +++ b/com.ublinux.ubl-settings-update.policy @@ -0,0 +1,24 @@ + + + + + UBLinux + https://ublinux.ru + + + Run ubl-settings-update as root + Запуск утилиты ubl-settings-update с правами root + Authentication is required to run ubl-settings-update + Требуется авторизация для запуска утилиты ubl-settings-update с правами root + + auth_admin + auth_admin + auth_admin + + /usr/bin/ubl-settings-update + true + + + diff --git a/com.ublinux.ubl-settings-update.svg b/com.ublinux.ubl-settings-update.svg index f636c26..bc1245d 100644 --- a/com.ublinux.ubl-settings-update.svg +++ b/com.ublinux.ubl-settings-update.svg @@ -4,8 +4,8 @@ height="180" version="1.0" id="svg8" - sodipodi:docname="ublinux-ubconfig.svg" - inkscape:version="1.1.1 (3bf5ae0d25, 2021-09-20)" + sodipodi:docname="ubl-settings-update.svg" + inkscape:version="1.1.2 (0a00cf5339, 2022-02-04, custom)" inkscape:export-filename="/media/Data/ShareMX/temp/archtoub_icons/ublinux-logo.png" inkscape:export-xdpi="136.53334" inkscape:export-ydpi="136.53334" @@ -2225,11 +2225,11 @@ + gradientTransform="matrix(3.779602,0,0,3.779602,-193.72728,-7.0470659)"> + + + + + id="filter55276" + x="-0.14871371" + y="-0.14870605" + width="1.2362248" + height="1.2362127"> + id="feFlood55266" /> + id="feComposite55268" /> + + + + + + + + + + + + + + + + id="feGaussianBlur104562" /> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + id="feOffset32783" /> + id="feComposite32785" /> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + inkscape:current-layer="layer3"> + + + inkscape:label="ubinstall_gui" + style="display:none"> - + id="g2035" + transform="matrix(1.7064512,0,0,1.7064512,182.08962,45.305852)" + style="filter:url(#filter104568)"> + + + + + + + + + + + + + cx="4.7361059" + cy="12.475146" + r="3.9282389" + fill="url(#linearGradient3529)" + stroke-width="0.927939" + id="circle34" + style="fill:url(#linearGradient3529)" /> + + + + + + + + + + + + + + + + + + cx="4.7361059" + cy="12.475146" + r="3.9282389" + fill="url(#linearGradient3529)" + stroke-width="0.927939" + id="circle34-6" + style="fill:url(#linearGradient3529-4)" /> + diff --git a/screenshot/screenshot.png b/screenshot/screenshot.png new file mode 100644 index 0000000000000000000000000000000000000000..485ce22301e724cfa67371fef5efde3f206cd6e3 GIT binary patch literal 51588 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 literal 0 HcmV?d00001 diff --git a/source/CMakeLists.txt b/source/CMakeLists.txt index b961ad3..ba44ab8 100644 --- a/source/CMakeLists.txt +++ b/source/CMakeLists.txt @@ -8,23 +8,41 @@ include_directories(${GTK_INCLUDE_DIRS}) link_directories(${GTK_LIBRARY_DIRS}) add_definitions(${GTK_CFLAGS_OTHER}) +find_library(WEBKIT_LIBRARIES_FOUND webkit2gtk-4.0 webkit2gtk-web-extension-4.0) + +option(WEBKIT_FOUND "No" OFF) +if(WEBKIT_LIBRARIES_FOUND) + option(WEBKIT_FOUND "Yes" ON) + PKG_CHECK_MODULES(WEBKIT REQUIRED webkit2gtk-4.0 webkit2gtk-web-extension-4.0) + include_directories(${WEBKIT_INCLUDE_DIRS}) + link_directories(${WEBKIT_LIBRARY_DIRS}) + add_definitions(${WEBKIT_CFLAGS_OTHER}) +endif() + +configure_file(ubl-settings-update.h.in ubl-settings-cmake.h) + + #set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -pedantic -Wall -Wextra -Werror -Wmissing-declarations -fdiagnostics-color=always -std=c++2a") #set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -pedantic -Wall -Wextra -Werror -Wmissing-declarations -fdiagnostics-color=always -lm") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -pedantic -Wall -Wextra -Werror -Wmissing-declarations -fdiagnostics-color=always \ -O2 -pipe -fno-plt -fexceptions \ -Wp,-D_FORTIFY_SOURCE=2 -Wformat -Werror=format-security \ - -fstack-clash-protection -fcf-protection") + -fstack-clash-protection -fcf-protection -g") set(SOURCE_FILES ubl-settings-update.c ubl-settings-update.h - ubl-utils.c) + ubl-utils.h + ubl-utils.c + ubl-settings-cmake.h) set(LIBRARIES ${GTK_LIBRARIES} + ${WEBKIT_LIBRARIES} pthread) -add_executable(ubl-settings-update ${SOURCE_FILES}) -target_link_libraries(ubl-settings-update ${LIBRARIES}) +add_executable(${PROJECT_NAME} ${SOURCE_FILES}) +target_link_libraries(${PROJECT_NAME} PUBLIC ${LIBRARIES}) +target_include_directories(${PROJECT_NAME} PUBLIC ${PROJECT_BINARY_DIR}) install(TARGETS ubl-settings-update DESTINATION bin) \ No newline at end of file diff --git a/source/ubl-settings-update-strings.h b/source/ubl-settings-update-strings.h index 26015da..eebe1a6 100644 --- a/source/ubl-settings-update-strings.h +++ b/source/ubl-settings-update-strings.h @@ -1,4 +1,7 @@ +#define VERSION_LABEL yon_char_unite(_("Version:")," ",version_application,"\n",NULL) +#define HELP_LABEL yon_char_unite(_("ubl-settings-update version:")," ", version_application,"\n",_("update settings"),"\n",_("Usage:"), " ubl-settings-update ",_("[OPTIONS]"),"\n",_("Options:"),"\n\t--help, -h\t\t\t",_("Show this help"),"\n\t--version, -V\t\t\t",_("Show package version"),"\n\t--lock-help\t\t\t",_("Lock this help menu"),"\n\t--lock-save\t\t\t",_("Lock configuration saving"),"\n\t--lock-save-local\t\t",_("Lock local configration saving"),"\n\t--lock-save-global\t\t",_("Lock global configration saving"),"\n\t--lock-load-global\t\t",_("Lock global configration loading"),"\n",NULL) #define TITLE_LABEL _("System update") +#define TITLE_INFO_LABEL _("System update settings management") #define CHECK_FOR_UPDATES_LABEL _("Check for updates") #define ABOUT_LABEL _("About") #define DOCUMENTATION_LABEL _("Documentation") @@ -15,6 +18,7 @@ #define PACKAGE_MANAGER_LABEL _("Package manager: ") #define URI_LABEL _("URI") #define ENABLED_LABEL _("Enabled") +#define DISTIBUTION_LABEL _("Distribution") #define UBUR_LABEL _("Activate UBUR") #define AUR_LABEL _("Activate AUR") #define EVERY_3_HOURS_LABEL _("Every 3 hours") @@ -29,4 +33,17 @@ #define ADRESS_LABEL _("Adress: ") #define DISTRIBUTION_LABEL _("Distribution: ") #define CANCEL_LABEL _("Cancel") -#define SAVE_LABEL _("Save") \ No newline at end of file +#define SAVE_LABEL _("Save") +#define HELP_TITLE_LABEL _("Would you like to read documentation in the Web?") +#define HELP_INFO_LABEL _("You will be redirected to documentation website where documentation is\ntranslated and supported by community.") +#define HELP_ALWAYS_OPEN_LABEL _("Always redirect to online documentation") +#define OPEN_HELP_LABEL _("Open documentation") +#define PROJECT_HOME_LABEL _("Project Home Page") +#define NOTHING_CHOSEN_LABEL _("Nothing were chosen") + +#define GLOBAL_LOAD_SUCCESS _("Global configuration loading succseeded.") +#define LOCAL_LOAD_SUCCESS _("Local configuration loading succseeded.") + +#define GLOBAL_LOCAL_SAVE_SUCCESS _("Local and global configuration saving succseeded.") +#define GLOBAL_SAVE_SUCCESS _("Global configuration saving succseeded.") +#define LOCAL_SAVE_SUCCESS _("Local configuration saving succseeded.") \ No newline at end of file diff --git a/source/ubl-settings-update.c b/source/ubl-settings-update.c index 02ddd8f..21fbd5d 100644 --- a/source/ubl-settings-update.c +++ b/source/ubl-settings-update.c @@ -1,34 +1,145 @@ -#include #include "ubl-settings-update.h" -void on_repo_window_open(GtkWidget *self){ - repo_window *widgets=setup_repo_window(); -} +config main_config; +render_data render; void on_close_subwindow(GtkWidget *self){ gtk_widget_destroy(gtk_widget_get_toplevel(self)); } +void yon_open_browser(GtkWidget *self, char *link){ + yon_ubl_browser_window_open(link,TITLE_LABEL); +} + +void on_open_documentation_confirmation(GtkWidget *self, char *link){ + if (main_config.always_open_documentation==0){ + GtkBuilder *builder = gtk_builder_new_from_file(glade_path); + documentation_confirmation_window *widgets = malloc(sizeof(documentation_confirmation_window)); + widgets->Window = yon_gtk_builder_get_widget(builder,"helpConfirmationWindow"); + widgets->AcceptButton = yon_gtk_builder_get_widget(builder,"ReadHelpButton"); + widgets->CloseButton = yon_gtk_builder_get_widget(builder,"CancelHelpButton"); + widgets->HatText = yon_gtk_builder_get_widget(builder,"webHeaderNameLabel"); + widgets->HeaderText = yon_gtk_builder_get_widget(builder,"helpHeader"); + widgets->InfoText = yon_gtk_builder_get_widget(builder,"helpText"); + widgets->AlwaysOpenCheck = yon_gtk_builder_get_widget(builder,"AlwaysOpenDocumentationCheckbox"); + gtk_label_set_text(GTK_LABEL(widgets->HatText),TITLE_LABEL); + gtk_label_set_text(GTK_LABEL(widgets->HeaderText),HELP_TITLE_LABEL); + gtk_label_set_text(GTK_LABEL(widgets->InfoText),HELP_INFO_LABEL); + gtk_button_set_label(GTK_BUTTON(widgets->AcceptButton),OPEN_HELP_LABEL); + gtk_button_set_label(GTK_BUTTON(widgets->AlwaysOpenCheck),HELP_ALWAYS_OPEN_LABEL); + gtk_button_set_label(GTK_BUTTON(widgets->CloseButton),CANCEL_LABEL); + gtk_widget_show_all(widgets->Window); + g_signal_connect(G_OBJECT(widgets->CloseButton),"clicked",G_CALLBACK(on_close_subwindow),NULL); + g_signal_connect(G_OBJECT(widgets->AcceptButton),"clicked",G_CALLBACK(yon_open_browser),yon_char_new(link)); + g_signal_connect(G_OBJECT(widgets->AcceptButton),"clicked",G_CALLBACK(on_close_subwindow),NULL); + + + } else { + yon_open_browser(self,link); + } +} + +void on_link(GtkWidget *self, char* uri, gpointer user_data){ + gtk_widget_destroy(self); + on_open_documentation_confirmation(self,uri); +} + void on_about(){ GtkBuilder *builder=gtk_builder_new_from_file(glade_path); GtkWidget *window=yon_gtk_builder_get_widget(builder,"AboutWindow"); + GtkWidget *title=yon_gtk_builder_get_widget(builder,"headerAboutTopic"); GtkWidget *hideButtonBox=yon_gtk_builder_get_widget(builder,"buttonBoxHide"); - gtk_about_dialog_set_program_name(GTK_ABOUT_DIALOG(window),_("UBlinux System update")); gtk_about_dialog_set_version(GTK_ABOUT_DIALOG(window),version_application); - gtk_about_dialog_set_website_label(GTK_ABOUT_DIALOG(window),_("Project Home Page")); - gtk_about_dialog_set_comments(GTK_ABOUT_DIALOG(window),_("Update configurator")); + gtk_about_dialog_set_website_label(GTK_ABOUT_DIALOG(window),PROJECT_HOME_LABEL); + gtk_about_dialog_set_comments(GTK_ABOUT_DIALOG(window),TITLE_LABEL); + gtk_label_set_text(GTK_LABEL(title),TITLE_LABEL); + g_signal_connect(G_OBJECT(window),"activate-link",G_CALLBACK(on_link),NULL); gtk_widget_set_visible(hideButtonBox,0); + gtk_widget_destroy(hideButtonBox); gtk_widget_show(window); } -repo_window *setup_repo_window(){ +void on_repos_add(GtkWidget *self, repo_window *repo){ + char *distr = yon_char_new((char*)gtk_entry_get_text(GTK_ENTRY(repo->repoDistributionEntry))); + char *address = yon_char_new((char*)gtk_entry_get_text(GTK_ENTRY(repo->repoTypeEntry))); + if ((distr&&address)||(strcmp(distr,"")!=0&&strcmp(address,"")!=0)){ + GtkTreeIter iter; + gtk_list_store_append(main_config.list,&iter); + gtk_list_store_set(main_config.list,&iter,1,address,2,distr,-1); + } +} + +void on_repos_delete(GtkWidget *self, GtkWidget *tree){ + GtkTreeIter iter; + GtkTreeModel *model = GTK_TREE_MODEL(main_config.list); + if (gtk_tree_selection_get_selected(gtk_tree_view_get_selection(GTK_TREE_VIEW(tree)),&model,&iter)){ + gtk_list_store_remove(main_config.list,&iter); + } else { + yon_ubl_status_box_render(render,NOTHING_CHOSEN_LABEL,BACKGROUND_IMAGE_FAIL_TYPE); + } +} + +void on_repos_edit(GtkWidget *self, repo_window *widgets){ + GtkTreeIter iter; + GtkTreeModel *model=GTK_TREE_MODEL(main_config.list); + if (gtk_tree_selection_get_selected(gtk_tree_view_get_selection(GTK_TREE_VIEW(widgets->tree)),&model,&iter)){ + char *adress=yon_char_new((char*)gtk_entry_get_text(GTK_ENTRY(widgets->repoTypeEntry))); + char *distro=yon_char_new((char*)gtk_entry_get_text(GTK_ENTRY(widgets->repoDistributionEntry))); + if ((distro&&adress)||(strcmp(distro,"")!=0&&strcmp(adress,"")!=0)) + gtk_list_store_set(main_config.list,&iter,1,adress,2,distro,-1); + } +} + +void on_repo_window_open_edit(GtkWidget *self, GtkWidget *tree){ + GtkTreeIter iter; + GtkTreeModel *model=GTK_TREE_MODEL(main_config.list); + if (gtk_tree_selection_get_selected(gtk_tree_view_get_selection(GTK_TREE_VIEW(tree)),&model,&iter)){ + repo_window *widgets=NULL; + widgets=malloc(sizeof(repo_window)); + widgets->builder= gtk_builder_new_from_file(glade_path); + widgets->window=yon_gtk_builder_get_widget(widgets->builder, "RepoWindow"); + + widgets->repoTypeLabel=yon_gtk_builder_get_widget(widgets->builder, "repoAdressLabel"); + widgets->repoTypeEntry=yon_gtk_builder_get_widget(widgets->builder, "repoAdressEntry"); + widgets->repoDistributionLabel=yon_gtk_builder_get_widget(widgets->builder, "repoDistributionLabel"); + widgets->repoDistributionEntry=yon_gtk_builder_get_widget(widgets->builder, "repoDistributionEntry"); + + widgets->repoCancelButton=yon_gtk_builder_get_widget(widgets->builder, "repoCancelButton"); + widgets->repoAcceptButton=yon_gtk_builder_get_widget(widgets->builder, "repoAcceptButton"); + widgets->tree=tree; + + g_signal_connect(G_OBJECT(widgets->repoCancelButton), "clicked", G_CALLBACK(on_close_subwindow), NULL); + g_signal_connect(G_OBJECT(widgets->repoAcceptButton), "clicked", G_CALLBACK(on_repos_edit), widgets); + g_signal_connect(G_OBJECT(widgets->repoAcceptButton), "clicked", G_CALLBACK(on_close_subwindow), NULL); + char *adress = NULL; + char *distro = NULL; + gtk_tree_model_get(GTK_TREE_MODEL(main_config.list),&iter,1,&adress,2,&distro,-1); + gtk_entry_set_text(GTK_ENTRY(widgets->repoTypeEntry),adress); + gtk_entry_set_text(GTK_ENTRY(widgets->repoDistributionEntry),distro); + + gtk_window_set_title(GTK_WINDOW(widgets->window),TITLE_LABEL); + + gtk_label_set_text(GTK_LABEL(widgets->repoTypeLabel),ADRESS_LABEL); + gtk_label_set_text(GTK_LABEL(widgets->repoDistributionLabel),DISTRIBUTION_LABEL); + + gtk_button_set_label(GTK_BUTTON(widgets->repoCancelButton),CANCEL_LABEL); + gtk_button_set_label(GTK_BUTTON(widgets->repoAcceptButton),SAVE_LABEL); + gtk_widget_show_all(widgets->window); + } else { + yon_ubl_status_box_render(render,NOTHING_CHOSEN_LABEL,BACKGROUND_IMAGE_FAIL_TYPE); + } + + +} + +repo_window *on_repo_window_open_create(GtkWidget *self){ repo_window *widgets=NULL; widgets=malloc(sizeof(repo_window)); widgets->builder= gtk_builder_new_from_file(glade_path); widgets->window=yon_gtk_builder_get_widget(widgets->builder, "RepoWindow"); - widgets->repoTypeLabel=yon_gtk_builder_get_widget(widgets->builder, "repoTypeLabel"); - widgets->repoTypeEntry=yon_gtk_builder_get_widget(widgets->builder, "repoTypeEntry"); + widgets->repoTypeLabel=yon_gtk_builder_get_widget(widgets->builder, "repoAdressLabel"); + widgets->repoTypeEntry=yon_gtk_builder_get_widget(widgets->builder, "repoAdressEntry"); widgets->repoDistributionLabel=yon_gtk_builder_get_widget(widgets->builder, "repoDistributionLabel"); widgets->repoDistributionEntry=yon_gtk_builder_get_widget(widgets->builder, "repoDistributionEntry"); @@ -36,6 +147,7 @@ repo_window *setup_repo_window(){ widgets->repoAcceptButton=yon_gtk_builder_get_widget(widgets->builder, "repoAcceptButton"); g_signal_connect(G_OBJECT(widgets->repoCancelButton), "clicked", G_CALLBACK(on_close_subwindow), NULL); + g_signal_connect(G_OBJECT(widgets->repoAcceptButton), "clicked", G_CALLBACK(on_repos_add), widgets); g_signal_connect(G_OBJECT(widgets->repoAcceptButton), "clicked", G_CALLBACK(on_close_subwindow), NULL); @@ -49,6 +161,23 @@ repo_window *setup_repo_window(){ gtk_widget_show_all(widgets->window); } +void init(GtkListStore *list){ + main_config.always_open_documentation=0; + main_config.win_height=600; + main_config.win_width=800; + main_config.win_pos_x=0; + main_config.win_pos_y=0; + main_config.socket_id=-1; + main_config.save_socket_id=-1; + main_config.load_socket_id=-1; + main_config.lock_help=0; + main_config.lock_help=0; + main_config.lock_load_global=0; + main_config.lock_save_global=0; + main_config.lock_save_local=0; + main_config.list=list; +} + main_window *setup_window(){ main_window *widgets=NULL; widgets=malloc(sizeof(main_window)); @@ -57,6 +186,10 @@ main_window *setup_window(){ widgets->HeaderTopic=yon_gtk_builder_get_widget(widgets->builder,"headerTopic"); + widgets->PlugBox=yon_gtk_builder_get_widget(widgets->builder,"plugBox"); + widgets->RightBox=yon_gtk_builder_get_widget(widgets->builder,"LeftBox"); + widgets->LeftBox=yon_gtk_builder_get_widget(widgets->builder,"RightBox"); + widgets->generalSettingsTabLabel=yon_gtk_builder_get_widget(widgets->builder,"generalTabLabel"); widgets->repositoriesSettingsTabLabel=yon_gtk_builder_get_widget(widgets->builder,"repositoriesTabLabel"); widgets->extraSettingsTabLabel=yon_gtk_builder_get_widget(widgets->builder,"extraTabLabel"); @@ -76,6 +209,7 @@ main_window *setup_window(){ widgets->repositoriesSettingsRepositoriesTreeView=yon_gtk_builder_get_widget(widgets->builder,"RepositoriesTreeView"); widgets->repositoriesSettingsEnabledColumn=GTK_TREE_VIEW_COLUMN(gtk_builder_get_object(widgets->builder,"EnabledColumn")); widgets->repositoriesSettingsURIColumn=GTK_TREE_VIEW_COLUMN(gtk_builder_get_object(widgets->builder,"URIColumn")); + widgets->repositoriesSettingsDistributionColumn=GTK_TREE_VIEW_COLUMN(gtk_builder_get_object(widgets->builder,"DistributionColumn")); widgets->extraSettingsPackageManagerLabel=yon_gtk_builder_get_widget(widgets->builder,"PackageManagerLabel"); widgets->extraSettingsPackageManagerEntry=yon_gtk_builder_get_widget(widgets->builder,"PackageManagerEntry"); @@ -99,6 +233,25 @@ main_window *setup_window(){ widgets->mainCheckForUpdatesButton=yon_gtk_builder_get_widget(widgets->builder,"checkForUpdatesButton"); + widgets->mainCheckForUpdatesButton = yon_gtk_builder_get_widget(widgets->builder,"checkForUpdatesButton"); + widgets->statusBox = yon_gtk_builder_get_widget(widgets->builder,"mainStatusBox"); + widgets->statusIcon = yon_gtk_builder_get_widget(widgets->builder,"mainStatusIcon"); + widgets->statusLabel = yon_gtk_builder_get_widget(widgets->builder,"mainStatusLabel"); + + main_config.list=GTK_LIST_STORE(gtk_builder_get_object(widgets->builder,"liststore1")); + + if (main_config.lock_load_global == 1){ + gtk_widget_set_sensitive(widgets->headerLoadGlobalConfigButton,0); + } + if (main_config.lock_save_global == 1){ + gtk_widget_set_sensitive(widgets->headerSaveGlobalConfigButton,0); + gtk_widget_set_sensitive(widgets->headerSaveGlobalLocalConfigButton,0); + } + if (main_config.lock_save_local == 1){ + gtk_widget_set_sensitive(widgets->headerSaveLocalConfigButton,0); + gtk_widget_set_sensitive(widgets->headerSaveGlobalLocalConfigButton,0); + } + gtk_window_set_title(GTK_WINDOW(widgets->window),TITLE_LABEL); gtk_label_set_text(GTK_LABEL(widgets->HeaderTopic),TITLE_LABEL); @@ -121,6 +274,7 @@ main_window *setup_window(){ // gtk_button_set_label(GTK_BUTTON(widgets->repositoriesSettingsDeleteButton),_("Delete")); gtk_tree_view_column_set_title(GTK_TREE_VIEW_COLUMN(widgets->repositoriesSettingsEnabledColumn),ENABLED_LABEL); gtk_tree_view_column_set_title(GTK_TREE_VIEW_COLUMN(widgets->repositoriesSettingsURIColumn),URI_LABEL); + gtk_tree_view_column_set_title(GTK_TREE_VIEW_COLUMN(widgets->repositoriesSettingsDistributionColumn),DISTIBUTION_LABEL); gtk_label_set_text(GTK_LABEL(widgets->extraSettingsPackageManagerLabel),PACKAGE_MANAGER_LABEL); gtk_label_set_text(GTK_LABEL(widgets->extraSettingsUpdateCommandLabel),UPDATE_COMMAND_LABEL); @@ -149,29 +303,100 @@ main_window *setup_window(){ GtkWidget *Overlay = yon_gtk_builder_get_widget(widgets->builder,"HeadOverlay"); GtkWidget *UnderNoteOverlay = yon_gtk_builder_get_widget(widgets->builder,"UnderNoteOverlay"); - GtkWidget *checkForUpdatesButton = yon_gtk_builder_get_widget(widgets->builder,"checkForUpdatesButton"); GtkWidget *headLabel = yon_gtk_builder_get_widget(widgets->builder,"headLabel"); + GtkWidget *headInfoLabel = yon_gtk_builder_get_widget(widgets->builder,"headInfoLabel"); yon_ubl_header_setup(Overlay,Header,Image,image_path); - gtk_overlay_add_overlay(GTK_OVERLAY(UnderNoteOverlay),checkForUpdatesButton); + gtk_overlay_add_overlay(GTK_OVERLAY(UnderNoteOverlay),widgets->mainCheckForUpdatesButton); gtk_label_set_text(GTK_LABEL(headLabel),TITLE_LABEL); + gtk_label_set_text(GTK_LABEL(headInfoLabel),TITLE_INFO_LABEL); gtk_widget_show_all(widgets->window); + render.box=widgets->statusBox; + render.icon=widgets->statusIcon; + render.label=widgets->statusLabel; + yon_ubl_setup_sockets(widgets->PlugBox,widgets->LeftBox,widgets->RightBox,main_config.socket_id,main_config.load_socket_id,main_config.save_socket_id); - g_signal_connect(G_OBJECT(widgets->repositoriesSettingsCreateButton), "clicked", G_CALLBACK(on_repo_window_open), NULL); - g_signal_connect(G_OBJECT(widgets->repositoriesSettingsEditButton), "clicked", G_CALLBACK(on_repo_window_open), NULL); + g_signal_connect(G_OBJECT(widgets->repositoriesSettingsCreateButton), "clicked", G_CALLBACK(on_repo_window_open_create), NULL); + g_signal_connect(G_OBJECT(widgets->repositoriesSettingsEditButton), "clicked", G_CALLBACK(on_repo_window_open_edit), widgets->repositoriesSettingsRepositoriesTreeView); + g_signal_connect(G_OBJECT(widgets->repositoriesSettingsDeleteButton), "clicked", G_CALLBACK(on_repos_delete), widgets->repositoriesSettingsRepositoriesTreeView); g_signal_connect(G_OBJECT(widgets->headerAboutButton), "activate", G_CALLBACK(on_about), NULL); g_signal_connect(G_OBJECT(widgets->window), "destroy", G_CALLBACK(gtk_main_quit), NULL); + g_signal_connect(G_OBJECT(widgets->headerDocumentationButton), "activate", G_CALLBACK(on_open_documentation_confirmation), WIKI_LINK); } int main(int argc, char *argv[]){ local=setlocale(LC_ALL, ""); textdomain (LocaleName); + init(NULL); + int option_index=0; + int show_help=0; + { + struct option long_options[] = { + {"help", 0, 0, 'h'}, + {"version", 0, 0, 'V'}, + {"lock-help", 0,0, 1}, + {"lock-save", 0,0, 2}, + {"lock-save-local", 0,0, 3}, + {"lock-save-global", 0,0, 4}, + {"lock-load-global", 0,0, 5}, + {"socket-id", 1, 0, 's'}, + {"socket-ext-id", 1,0, 'e'}, + {"socket-trd-id", 1,0, 't'}, + { NULL, 0, NULL, 0 } + }; + for (int i=0;i +#include #include "ubl-utils.h" #include #include #include #include #include +#include +#include +#include "ubl-settings-cmake.h" +#ifdef WEBKIT_FOUND + #include +#endif #include "ubl-settings-update-strings.h" +#define WIKI_LINK "https://wiki.ublinux.ru/ru/Программное_обеспечение/Программы_и_утилиты/Все/ubl-settings-update" + #define _(String) gettext(String) #define glade_path "/usr/share/ubl-settings-update/ui/ubl-settings-update.glade" @@ -20,12 +29,35 @@ string version_application = "1.2"; char *local; +typedef struct { + int always_open_documentation; + int win_pos_x; + int win_pos_y; + int win_width; + int win_height; + + int socket_id; + int load_socket_id; + int save_socket_id; + + int lock_help; + int lock_save_local; + int lock_save_global; + int lock_load_global; + + GtkListStore *list; +} config; + typedef struct { GtkWidget *window; GtkBuilder *builder; GtkWidget *HeaderTopic; + GtkWidget *PlugBox; + GtkWidget *LeftBox; + GtkWidget *RightBox; + GtkWidget *generalSettingsTabLabel; GtkWidget *repositoriesSettingsTabLabel; GtkWidget *extraSettingsTabLabel; @@ -45,6 +77,7 @@ typedef struct { GtkWidget *repositoriesSettingsRepositoriesTreeView; GtkTreeViewColumn *repositoriesSettingsEnabledColumn; GtkTreeViewColumn *repositoriesSettingsURIColumn; + GtkTreeViewColumn *repositoriesSettingsDistributionColumn; GtkWidget *extraSettingsPackageManagerLabel; GtkWidget *extraSettingsPackageManagerEntry; @@ -68,11 +101,16 @@ typedef struct { GtkWidget *mainCheckForUpdatesButton; + GtkWidget *statusBox; + GtkWidget *statusIcon; + GtkWidget *statusLabel; + } main_window; typedef struct { GtkWidget *window; GtkBuilder *builder; + GtkListStore *list; GtkWidget *repoTypeLabel; GtkWidget *repoTypeEntry; @@ -81,9 +119,23 @@ typedef struct { GtkWidget *repoCancelButton; GtkWidget *repoAcceptButton; + GtkWidget *tree; } repo_window; +typedef struct { + GtkWidget *Window; + + GtkWidget *HatText; + GtkWidget *HeaderText; + GtkWidget *InfoText; + GtkWidget *AlwaysOpenCheck; + + GtkWidget *CloseButton; + GtkWidget *AcceptButton; +} documentation_confirmation_window; + void on_repo_window_open(GtkWidget *self); -main_window *setup_window(); -repo_window *setup_repo_window(); \ No newline at end of file +void on_repo_window_open_edit(GtkWidget *self, GtkWidget *tree); +repo_window *on_repo_window_open_create(GtkWidget *self); +main_window *setup_window(); \ No newline at end of file diff --git a/source/ubl-settings-update.h.in b/source/ubl-settings-update.h.in new file mode 100644 index 0000000..d4623a7 --- /dev/null +++ b/source/ubl-settings-update.h.in @@ -0,0 +1 @@ +#cmakedefine WEBKIT_FOUND diff --git a/source/ubl-utils.c b/source/ubl-utils.c index ed01b97..1565aa3 100644 --- a/source/ubl-utils.c +++ b/source/ubl-utils.c @@ -1,397 +1,632 @@ #include "ubl-utils.h" -#ifndef UBL_UTILS - -typedef enum { - DICTIONARY_ACTION_WIDGETS_TYPE, - DICTIONARY_IVGRAPHICALS_TYPE, - DICTIONARY_OTHER_TYPE - -} DICT_TYPE; - -typedef struct dictionary { - char *key; - void *data; - struct dictionary *next; - struct dictionary *prev; - struct dictionary *first; - DICT_TYPE data_type; -} dictionary; - -typedef struct apps{ - char *Name; - int Type; - char *Categories; - char *Exec; - char *Icon; - int Pluggable; - int DualPluggable; - } apps; - -typedef struct { - char *command; - int *exitcode; -} thread_output; -#ifdef __GTK_H__ -typedef struct IVGrapgicals{ - char *sectionName; - char *categories; - GtkListStore *LV; - GtkWidget *Box; - GtkWidget *IV; - GtkWidget *label; - GtkWidget *sep; - GtkCellRendererPixbuf *iconRender; -} IVGraphicals; -#endif -#endif +#include "ubl-settings-cmake.h" +#ifdef WEBKIT_FOUND + #include +#endif +// dictionary functions - -//dictionary functions - -/** - * yon_dictionary_create_empty: - * Creates and returns empty dictionary -*/ -dictionary *yon_dictionary_create_empty(){ - dictionary *dict=malloc(sizeof(dictionary)); - dict->data=NULL; - dict->key=NULL; - dict->next=NULL; - dict->prev=NULL; - dict->first=dict; - dict->data_type=DICTIONARY_OTHER_TYPE; +/**[EN] + * yon_dictionary_create_empty(): + * Creates and returns empty dictionary + */ +dictionary *yon_dictionary_create_empty() +{ + dictionary *dict = malloc(sizeof(dictionary)); + dict->data = NULL; + dict->key = NULL; + dict->next = NULL; + dict->prev = NULL; + dict->first = dict; + dict->data_type = DICTIONARY_OTHER_TYPE; return dict; } -void yon_dictionary_switch_to_last(dictionary **dict){ - if ((*dict)->next!=NULL) - for ((*dict)=(*dict)->first;(*dict)->next!=NULL;(*dict)=(*dict)->next){} +void yon_dictionary_switch_to_last(dictionary **dict) +{ + if ((*dict)->next != NULL) + for ((*dict) = (*dict)->first; (*dict)->next != NULL; (*dict) = (*dict)->next) + { + } } -dictionary * yon_dictionary_create_conneced(dictionary *targetdict){ - targetdict=yon_dictionary_get_last(targetdict); - targetdict->next=yon_dictionary_create_empty(); - targetdict->next->prev=targetdict; - targetdict->next->first=targetdict->first; - targetdict->next->data_type=DICTIONARY_OTHER_TYPE; +dictionary *yon_dictionary_create_conneced(dictionary *targetdict) +{ + targetdict = yon_dictionary_get_last(targetdict); + targetdict->next = yon_dictionary_create_empty(); + targetdict->next->prev = targetdict; + targetdict->next->first = targetdict->first; + targetdict->next->data_type = DICTIONARY_OTHER_TYPE; return targetdict->next; } -dictionary *yon_dictionary_get_last(dictionary *dict){ - dictionary *dct=NULL; - for (dct=dict->first;dct->next!=NULL;dct=dct->next){} +dictionary *yon_dictionary_get_last(dictionary *dict) +{ + dictionary *dct = NULL; + for (dct = dict->first; dct->next != NULL; dct = dct->next) + { + } return dct; } -dictionary *yon_dictionary_switch_places(dictionary *dict,int aim){ - if (aim<0){ - if (dict->prev){ - if (dict->prev->prev){ - dictionary *next = dict->next,*prev=dict->prev,*preprev=prev->prev; - if (next){ - preprev->next=dict; - dict->prev=preprev; - dict->next=prev; - prev->prev=dict; - prev->next=next; - next->prev=prev; - } else { - preprev->next=dict; - dict->prev=preprev; - dict->next=prev; - prev->prev=dict; - prev->next=NULL; +dictionary *yon_dictionary_switch_places(dictionary *dict, int aim) +{ + if (aim < 0) + { + if (dict->prev) + { + if (dict->prev->prev) + { + dictionary *next = dict->next, *prev = dict->prev, *preprev = prev->prev; + if (next) + { + preprev->next = dict; + dict->prev = preprev; + dict->next = prev; + prev->prev = dict; + prev->next = next; + next->prev = prev; + } + else + { + preprev->next = dict; + dict->prev = preprev; + dict->next = prev; + prev->prev = dict; + prev->next = NULL; } return prev; - } else { - dictionary *next = dict->next,*prev=dict->prev; - if (next){ - yon_dictionary_make_first(dict); - dict->prev=NULL; - dict->next=prev; - prev->prev=dict; - prev->next=next; - next->prev=prev; - } else { - dict->prev=NULL; - dict->next=prev; - prev->prev=dict; - prev->next=NULL; } - return prev; + else + { + dictionary *next = dict->next, *prev = dict->prev; + if (next) + { + yon_dictionary_make_first(dict); + dict->prev = NULL; + dict->next = prev; + prev->prev = dict; + prev->next = next; + next->prev = prev; + } + else + { + dict->prev = NULL; + dict->next = prev; + prev->prev = dict; + prev->next = NULL; + } + return prev; } } - } else if (aim>0){ - if (dict->next){ - if (dict->next->next){ - dictionary *next = dict->next,*prev=dict->prev,*afnext=next->next; - if (prev){ - prev->next=next; - next->prev=prev; - next->next=dict; - dict->prev=next; - dict->next=afnext; - afnext->prev=dict; - } else { + } + else if (aim > 0) + { + if (dict->next) + { + if (dict->next->next) + { + dictionary *next = dict->next, *prev = dict->prev, *afnext = next->next; + if (prev) + { + prev->next = next; + next->prev = prev; + next->next = dict; + dict->prev = next; + dict->next = afnext; + afnext->prev = dict; + } + else + { yon_dictionary_make_first(next); - next->prev=NULL; - next->next=dict; - dict->prev=next; - dict->next=afnext; - afnext->prev=dict; + next->prev = NULL; + next->next = dict; + dict->prev = next; + dict->next = afnext; + afnext->prev = dict; } return next; - } else { - dictionary *next = dict->next,*prev=dict->prev; - if (prev){ - prev->next=next; - next->prev=prev; - next->next=dict; - dict->prev=next; - dict->next=NULL; - } else { - next->prev=NULL; - next->next=dict; - dict->prev=next; - dict->next=NULL; + } + else + { + dictionary *next = dict->next, *prev = dict->prev; + if (prev) + { + prev->next = next; + next->prev = prev; + next->next = dict; + dict->prev = next; + dict->next = NULL; + } + else + { + next->prev = NULL; + next->next = dict; + dict->prev = next; + dict->next = NULL; } } } } } -void yon_dictionary_make_first(dictionary *dict){ - for (dictionary *dct=dict->first;dct!=NULL;dct=dct->next){ - dct->first=dict; +void yon_dictionary_make_first(dictionary *dict) +{ + for (dictionary *dct = dict->first; dct != NULL; dct = dct->next) + { + dct->first = dict; } } -void yon_dictionary_make_nth(dictionary *dict, int nth){ - dictionary *dct=dict->first; - for (int i=0;inext;} +void yon_dictionary_make_nth(dictionary *dict, int nth) +{ + dictionary *dct = dict->first; + for (int i = 0; i < nth; i++) + { + if (dct == NULL) + return; + else + dct = dct->next; + } yon_dictionary_rip(dict); - dictionary *prev=dct->prev; - prev->next=dict; - dict->prev=prev; - dict->next=dct; - dct->prev=dict; -} - -dictionary *yon_dictionary_create_with_data(char *key, void *data){ - dictionary *dct=yon_dictionary_create_empty(); - dct->key=yon_char_new(key); - dct->data=data; - dct->data_type=DICTIONARY_OTHER_TYPE; + dictionary *prev = dct->prev; + prev->next = dict; + dict->prev = prev; + dict->next = dct; + dct->prev = dict; +} + +dictionary *yon_dictionary_create_with_data(char *key, void *data) +{ + dictionary *dct = yon_dictionary_create_empty(); + dct->key = yon_char_new(key); + dct->data = data; + dct->data_type = DICTIONARY_OTHER_TYPE; return dct; } -dictionary *yon_dictionary_create_with_data_connected(dictionary *dict, char *key, void *data){ - dictionary *dct=yon_dictionary_create_conneced(dict); - dct->key=yon_char_new(key); - dct->data=data; - dct->data_type=DICTIONARY_OTHER_TYPE; +/** void *yon_dictionary_free_all(dictionary *dictionary,void *data_manipulation) + * [EN] + * Frees whole [dictionary] and activates [data_manipulation] function if not NULL with [dictionary]->data argument for each dictionary. + * [RU] + * Освобождает память для всех элементов словаря [dictionary] и активирует функцию [data_manipulation], если она была передана, с аргументом [dictionary]->data на каждый элемент словаря. +*/ +void *yon_dictionary_free_all(dictionary *dictionary_to_free,void (*data_manipulation)(void*)){ + dictionary *dict=NULL; + for_dictionaries(dict,dictionary_to_free){ + if(data_manipulation) + data_manipulation(dict->data); + if(dict->prev) + free(dict->prev); + } + free(dict); + return NULL; +} + +dictionary *yon_dictionary_create_with_data_connected(dictionary *dict, char *key, void *data) +{ + dictionary *dct = yon_dictionary_create_conneced(dict); + dct->key = yon_char_new(key); + dct->data = data; + dct->data_type = DICTIONARY_OTHER_TYPE; return dct; } -dictionary *yon_dictionary_connect(dictionary *old, dictionary *toconnect){ - dictionary *dict=yon_dictionary_get_last(old); - dict->next=toconnect; - toconnect->prev=dict; - toconnect->first=dict->first; +dictionary *yon_dictionary_connect(dictionary *old, dictionary *toconnect) +{ + dictionary *dict = yon_dictionary_get_last(old); + dict->next = toconnect; + toconnect->prev = dict; + toconnect->first = dict->first; return toconnect; } -dictionary *yon_dictionary_find(dictionary **dict, char *key){ - dictionary *dct=*dict; - for (dictionary *pointer=dct->first;pointer!=NULL;pointer=pointer->next){ - if (strcmp(pointer->key,key)==0){ - *dict=pointer; +dictionary *yon_dictionary_find(dictionary **dict, char *key) +{ + dictionary *dct = *dict; + for (dictionary *pointer = dct->first; pointer != NULL; pointer = pointer->next) + { + if (strcmp(pointer->key, key) == 0) + { + *dict = pointer; return pointer; } } return NULL; } - -dictionary *yon_dictionary_rip(dictionary *dict){ - if (!dict->next){ - dictionary *prev=dict->prev; - if (prev){ - prev->next=NULL; - return prev; - } else return dict; +dictionary *yon_dictionary_rip(dictionary *dict) +{ + if (!dict->next&&!dict->prev) return NULL; + else if (!dict->next) + { + dictionary *prev = dict->prev; + if (prev) + { + prev->next = NULL; + return prev; + } + else + return dict; } - else if (!dict->prev){ - dictionary *next=dict->next; - if (next){ + else if (!dict->prev) + { + dictionary *next = dict->next; + if (next) + { yon_dictionary_make_first(next); - next->prev=NULL; + next->prev = NULL; return next; } - else return dict; + else + return dict; } - else { - dictionary *next=dict->next, *prev=dict->prev; - next->prev=prev; - prev->next=next; + else + { + dictionary *next = dict->next, *prev = dict->prev; + next->prev = prev; + prev->next = next; return next; } } -dictionary *yon_dictionary_get_nth(dictionary *dict, int place){ - dict=dict->first; - for (int i=0;inext; - if (dict) return dict; - else return NULL; +dictionary *yon_dictionary_get_nth(dictionary *dict, int place) +{ + if (dict){ + dict = dict->first; + int i = 0; + for (i = 0; i < place; i++) + if (dict->next) + dict = dict->next; + else + break; + if (i == place) + return dict; + else + return NULL; + } else return NULL; } -//char functions +// char functions -/** +/**[EN] + * * creates new char string by combining two char strings. -*/ -char *yon_char_get_augumented(char *source, char *append){ - if (source&&append){ - int size=strlen(source)+strlen(append)+1; - char *final=malloc(size); - memset(final,0,size); - if (strstr(source,"%%")) - sprintf(final,source,append); + */ +char *yon_char_get_augumented(char *source, char *append) +{ + if (source && append) + { + int size = strlen(source) + strlen(append) + 1; + char *final = malloc(size); + memset(final, 0, size); + if (strstr(source, "%%")) + sprintf(final, source, append); + else + sprintf(final, "%s%s", source, append); + return final; + } else - sprintf(final,"%s%s",source,append); - return final; - } else return NULL; } -/** +/**[EN] + * * creates new char string by copying another char. -*/ -char *yon_char_new(char *chr){ - char *newchar=malloc(strlen(chr)+1); - memset(newchar,0,strlen(chr)+1); - memcpy(newchar,chr,strlen(chr)); - return newchar; + */ +char *yon_char_new(char *chr) +{ + if (chr){ + char *newchar = malloc(strlen(chr) + 1); + memset(newchar, 0, strlen(chr) + 1); + memcpy(newchar, chr, strlen(chr)); + return newchar; + } else + return NULL; } -/** +// char *yon_char_unite(char *source, ...) + +char *yon_char_unite(char *source, ...){ + va_list arglist; + char *new_char=NULL; + char *unite_char=NULL; + new_char=yon_char_new(source); + va_start(arglist,source); + unite_char = va_arg(arglist,char*); + while(unite_char){ + new_char = yon_char_get_augumented(new_char,unite_char); + unite_char = va_arg(arglist,char*); + } + va_end(arglist); + return new_char; +} + +/**[EN] + * * cuts source string by size length from startpos position. -*/ -char *yon_cut(char *source, int size, int startpos){ - char *cut=NULL; - cut=malloc(size+1); - memset(cut,0,size+1); - memcpy(cut,source+startpos,size); + */ +char *yon_cut(char *source, int size, int startpos) +{ + char *cut = NULL; + cut = malloc(size + 1); + memset(cut, 0, size + 1); + memcpy(cut, source + startpos, size); return cut; } -/** +/**[EN] + * * divides source string in dividepos position, * returning left part of divided string and * inserting right part to source string. -*/ -char *yon_char_divide(char *source, int dividepos){ - char *cut=malloc(dividepos+1); - memset(cut,0,dividepos+1); - memcpy(cut,source,dividepos); - char *left=malloc(strlen(source)-strlen(cut)); - memset(left,0,strlen(source)-strlen(cut)); - memcpy(left,source+dividepos+1,(strlen(source)-dividepos)); - memset(source,0,strlen(source)); - memcpy(source,left,strlen(left)); + */ +char *yon_char_divide(char *source, int dividepos) +{ + char *cut = malloc(dividepos + 1); + memset(cut, 0, dividepos + 1); + memcpy(cut, source, dividepos); + char *left = malloc(strlen(source) - strlen(cut)); + memset(left, 0, strlen(source) - strlen(cut)); + memcpy(left, source + dividepos + 1, (strlen(source) - dividepos)); + memset(source, 0, strlen(source)); + memcpy(source, left, strlen(left)); return cut; } -/** - * searches string dividepos in source string and divides it, +int yon_char_find_count(char *source, char *find){ + char *working_string=yon_char_new(source); + int i=0; + int size=0; + int pos=0; + config_str rtn = yon_char_parse(working_string,&size,"\n"); + for (int j=0;j 10; i++) + { + convert_check = convert_check / 10; + } + char *ch = malloc(i * sizeof(char) + 1); + sprintf(ch, "%d", int_to_convert); + return ch; +} + +char *yon_char_replace(char *source, char *find, char*replace){ + char *final=NULL; + char *temp=NULL; + if(!strstr(replace,find)){ + while ((final=strstr(source,find))){ + temp=malloc(strlen(source)-strlen(final)); + memset(temp,0,strlen(source)-strlen(final)+strlen(replace)); + memcpy(temp,source,strlen(source)-strlen(final)); + temp=yon_char_get_augumented(temp,replace); + source=yon_char_get_augumented(temp,final+1); + } + return source; + } +} + +/**[EN] + * char **yon_char_parse(char *parameters, int *size, char *divider) + * Parses string [parameters], divided by [divider], + * then returns parsed string array and sets [size] to + * size of returned array */ -char *yon_char_from_int(int int_to_convert){ +char **yon_char_parse(char *parameters, int *size, char *divider){ + char **string=NULL; int i=1; - float convert_check=(float)int_to_convert; - for (i=1;convert_check>10;i++){ - convert_check=convert_check/10; + string=malloc(sizeof(char*)); + char *paramline=yon_char_new(parameters); + char *param; + while ((param=yon_char_divide_search(paramline,divider,1))){ + string=realloc(string,sizeof(char*)*i); + string[i-1]=yon_char_new(param); + i++; + if (strcmp(param,paramline)==0) break; } - char *ch=malloc(i*sizeof(char)+1); - sprintf(ch,"%d",int_to_convert); - return ch; + string=realloc(string,sizeof(char*)*i); + string[i-1]=yon_char_new(paramline); + i++; + // printf("%d\n",i); + *size=i-1; + return string; + } +char **yon_char_parsed_shrink(char **char_string, int *size, int item_to_delete){ + char **new_char_parsed=NULL; + new_char_parsed=malloc(sizeof(char*)*(*size)-2); + int sz=0; + for (int i=0;i<*size-2;i++){ + if (i!=item_to_delete){ + new_char_parsed[i]=yon_char_new(char_string[i]); + sz++; + } + + } + *size=sz; + return new_char_parsed; +} -//parsing functions +/**[EN] + * + * Checks if [parameters] string array of length [size] + * has [param] element; +*/ +int yon_char_parsed_check_exist(char **parameters, int size, char *param){ + + for (int i=0;id_name); - file=fopen(path,"r"); - if (strlen(de->d_name)>9) + char *path = yon_char_get_augumented(DesktopPath, de->d_name); + file = fopen(path, "r"); + if (strlen(de->d_name) > 9) { - char *extension=strstr(path,"."); - if (extension!=NULL) + char *extension = strstr(path, "."); + if (extension != NULL) { - if (strcmp(extension,".desktop")==0) + if (strcmp(extension, ".desktop") == 0) { apps tempapp; - GKeyFile *gfile=g_key_file_new(); - GError *err=NULL; - g_key_file_load_from_file(gfile,path,G_KEY_FILE_KEEP_TRANSLATIONS,NULL); - char *Type=g_key_file_get_string(gfile,"Desktop Entry", "Type",&err); - if (err){ - printf("%s\n",err->message); + GKeyFile *gfile = g_key_file_new(); + GError *err = NULL; + g_key_file_load_from_file(gfile, path, G_KEY_FILE_KEEP_TRANSLATIONS, NULL); + char *Type = g_key_file_get_string(gfile, "Desktop Entry", "Type", &err); + if (err) + { + printf("%s\n", err->message); } - if (strcmp(Type,"Application")==0) tempapp.Type=1; else if (strcmp(Type,"pyApplication")==0) tempapp.Type=2; else continue; - tempapp.Name=g_key_file_get_locale_string(gfile,"Desktop Entry","Name",setlocale(LC_ALL,NULL),NULL); - if (tempapp.Name==NULL) continue; - tempapp.Categories=g_key_file_get_string(gfile,"Desktop Entry", "Categories",NULL); - if (tempapp.Categories==NULL) continue; - tempapp.Exec=g_key_file_get_string(gfile,"Desktop Entry", "Exec",NULL); - if (tempapp.Exec==NULL) continue; - tempapp.Icon=g_key_file_get_string(gfile,"Desktop Entry", "Icon",NULL); - if (tempapp.Icon==NULL) continue; - tempapp.Pluggable=g_key_file_get_boolean(gfile,"Desktop Entry", "Pluggable",NULL); - if (!tempapp.Pluggable) tempapp.Pluggable=g_key_file_get_boolean(gfile,"Desktop Entry", "X-XfcePluggable",NULL); - if (tempapp.Pluggable) tempapp.DualPluggable=g_key_file_get_boolean(gfile,"Desktop Entry", "X-UBLPluggable",NULL); - if (g_key_file_get_boolean(gfile,"Desktop Entry", "X-UBL-SettingsManager-Hidden",NULL)==0) - if (size==0){ - applist=(apps*)malloc(size+1*sizeof(apps)); - applist[0].Name=yon_char_new(tempapp.Name); - applist[0].Categories=yon_char_new(tempapp.Categories); - applist[0].Exec=yon_char_new(tempapp.Exec); - applist[0].Icon=yon_char_new(tempapp.Icon); - applist[0].Type=tempapp.Type; - applist[0].Pluggable=tempapp.Pluggable; - applist[0].DualPluggable=tempapp.DualPluggable; + if (strcmp(Type, "Application") == 0) + tempapp.Type = 1; + else if (strcmp(Type, "pyApplication") == 0) + tempapp.Type = 2; + else + continue; + tempapp.Name = g_key_file_get_locale_string(gfile, "Desktop Entry", "Name", setlocale(LC_ALL, NULL), NULL); + if (tempapp.Name == NULL) + continue; + tempapp.Categories = g_key_file_get_string(gfile, "Desktop Entry", "Categories", NULL); + if (tempapp.Categories == NULL) + continue; + tempapp.Exec = g_key_file_get_string(gfile, "Desktop Entry", "Exec", NULL); + if (tempapp.Exec == NULL) + continue; + tempapp.Icon = g_key_file_get_string(gfile, "Desktop Entry", "Icon", NULL); + if (tempapp.Icon == NULL) + continue; + tempapp.Pluggable = g_key_file_get_boolean(gfile, "Desktop Entry", "Pluggable", NULL); + if (!tempapp.Pluggable) + tempapp.Pluggable = g_key_file_get_boolean(gfile, "Desktop Entry", "X-XfcePluggable", NULL); + if (tempapp.Pluggable) + tempapp.DualPluggable = g_key_file_get_boolean(gfile, "Desktop Entry", "X-UBLPluggable", NULL); + if (g_key_file_get_boolean(gfile, "Desktop Entry", "X-UBL-SettingsManager-Hidden", NULL) == 0) + if (size == 0) + { + applist = (apps *)malloc(size + 1 * sizeof(apps)); + applist[0].Name = yon_char_new(tempapp.Name); + applist[0].Categories = yon_char_new(tempapp.Categories); + applist[0].Exec = yon_char_new(tempapp.Exec); + applist[0].Icon = yon_char_new(tempapp.Icon); + applist[0].Type = tempapp.Type; + applist[0].Pluggable = tempapp.Pluggable; + applist[0].DualPluggable = tempapp.DualPluggable; size++; - } else { - applist=(apps*)realloc(applist,(size+1)*sizeof(apps)); - applist[size].Name=yon_char_new(tempapp.Name); - applist[size].Categories=yon_char_new(tempapp.Categories); - applist[size].Exec=yon_char_new(tempapp.Exec); - applist[size].Icon=yon_char_new(tempapp.Icon); - applist[size].Pluggable=tempapp.Pluggable; - applist[size].DualPluggable=tempapp.DualPluggable; - applist[size].Type=tempapp.Type; + } + else + { + applist = (apps *)realloc(applist, (size + 1) * sizeof(apps)); + applist[size].Name = yon_char_new(tempapp.Name); + applist[size].Categories = yon_char_new(tempapp.Categories); + applist[size].Exec = yon_char_new(tempapp.Exec); + applist[size].Icon = yon_char_new(tempapp.Icon); + applist[size].Pluggable = tempapp.Pluggable; + applist[size].DualPluggable = tempapp.DualPluggable; + applist[size].Type = tempapp.Type; size++; } } @@ -399,201 +634,427 @@ apps *yon_apps_scan_and_parse_desktops(int *sizef){ } } } - *sizef=size; + *sizef = size; return applist; }; - -void yon_apps_sort(apps *applist,int size){ +void yon_apps_sort(apps *applist, int size) +{ apps tmp; - if (size>2) + if (size > 2) { - for (int i=1;i0){ + *str_len = i; + return output_strings; + } else{ + *str_len=-1; + return NULL; + } +} -//terminal-using functions +/**[EN] + * int yon_config_save(char *command) + * Saves config with [command] + * [RU] +*/ +int yon_config_save(char *command) +{ + FILE *output = popen(command, "r"); + return 1; +} +/**[EN] + * char *yon_config_get_parameter(config parameters, int size, char *param) + * Gets parameter from parameter list; + * + * [RU] +*/ +char *yon_config_get_parameter(config_str parameters, int size, char *param) +{ + if (param[0]==' ') + yon_char_divide_search(param," ",-1); + param=yon_char_divide_search(yon_char_new(param)," ",-1); + + char *str = NULL; + for (int j = 0; j < size; j++) + { + char *name = yon_char_divide_search(yon_char_new(parameters[j]), "=", 1); + if (name) + { + if (strcmp(name, param) == 0) + { + str = yon_char_divide_search(yon_char_new(parameters[j]), "\n", 1); + if (strcmp(str, "") != 0 && strcmp(str, "(null)") != 0) + return str; + else + return NULL; + } + } + } + return NULL; +} + +/**[EN] + * Parses, modifies and connects string to use it as one of arguments, + * sended to ubconfig. + * + * [RU] + */ +char *yon_config_make_save_parameter_with_multiple_arguments(char *parameter_string, char *config_parameter, char *divider){ + char *final=""; + int done=0; + char *cur=yon_char_new(parameter_string); + yon_char_divide_search(cur,"=",1); + char *cur_param=NULL; + while (cur_param=yon_char_divide_search(cur,",",1)){ + if (done==0){ + final=yon_char_get_augumented(final,yon_char_get_augumented(yon_char_get_augumented(config_parameter,"="), yon_char_get_augumented(cur_param,", "))); + done=1; + } else { + final=yon_char_get_augumented(final,yon_char_get_augumented(yon_char_get_augumented(config_parameter,"+="), yon_char_get_augumented(cur_param,", "))); + } + } + if (cur&&strcmp(cur,"")!=0) + if (done==0) + final=yon_char_get_augumented(final,yon_char_get_augumented(yon_char_get_augumented(config_parameter,"="), yon_char_get_augumented(cur,", "))); + else + final=yon_char_get_augumented(final,yon_char_get_augumented(yon_char_get_augumented(config_parameter,"+="), yon_char_get_augumented(cur,", "))); + return final; +} +// terminal-using functions -int yon_launch_app(char *name){ - char *path=name; - thread_output *thread=malloc(sizeof(thread_output)); - thread->command=path; - thread->exitcode=malloc(sizeof(int)); +int yon_launch_app(char *name) +{ + char *path = name; + thread_output *thread = malloc(sizeof(thread_output)); + thread->command = path; + thread->exitcode = malloc(sizeof(int)); pthread_t thread_id; - pthread_create(&thread_id, NULL, (void*)yon_launch, thread); + pthread_create(&thread_id, NULL, (void *)yon_launch, thread); return *thread->exitcode; }; - -int yon_launch_app_with_arguments(char *name, char *args){ - char *path=yon_char_get_augumented("/usr/bin/",name); - path=yon_char_get_augumented(path," "); - path=yon_char_get_augumented(path,args); +int yon_launch_app_with_arguments(char *name, char *args) +{ + char *path = yon_char_get_augumented("/usr/bin/", name); + path = yon_char_get_augumented(path, " "); + path = yon_char_get_augumented(path, args); pthread_t thread_id; - thread_output *thread=malloc(sizeof(thread_output)); - thread->command=path; - thread->exitcode=malloc(sizeof(int)); - pthread_create(&thread_id, NULL, (void*)yon_launch, thread); + thread_output *thread = malloc(sizeof(thread_output)); + thread->command = path; + thread->exitcode = malloc(sizeof(int)); + pthread_create(&thread_id, NULL, (void *)yon_launch, thread); return *thread->exitcode; }; - -int yon_launch(thread_output *thread){ - int a=0; - a=system(thread->command); - *thread->exitcode=a; +int yon_launch(thread_output *thread) +{ + int a = 0; + a = system(thread->command); + *thread->exitcode = a; return *thread->exitcode; } +// Gtk functions -//Gtk functions #ifdef __GTK_H__ -// dictionary *yon_gtk_app_chooser_create(GtkBuilder *builder){ -// GtkWidget *chooserWindow=gtk_window_new(GTK_WINDOW_TOPLEVEL); -// GtkWidget *Box=gtk_box_new(GTK_ORIENTATION_VERTICAL,5); -// GtkWidget *Frame=gtk_frame_new(""); -// GtkWidget *Scroll=gtk_scrolled_window_new(NULL, gtk_adjustment_new(0,0,10000,1,10,100)); -// GtkWidget *PackBox=gtk_box_new(GTK_ORIENTATION_VERTICAL,5); -// GtkWidget *ButtonsBox=gtk_box_new(GTK_ORIENTATION_HORIZONTAL,5); -// GtkWidget *ButtonsPlaceBox=gtk_box_new(GTK_ORIENTATION_HORIZONTAL,5); - -// GtkWidget *CancelButton=gtk_button_new_with_label("Cancel"); -// GtkWidget *AcceptButton=gtk_button_new_with_label("Accept"); -// gtk_container_add(GTK_CONTAINER(chooserWindow),Box); -// gtk_box_pack_start(GTK_BOX(Box),Frame,1,1,0); -// gtk_container_add(GTK_CONTAINER(Frame),PackBox); -// gtk_box_pack_start(GTK_BOX(Box),ButtonsBox,0,0,0); -// gtk_box_pack_end(GTK_BOX(ButtonsBox),ButtonsPlaceBox,0,0,0); -// gtk_box_pack_end(GTK_BOX(ButtonsPlaceBox),AcceptButton,0,0,0); -// gtk_box_pack_end(GTK_BOX(ButtonsPlaceBox),CancelButton,0,0,0); -// gtk_box_pack_start(GTK_BOX(PackBox),(GtkWidget*)yon_gtk_app_chooser_apps_create(builder),0,0,0); -// gtk_widget_show_all(chooserWindow); -// } +#ifdef VTE_TERMINAL /** - * yon_iv_segment_create: - * connect_to - dictionary, in the end of which new one will be connected; - * name - name of this segment, renders on label; - * categories - desktop file categories that application NEEDS to have to render in that category; - * segment_icon_name - icon name for this section; - * builder - newly allocated builder with glade file connected where template widgets are stored: - * - templateAppsIconView - setted up icon view; - * - templateAppsPack - setted up container for every template widget; - * - templateAppsImage - image for rendering section image; - * - templateAppsLabel - label for rendering section name; + * void yon_terminal_integrated_launch(GtkWidget *place_to_show, void *endwork_function, void* endwork_function_argument) + * [EN] + * launches terminal with specific [command], + * terminal is shown in [place_to_show] container, + * after terminal done its work [endwork_function] is called with [endwork_function_argument] argument. + * [RU] + * Запускает терминал с командой [command], + * терминал добавляется в контейнер [place_to_show] виджета, + * после завершения работы терминала вызывается функция [endwork_function] с аргументом [endwork_function_argument]. */ -// dictionary *yon_iv_segment_create(dictionary *connect_to, char *name, char *categories, char *segment_icon_name){ -// IVSegment *segment=malloc(sizeof(IVSegment)); -// segment->name=name; -// segment->categories=categories; -// GtkBuilder *builder=gtk_builder_new_from_string(return_app_string(),-1); -// GtkWidget *iv=yon_gtk_builder_get_widget(builder,"templateAppsIconView"); -// GtkWidget *expander=yon_gtk_builder_get_widget(builder,"templateAppsPack"); -// GtkWidget *image=yon_gtk_builder_get_widget(builder,"templateAppsImage"); -// GtkWidget *label=yon_gtk_builder_get_widget(builder,"templateAppsLabel"); -// GtkIconTheme *theme=gtk_icon_theme_get_default(); -// gtk_image_set_from_pixbuf(GTK_IMAGE(image),gtk_icon_theme_load_icon_for_scale(theme,segment_icon_name,20,1,GTK_ICON_LOOKUP_FORCE_SVG,NULL)); -// gtk_label_set_text(GTK_LABEL(label),name); -// GtkListStore *ls=GTK_LIST_STORE(gtk_builder_get_object(builder,"liststore5")); -// // g_signal_connect(G_OBJECT(iv), "item-activated", G_CALLBACK(on_activate), videoconfig.applist); -// segment->Expander=expander; -// segment->IV=iv; -// segment->LS=ls; -// segment->Image=image; -// dictionary *dict=NULL; -// if (connect_to) { -// // connect_to=yon_dictionary_get_last(connect_to); -// dict=yon_dictionary_create_with_data_connected(connect_to,name,segment); -// } else -// dict=yon_dictionary_create_with_data(name,segment); -// return dict; -// } - -// GtkWidget *yon_gtk_app_chooser_apps_create(){ -// GtkWidget *Box=gtk_box_new(GTK_ORIENTATION_VERTICAL,0); -// dictionary *IVS=yon_iv_segment_create(NULL, "Graphics", "", "dialog-yes-symbolic"); -// yon_iv_segment_create(IVS, "Tools", "", "dialog-yes-symbolic"); -// yon_iv_segment_create(IVS, "Internet", "", "dialog-yes-symbolic"); -// yon_iv_segment_create(IVS, "Multimedia", "", "dialog-yes-symbolic"); -// yon_iv_segment_create(IVS, "Settings", "", "dialog-yes-symbolic"); -// yon_iv_segment_create(IVS, "Education", "", "dialog-yes-symbolic"); -// yon_iv_segment_create(IVS, "Office", "", "dialog-yes-symbolic"); -// yon_iv_segment_create(IVS, "Other", "", "dialog-yes-symbolic"); -// yon_iv_segment_create(IVS, "Development", "", "dialog-yes-symbolic"); -// yon_iv_segment_create(IVS, "System", "", "dialog-yes-symbolic"); -// dictionary *nd; -// for_dictionaries(nd,IVS){ -// gtk_box_pack_start(GTK_BOX(Box),((IVSegment*)nd->data)->Expander,0,0,0); -// } -// return Box; - -// } - -// GtkWidget *yon_gtk_socket_create_new_with_connect(GtkWidget *container, gpointer data){ -// GtkWidget *socket; -// socket = gtk_socket_new(); -// g_signal_connect(G_OBJECT(socket),"plug-added",G_CALLBACK(yon_on_plug_added),data); -// g_signal_connect(G_OBJECT(socket),"plug-removed",G_CALLBACK(yon_on_plug_removed),data); -// g_signal_connect(G_OBJECT(socket),"destroy",G_CALLBACK(yon_on_plug_removed),data); -// gtk_box_pack_start(GTK_BOX(container),socket,1,1,0); -// return socket; -// }; - -int yon_dictionary_gtk_pack_start_multiple_widgets(dictionary *dict, GtkWidget *destination, gboolean expand, gboolean fill, int padding){ - for (dictionary *dct=dict->first; dct!=NULL;dct=dct->next){ - gtk_box_pack_start(GTK_BOX(destination),(GtkWidget*)dct->data,expand,fill,padding); +void yon_terminal_integrated_launch(GtkWidget *place_to_show, char* command, void *endwork_function, void* endwork_function_argument){ + GtkWidget *terminal = vte_terminal_new(); + vte_terminal_set_size(VTE_TERMINAL(terminal),10,15); + VtePty *pty = vte_pty_new_sync(VTE_PTY_DEFAULT,NULL,NULL); + vte_terminal_set_pty(VTE_TERMINAL(terminal),pty); + char *install_command=yon_char_unite("tput cup 0 0 && tput ed; ",command," ; sleep 5;exit 0","\n",NULL); + g_signal_connect(G_OBJECT(terminal), "child-exited", G_CALLBACK(on_terminal_done), widgets); + vte_terminal_spawn_async(VTE_TERMINAL(terminal), + VTE_PTY_DEFAULT, + NULL, + install_command, + NULL, + 0, + NULL, NULL, + NULL, + -1, + NULL, + NULL, + NULL); + vte_pty_spawn_async(pty, + NULL, + install_command, + NULL, + 0, + NULL, NULL, + NULL, + -1, + NULL, + NULL, + NULL); + vte_terminal_set_scrollback_lines(VTE_TERMINAL(terminal), 100); + vte_terminal_set_scroll_on_output(VTE_TERMINAL(terminal), TRUE); + vte_terminal_set_scroll_on_keystroke(VTE_TERMINAL(terminal), TRUE); + gtk_widget_show_all(widgets->TerminalRevealer); } + +#endif + +int yon_gtk_combo_box_fill(GtkWidget *combo, config_str parameters,int size){ + if (combo&¶meters){ + for (int i=0;ifirst; dct != NULL; dct = dct->next) + { + gtk_box_pack_start(GTK_BOX(destination), (GtkWidget *)dct->data, expand, fill, padding); + } return 1; + }else return 0; } -int yon_dictionary_gtk_pack_end_multiple_widgets(dictionary *dict, GtkWidget *destination, gboolean expand, gboolean fill, int padding){ - for (dictionary *dct=dict->first; dct!=NULL;dct=dct->next){ - gtk_box_pack_end(GTK_BOX(destination),(GtkWidget*)dct->data,expand,fill,padding); +int yon_dictionary_gtk_pack_end_multiple_widgets(dictionary *dict, GtkWidget *destination, gboolean expand, gboolean fill, int padding) +{ + for (dictionary *dct = dict->first; dct != NULL; dct = dct->next) + { + gtk_box_pack_end(GTK_BOX(destination), (GtkWidget *)dct->data, expand, fill, padding); } return 1; } -void _yon_ubl_header_setup(GtkWidget *Overlay, GtkWidget *Head, GtkWidget *Image, char *image_path){ - gtk_overlay_add_overlay(GTK_OVERLAY(Overlay),Head); - gtk_image_set_from_file(GTK_IMAGE(Image),image_path); +void _yon_ubl_header_setup(GtkWidget *Overlay, GtkWidget *Head, GtkWidget *Image, char *image_path) +{ + gtk_overlay_add_overlay(GTK_OVERLAY(Overlay), Head); + gtk_image_set_from_file(GTK_IMAGE(Image), image_path); } -void _yon_ubl_status_box_render(GtkWidget *StatusBox, GtkWidget *StatusIcon, GtkWidget *StatusLabel, char *IconName, char* StatusText, BACKGROUND_IMAGE_TYPE BackgroundClass){ - GtkIconTheme *ictheme=gtk_icon_theme_get_default(); - GError *err=NULL; - gtk_image_set_from_pixbuf(GTK_IMAGE(StatusIcon),gtk_icon_theme_load_icon_for_scale(ictheme,IconName,25,1,GTK_ICON_LOOKUP_FORCE_SIZE,&err)); - if (err){ - printf("%s\n",err->message); +/** + * +*/ +void _yon_ubl_status_box_render(render_data *datav) +{ + render_data data = *(render_data*)datav; + GtkIconTheme *ictheme = gtk_icon_theme_get_default(); + GError *err = NULL; + if (err) + { + printf("%s\n", err->message); g_error_free(err); } - gtk_label_set_text(GTK_LABEL(StatusLabel),StatusText); - if (BackgroundClass==BACKGROUND_IMAGE_SUCCESS_TYPE){ - gtk_style_context_add_class(gtk_widget_get_style_context(StatusBox),"boxInfoMessOK"); - } else if (BackgroundClass==BACKGROUND_IMAGE_FAIL_TYPE){ - gtk_style_context_add_class(gtk_widget_get_style_context(StatusBox),"boxInfoMessError"); + if (data.type == BACKGROUND_IMAGE_SUCCESS_TYPE||! data.type) + { + gtk_style_context_remove_class(gtk_widget_get_style_context(data.box), "boxInfoMessError"); + gtk_style_context_add_class(gtk_widget_get_style_context(data.box), "boxInfoMessOK"); + gtk_image_set_from_pixbuf(GTK_IMAGE(data.icon), gtk_icon_theme_load_icon_for_scale(ictheme, "com.ublinux.ubl-settings-video.checked", 25, 1, GTK_ICON_LOOKUP_FORCE_SIZE, &err)); + } + else if (data.type == BACKGROUND_IMAGE_FAIL_TYPE) + { + gtk_style_context_remove_class(gtk_widget_get_style_context(data.box), "boxInfoMessOK"); + gtk_style_context_add_class(gtk_widget_get_style_context(data.box), "boxInfoMessError"); + gtk_image_set_from_pixbuf(GTK_IMAGE(data.icon), gtk_icon_theme_load_icon_for_scale(ictheme, "com.ublinux.ubl-settings-video.warning", 25, 1, GTK_ICON_LOOKUP_FORCE_SIZE, &err)); } + if (data.text_to_render) + gtk_label_set_text(GTK_LABEL(data.label), data.text_to_render); } + +/**yon_ubl_setup_sockets(GtkWidget *main_window, GtkWidget *left_window, GtkWidget *right_window, int socket_main_id, int socket_left_id, int socket_right_id) + * [EN] + * Set up plugs for using with GtkSockets insine ubl-settings-manager. + * [main_window] is container widget, which holds main application functionality. + * [left_window] is container widget, which holds widgets, have to be shown at left part of ubl-settings-manager header. + * [right_window] is container widget, which holds widgets, have to be shown at right part of ubl-settings-manager header. + * [socket_main_id] is id of socket for [main_window]. + * [socket_left_id] is id of socket for [left_window]. + * [socket_right_id] is id of socket for [right_window]. + * [RU] + * Настраивает плаги для работы с сокетами в утилите ubl-settings-manager. + * [main_window] - контейнер основного интерфейса приложения. + * [left_window] - контейнер для виджетов которые должны отображаться в левой части шапки ubl-settings-manager. + * [right_window] - контейнер для виджетов которые должны отображаться в правой части шапки ubl-settings-manager. + * [socket_main_id] - id сокета для [main_window]. + * [socket_left_id] - id сокета для [left_window]. + * [socket_right_id] - id сокета для [right_window]. +*/ +void yon_ubl_setup_sockets(GtkWidget *main_window, GtkWidget *left_window, GtkWidget *right_window, int socket_main_id, int socket_left_id, int socket_right_id){ + if (main_window&&socket_main_id>-1){ + gtk_widget_hide(gtk_widget_get_toplevel(main_window)); + GtkWidget *plug_main=gtk_plug_new(socket_main_id); + GtkWidget *plug_left=NULL; + GtkWidget *plug_right=NULL; + GtkWidget *box=NULL; + g_signal_connect(G_OBJECT(plug_main), "destroy", G_CALLBACK(gtk_main_quit),NULL); + if (socket_left_id>-1&&left_window){ + plug_left=gtk_plug_new(socket_left_id); + g_object_ref(left_window); + gtk_container_remove(GTK_CONTAINER(gtk_widget_get_parent(left_window)),left_window); + gtk_container_add(GTK_CONTAINER(plug_left),left_window); + gtk_style_context_add_class(gtk_widget_get_style_context(plug_left),"primary-toolbar"); + gtk_style_context_add_class(gtk_widget_get_style_context(left_window),"button"); + gtk_style_context_add_class(gtk_widget_get_style_context(left_window),"opacited"); + gtk_style_context_add_class(gtk_widget_get_style_context(left_window),"color"); + gtk_style_context_add_class(gtk_widget_get_style_context(plug_left),"noborder"); + gtk_widget_show(plug_left); + } + else if (left_window){ + if (box==NULL){ + box=gtk_box_new(GTK_ORIENTATION_HORIZONTAL,5); + gtk_box_pack_start(GTK_BOX(main_window),box,0,0,5); + gtk_box_reorder_child(GTK_BOX(main_window),box,0); + gtk_widget_show(box); + } + gtk_style_context_add_class(gtk_widget_get_style_context(left_window),"inherited"); + gtk_container_remove(GTK_CONTAINER(gtk_widget_get_parent(left_window)),left_window); + gtk_box_pack_end(GTK_BOX(box),left_window,0,0,5); + } + if (socket_right_id>-1&&right_window){ + plug_right=gtk_plug_new(socket_right_id); + g_object_ref(right_window); + gtk_container_remove(GTK_CONTAINER(gtk_widget_get_parent(right_window)),right_window); + gtk_container_add(GTK_CONTAINER(plug_right),right_window); + gtk_style_context_add_class(gtk_widget_get_style_context(plug_right),"primary-toolbar"); + gtk_style_context_add_class(gtk_widget_get_style_context(right_window),"button"); + gtk_style_context_add_class(gtk_widget_get_style_context(right_window),"opacited"); + gtk_style_context_add_class(gtk_widget_get_style_context(right_window),"color"); + gtk_style_context_add_class(gtk_widget_get_style_context(plug_right),"noborder"); + gtk_widget_show(plug_right); + } + else if (right_window){ + if (box==NULL){ + box=gtk_box_new(GTK_ORIENTATION_HORIZONTAL,5); + gtk_box_pack_start(GTK_BOX(main_window),box,0,0,5); + gtk_box_reorder_child(GTK_BOX(main_window),box,0); + gtk_widget_show(box); + } + gtk_style_context_add_class(gtk_widget_get_style_context(right_window),"inherited"); + gtk_container_remove(GTK_CONTAINER(gtk_widget_get_parent(right_window)),right_window); + gtk_box_pack_start(GTK_BOX(box),right_window,0,0,5); + } + g_object_ref(main_window); + gtk_container_remove(GTK_CONTAINER(gtk_widget_get_parent(main_window)),main_window); + gtk_container_add(GTK_CONTAINER(plug_main),main_window); + gtk_widget_show(plug_main); + } +} + +#ifdef WEBKIT_FOUND + +/**yon_ubl_browser_window_open(char *link, char *browser_window_name) + * [EN] + * Launches integrated browser window, named [browser_window_name] at header with [link]. + * [RU] + * Открывает встроенный браузер с именем [browser_window_name] и показываемой страницей по ссылке [link] +*/ +void yon_ubl_browser_window_open(char *link, char *browser_window_name){ + GtkWidget *browser=gtk_window_new(GTK_WINDOW_TOPLEVEL); + GtkWidget *web_place=gtk_box_new(GTK_ORIENTATION_VERTICAL,0); + GtkWidget *header=gtk_header_bar_new(); + GtkWidget *header_label=gtk_label_new(browser_window_name); + GtkWidget *WebView=webkit_web_view_new(); + gtk_container_add(GTK_CONTAINER(browser),web_place); + gtk_window_set_titlebar(GTK_WINDOW(browser),header); + gtk_window_set_title(GTK_WINDOW(browser),browser_window_name); + gtk_widget_set_size_request(browser,800,600); + gtk_header_bar_set_custom_title(GTK_HEADER_BAR(header),header_label); + gtk_header_bar_set_show_close_button(GTK_HEADER_BAR(header),1); + webkit_web_view_load_uri(WEBKIT_WEB_VIEW(WebView),link); + gtk_box_pack_start(GTK_BOX(web_place),WebView,1,1,0); + gtk_widget_show_all(browser); +} +#else + +/**yon_ubl_browser_window_open(char *link, char *browser_window_name) + * [EN] + * Launches browser with [link]. + * [browser_window_name] is't used. It's needed for compatibility with webkit version of that function. + * [RU] + * Открывает браузер со страницей по ссылке [link] + * [browser_window_name] не используется. Нужна для совместимости с webkit версией этой функции. +*/ +void yon_ubl_browser_window_open(char *link, char *browser_window_name){ + char *user=getenv("SUDO_USER"); + if (!user) + user=getlogin(); + char *command=yon_char_unite("sudo -u ",user," xdg-open ", link,NULL); + yon_launch_app(command); +} +#endif + #endif \ No newline at end of file diff --git a/source/ubl-utils.h b/source/ubl-utils.h index 444fd93..7004cca 100644 --- a/source/ubl-utils.h +++ b/source/ubl-utils.h @@ -3,6 +3,7 @@ #include #include #include +#include #include #include #include @@ -12,22 +13,36 @@ #define DesktopPath "/usr/share/applications/" -#define for_dictionaries(obj,obj1) for(obj=obj1->first;obj!=NULL;obj=obj->next) +#define for_dictionaries(obj, obj1) for (obj = obj1->first; obj != NULL; obj = obj->next) -typedef enum { - DICTIONARY_ACTION_WIDGETS_TYPE, - DICTIONARY_IVGRAPHICALS_TYPE, +#define new(type) malloc(sizeof(type)) +#define new_arr(type,size) malloc(sizeof(type)*size) + +#define yon_ubl_set_config_save_data_pointer(command) config_commands.config_save_data = command + +#define yon_ubl_load_global_config(command, size_pointer) yon_config_load(command, size_pointer) +#define yon_ubl_load_local_config(command, size_pointer) yon_config_load(command, size_pointer) +#define yon_ubl_save_global_config(command) yon_config_save(command) +#define yon_ubl_save_local_config(command) yon_config_save(command) + +typedef enum +{ + #ifdef __GTK_H__ + DICTIONARY_GTK_WIDGETS_TYPE, + #endif DICTIONARY_OTHER_TYPE } DICT_TYPE; - -typedef struct { +typedef struct +{ char *command; int *exitcode; } thread_output; -typedef struct dictionary { + +typedef struct dictionary +{ char *key; void *data; struct dictionary *next; @@ -36,26 +51,41 @@ typedef struct dictionary { DICT_TYPE data_type; } dictionary; -typedef struct apps{ - char *Name; - int Type; - char *Categories; - char *Exec; - char *Icon; - int Pluggable; - int DualPluggable; - } apps; - - -//dictionary functions +typedef struct apps +{ + char *Name; + int Type; + char *Categories; + char *Exec; + char *Icon; + int Pluggable; + int DualPluggable; +} apps; + +typedef char** config_str; +// dictionary functions + +/**yon_dictionary_get_data(dictionary, type) + * [EN] + * Gets data from dictionary. + * [dictionary] is dictionary, from which data should be extracted; + * [type] is type of data, [dictionary] contains. + * [RU] + * Возвращает данные из словаря. + * [dictionary] - словарь из которого достаются данные. + * [type] - тип данных, хранящихся в словаре [dictionary]. +*/ +#define yon_dictionary_get_data(dictionary, type) ((type)dictionary->data) +#define yon_dictionary_add_or_create_if_exists_with_data(dict,key,data) {if (!dict) dict=yon_dictionary_create_with_data(key,data); \ + else dict=yon_dictionary_create_with_data_connected(dict,key,data);} dictionary *yon_dictionary_create_empty(); -dictionary * yon_dictionary_create_conneced(dictionary *targetdict); +dictionary *yon_dictionary_create_conneced(dictionary *targetdict); dictionary *yon_dictionary_get_last(dictionary *dict); -dictionary *yon_dictionary_switch_places(dictionary *dict,int aim); +dictionary *yon_dictionary_switch_places(dictionary *dict, int aim); void yon_dictionary_make_first(dictionary *dict); @@ -73,92 +103,195 @@ dictionary *yon_dictionary_rip(dictionary *dict); dictionary *yon_dictionary_get_nth(dictionary *dict, int place); -//char functions +void *yon_dictionary_free_all(dictionary *dictionary,void (data_manipulation)(void*)); + +// char functions char *yon_char_get_augumented(char *source, char *append); char *yon_char_new(char *chr); +char *yon_char_unite(char *source, ...); + char *yon_cut(char *source, int size, int startpos); char *yon_char_divide(char *source, int dividepos); -char *yon_char_divide_search(char *source, char* dividepos, int delete_divider); +char *yon_char_divide_search(char *source, char *dividepos, int delete_divider); char *yon_char_from_int(int int_to_convert); +char *yon_char_replace(char *source, char *find, char*replace); +char **yon_char_parse(char *parameters, int *size, char *divider); -//parsing functions +char **yon_char_parsed_shrink(char **char_string, int *size, int item_to_delete); -apps *yon_apps_scan_and_parse_desktops(int *sizef); +int yon_char_parsed_check_exist(char **parameters, int size, char *param); +int yon_char_find_count(char *source, char *find); -void yon_apps_sort(apps *applist,int size); +int yon_char_parsed_includes_char_parsed (config_str source, config_str to_check, int source_size, int check_size); +config_str yon_char_parsed_new (config_str old, int *old_size, ...); -apps *yon_apps_get_by_name(apps *applist,char *name, int size); +// parsing functions +apps *yon_apps_scan_and_parse_desktops(int *sizef); -//terminal-using functions +void yon_apps_sort(apps *applist, int size); +apps *yon_apps_get_by_name(apps *applist, char *name, int size); +config_str yon_config_load(char *command, int *str_len); -int yon_launch_app(char *name); +int yon_config_save(char *command); +char *yon_config_get_parameter(config_str parameters, int size, char *param); -int yon_launch_app_with_arguments(char *name, char *args); +char *yon_config_make_save_parameter_with_multiple_arguments(char *parameter_string, char *config_parameter, char *divider); + +// terminal-using functions +int yon_launch_app(char *name); + +int yon_launch_app_with_arguments(char *name, char *args); int yon_launch(thread_output *thread); -//Gtk functions +// Gtk functions #ifdef __GTK_H__ +#ifdef VTE_TERMINAL -#define yon_gtk_builder_get_widget(obj,obj2) GTK_WIDGET(gtk_builder_get_object(obj,obj2)) +/** + * +*/ +void yon_terminal_integrated_launch(GtkWidget *place_to_show, char* command, void *endwork_function, void* endwork_function_argument); +#endif +/**yon_gtk_builder_get_widget(builder, widget_name) + * [EN] + * Returns GtkWidget from GtkBuilder *[builder]. + * [builder] is GtkBuilder*; + * [widget_name] is id of widget; +*/ +#define yon_gtk_builder_get_widget(builder, widget_name) GTK_WIDGET(gtk_builder_get_object(builder, widget_name)) -typedef struct { +typedef struct +{ GtkWidget *Icon; GtkWidget *Label; GtkWidget *IconView; GtkListStore *List; } expander_icon_view; - // GtkWidget *yon_gtk_app_chooser_apps_create(); // dictionary *yon_gtk_app_chooser_create(); // expander_icon_view yon_gtk_icon_view_expander_create(GtkWidget *pack, ...); -GtkWidget *yon_gtk_socket_create_new_with_connect(GtkWidget *container, gpointer data); +int yon_gtk_combo_box_fill(GtkWidget *combo, char **parameters,int size); + +int yon_gtk_combo_box_text_find(GtkWidget *combo_box, char *text_to_find); int yon_gtk_icon_view_hide_empty(dictionary *icon_view_segment); int yon_dictionary_gtk_pack_start_multiple_widgets(dictionary *dict, GtkWidget *destination, gboolean expand, gboolean fill, int padding); int yon_dictionary_gtk_pack_end_multiple_widgets(dictionary *dict, GtkWidget *destination, gboolean expand, gboolean fill, int padding); -//uninitialised - -void yon_on_plug_added(GtkSocket* self, gpointer user_data); -void yon_on_plug_removed(GtkSocket* self, gpointer user_data); -#endif -typedef enum { +typedef enum +{ BACKGROUND_IMAGE_SUCCESS_TYPE, BACKGROUND_IMAGE_FAIL_TYPE } BACKGROUND_IMAGE_TYPE; + +typedef struct { + BACKGROUND_IMAGE_TYPE type; + GtkWidget *icon; + GtkWidget *box; + GtkWidget *label; + char* text_to_render; +} render_data; + +/**yon_ubl_status_box_setup(render,icon,box,label) + * [EN] + * Sets up [render] structure of type render_data. + * [icon] is GtkImage widget of status box for showing status icons; + * [box] is GtkBox widget of status box for showing status color; + * [label] is GtkLabel widget of status box for showing status text; + * [RU] + * Настраивает структуру [render] типа render_data. + * [icon] - виджет типа GtkIcon в котором будут отображаться статусные иконки; + * [box] - виджет типа GtkBox в котором будет отображаться цвет статуса; + * [label] - виджет типа GtkLabel в котором будет отображаться текст статусного сообщения; +*/ +#define yon_ubl_status_box_setup(render,icon,box,label) {render.icon=GTK_WIDGET(icon); render.box=GTK_WIDGET(box); render.label=GTK_WIDGET(label);} + +/**yon_ubl_status_box_render(render,text,type) + * [EN] + * Renders message in status box; + * [render] is render_data structure of status box; + * [text] is text to be shown in status box; + * [type] if type of message. Can be BACKGROUND_IMAGE_FAIL_TYPE or BACKGROUND_IMAGE_SUCCESS_TYPE + * [RU] + * Отображает сообщение в статусном окне. + * [render] - структура типа render_data для нужного статусного окна; + * [text] - текст, отображаемый в статусном окне; + * [type] - тип сообщения. Может быть: + * BACKGROUND_IMAGE_FAIL_TYPE (красный фон,иконка - восклицательный знак) + * или + * BACKGROUND_IMAGE_SUCCESS_TYPE (Жёлтный фон, иконка - галка) +*/ +#define yon_ubl_status_box_render(render,text,m_type) {render.text_to_render=text; render.type=m_type; pthread_attr_t attr; pthread_attr_init(&attr); pthread_t tid; pthread_create(&tid,&attr,(void*)_yon_ubl_status_box_render,((void*)&render)); } + #ifdef __cplusplus -#define yon_ubl_header_setup(overlay,head,image,imag_path) _yon_ubl_header_setup(GTK_WIDGET(overlay.gobj()),GTK_WIDGET(head.gobj()),GTK_WIDGET(image.gobj()),(char*)imag_path) -#define yon_ubl_status_box_render(statusbox, statusicon, statuslabel, iconname, statustext, backgroundclass) _yon_ubl_status_box_render(GTK_WIDGET(statusbox.gobj()), GTK_WIDGET(statusicon.gobj()), GTK_WIDGET(statuslabel.gobj()), (char*)iconname, (char*)statustext, backgroundclass) + +/**yon_ubl_header_setup(overlay, head, image, imag_path) + * [EN] + * Sets up header of app. + * [overlay] is overlay for app header; + * [head] is box of header, which connects to [overlay] + * [image] is header background image; + * [imag_path] is path of image, shown in [image] + * [RU] + * Настраивает заголовок приложения. + * [overlay] - оверлей заголовка приложения; + * [head] - шапка заголовка, присоединяемая к [overlay] + * [image] - виджет картинки для заднего фона; + * [imag_path] - путь до картинки, загружаемой в [image] +*/ +#define yon_ubl_header_setup(overlay, head, image, imag_path) _yon_ubl_header_setup(GTK_WIDGET(overlay.gobj()), GTK_WIDGET(head.gobj()), GTK_WIDGET(image.gobj()), (char *)imag_path) #else -#define yon_ubl_header_setup(overlay,head,image,imag_path) _yon_ubl_header_setup(GTK_WIDGET(overlay),GTK_WIDGET(head),GTK_WIDGET(image), (char*)imag_path) -#define yon_ubl_status_box_render(statusbox, statusicon, statuslabel, iconname, statustext, backgroundclass) _yon_ubl_status_box_render(statusbox, statusicon, statuslabel, iconname, statustext, backgroundclass) + +/**yon_ubl_header_setup(overlay, head, image, imag_path) + * [EN] + * Sets up header of app. + * [overlay] is overlay for app header; + * [head] is box of header, which connects to [overlay] + * [image] is header background image; + * [imag_path] is path of image, shown in [image] + * [RU] + * Настраивает заголовок приложения. + * [overlay] - оверлей заголовка приложения; + * [head] - шапка заголовка, присоединяемая к [overlay] + * [image] - виджет картинки для заднего фона; + * [imag_path] - путь до картинки, загружаемой в [image] +*/ +#define yon_ubl_header_setup(overlay, head, image, imag_path) _yon_ubl_header_setup(GTK_WIDGET(overlay), GTK_WIDGET(head), GTK_WIDGET(image), (char *)imag_path) #endif void _yon_ubl_header_setup(GtkWidget *Overlay, GtkWidget *Head, GtkWidget *Image, char *image_path); -void _yon_ubl_status_box_render(GtkWidget *StatusBox, GtkWidget *StatusIcon, GtkWidget *StatusLabel, char *IconName, char* StatusText, BACKGROUND_IMAGE_TYPE BackgroundClass); +void _yon_ubl_status_box_render(render_data *datav); +void yon_ubl_setup_sockets(GtkWidget *main_window, GtkWidget *left_window, GtkWidget *right_window, int socket_main_id, int socket_left_id, int socket_right_id); +#ifdef WEBKIT_FOUND + +void yon_ubl_browser_window_open(char *link, char *browser_window_name); +#else +void yon_ubl_browser_window_open(char *link, char *browser_window_name); +#endif +#endif #endif \ No newline at end of file diff --git a/ubl-settings-update.css b/ubl-settings-update.css index 515d75a..8687d4a 100644 --- a/ubl-settings-update.css +++ b/ubl-settings-update.css @@ -12,3 +12,97 @@ background:transparent; .nobackground:active { background:transparent; } +.textHead{ + text-shadow: 2px 2px @theme_bg_color; + color: @theme_text_color; +} + +.inherited>* { + border:none; + background:inherit; +} +.workingbg { + background:@theme_base_color; +} +.menuitembottom{ + margin-top:0px; + margin-bottom:3px; + border-color:inherit; + border-left-width:inherit; + border-right-width:inherit; + } + .menuitemmiddle{ + margin-top:0px; + margin-bottom:0px; + border-color:inherit; + border-left-width:inherit; + border-right-width:inherit; + } + + .menuitemtop{ + margin-bottom:0px; + border-color:inherit; + border-top-width:inherit; + border-left-width:inherit; + border-right-width:inherit; + } + .menuitemtop *{ + margin:2px 2px 0 2px; + padding: 5px 10px 3px 5px; + border:transparent; + } + .menuitemmiddle *{ + margin:0 2px 0 2px; + padding: 3px 10px 3px 5px; + border:transparent; + } + .menuitembottom *{ + margin:0 2px 2px 2px; + padding: 3px 10px 5px 5px; + } + .menuitemtop:hover { + background:@theme_bg_color; + border-color:inherit; + border-top-width:inherit; + border-left-width:inherit; + border-right-width:inherit; + } + .menuitemmiddle:hover { + background:@theme_bg_color; + border-color:inherit; + border-left-width:inherit; + border-right-width:inherit; + } + .menuitembottom:hover { + background:@theme_bg_color; + border-color:inherit; + border-bottom-width:0px; + border-left-width:inherit; + border-right-width:inherit; + + } + .menuitemtop:hover* { + margin:2px 2px 0 2px; + padding: 5px 10px 3px 5px; + background:@theme_selected_bg_color; + border-radius:2px; + } + .menuitemmiddle:hover* { + margin:0 2px 0 2px; + padding: 3px 10px 3px 5px; + background:@theme_selected_bg_color; + border-radius:2px; + } + .menuitembottom:hover* { + margin:0 2px 2px 2px; + padding: 3px 10px 5px 5px; + background:@theme_selected_bg_color; + border-radius:2px; + } + .boxInfoMessError{ + background-color: #ea9999; +} + +.boxInfoMessOK{ + background-color: #f3f0ac; +} \ No newline at end of file diff --git a/ubl-settings-update.desktop b/ubl-settings-update.desktop index 74138da..8428d00 100644 --- a/ubl-settings-update.desktop +++ b/ubl-settings-update.desktop @@ -2,8 +2,8 @@ Encoding=UTF-8 Name=ubl-settings-update Name[ru]=Обновление системы -GenericName=ubl-settings-quotas -GenericName[ru]=Обвноление системы +GenericName=ubl-settings-update +GenericName[ru]=Обновление системы Comment=ubl-settings-update Comment[ru]=Приложение для управления настройками обновлений Type=Application diff --git a/ubl-settings-update.glade b/ubl-settings-update.glade index d89d9df..5ebde48 100644 --- a/ubl-settings-update.glade +++ b/ubl-settings-update.glade @@ -1,8 +1,30 @@ - - + + + + + False False @@ -11,7 +33,7 @@ com.ublinux.ubl-settings-update dialog True - Update + ubl-settings-update 1.1 Copyright © 2022 - 2023, UBSoft LLC Update confugurator @@ -108,7 +130,9 @@ 255 True False + end System update parameter configuration + 0 @@ -123,6 +147,28 @@ 0 + + + 255 + True + False + start + hsrdtfhbfn + 0 + + + + + + + + True + True + 1 + + False @@ -158,6 +204,7 @@ False System update + False True com.ublinux.ubl-settings-update @@ -176,10 +223,10 @@ False 5 - + True False - Type: + Adress: 0 @@ -189,7 +236,7 @@ - + True True @@ -231,7 +278,7 @@ - + True True @@ -325,7 +372,7 @@ - + @@ -364,81 +411,217 @@ False user-trash-symbolic - - - - - - - - - + True False - - - True - False - Load from global configuration - - - - - True - False - Load from local configuration - - + process-stop-symbolic - + True False - False - False - - - True - False - Documentation - True - - - - - True - False - About - - - + emblem-ok-symbolic - - True + False + False + 450 + dialog-question-symbolic - - True - False - Save to global and local documentation - - - - + True False - Save to global configuration + 5 + 5 + 5 + 5 + vertical + 10 + + + True + False + + + True + False + start + 20 + 20 + dialog-question-symbolic + 6 + + + False + True + 0 + + + + + True + False + vertical + + + True + False + start + 10 + 5 + Would you like to read documentation in the Web? + True + 0 + + + + + + + False + True + 0 + + + + + True + False + start + start + 10 + 10 + You will be redirected to documentation website where documentation is +translated and supported by community. + True + 0 + + + + False + True + 1 + + + + + Always redirect to online documentation + True + True + False + end + True + + + + False + True + end + 2 + + + + + + True + True + 1 + + + + + + True + True + 0 + + + + + True + False + 30 + True + + + Cancel + True + True + True + image8 + + + + True + True + 0 + + + + + Read Online + True + True + True + image9 + + + + True + True + 1 + + + + + False + True + 1 + + - - + + True False - Save to local configuration + True + + + True + False + UBLinux Settings + + + + + + + + + + + + + + + 800 600 @@ -456,6 +639,57 @@ True False vertical + + + True + False + + + True + False + 5 + 5 + 5 + 5 + 5 + 5 + 25 + + + False + True + 0 + + + + + True + False + start + 5 + 5 + 5 + 5 + 6 + 6 + + + + + + + False + True + 1 + + + + + False + True + 0 + + True @@ -471,7 +705,6 @@ True False start - gtk-missing-image -1 @@ -560,6 +793,7 @@ True False + 0 False @@ -671,9 +905,6 @@ Enabled - - 0 - @@ -683,7 +914,18 @@ - 0 + 1 + + + + + + + Distribution + + + + 2 @@ -1070,63 +1312,52 @@ - + True - True - True - False - True - True - menu2 - none - - - - - - - end - 1 - - - - - True - True - False - True - menu1 + False - + True - False - - - True - False - Load - - - False - True - 0 - - + True + False + True + menu1 - + True False - pan-down-symbolic + + + True + False + Load + + + False + True + 0 + + + + + True + False + pan-down-symbolic + + + False + True + 1 + + - - False - True - 1 - + + False + True + 0 + @@ -1134,41 +1365,75 @@ - + True - True - False - True - menu3 + False - + True - False + True + False + True + menu3 - + True False - Save + + + True + False + Save + + + False + True + 0 + + + + + True + False + pan-down-symbolic + + + False + True + 1 + + - - False - True - 0 - + + + False + True + 0 + + + + + True + True + True + False + True + True + menu2 + none - - True - False - pan-down-symbolic - - - False - True - 1 - + + + + False + True + 1 + @@ -1189,4 +1454,92 @@ + + True + False + False + + + True + False + Load from global configuration + + + + + + True + False + Load from local configuration + + + + + + True + False + False + False + + + True + False + Documentation + True + + + + + + True + False + About + + + + + + True + False + False + + + True + False + Save to global and local documentation + + + + + + True + False + Save to global configuration + + + + + + True + False + Save to local configuration + + + + diff --git a/ubl-settings-update.pot b/ubl-settings-update.pot index 7ee8f2e..d5ca432 100644 --- a/ubl-settings-update.pot +++ b/ubl-settings-update.pot @@ -1,184 +1,249 @@ -# language translations for ubl-settings-manager package. +# Language translations for ubl-settings-update package. # Copyright (C) 2022, UBTech LLC -# This file is distributed under the same license as the ubl-settings-manager package. +# This file is distributed under the same license as the ubl-settings-update package. # UBLinux Team , 2022 # #, fuzzy msgid "" msgstr "" -"Project-Id-Version: ubl-settings-manager 1.0\n" -"Report-Msgid-Bugs-To: info@ublinux.com\n" -"POT-Creation-Date: 2023-04-21 12:33+0000\n" -"PO-Revision-Date: 2023-01-01 00:00+0600\n" -"Last-Translator: UBLinux Team \n" -"Language-Team: Russian - UBLinux Team \n" -"Language: Russian\n" +"Project-Id-Version: ubl-settings-update 1.0\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2023-05-22 17:22+0600\n" +"PO-Revision-Date: \n" +"Last-Translator: \n" +"Language-Team: \n" +"Language: \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -#: source/ubl-settings-update.c:16 -msgid "UBlinux System update" +#: source/ubl-settings-update-strings.h:1 +msgid "Version:" msgstr "" -#: source/ubl-settings-update.c:18 -msgid "Project Home Page" +#: source/ubl-settings-update-strings.h:2 +msgid "ubl-settings-update version:" +msgstr "" + +#: source/ubl-settings-update-strings.h:2 +msgid "update settings" +msgstr "" + +#: source/ubl-settings-update-strings.h:2 +msgid "Usage:" +msgstr "" + +#: source/ubl-settings-update-strings.h:2 +msgid "[OPTIONS]" +msgstr "" + +#: source/ubl-settings-update-strings.h:2 +msgid "Options:" +msgstr "" + +#: source/ubl-settings-update-strings.h:2 +msgid "Show this help" msgstr "" -#: source/ubl-settings-update.c:19 -msgid "Update configurator" +#: source/ubl-settings-update-strings.h:2 +msgid "Show package version" msgstr "" -#: source/ubl-settings-update.c:46 source/ubl-settings-update.c:111 -#: source/ubl-settings-update.c:113 +#: source/ubl-settings-update-strings.h:2 +msgid "Lock this help menu" +msgstr "" + +#: source/ubl-settings-update-strings.h:2 +msgid "Lock configuration saving" +msgstr "" + +#: source/ubl-settings-update-strings.h:2 +msgid "Lock local configration saving" +msgstr "" + +#: source/ubl-settings-update-strings.h:2 +msgid "Lock global configration saving" +msgstr "" + +#: source/ubl-settings-update-strings.h:2 +msgid "Lock global configration loading" +msgstr "" + +#: source/ubl-settings-update-strings.h:3 msgid "System update" msgstr "" -#: source/ubl-settings-update.c:48 -msgid "Type: " +#: source/ubl-settings-update-strings.h:4 +msgid "System update settings management" +msgstr "" + +#: source/ubl-settings-update-strings.h:5 +msgid "Check for updates" msgstr "" -#: source/ubl-settings-update.c:49 -msgid "URI: " +#: source/ubl-settings-update-strings.h:6 +msgid "About" msgstr "" -#: source/ubl-settings-update.c:50 source/ubl-settings-update.c:52 -#: source/ubl-settings-update.c:54 -msgid " " +#: source/ubl-settings-update-strings.h:7 +msgid "Documentation" msgstr "" -#: source/ubl-settings-update.c:51 -msgid "Distribution: " +#: source/ubl-settings-update-strings.h:8 +msgid "Save to local configuration" msgstr "" -#: source/ubl-settings-update.c:53 -msgid "Sections: " +#: source/ubl-settings-update-strings.h:9 +msgid "Save to global configuration" msgstr "" -#: source/ubl-settings-update.c:56 -msgid "Cancel" +#: source/ubl-settings-update-strings.h:10 +msgid "Save configuration" msgstr "" -#: source/ubl-settings-update.c:57 source/ubl-settings-update.c:143 +#: source/ubl-settings-update-strings.h:11 +#: source/ubl-settings-update-strings.h:36 msgid "Save" msgstr "" -#: source/ubl-settings-update.c:115 -msgid "General" +#: source/ubl-settings-update-strings.h:12 +msgid "Load local configuration" msgstr "" -#: source/ubl-settings-update.c:116 -msgid "Repositories" +#: source/ubl-settings-update-strings.h:13 +msgid "Load global configuration" msgstr "" -#: source/ubl-settings-update.c:117 -msgid "Extra" +#: source/ubl-settings-update-strings.h:14 +msgid "load" msgstr "" -#: source/ubl-settings-update.c:119 -msgid "Update checking frequency" +#: source/ubl-settings-update-strings.h:15 +msgid "Launch package manager" msgstr "" -#: source/ubl-settings-update.c:120 -msgid "Hide icon of no updates found" +#: source/ubl-settings-update-strings.h:16 +msgid "Cache clean command: " msgstr "" -#: source/ubl-settings-update.c:121 -msgid "Download updates automatically" +#: source/ubl-settings-update-strings.h:17 +msgid "Update command: " msgstr "" -#: source/ubl-settings-update.c:122 -msgid "Every 1 hour" +#: source/ubl-settings-update-strings.h:18 +msgid "Package manager: " msgstr "" -#: source/ubl-settings-update.c:123 -msgid "Every 2 hours" +#: source/ubl-settings-update-strings.h:19 +msgid "URI" msgstr "" -#: source/ubl-settings-update.c:124 -msgid "Every 3 hours" +#: source/ubl-settings-update-strings.h:20 +msgid "Enabled" msgstr "" -#: source/ubl-settings-update.c:126 -msgid "Activate AUR" +#: source/ubl-settings-update-strings.h:21 +msgid "Distribution" msgstr "" -#: source/ubl-settings-update.c:127 +#: source/ubl-settings-update-strings.h:22 msgid "Activate UBUR" msgstr "" -#: source/ubl-settings-update.c:128 -msgid "Create" +#: source/ubl-settings-update-strings.h:23 +msgid "Activate AUR" msgstr "" -#: source/ubl-settings-update.c:129 -msgid "Edit" +#: source/ubl-settings-update-strings.h:24 +msgid "Every 3 hours" msgstr "" -#: source/ubl-settings-update.c:130 -msgid "Delete" +#: source/ubl-settings-update-strings.h:25 +msgid "Every 2 hours" msgstr "" -#: source/ubl-settings-update.c:131 -msgid "Enabled" +#: source/ubl-settings-update-strings.h:26 +msgid "Every 1 hour" msgstr "" -#: source/ubl-settings-update.c:132 -msgid "URI" +#: source/ubl-settings-update-strings.h:27 +msgid "Download updates automatically" msgstr "" -#: source/ubl-settings-update.c:134 -msgid "Package manager: " +#: source/ubl-settings-update-strings.h:28 +msgid "Hide icon of no updates found" msgstr "" -#: source/ubl-settings-update.c:135 -msgid "Update command: " +#: source/ubl-settings-update-strings.h:29 +msgid "Update checking frequency" msgstr "" -#: source/ubl-settings-update.c:136 -msgid "Cache clean command: " +#: source/ubl-settings-update-strings.h:30 +msgid "Extra" msgstr "" -#: source/ubl-settings-update.c:137 -msgid "Launch package manager" +#: source/ubl-settings-update-strings.h:31 +msgid "Repositories" msgstr "" -#: source/ubl-settings-update.c:139 -msgid "load" +#: source/ubl-settings-update-strings.h:32 +msgid "General" msgstr "" -#: source/ubl-settings-update.c:140 -msgid "Load global configuration" +#: source/ubl-settings-update-strings.h:33 +msgid "Adress: " msgstr "" -#: source/ubl-settings-update.c:141 -msgid "Load local configuration" +#: source/ubl-settings-update-strings.h:34 +msgid "Distribution: " msgstr "" -#: source/ubl-settings-update.c:144 -msgid "Save to global and local configuration" +#: source/ubl-settings-update-strings.h:35 +msgid "Cancel" msgstr "" -#: source/ubl-settings-update.c:145 -msgid "Save to global configuration" +#: source/ubl-settings-update-strings.h:37 +msgid "Would you like to read documentation in the Web?" msgstr "" -#: source/ubl-settings-update.c:146 -msgid "Save to local configuration" +#: source/ubl-settings-update-strings.h:38 +msgid "" +"You will be redirected to documentation website where documentation is\n" +"translated and supported by community." msgstr "" -#: source/ubl-settings-update.c:148 -msgid "Documentation" +#: source/ubl-settings-update-strings.h:39 +msgid "Always redirect to online documentation" msgstr "" -#: source/ubl-settings-update.c:149 -msgid "About" +#: source/ubl-settings-update-strings.h:40 +msgid "Open documentation" msgstr "" -#: source/ubl-settings-update.c:151 -msgid "Check for updates" +#: source/ubl-settings-update-strings.h:41 +msgid "Project Home Page" +msgstr "" + +#: source/ubl-settings-update-strings.h:42 +msgid "Nothing were chosen" +msgstr "" + +#: source/ubl-settings-update-strings.h:44 +msgid "Global configuration loading succseeded." +msgstr "" + +#: source/ubl-settings-update-strings.h:45 +msgid "Local configuration loading succseeded." +msgstr "" + +#: source/ubl-settings-update-strings.h:47 +msgid "Local and global configuration saving succseeded." +msgstr "" + +#: source/ubl-settings-update-strings.h:48 +msgid "Global configuration saving succseeded." msgstr "" -#: source/ubl-settings-update.c:166 -msgid "System update parameter configuration" +#: source/ubl-settings-update-strings.h:49 +msgid "Local configuration saving succseeded." msgstr "" diff --git a/ubl-settings-update_ru.po b/ubl-settings-update_ru.po index fe04db6..655c950 100644 --- a/ubl-settings-update_ru.po +++ b/ubl-settings-update_ru.po @@ -1,14 +1,14 @@ -# Russian translations for ubl-settings-manager package. +# Russian translations for ubl-settings-update package. # Copyright (C) 2022, UBTech LLC -# This file is distributed under the same license as the ubl-settings-manager package. +# This file is distributed under the same license as the ubl-settings-update package. # UBLinux Team , 2022 # #, fuzzy msgid "" msgstr "" -"Project-Id-Version: ubl-settings-manager 1.0\n" -"Report-Msgid-Bugs-To: info@ublinux.com\n" -"POT-Creation-Date: 2023-04-21 12:33+0000\n" +"Project-Id-Version: ubl-settings-update 1.0\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2023-05-22 17:22+0600\n" "PO-Revision-Date: 2023-01-01 00:00+0600\n" "Last-Translator: UBLinux Team \n" "Language-Team: Russian - UBLinux Team \n" @@ -17,173 +17,236 @@ msgstr "" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -#: source/ubl-settings-update.c:16 -#, fuzzy -msgid "UBlinux System update" -msgstr "Обновление системы" +#: source/ubl-settings-update-strings.h:1 +msgid "Version:" +msgstr "Версия:" -#: source/ubl-settings-update.c:18 -#, fuzzy -msgid "Project Home Page" -msgstr "Домашняя страница проекта" +#: source/ubl-settings-update-strings.h:2 +msgid "ubl-settings-update version:" +msgstr "Версия ubl-settings-update: " -#: source/ubl-settings-update.c:19 -#, fuzzy -msgid "Update configurator" -msgstr "Загрузить локальную конфигурацию" +#: source/ubl-settings-update-strings.h:2 +msgid "update settings" +msgstr "Настройки обновлений" + +#: source/ubl-settings-update-strings.h:2 +msgid "Usage:" +msgstr "Использование:" + +#: source/ubl-settings-update-strings.h:2 +msgid "[OPTIONS]" +msgstr "[АРГУМЕНТЫ]" + +#: source/ubl-settings-update-strings.h:2 +msgid "Options:" +msgstr "Аргументы:" + +#: source/ubl-settings-update-strings.h:2 +msgid "Show this help" +msgstr "Показать параметры справки" + +#: source/ubl-settings-update-strings.h:2 +msgid "Show package version" +msgstr "Показать текущую версию" + +#: source/ubl-settings-update-strings.h:2 +msgid "Lock this help menu" +msgstr "Блокировка вызова справки" + +#: source/ubl-settings-update-strings.h:2 +msgid "Lock configuration saving" +msgstr "Блокировка сохранения локальной и глобальной конфигурации" + +#: source/ubl-settings-update-strings.h:2 +msgid "Lock local configration saving" +msgstr "Блокировка сохранения локальной конфигурации" + +#: source/ubl-settings-update-strings.h:2 +msgid "Lock global configration saving" +msgstr "Блокировка сохранения глобальной конфигурации" + +#: source/ubl-settings-update-strings.h:2 +msgid "Lock global configration loading" +msgstr "Блокировка загрузки глобальной конфигурации" -#: source/ubl-settings-update.c:46 source/ubl-settings-update.c:111 -#: source/ubl-settings-update.c:113 +#: source/ubl-settings-update-strings.h:3 msgid "System update" msgstr "Обновление системы" -#: source/ubl-settings-update.c:48 -msgid "Type: " -msgstr "Тип: " +#: source/ubl-settings-update-strings.h:4 +msgid "System update settings management" +msgstr "Настройка параметров обновления системы" -#: source/ubl-settings-update.c:49 -msgid "URI: " -msgstr "URI: " +#: source/ubl-settings-update-strings.h:5 +msgid "Check for updates" +msgstr "Проверить обновления" -#: source/ubl-settings-update.c:50 source/ubl-settings-update.c:52 -#: source/ubl-settings-update.c:54 -msgid " " -msgstr " " +#: source/ubl-settings-update-strings.h:6 +msgid "About" +msgstr "О программе" -#: source/ubl-settings-update.c:51 -msgid "Distribution: " -msgstr "Дистрибутив: " +#: source/ubl-settings-update-strings.h:7 +msgid "Documentation" +msgstr "Справка" -#: source/ubl-settings-update.c:53 -msgid "Sections: " -msgstr "Разделы: " +#: source/ubl-settings-update-strings.h:8 +msgid "Save to local configuration" +msgstr "Сохранить в локальную конфигурацию" -#: source/ubl-settings-update.c:56 -msgid "Cancel" -msgstr "Отмена" +#: source/ubl-settings-update-strings.h:9 +msgid "Save to global configuration" +msgstr "Сохранить в глобальную конфигурацию" + +#: source/ubl-settings-update-strings.h:10 +msgid "Save configuration" +msgstr "Сохранить в конфигурацию" -#: source/ubl-settings-update.c:57 source/ubl-settings-update.c:143 +#: source/ubl-settings-update-strings.h:11 +#: source/ubl-settings-update-strings.h:36 msgid "Save" msgstr "Сохранить" -#: source/ubl-settings-update.c:115 -msgid "General" -msgstr "Общие настройки" +#: source/ubl-settings-update-strings.h:12 +msgid "Load local configuration" +msgstr "Загрузить локальную конфигурацию" -#: source/ubl-settings-update.c:116 -msgid "Repositories" -msgstr "Репозитории" +#: source/ubl-settings-update-strings.h:13 +msgid "Load global configuration" +msgstr "Загрузить глобальную конфигурацию" -#: source/ubl-settings-update.c:117 -msgid "Extra" -msgstr "Дополнительно" +#: source/ubl-settings-update-strings.h:14 +msgid "load" +msgstr "Загрузить" -#: source/ubl-settings-update.c:119 -msgid "Update checking frequency" -msgstr "Частота проверки обновлений" +#: source/ubl-settings-update-strings.h:15 +msgid "Launch package manager" +msgstr "Запустить менеджер пакетов" -#: source/ubl-settings-update.c:120 -msgid "Hide icon of no updates found" -msgstr "Скрыть значок в трее при отсутствии обновлений" +#: source/ubl-settings-update-strings.h:16 +msgid "Cache clean command: " +msgstr "Команда очистки кеша пакетов: " -#: source/ubl-settings-update.c:121 -msgid "Download updates automatically" -msgstr "Автоматически скачивать обновления" +#: source/ubl-settings-update-strings.h:17 +msgid "Update command: " +msgstr "Команда обновления: " -#: source/ubl-settings-update.c:122 -msgid "Every 1 hour" -msgstr "Каждый час" +#: source/ubl-settings-update-strings.h:18 +msgid "Package manager: " +msgstr "Менеджер пакетов: " -#: source/ubl-settings-update.c:123 -msgid "Every 2 hours" -msgstr "Каждые 2 часа" +#: source/ubl-settings-update-strings.h:19 +msgid "URI" +msgstr "URI" -#: source/ubl-settings-update.c:124 -msgid "Every 3 hours" -msgstr "Каждые 3 часа" +#: source/ubl-settings-update-strings.h:20 +msgid "Enabled" +msgstr "Включен" -#: source/ubl-settings-update.c:126 -msgid "Activate AUR" -msgstr "Активировать AUR" +#: source/ubl-settings-update-strings.h:21 +msgid "Distribution" +msgstr "Дистрибутив" -#: source/ubl-settings-update.c:127 +#: source/ubl-settings-update-strings.h:22 msgid "Activate UBUR" msgstr "Активировать UBUR" -#: source/ubl-settings-update.c:128 -msgid "Create" -msgstr "Создать" +#: source/ubl-settings-update-strings.h:23 +msgid "Activate AUR" +msgstr "Активировать AUR" -#: source/ubl-settings-update.c:129 -msgid "Edit" -msgstr "Изменить" +#: source/ubl-settings-update-strings.h:24 +msgid "Every 3 hours" +msgstr "Каждые 3 часа" -#: source/ubl-settings-update.c:130 -msgid "Delete" -msgstr "Удалить" +#: source/ubl-settings-update-strings.h:25 +msgid "Every 2 hours" +msgstr "Каждые 2 часа" -#: source/ubl-settings-update.c:131 -msgid "Enabled" -msgstr "Включен" +#: source/ubl-settings-update-strings.h:26 +msgid "Every 1 hour" +msgstr "Каждый час" -#: source/ubl-settings-update.c:132 -#, fuzzy -msgid "URI" -msgstr "URI" +#: source/ubl-settings-update-strings.h:27 +msgid "Download updates automatically" +msgstr "Автоматически скачивать обновления" -#: source/ubl-settings-update.c:134 -msgid "Package manager: " -msgstr "Менеджер пакетов: " +#: source/ubl-settings-update-strings.h:28 +msgid "Hide icon of no updates found" +msgstr "Скрыть значок в трее при отсутствии обновлений" -#: source/ubl-settings-update.c:135 -msgid "Update command: " -msgstr "Команда обновления: " +#: source/ubl-settings-update-strings.h:29 +msgid "Update checking frequency" +msgstr "Частота проверки обновлений" -#: source/ubl-settings-update.c:136 -msgid "Cache clean command: " -msgstr "Команда очистки кеша пакетов: " +#: source/ubl-settings-update-strings.h:30 +msgid "Extra" +msgstr "Дополнительно" -#: source/ubl-settings-update.c:137 -msgid "Launch package manager" -msgstr "Запустить менеджер пакетов" +#: source/ubl-settings-update-strings.h:31 +msgid "Repositories" +msgstr "Репозитории" -#: source/ubl-settings-update.c:139 -msgid "load" -msgstr "Загрузить" +#: source/ubl-settings-update-strings.h:32 +msgid "General" +msgstr "Общие настройки" -#: source/ubl-settings-update.c:140 -msgid "Load global configuration" -msgstr "Загрузить глобальную конфигурацию" +#: source/ubl-settings-update-strings.h:33 +msgid "Adress: " +msgstr "Адрес: " -#: source/ubl-settings-update.c:141 -msgid "Load local configuration" -msgstr "Загрузить локальную конфигурацию" +#: source/ubl-settings-update-strings.h:34 +msgid "Distribution: " +msgstr "Дистрибутив: " -#: source/ubl-settings-update.c:144 -msgid "Save to global and local configuration" -msgstr "Сохранить в глобальную и локальную конфигурацию" +#: source/ubl-settings-update-strings.h:35 +msgid "Cancel" +msgstr "Отмена" -#: source/ubl-settings-update.c:145 -msgid "Save to global configuration" -msgstr "Сохранить в глобальную конфигурацию" +#: source/ubl-settings-update-strings.h:37 +msgid "Would you like to read documentation in the Web?" +msgstr "Вы хотите прочитать справку в Сети?" -#: source/ubl-settings-update.c:146 -msgid "Save to local configuration" -msgstr "Сохранить в локальную конфигурацию" +#: source/ubl-settings-update-strings.h:38 +msgid "" +"You will be redirected to documentation website where documentation is\n" +"translated and supported by community." +msgstr "" +"Вы будете перенаправлены на сайт с документацией где страницы помощи\n" +"переводятся и поддерживаются сообществом." -#: source/ubl-settings-update.c:148 -msgid "Documentation" +#: source/ubl-settings-update-strings.h:39 +msgid "Always redirect to online documentation" +msgstr "Всегда перенаправлять" + +#: source/ubl-settings-update-strings.h:40 +msgid "Open documentation" msgstr "Справка" -#: source/ubl-settings-update.c:149 -msgid "About" -msgstr "О программе" +#: source/ubl-settings-update-strings.h:41 +msgid "Project Home Page" +msgstr "Домашняя страница проекта" -#: source/ubl-settings-update.c:151 -msgid "Check for updates" -msgstr "Проверить обновления" +#: source/ubl-settings-update-strings.h:42 +msgid "Nothing were chosen" +msgstr "Ничего не выбрано" + +#: source/ubl-settings-update-strings.h:44 +msgid "Global configuration loading succseeded." +msgstr "Успешно загружена глобальная конфигурация" + +#: source/ubl-settings-update-strings.h:45 +msgid "Local configuration loading succseeded." +msgstr "Успешно загружена локальная конфигурация" + +#: source/ubl-settings-update-strings.h:47 +msgid "Local and global configuration saving succseeded." +msgstr "Успешно записаны локальная и глобальная конфигурация" + +#: source/ubl-settings-update-strings.h:48 +msgid "Global configuration saving succseeded." +msgstr "Успешно записана глобальная конфигурация" + +#: source/ubl-settings-update-strings.h:49 +msgid "Local configuration saving succseeded." +msgstr "Успешно записана локальная конфигурация" -#: source/ubl-settings-update.c:166 -#, fuzzy -msgid "System update parameter configuration" -msgstr "настройка параметров обновления системы" From 28f61b17cf6a5b5a3aaaf1bc35fbcf9a71813521 Mon Sep 17 00:00:00 2001 From: Ivan Yarcev Date: Tue, 23 May 2023 17:11:09 +0600 Subject: [PATCH 5/5] Debug flag removed --- source/CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/CMakeLists.txt b/source/CMakeLists.txt index ba44ab8..3c31c40 100644 --- a/source/CMakeLists.txt +++ b/source/CMakeLists.txt @@ -27,7 +27,7 @@ configure_file(ubl-settings-update.h.in ubl-settings-cmake.h) set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -pedantic -Wall -Wextra -Werror -Wmissing-declarations -fdiagnostics-color=always \ -O2 -pipe -fno-plt -fexceptions \ -Wp,-D_FORTIFY_SOURCE=2 -Wformat -Werror=format-security \ - -fstack-clash-protection -fcf-protection -g") + -fstack-clash-protection -fcf-protection") set(SOURCE_FILES ubl-settings-update.c