From 18b5433c43d355930f6a32b108ba76dd51c989d1 Mon Sep 17 00:00:00 2001 From: Ivan Yarcev Date: Thu, 27 Jul 2023 17:48:04 +0600 Subject: [PATCH 1/7] Rename --- .gitignore | 128 +- Makefile | 160 + com.ublinux.ublsettings-ui.checked.svg | 327 ++ com.ublinux.ublsettings-ui.policy | 24 + com.ublinux.ublsettings-ui.svg | 4957 ++++++++++++++++++++++++ com.ublinux.ublsettings-ui.warning.svg | 55 + gresource.xml | 12 + source/CMakeLists.txt | 95 + source/ubl-cmake.in | 1 + source/ublsettings-ui.c | 190 + source/ublsettings-ui.h | 109 + source/ublsettings-ui.pc.in | 10 + ubl-utils/CMakeLists.txt | 60 + ubl-utils/ubl-cmake.in | 1 + ubl-utils/ubl-utils.c | 1901 +++++++++ ubl-utils/ubl-utils.h | 364 ++ ubl-utils/ubl-utils.pc.in | 10 + ublsettings-ui-banner.png | Bin 0 -> 33872 bytes ublsettings-ui.css | 114 + ublsettings-ui.desktop | 15 + ublsettings-ui.glade | 766 ++++ ublsettings-ui.pot | 174 + ublsettings-ui_ru.po | 177 + 23 files changed, 9534 insertions(+), 116 deletions(-) create mode 100644 Makefile create mode 100644 com.ublinux.ublsettings-ui.checked.svg create mode 100644 com.ublinux.ublsettings-ui.policy create mode 100644 com.ublinux.ublsettings-ui.svg create mode 100644 com.ublinux.ublsettings-ui.warning.svg create mode 100644 gresource.xml create mode 100644 source/CMakeLists.txt create mode 100644 source/ubl-cmake.in create mode 100644 source/ublsettings-ui.c create mode 100644 source/ublsettings-ui.h create mode 100644 source/ublsettings-ui.pc.in create mode 100644 ubl-utils/CMakeLists.txt create mode 120000 ubl-utils/ubl-cmake.in create mode 100644 ubl-utils/ubl-utils.c create mode 100644 ubl-utils/ubl-utils.h create mode 100644 ubl-utils/ubl-utils.pc.in create mode 100644 ublsettings-ui-banner.png create mode 100644 ublsettings-ui.css create mode 100644 ublsettings-ui.desktop create mode 100644 ublsettings-ui.glade create mode 100644 ublsettings-ui.pot create mode 100644 ublsettings-ui_ru.po diff --git a/.gitignore b/.gitignore index 50e2ca3..4a609ef 100644 --- a/.gitignore +++ b/.gitignore @@ -1,116 +1,12 @@ -# ---> C -# Prerequisites -*.d - -# Object files -*.o -*.ko -*.obj -*.elf - -# Linker output -*.ilk -*.map -*.exp - -# Precompiled Headers -*.gch -*.pch - -# Libraries -*.lib -*.a -*.la -*.lo - -# Shared objects (inc. Windows DLLs) -*.dll -*.so -*.so.* -*.dylib - -# Executables -*.exe -*.out -*.app -*.i*86 -*.x86_64 -*.hex - -# Debug files -*.dSYM/ -*.su -*.idb -*.pdb - -# Kernel Module Compile Results -*.mod* -*.cmd -.tmp_versions/ -modules.order -Module.symvers -Mkfile.old -dkms.conf - -# ---> C++ -# Prerequisites -*.d - -# Compiled Object files -*.slo -*.lo -*.o -*.obj - -# Precompiled Headers -*.gch -*.pch - -# Compiled Dynamic libraries -*.so -*.dylib -*.dll - -# Fortran module files -*.mod -*.smod - -# Compiled Static libraries -*.lai -*.la -*.a -*.lib - -# Executables -*.exe -*.out -*.app - -# ---> CMake -CMakeLists.txt.user -CMakeCache.txt -CMakeFiles -CMakeScripts -Testing -Makefile -cmake_install.cmake -install_manifest.txt -compile_commands.json -CTestTestfile.cmake -_deps - -# ---> ArchLinuxPackages -*.tar -*.tar.* -*.jar -*.exe -*.msi -*.zip -*.tgz -*.log -*.log.* -*.sig - -pkg/ -src/ - +.vscode/ +ubl-settings-TEMPLATE +*~ +build/ +*compile/ +*# +terminal-commands/ +source/ubl-cmake.h +vgcore* +.BUILD.md +.updatebuild.sh +.install.sh \ No newline at end of file diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..aae2afb --- /dev/null +++ b/Makefile @@ -0,0 +1,160 @@ +#!/usr/bin/make -f + +#SHELL := /bin/bash +MAKEFILE_FILEPATH := $(abspath $(lastword $(MAKEFILE_LIST))) +MAKEFILE_DIR := $(notdir $(patsubst %/,%,$(dir $(MAKEFILE_FILEPATH)))) +MAKEFILE_PATH := $(dir $(MAKEFILE_FILEPATH)) + +CMAKE_UI_COMMAND = cmake +CMAKE_UTILS_COMMAND = cmake +CMAKE_UI_SOURCE_DIR = $(MAKEFILE_PATH)source +CMAKE_UTILS_SOURCE_DIR = $(MAKEFILE_PATH)ubl-utils +CMAKE_UI_BUILD_DIR = $(MAKEFILE_PATH)ui-compile +CMAKE_UTILS_BUILD_DIR = $(MAKEFILE_PATH)utils-compile +DEPENDS = /bin/cmake +PREFIX ?= /usr/local +PKGNAME = $(MAKEFILE_DIR) +FILE_VER = source/${PKGNAME}.h +PKGIDENT=$(subst /,-,${PREFIX}) + +default_target: all + +.PHONY: all init depend debug prepare check build uninstall install clean help + +all: init build + +init: + @echo "Initialize ..."; \ + if [ -d ".git" ]; then \ + LATEST_TAG=$$(git describe --abbrev=0 --tags | sed 's/^v//'); \ + if [ -z "$${LATEST_TAG}" ]; \ + then \ + LATEST_TAG=$$"0.0"; \ + echo "$${LATEST_TAG} is empty"; \ + fi; \ + else \ + LATEST_TAG="Development"; \ + fi; \ + sed -r "s/^(string version_application).*/\1 = \"$${LATEST_TAG}\";/" -i ${FILE_VER}; \ + echo "-- Build path: ${CMAKE_UI_BUILD_DIR}" + +depend: + @echo "Check depends ..." + @for FILE_DEPEND in $(DEPENDS); do \ + if [ ! -f $${FILE_DEPEND} ]; then \ + echo "ERROR: Depend '$${FILE_DEPEND}' not found !"; \ + exit 1; \ + fi; \ + done; \ + $(CMAKE_UI_COMMAND) -S$(CMAKE_UI_SOURCE_DIR) -B${CMAKE_UI_BUILD_DIR} --check-build-system CMakeFiles/Makefile.cmake 1 || exit 1; \ + $(CMAKE_UTILS_COMMAND) -S$(CMAKE_UTILS_SOURCE_DIR) -B${CMAKE_UTILS_BUILD_DIR} --check-build-system CMakeFiles/Makefile.cmake 1 || exit 1; \ + echo "Check depends: OK" + +debug: + @echo "Debug ..." + if [ ! -d ${CMAKE_UI_BUILD_DIR} ]; then \ + $(CMAKE_UI_COMMAND) -S${CMAKE_UI_SOURCE_DIR} -B${CMAKE_UI_BUILD_DIR} -DCMAKE_BUILD_TYPE=Debug -DCMAKE_INSTALL_PREFIX="${PREFIX}"; \ + fi; \ + echo "Debug: OK" + +prepare: + @echo "Prepare ..."; \ + if [ ! -d ${CMAKE_UI_BUILD_DIR} ]; then \ + $(CMAKE_UI_COMMAND) -S${CMAKE_UI_SOURCE_DIR} -B${CMAKE_UI_BUILD_DIR} -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX="${PREFIX}"; \ + $(CMAKE_UTILS_COMMAND) -S${CMAKE_UTILS_SOURCE_DIR} -B${CMAKE_UTILS_BUILD_DIR} -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX="${PREFIX}"; \ + fi; \ + echo "Prepare: OK" + +check: + @echo "Check ..."; \ + if [ -f ${CMAKE_UI_BUILD_DIR}/lib${PKGNAME}.so ]; then \ + echo "Check: OK"; \ + else \ + echo "Check: ${CMAKE_UI_BUILD_DIR}/lib${PKGNAME}.so not found !"; \ + exit 1; \ + fi + +build: depend prepare + @echo "Build ..."; \ + $(MAKE_COMMAND) --directory=${CMAKE_UI_BUILD_DIR}; \ + $(MAKE_COMMAND) --directory=${CMAKE_UTILS_BUILD_DIR}; \ + sed -r "s/^(string version_application).*/\1;/" -i ${FILE_VER}; \ + echo "Build: OK" + +uninstall: + @echo "Uninstall ..." + @for FILE_PO in $(wildcard *.po); do \ + LANG=$${FILE_PO##*_};LANG=$${LANG%.*}; \ + FILE_MO=$${FILE_PO##*/}; FILE_MO="$${FILE_MO%_*.po}.mo"; \ + PATH_FILE_MO="${DESTDIR}/usr/share/locale/$${LANG}/LC_MESSAGES/$${FILE_MO}"; \ + $(RM) "$${PATH_FILE_MO}"; \ + done + @for SIZE in 16x16 32x32 48x48 scalable; do \ + $(RM) "${DESTDIR}${PREFIX}/share/icons/hicolor/$${SIZE}/apps/com.ublinux.${PKGNAME}.svg"; \ + $(RM) "${DESTDIR}${PREFIX}/share/icons/hicolor/$${SIZE}/apps/com.ublinux.${PKGNAME}.png"; \ + done + @for FILE_SVG in $(wildcard *.svg); do \ + for SIZE in 16x16 32x32 48x48 scalable; do \ + $(RM) "${DESTDIR}${PREFIX}/share/icons/hicolor/$${SIZE}/status/$${FILE_SVG%.*}".{svg,png,jpg}; \ + done; \ + done + @$(RM) -r /usr/local/lib/libubl-utils.so* + @$(RM) -r /usr/local/lib/libublsettings-ui.a* + @$(RM) -r /usr/local/include/*ubl-utils.h* + @$(RM) -r /usr/local/include/*ublsettings-ui.h* + @$(RM) "${DESTDIR}${PREFIX}/share/applications/${PKGNAME}.desktop" + @$(RM) "${DESTDIR}${PREFIX}/share/icons/hicolor/scalable/apps/com.ublinux.${PKGNAME}.svg" + @$(RM) "${DESTDIR}/usr/share/polkit-1/actions/com.ublinux.${PKGNAME}${PKGIDENT}.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; \ + [ -d "${DESTDIR}${PREFIX}/share/applications" ] && touch "${DESTDIR}${PREFIX}/share/applications" &>/dev/null || true; \ + fi + @echo "Uninstall: OK" + +install: check uninstall + @echo "Install ..." + @for FILE_PO in $(wildcard *.po); do \ + LANG=$${FILE_PO##*_};LANG=$${LANG%.*}; \ + install -dm755 "${DESTDIR}/usr/share/locale/$${LANG}/LC_MESSAGES"; \ + FILE_MO=$${FILE_PO##*/}; FILE_MO="$${FILE_MO%_*.po}.mo"; \ + PATH_FILE_MO="${DESTDIR}/usr/share/locale/$${LANG}/LC_MESSAGES/$${FILE_MO}"; \ + echo "$${FILE_PO}"; \ + msgfmt "$${FILE_PO}" -v -f -o "$${PATH_FILE_MO}"; \ + done + @for SIZE in 16 32 48; do \ + install -dm755 "${DESTDIR}${PREFIX}/share/icons/hicolor/$${SIZE}x$${SIZE}/apps"; \ + rsvg-convert -w $${SIZE} -h $${SIZE} -f svg --keep-image-data "com.ublinux.${PKGNAME}.svg" -o "${DESTDIR}${PREFIX}/share/icons/hicolor/$${SIZE}x$${SIZE}/apps/com.ublinux.${PKGNAME}.svg"; \ + done + @install -Dm644 -t "${DESTDIR}${PREFIX}/share/icons/hicolor/scalable/apps/" "com.ublinux.${PKGNAME}.svg" + @install -Dm644 -t "${DESTDIR}${PREFIX}/share/icons/hicolor/scalable/status/" "com.ublinux.${PKGNAME}.checked.svg" + @install -Dm644 -t "${DESTDIR}${PREFIX}/share/icons/hicolor/scalable/status/" "com.ublinux.${PKGNAME}.warning.svg"; \ + $(MAKE_COMMAND) install --directory=${CMAKE_UI_BUILD_DIR}; \ + $(MAKE_COMMAND) install --directory=${CMAKE_UTILS_BUILD_DIR} + @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; \ + [ -d "${DESTDIR}${PREFIX}/share/applications" ] && touch "${DESTDIR}${PREFIX}/share/applications" &>/dev/null || true; \ + fi + @echo "Install: OK" + +clean: + @echo "Clean ..." + @$(RM) -rd ${CMAKE_UI_BUILD_DIR} + @$(RM) -rd ${CMAKE_UTILS_BUILD_DIR} + @if [ -d ${CMAKE_UI_BUILD_DIR} ]; then \ + echo "Clean: error, compile directory exist ${CMAKE_UI_BUILD_DIR}"; \ + else \ + echo "Clean: OK"; \ + fi + +help: + @echo "The following are some of the valid targets for this Makefile:"; \ + echo "... all (the default if no target is provided)"; \ + echo "... init"; \ + echo "... debug"; \ + echo "... prepare"; \ + echo "... compile"; \ + echo "... install"; \ + echo "... uninstall"; \ + echo "... clean" \ No newline at end of file diff --git a/com.ublinux.ublsettings-ui.checked.svg b/com.ublinux.ublsettings-ui.checked.svg new file mode 100644 index 0000000..e3cab42 --- /dev/null +++ b/com.ublinux.ublsettings-ui.checked.svg @@ -0,0 +1,327 @@ + + + + + + + + + + + + + + + + diff --git a/com.ublinux.ublsettings-ui.policy b/com.ublinux.ublsettings-ui.policy new file mode 100644 index 0000000..eaa2b92 --- /dev/null +++ b/com.ublinux.ublsettings-ui.policy @@ -0,0 +1,24 @@ + + + + + UBLinux + https://ublinux.ru + + + Run ublsettings-ui as root + Запуск утилиты ublsettings-ui с правами root + Authentication is required to run ublsettings-ui + Требуется авторизация для запуска утилиты ublsettings-ui с правами root + + auth_admin + auth_admin + auth_admin + + /usr/bin/ublsettings-ui + true + + + diff --git a/com.ublinux.ublsettings-ui.svg b/com.ublinux.ublsettings-ui.svg new file mode 100644 index 0000000..f636c26 --- /dev/null +++ b/com.ublinux.ublsettings-ui.svg @@ -0,0 +1,4957 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/com.ublinux.ublsettings-ui.warning.svg b/com.ublinux.ublsettings-ui.warning.svg new file mode 100644 index 0000000..9a90dba --- /dev/null +++ b/com.ublinux.ublsettings-ui.warning.svg @@ -0,0 +1,55 @@ + + + + + + image/svg+xml + + + + + + + + diff --git a/gresource.xml b/gresource.xml new file mode 100644 index 0000000..7861abe --- /dev/null +++ b/gresource.xml @@ -0,0 +1,12 @@ + + + + ublsettings-ui.glade + + + ublsettings-ui.css + + + ublsettings-ui-banner.png + + \ No newline at end of file diff --git a/source/CMakeLists.txt b/source/CMakeLists.txt new file mode 100644 index 0000000..042a36a --- /dev/null +++ b/source/CMakeLists.txt @@ -0,0 +1,95 @@ +cmake_minimum_required(VERSION 3.9) +project(ublsettings-ui VERSION 3.1) +include(GNUInstallDirs) + +find_package(PkgConfig REQUIRED) + +pkg_check_modules(GTK REQUIRED gtk+-3.0) +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-cmake.in ubl-cmake.h) + +file(COPY ${CMAKE_CURRENT_BINARY_DIR}/ubl-cmake.h DESTINATION ../compile) + +set(GRESOURCE_C resources.c) +set(GRESOURCE_XML gresource.xml) + +find_program(GLIB_COMPILE_RESOURCES NAMES glib-compile-resources REQUIRED) +add_custom_target(GLADE ublsettings-ui.glade) + +set(DEPENDFILES + ../ublsettings-ui.glade + ../gresource.xml + ../ublsettings-ui-banner.png + ../ublsettings-ui.css + ) + +file(COPY ${DEPENDFILES} DESTINATION ${CMAKE_CURRENT_BINARY_DIR}) + +add_custom_command( + OUTPUT ${GRESOURCE_C} + WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} + COMMAND ${GLIB_COMPILE_RESOURCES} + ARGS + --generate-source + --target=${CMAKE_CURRENT_BINARY_DIR}/${GRESOURCE_C} + ${GRESOURCE_XML} + VERBATIM + MAIN_DEPENDENCY ${GRESOURCE_XML} + DEPENDS + ${GLADE} +) +add_custom_target( + dummy-resource + DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/${GRESOURCE_C} +) + +#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") + +add_library(${PROJECT_NAME} SHARED + ublsettings-ui.c + ublsettings-ui.h) + + +set(LIBRARIES +${GTK_LIBRARIES} +${WEBKIT_LIBRARIES} +# ${VTE291_LIBRARIES} +pthread) + +target_include_directories(${PROJECT_NAME} PUBLIC ${PROJECT_BINARY_DIR}) + +target_link_libraries(${PROJECT_NAME} PUBLIC ${LIBRARIES}) + +set_target_properties(${PROJECT_NAME} PROPERTIES LINKER_LANGUAGE C) +set_target_properties(${PROJECT_NAME} PROPERTIES VERSION ${PROJECT_VERSION}) +set_target_properties(${PROJECT_NAME} PROPERTIES SOVERSION ${PROJECT_VERSION_MAJOR}) +set_target_properties(${PROJECT_NAME} PROPERTIES PUBLIC_HEADER ${PROJECT_NAME}.h) + +install(TARGETS ${PROJECT_NAME} + LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} + PUBLIC_HEADER DESTINATION ${CMAKE_INSTALL_INCLUDEDIR} +) +configure_file(${PROJECT_NAME}.pc.in ${CMAKE_BINARY_DIR}/${PROJECT_NAME}.pc @ONLY) +# Set pkg-config file to install. +install(FILES ${CMAKE_BINARY_DIR}/${PROJECT_NAME}.pc + DESTINATION ${CMAKE_INSTALL_LIBDIR}/pkgconfig +) \ No newline at end of file diff --git a/source/ubl-cmake.in b/source/ubl-cmake.in new file mode 100644 index 0000000..d4623a7 --- /dev/null +++ b/source/ubl-cmake.in @@ -0,0 +1 @@ +#cmakedefine WEBKIT_FOUND diff --git a/source/ublsettings-ui.c b/source/ublsettings-ui.c new file mode 100644 index 0000000..6062e11 --- /dev/null +++ b/source/ublsettings-ui.c @@ -0,0 +1,190 @@ +#include "ublsettings-ui.h" + + + +//signal emmit handlers - no header initialization + +/**on_close_subwindow(GtkWidget *self) + * [EN] + * Closes window in which [self] is contained. + * [RU] + * Закрывает окно, в котором расположен виджет [self]. +*/ +void on_close_subwindow(GtkWidget *self){ + gtk_widget_destroy(gtk_widget_get_toplevel(self)); +} + +/**yon_open_browser(GtkWidget *self, char *link) + * [EN] + * Opens browser with [link] link. + * [RU] + * Открывает браузер с [link] ссылкой. +*/ +void yon_open_browser(GtkWidget *self, char *link){ + yon_ubl_browser_window_open(link,app_information.app_name); +} + +/**on_open_documentation_confirmation(GtkWidget *self, char *link) + * [EN] + * Opens confirmation window for [link] link. + * [RU] + * Открывает окно подтверждение перехода по ссылке [link]. +*/ +void on_open_documentation_confirmation(GtkWidget *self, char *link){ + if (app_information.always_open_documentation==0){ + GtkBuilder *builder = gtk_builder_new_from_resource(ui_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),app_information.app_name); + 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); + } +} + +/**on_link(GtkWidget *self, char* uri, gpointer user_data) + * [EN] + * Signal for hadnling AboutDialog links. + * Connect to "activate-link" signal. + * [self] is AboutDialog window; + * [uri] is activated link; + * [user_data] is pointer for user data, hasn't used in standard handler; + * [RU] + * Функция для обработки сигнала нажатия на ссылку окна AboutDialog. + * Присоединять к сигналу "activate-link". + * [self] - окно AboutDialog; + * [uri] - ссылка, по которой совершается переход; + * [user_data] - указатель на любые другие данные, не используется в стандартном обработчике; +*/ +void on_link(GtkWidget *self, char* uri, gpointer user_data){ + gtk_widget_destroy(self); + on_open_documentation_confirmation(self,uri); +} + +/**on_about() + * [EN] + * Function for setting up and showing AboutDialog. + * Connect it to "activate" signal of Documentation MenuItem. + * [RU] + * Функиця для настройки и показа окна AboutDialog. + * Присоединять к сигналу "activate" кнопки справки типа MenuItem. +*/ +void on_about(){ + GtkBuilder *builder=gtk_builder_new_from_resource(ui_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_version(GTK_ABOUT_DIALOG(window),version_application); + gtk_about_dialog_set_comments(GTK_ABOUT_DIALOG(window),app_information.app_name); + gtk_label_set_text(GTK_LABEL(title),app_information.app_name); + 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); +} + +//functions + +void yon_load_proceed(char *command){ + if (yon_config_load_register(command)) + yon_ubl_status_box_render(LOCAL_SAVE_SUCCESS_LABEL,BACKGROUND_IMAGE_SUCCESS_TYPE); + else + yon_ubl_status_box_render(LOAD_FAILED_LABEL,BACKGROUND_IMAGE_FAIL_TYPE); + +} + +// standard functions + + +main_window *setup_window(){ + /* Widgets getting | Получение виджетов */ + main_window *widgets = malloc(sizeof(main_window)); + GtkBuilder *builder = gtk_builder_new_from_resource(ui_glade_path); + widgets->Window = yon_gtk_builder_get_widget(builder,"MainWindow"); + widgets->HatLabel = yon_gtk_builder_get_widget(builder,"headerTopic"); + widgets->PlugBox = yon_gtk_builder_get_widget(builder,"plugBox"); + + widgets->HeadOverlay = yon_gtk_builder_get_widget(builder,"HeadOverlay"); + widgets->HeadImage = yon_gtk_builder_get_widget(builder,"HeadBackgroundImage"); + widgets->HeadBox = yon_gtk_builder_get_widget(builder,"HeaderBox"); + widgets->HeadTitleLabel = yon_gtk_builder_get_widget(builder,"HeaderTitleLabel"); + widgets->HeadInfoLabel = yon_gtk_builder_get_widget(builder,"HeaderInfoLabel"); + + widgets->StatusBox = yon_gtk_builder_get_widget(builder,"mainStatusBox"); + widgets->StatusIcon = yon_gtk_builder_get_widget(builder,"mainStatusIcon"); + widgets->StatusLabel = yon_gtk_builder_get_widget(builder,"mainStatusLabel"); + + widgets->SaveLabel = yon_gtk_builder_get_widget(builder,"headerSaveConfigLabel"); + widgets->SaveMenuItem = yon_gtk_builder_get_widget(builder,"SaveGlobalLocalConfigurationMenuItem"); + widgets->SaveGlobalMenuItem = yon_gtk_builder_get_widget(builder,"SaveGlobalConfigurationMenuItem"); + widgets->SaveLocalMenuItem = yon_gtk_builder_get_widget(builder,"SaveLocalConfigurationMenuItem"); + widgets->RightBox = yon_gtk_builder_get_widget(builder,"HeaderRightBox"); + + widgets->LoadLabel = yon_gtk_builder_get_widget(builder,"headerLoadConfigLabel"); + widgets->LoadGlobalMenuItem = yon_gtk_builder_get_widget(builder,"LoadGlobalConfigurationMenuItem"); + widgets->LoadLocalMenuItem = yon_gtk_builder_get_widget(builder,"LoadLocalConfigurationMenuItem"); + widgets->LeftBox = yon_gtk_builder_get_widget(builder,"HeaderLeftBox"); + + widgets->DocumentationMenuItem = yon_ubl_menu_item_documentation_new(DOCUMENTATION_LABEL); + widgets->AboutMenuItem = yon_ubl_menu_item_about_new(ABOUT_LABEL); + + gtk_window_set_title(GTK_WINDOW(widgets->Window),app_information.app_name); + + GtkWidget *menu = yon_gtk_builder_get_widget(builder,"menu2"); + gtk_menu_shell_append(GTK_MENU_SHELL(menu),widgets->DocumentationMenuItem); + gtk_menu_shell_append(GTK_MENU_SHELL(menu),widgets->AboutMenuItem); + + /* Widget registration for config monitoring | Регистрация виджетов для мониторинга конфига */ + // yon_window_config_add_listener(widgets->HeadInfoLabel,"head-text","label",YON_TYPE_STRING); + + /* Signal connection | Присоединение сигналов */ + g_signal_connect(G_OBJECT(widgets->Window), "destroy", G_CALLBACK(gtk_main_quit), NULL); + g_signal_connect(G_OBJECT(widgets->DocumentationMenuItem),"activate",G_CALLBACK(on_open_documentation_confirmation),app_information.wiki_link); + g_signal_connect(G_OBJECT(widgets->AboutMenuItem),"activate",G_CALLBACK(on_about),NULL); + + + gtk_widget_show(widgets->Window); + return widgets; +} + +int yon_ubl_window_setup(GtkWidget *interface, char *app_name, char *app_description, char *locale){ + app_information.interface=interface; + app_information.app_name=app_name; + app_information.app_description=app_description; + app_information.app_locale=locale; +} + +main_window *yon_ubl_window_init(){ + local=setlocale(LC_ALL, ""); + textdomain (app_information.app_locale); + + + main_window *widgets = setup_window(); + yon_ubl_header_setup_resource(widgets->HeadOverlay,widgets->HeadBox,widgets->HeadImage,ui_banner_path); + + yon_ubl_status_box_setup(widgets->StatusIcon,widgets->StatusBox,widgets->StatusLabel); + if (getuid()!=0) + yon_ubl_status_box_render(ROOT_WARNING_LABEL,BACKGROUND_IMAGE_FAIL_TYPE); + else + yon_ubl_status_box_render(app_information.app_name,BACKGROUND_IMAGE_SUCCESS_TYPE); + yon_ubl_setup_sockets(widgets->PlugBox,widgets->LeftBox,widgets->RightBox,app_information.socket_id,app_information.load_socket_id,app_information.save_socket_id); + yon_window_config_setup(GTK_WINDOW(widgets->Window)); + yon_window_config_load(ui_config_path); + GtkCssProvider *css=gtk_css_provider_new(); + gtk_css_provider_load_from_resource(css,ui_CssPath); + gtk_style_context_add_provider_for_screen(gdk_screen_get_default(), + GTK_STYLE_PROVIDER(css), + -1); + return widgets; +} \ No newline at end of file diff --git a/source/ublsettings-ui.h b/source/ublsettings-ui.h new file mode 100644 index 0000000..5936f59 --- /dev/null +++ b/source/ublsettings-ui.h @@ -0,0 +1,109 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "../compile/ubl-cmake.h" +#ifdef WEBKIT_FOUND + #include +#endif + +#define ui_WIKI_LINK "https://wiki.ublinux.ru/ru/Программное_обеспечение/Программы_и_утилиты/Все/ublsettings-ui" + +#define _(String) gettext(String) + +#define ui_glade_path "/com/ublinux/ui/ublsettings-ui.glade" +#define ui_banner_path "/com/ublinux/images/ublsettings-ui-banner.png" +#define ui_CssPath "/com/ublinux/css/ublsettings-ui.css" +#define ui_config_path yon_char_unite(yon_ubl_user_get_home_directory(),"/.config/",app_information.app_locale,"/",app_information.app_locale,".conf",NULL) + +#define ui_LocalePath "/usr/share/locale" +#define ui_LocaleName "ublsettings-ui" +typedef char* string; +string version_application = "0.0"; + +char *local; + + +typedef struct { + GtkWidget *interface; + char *app_name; + char *app_description; + char *app_locale; + char *app_title; + char *wiki_link; + gboolean always_open_documentation; + int socket_id; + int load_socket_id; + int save_socket_id; +} app_info; + +static app_info app_information; + +typedef struct { + //Standard + GtkWidget *Window; + GtkWidget *HatLabel; + GtkWidget *PlugBox; + + GtkWidget *HeadOverlay; + GtkWidget *HeadImage; + GtkWidget *HeadBox; + GtkWidget *HeadTitleLabel; + GtkWidget *HeadInfoLabel; + + GtkWidget *StatusBox; + GtkWidget *StatusIcon; + GtkWidget *StatusLabel; + + GtkWidget *SaveLabel; + GtkWidget *SaveMenuItem; + GtkWidget *SaveGlobalMenuItem; + GtkWidget *SaveLocalMenuItem; + GtkWidget *RightBox; + + GtkWidget *LoadLabel; + GtkWidget *LoadGlobalMenuItem; + GtkWidget *LoadLocalMenuItem; + GtkWidget *LeftBox; + + GtkWidget *DocumentationMenuItem; + GtkWidget *AboutMenuItem; + // Custom +} main_window; + + +typedef struct { + GtkWidget *Window; + + GtkWidget *HatText; + GtkWidget *HeaderText; + GtkWidget *InfoText; + GtkWidget *AlwaysOpenCheck; + + GtkWidget *CloseButton; + GtkWidget *AcceptButton; +} documentation_confirmation_window; + + +#define GLOBAL_LOAD_SUCCESS_LABEL _("Global configuration loading succseeded.") +#define LOCAL_LOAD_SUCCESS_LABEL _("Local configuration loading succseeded.") +#define LOAD_FAILED_LABEL _("Config loading failed") + +#define GLOBAL_LOCAL_SAVE_SUCCESS_LABEL _("Local and global configuration saving succseeded.") +#define GLOBAL_SAVE_SUCCESS_LABEL _("Global configuration saving succseeded.") +#define LOCAL_SAVE_SUCCESS_LABEL _("Local configuration saving succseeded.") + +#define ABOUT_LABEL _("About") +#define DOCUMENTATION_LABEL _("Documentation") + +#define SUCCESS_LABEL _("Operation succeeded") +#define ROOT_WARNING_LABEL _("Warning! Application was launched without root - root-dependent actions are locked") + +main_window *yon_ubl_window_init(); +int yon_ubl_window_setup(GtkWidget *interface, char *app_name, char *app_description, char *locale); \ No newline at end of file diff --git a/source/ublsettings-ui.pc.in b/source/ublsettings-ui.pc.in new file mode 100644 index 0000000..a170ac9 --- /dev/null +++ b/source/ublsettings-ui.pc.in @@ -0,0 +1,10 @@ +prefix=@CMAKE_INSTALL_PREFIX@ +exec_prefix=@CMAKE_INSTALL_PREFIX@ +libdir=${exec_prefix}/@CMAKE_INSTALL_LIBDIR@ +includedir=${prefix}/@CMAKE_INSTALL_INCLUDEDIR@ +Name: @PROJECT_NAME@ +Description: @PROJECT_DESCRIPTION@ +Version: @PROJECT_VERSION@ +Requires: +Libs: -L${libdir} -l@PROJECT_NAME@ +Cflags: -I${includedir} \ No newline at end of file diff --git a/ubl-utils/CMakeLists.txt b/ubl-utils/CMakeLists.txt new file mode 100644 index 0000000..310149a --- /dev/null +++ b/ubl-utils/CMakeLists.txt @@ -0,0 +1,60 @@ +cmake_minimum_required(VERSION 3.9) +project(ubl-utils VERSION 3.1) +include(GNUInstallDirs) + +find_package(PkgConfig REQUIRED) + +pkg_check_modules(GTK REQUIRED gtk+-3.0) +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() + +file(COPY ${CMAKE_CURRENT_BINARY_DIR}/../ui-compile/ubl-cmake.h DESTINATION ./) + +#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") + +add_library(${PROJECT_NAME} SHARED + ubl-utils.c + ubl-utils.h) + + +set(LIBRARIES +${GTK_LIBRARIES} +${WEBKIT_LIBRARIES} +# ${VTE291_LIBRARIES} +pthread) + +target_include_directories(${PROJECT_NAME} PUBLIC ${PROJECT_BINARY_DIR}) + +target_link_libraries(${PROJECT_NAME} PUBLIC ${LIBRARIES}) + +set_target_properties(${PROJECT_NAME} PROPERTIES LINKER_LANGUAGE C) +set_target_properties(${PROJECT_NAME} PROPERTIES VERSION ${PROJECT_VERSION}) +set_target_properties(${PROJECT_NAME} PROPERTIES SOVERSION ${PROJECT_VERSION_MAJOR}) +set_target_properties(${PROJECT_NAME} PROPERTIES PUBLIC_HEADER ${PROJECT_NAME}.h) + +install(TARGETS ${PROJECT_NAME} + LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} + PUBLIC_HEADER DESTINATION ${CMAKE_INSTALL_INCLUDEDIR} +) +configure_file(${PROJECT_NAME}.pc.in ${CMAKE_BINARY_DIR}/${PROJECT_NAME}.pc @ONLY) +# Set pkg-config file to install. +install(FILES ${CMAKE_BINARY_DIR}/${PROJECT_NAME}.pc + DESTINATION ${CMAKE_INSTALL_LIBDIR}/pkgconfig +) \ No newline at end of file diff --git a/ubl-utils/ubl-cmake.in b/ubl-utils/ubl-cmake.in new file mode 120000 index 0000000..393ccdb --- /dev/null +++ b/ubl-utils/ubl-cmake.in @@ -0,0 +1 @@ +/home/superadmin/Документы/libublsettings-ui/source/ubl-cmake.in \ No newline at end of file diff --git a/ubl-utils/ubl-utils.c b/ubl-utils/ubl-utils.c new file mode 100644 index 0000000..0810a44 --- /dev/null +++ b/ubl-utils/ubl-utils.c @@ -0,0 +1,1901 @@ +#include "ubl-utils.h" + +// dictionary functions + +/**yon_dictionary_new(): + * [EN] + * Creates and returns empty dictionary + * [RU] + * Создаёт и возвращает пустой словарь. + */ +dictionary *yon_dictionary_new() +{ + 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; +} + +/**yon_dictionary_copy(dictionary *dict) + * [EN] + * + * [RU] + * Создаёт и возвращает копию элемента словаря [dict] +*/ +dictionary *yon_dictinoary_copy(dictionary *dict){ + dictionary *dct = yon_dictionary_new_with_data(dict->key,dict->data); + dct->data_type= dict->data_type; + return dct; +} + +/**yon_dictionary_copy_deep(dictionary *dict) + * [EN] + * + * [RU] + * Создаёт полную копию словаря [dict] и возвращает первый элемент +*/ +dictionary *yon_dictionary_copy_deep(dictionary *dict){ + dictionary *dct = NULL; + dictionary *newone=NULL; + for_dictionaries(dct,dict){ + yon_dictionary_add_or_create_if_exists_with_data(newone,dct->key,dct->data); + newone->data_type=dct->data_type; + } + return newone->first; +} + +/**int yon_dictionary_set_data(dictionary *dict, void *data) + * [EN] + * + * [RU] + * Установить элементу словаря [dict] значение [data] +*/ +int yon_dictionary_set_data(dictionary *dict, void *data){ + dict->data=data; +} + +/**int yon_dictionary_set_key(dictionary *dict, char *key) + * [EN] + * + * [RU] + * Изменяет ключ элемента словаря [dict] на [key] +*/ +int yon_dictionary_set_key(dictionary *dict, char *key){ + dict->key=key; + return 1; +} + +/** int yon_dictionary_set(dictionary *dict, char *key, void *data) + * [EN] + * + * [RU] +* Устанавливает значение ключа элемента словаря [dict] на [key] и его данные на [data] +*/ +int yon_dictionary_set(dictionary *dict, char *key, void *data){ + dict->key=key; + dict->data=data; + return 1; +} + +/**int yon_dictionary_empty(dictionary *dict) + * [EN] + * + * [RU] + * Очищает элемент словаря [dict] от данных +*/ +int yon_dictionary_empty(dictionary *dict){ + dict->data=NULL; + dict->data_type=DICTIONARY_OTHER_TYPE; + return 1; +} + +/**yon_dictionary_switch_to_last(dictionary **dict) + * [EN] + * + * [RU] + * Переключает словарь [dict] на последний элемент. +*/ +void yon_dictionary_switch_to_last(dictionary **dict) +{ + dictionary *dct=NULL, *dact=*dict; + for_dictionaries(dct,dact); +} + +/**yon_dictionary_create_conneced(dictionary *targetdict) + * [EN] + * + * [RU] + * Создаёт новый элемент словаря [targetdict] +*/ +dictionary *yon_dictionary_append(dictionary *targetdict) +{ + targetdict = yon_dictionary_get_last(targetdict); + targetdict->next = yon_dictionary_new(); + targetdict->next->prev = targetdict; + targetdict->next->first = targetdict->first; + targetdict->next->data_type = DICTIONARY_OTHER_TYPE; + return targetdict->next; +} + +/**yon_dictionary_get_last(dictionary *dict) + * [EN] + * + * [RU] + * Возвращает последний элемент словаря [dict]. + * В отличае от yon_dictionary_switch_to_last() + * словарь [dict] остаётся на прежнем элементе. +*/ +dictionary *yon_dictionary_get_last(dictionary *dict) +{ + if (dict->next){ + dictionary *dct = NULL; + for_dictionaries(dct,dict); + return dct; + } else return dict; +} + +/**yon_dictionary_switch_places(dictionary *dict, int aim) + * [EN] + * + * [RU] + * Меняет элемент словаря [dict] местами с другим элементом. + * если [aim]<0 элемент меняется местами с левым элементом; + * если [aim]>0 элемент меняется местами с правым элементом; +*/ +dictionary *yon_dictionary_swap(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 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; + } + 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; + } + } + } + } +} + +/**yon_dictionary_make_first(dictionary *dict) + * [EN] + * + * [RU] + * Устанавливает указатель первого элемента словаря [dict] + * на текущий элемент. Не использовать. +*/ +void yon_dictionary_make_first(dictionary *dict) +{ + for (dictionary *dct = dict->first; dct != NULL; dct = dct->next) + { + dct->first = dict; + } +} + +/**yon_dictionary_make_nth(dictionary *dict, int nth) + * [EN] + * + * [RU] + * Перемещает элемент словаря [dict] на позицию [nth]. +*/ +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; +} + +/**yon_dictionary_create_with_data(char *key, void *data) + * [EN] + * + * [RU] + * Создаёт новый словарь с ключом [key] и указателем на данные [data] +*/ +dictionary *yon_dictionary_new_with_data(char *key, void *data) +{ + dictionary *dct = yon_dictionary_new(); + dct->key = yon_char_new(key); + dct->data = data; + dct->data_type = DICTIONARY_OTHER_TYPE; + return dct; +} + +/** 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; +} + +/**yon_dictionary_create_with_data_connected(dictionary *dict, char *key, void *data) + * [EN] + * + * [RU] + * Создаёт новый элемент словаря, присоединяемый в конец словаря [dict] + * с ключом [key] и указателем на данные [data] +*/ +dictionary *yon_dictionary_append_with_data(dictionary *dict, char *key, void *data) +{ + dictionary *dct = yon_dictionary_append(dict); + dct->key = yon_char_new(key); + dct->data = data; + dct->data_type = DICTIONARY_OTHER_TYPE; + return dct; +} + +/**yon_dictionary_connect(dictionary *old, dictionary *toconnect) + * [EN] + * + * [RU] + * Присоединяет словарь [toconnect] в конец словаря [old]. +*/ +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; +} + +/**yon_dictionary_get(dictionary **dict, char *key) + * [EN] + * + * [RU] + * Возвращает элемент словаря [dict] с ключом [key]. + * Если такого элемента не было обнаружено, возвращается NULL +*/ +dictionary *yon_dictionary_get(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; +} + +/**yon_dictionary_rip(dictionary *dict) + * [EN] + * + * [RU] + * Вырезает элемент из словаря и возвращает вырезанный элемент. +*/ +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) + { + yon_dictionary_make_first(next); + next->prev = NULL; + return next; + } + else + return dict; + } + else + { + dictionary *next = dict->next, *prev = dict->prev; + next->prev = prev; + prev->next = next; + return next; + } +} + +/**yon_dictionary_get_nth(dictionary *dict, int place) + * [EN] + * + * [RU] + * Возвращает [place]-й элемент словаря [dict] +*/ +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 + +int yon_char_find_last(char *source, char find){ + int size = strlen(source); + int i=size; + for (;source[i]!=find&&i>0;i--); + return i; +} + +/**[EN] + * + * creates new char string by combining two char strings. + */ +char *yon_char_append(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 + return NULL; +} + +/**[EN] + * + * creates new char string by copying another char. + */ +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; +} + +/**yon_char_unite(char *source, ...) + * [En] + * + * [RU] + * Объединяет строку [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_append(new_char,unite_char); + unite_char = va_arg(arglist,char*); + } + va_end(arglist); + return new_char; +} + +/**yon_cut(char *source, int size, int startpos) + * [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); + return cut; +} + +/**yon_char_divide(char *source, int dividepos) + * [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)); + return cut; +} + +/**yon_char_find_count(char *source, char *find) + * [EN] + * + * [RU] + * Считает количество символов [find] в строке [source] +*/ +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 = g_malloc0(i * sizeof(char) + 1); + sprintf(ch, "%d", int_to_convert); + return ch; +} + +/**yon_char_replace(char *source, char *find, char*replace) + * [EN] + * + * [RU] + * Заменяет в строке [source] все вхождения строки [find] на [replace] +*/ +char *yon_char_replace(char *source, char *find, char*replace){ + if (!strstr(replace,find)){ + + + 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_append(temp,replace); + source=yon_char_append(temp,final+1); + } + + } + } + return source; +} + +/**yon_char_parse(char *parameters, int *size, char *divider) + * [EN] + * Parses string [parameters], divided by [divider], + * then returns parsed string array and sets [size] to + * size of returned array +*/ +char **yon_char_parse(char *parameters, int *size, char *divider){ + char **string=NULL; + int i=1; + 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; + } + string=realloc(string,sizeof(char*)*i); + string[i-1]=yon_char_new(paramline); + i++; + // printf("%d\n",i); + *size=i-1; + return string; + +} + +/**yon_char_parsed_rip(char **char_string, int *size, int item_to_delete) + * [EN] + * + * [RU] + * Удаляет элемент [item_to_delete] из массива строк [char_string], размера [size] + * Возвращает получившийся массив, в [size] загружается размер нового массива. +*/ +char **yon_char_parsed_rip(char **char_string, int *size, int item_to_delete){ + char **new_char_parsed=NULL; + new_char_parsed=malloc(sizeof(char*)*((*size)-1)); + int flag = 0; + for (int i=0;i < (*size);i++){ + if (i==item_to_delete) { + flag = 1; + } + if (flag == 0) { + new_char_parsed[i]=yon_char_new(char_string[i]); + } + else if (flag == 1 && i!=item_to_delete) { + new_char_parsed[i-1]=yon_char_new(char_string[i]); + } + } + (*size)=(*size)-1; + return new_char_parsed; +} + +/**yon_char_parsed_check_exist(char **parameters, int size, char *param) + * [EN] + * Checks if [parameters] string array of length [size] + * has [param] element; + * [RU] + * Проверяет есть ли в массиве строк [parameters], размера [size] + * элемент [param] +*/ +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 *extension = strstr(path, "."); + if (extension != NULL) + { + 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); + } + 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; + size++; + } + } + } + } + } + } + *sizef = size; + return applist; +}; + +void yon_apps_sort(apps *applist, int size) +{ + apps tmp; + if (size > 2) + { + for (int i = 1; i < size; i++) + { + for (int j = 1; j < size; j++) + { + if (strcmp(applist[j].Name, applist[j - 1].Name) < 0) + { + tmp = applist[j]; + applist[j] = applist[j - 1]; + applist[j - 1] = tmp; + }; + } + }; + } +}; + +apps *yon_apps_get_by_name(apps *applist, char *name, int size) +{ + for (int i = 0; i < size; i++) + { + if (strcmp(applist[i].Name, name) == 0) + return &applist[i]; + } + return NULL; +}; + +//config functions + +/**yon_config_load_register(char *command) + * [EN] + * + * [RU] + * Выполняет команду [command]. + * Полученные данные парсятся и регистрируются в конфиг. +*/ +int yon_config_load_register(char *command){ + if (__yon__config__strings){ + __yon__config__strings = yon_dictionary_free_all(__yon__config__strings,NULL); + } + FILE *output = popen(command, "r"); + char **output_strings = NULL; + output_strings = malloc(sizeof(char)); + int i = 0; + char str[4096]; + memset(str, 0, 4096); + while (fgets(str, 4096, output)) + { + if (strcmp(str, "") != 0&& strcmp(str,"(null)\n")!=0) + { + char *key = yon_char_divide_search(str,"=",-1); + yon_dictionary_add_or_create_if_exists_with_data(__yon__config__strings,key,str); + __yon__config__strings->data_type=DICTIONARY_CHAR_TYPE; + } + } + check_config + return 0; + else return 1; +} + +/**yon_config_remove_by_key(char *key) + * [EN] + * + * [RU] + * Удаляет параметр конфига по ключу [key] +*/ +int yon_config_remove_by_key(char *key){ + check_config{ + dictionary *dict = yon_dictionary_get(&__yon__config__strings,key); + if (dict){ + yon_dictionary_rip(dict); + return 1; + }else return 0; + } + return 0; +} + +/**yon_config_remove_by_data(void *data) + * [EN] + * + * [RU] + * Производит поиск по конфигу на наличие параметра со значением [data] и удаляет найденное значение из конфига. +*/ +int yon_config_remove_by_data(void *data){ + check_config{ + dictionary *dict = NULL; + for_dictionaries(dict,__yon__config__strings){ + if (dict->data==data){ + yon_dictionary_rip(dict); + return 1; + } + } + return 0; + } + return 0; +} + +/**yon_config_remove_element(char *key, char *deleted) + * [EN] + * + * [RU] + * Удаляет элемент [deleted] из массива параметров с ключом [key] +*/ +int yon_config_remove_element(char *key, char *deleted){ + check_config{ + dictionary *dict = yon_dictionary_get(&__yon__config__strings,key); + char *data = (char*)dict->data; + char *found = strstr(data,deleted); + int size=strlen(data)-strlen(found)+1; + char *new_data = malloc(size); + memset(new_data,0,size); + if (strlen(found)!=strlen(deleted)){ + memcpy(new_data,data,size-1); + new_data = yon_char_append(new_data,found+strlen(deleted)+1); + } else { + memcpy(new_data,data,size-2); + new_data = yon_char_append(new_data,found+strlen(deleted)); + } + dict->data=(void*)(new_data); + free(data); + dict->flag1=1; + return 1; + } else return 0; +} + +/**yon_config_get_by_key(char *key) + * [EN] + * + * [RU] + * Возвращает значение параметра конфига с ключом [key] +*/ +void *yon_config_get_by_key(char *key){ + check_config{ + dictionary *dict = NULL; + for_dictionaries(dict, __yon__config__strings){ + if (strcmp(dict->key,key)==0){ + return dict->data; + } + } + } + return NULL; +} + +/**yon_config_get_key_by_data(char *data) + * [EN] + * + * [RU] + * Возвращает ключ параметра конфига со значением [data]. + * Если параметр с таким значением не найден, возвращается NULL +*/ +char *yon_config_get_key_by_data(char *data){ + check_config{ + dictionary *dict = NULL; + for_dictionaries(dict, __yon__config__strings){ + if (strcmp(((char*)dict->data),data)==0){ + return dict->key; + } + } + } + return NULL; +} + +/**yon_config_set(char *key, void *data) + * [EN] + * + * [RU] + * Производит поиск по конфигу и заменяет значение параметра с ключом [key] на новое значение [data]; +*/ +int yon_config_set(char *key, void *data){ + check_config{ + dictionary *dict = yon_dictionary_get(&__yon__config__strings,key); + dict->data=data; + return 1; + } else return 0; +} + +/**yon_config_clean() + * [EN] + * Erase all parameters from config; + * [RU] + * Удаляет все параметры из конфига; +*/ +int yon_config_clean(){ + check_config{ + __yon__config__strings = yon_dictionary_free_all(__yon__config__strings, NULL); + return 1; + } + else return 0; +} + +/**yon_config_register(char *key, void *data) + * [EN] + * + * [RU] + * Регистрирует новый параметр конфига. + * [key] - ключ параметра; + * [data] - значение параметра; +*/ +void yon_config_register(char *key, void *data){ + yon_dictionary_add_or_create_if_exists_with_data(__yon__config__strings,key,data); + __yon__config__strings->data_type=DICTIONARY_CHAR_TYPE; +} + +/**yon_config_load(char *command, int *str_len) + * [EN] + * + * [RU] + * Выполняет команду [command] и возвращает распаршеный результат выполнения команды. + * В [str_len] возвращается длина возвращаемого массива +*/ +config_str yon_config_load(char *command, int *str_len){ + FILE *output = popen(command, "r"); + char **output_strings = NULL; + output_strings = malloc(sizeof(char)); + int i = 0; + char str[4096]; + memset(str, 0, 4096); + while (fgets(str, 4096, output)) + { + if (strcmp(str, "") != 0) + { + output_strings = realloc(output_strings, sizeof(char *) * (i + 1)); + // printf("%s\n", str); + output_strings[i] = NULL; + output_strings[i] = yon_char_new(str); + memset(str, 0, 4096); + i++; + } + } + if (i>0){ + *str_len = i; + return output_strings; + } else{ + *str_len=-1; + return NULL; + } +} + +/**int yon_config_save(char *command) + * [EN] + * Saves config with [command] + * [RU] + * Выполняет команду [command], добавляя в конец все записи конфига в таком виде: + * [ПАРАМЕТР1]="[значения1]" [ПАРАМЕТР2]="[значения2]" +*/ +int yon_config_save_registered(char *command){ + check_config{ + dictionary *dict = NULL; + for_dictionaries(dict,__yon__config__strings){ + command = yon_char_unite(command, " ", yon_dictionary_get_data(dict,char*), NULL); + } + if (popen(command, "r")) return 1; + else return 0; + } else return 0; +} + +/**yon_config_get_all(int *size) + * [EN] + * + * [RU] + * Возвращает массив со всеми параметрами конфига, оканчивающаяся NULL + * [size] - указатель, в который выгружается длина массива +*/ +config_str yon_config_get_all(int *size){ + check_config{ + *size = 1; + config_str conf = NULL; + dictionary *dict = NULL; + for_dictionaries(dict,__yon__config__strings){ + conf = yon_remalloc(conf,sizeof(char*)*(*size)); + conf[(*size)-1] = yon_char_unite(dict->key,"=",(char*)dict->data,NULL); + size++; + } + conf = yon_remalloc(conf,sizeof(char*)*(*size+1)); + conf[*size] = NULL; + return conf; + } else return NULL; +} + +/**char *yon_config_get_parameter(config parameters, int size, char *param) + * [EN] + * Gets parameter [param] from parameter list [parameters] of size [size]; + * or NULL if nothing were found + * [RU] + * Возвращает параметр [param] из массива строк [parameters] размером [size] + * или NULL если такой не был найден +*/ +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; +} + + + +// terminal-using functions + +/**yon_launch_app_with_arguments(char *name, char *args) + * [EN] + * Execute [command] in separate thread; + * [RU] + * Выполнить команду [command] в отдельном потоке; +*/ +int yon_launch_app_with_arguments(char *name, char *args) +{ + char *path = yon_char_unite("/usr/bin/", name, " ", args,NULL); + pthread_t thread_id; + char *command = NULL; + command = path; + pthread_create(&thread_id, NULL, (void *)yon_launch, command); +}; + +/**yon_launch(char *command) + * [EN] + * Execute command [command] + * [RU] + * Выполнить команду [command] +*/ +void yon_launch(char *command) +{ + system(command); +} + +// Gtk functions + + +#ifdef __GTK_H__ + + +static render_data render; + +#ifdef VTE_TERMINAL + +static void child_ready(VteTerminal *terminal, GPid pid, GError *error, gpointer user_data) +{ + if (!terminal) return; + if (pid == -1) printf("Error\n\n\n"); + else vte_terminal_feed_child(VTE_TERMINAL(terminal),(char*)user_data,strlen((char*)user_data)); +} + +/** + * 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]. +*/ +void yon_terminal_integrated_launch(GtkWidget *place_to_show, char* command, void *endwork_function, void* endwork_function_argument){ + char **commands=new_arr(char*,2); + gchar **envp = g_get_environ(); + commands[0]=(gchar *)g_strdup(g_environ_getenv(envp, "SHELL")); + commands[1]=NULL; + char **env=new_arr(char*,2); + env[0]=""; + env[1]=NULL; + 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); + gtk_container_add(GTK_CONTAINER(place_to_show),terminal); + char *install_command=yon_char_unite("tput cup 0 0 && tput ed; ",command," ; sleep 5;exit 0","\n",NULL); + printf("%s\n",install_command); + if(endwork_function) + g_signal_connect(G_OBJECT(terminal), "child-exited", G_CALLBACK(endwork_function), endwork_function_argument); + vte_terminal_spawn_async(VTE_TERMINAL(terminal), + VTE_PTY_DEFAULT, + NULL, + commands, + NULL, + 0, + NULL, NULL, + NULL, + -1, + NULL, + child_ready, + install_command); + vte_pty_spawn_async(pty, + NULL, + commands, + NULL, + 0, + NULL, NULL, + NULL, + -1, + NULL, + NULL, + NULL); + vte_terminal_set_scrollback_lines(VTE_TERMINAL(terminal), -1); + vte_terminal_set_scroll_on_output(VTE_TERMINAL(terminal), TRUE); + vte_terminal_set_scroll_on_keystroke(VTE_TERMINAL(terminal), TRUE); + gtk_widget_show_all(terminal); + } + +/**yon_terminal_integrated_start(GtkWidget *terminal, char* command, 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]. +*/ +void yon_terminal_integrated_start(GtkWidget *terminal, char* command, void *endwork_function, void* endwork_function_argument){ + char **commands=new_arr(char*,2); + gchar **envp = g_get_environ(); + commands[0]=(gchar *)g_strdup(g_environ_getenv(envp, "SHELL")); + commands[1]=NULL; + char **env=new_arr(char*,2); + env[0]=""; + env[1]=NULL; + 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); + if(endwork_function) + g_signal_connect(G_OBJECT(terminal), "child-exited", G_CALLBACK(endwork_function), endwork_function_argument); + vte_terminal_spawn_async(VTE_TERMINAL(terminal), + VTE_PTY_DEFAULT, + NULL, + commands, + NULL, + 0, + NULL, NULL, + NULL, + -1, + NULL, + child_ready, + install_command); + vte_pty_spawn_async(pty, + NULL, + commands, + 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(terminal); + } +#endif + + // Window config functions + + #define check_window_config_setup if(__yon_window_config_target_window) + + typedef struct { + char *parameter_name; + enum YON_TYPE containing_type; + GtkWidget *track_widget; + char *property_name; + } __yon_listener_parameter; + + typedef struct { + char *parameter_name; + char *section; + enum YON_TYPE containing_type; + void *property; + } __yon_custom_parameter; + + struct { + int x; + int y; + int width; + int height; + int fullscreen; + dictionary *custom_listeners; + dictionary *custom_parameters; + dictionary *deleted_parameters; + } __yon_main_window_config; + + static GtkWindow *__yon_window_config_target_window = NULL; + static GKeyFile *__yon_window_config_file = NULL; + static char *__yon_window_config_path = NULL; + + void yon_window_config_save(){ + g_key_file_set_integer(__yon_window_config_file,"window","WindowPosX",__yon_main_window_config.x); + g_key_file_set_integer(__yon_window_config_file,"window","WindowPosY",__yon_main_window_config.y); + g_key_file_set_integer(__yon_window_config_file,"window","WindowWidth",__yon_main_window_config.width); + g_key_file_set_integer(__yon_window_config_file,"window","WindowHeight",__yon_main_window_config.height); + g_key_file_set_integer(__yon_window_config_file,"window","fullscreen",__yon_main_window_config.fullscreen); + dictionary *dict=NULL; + if (__yon_main_window_config.custom_listeners) + for_dictionaries(dict,__yon_main_window_config.custom_listeners){ + __yon_listener_parameter *param = yon_dictionary_get_data(dict,__yon_listener_parameter*); + GValue *val = g_malloc0(sizeof(GValue)); + g_object_get_property(G_OBJECT(param->track_widget),param->property_name,val); + switch(param->containing_type){ + case YON_TYPE_STRING: + g_key_file_set_string(__yon_window_config_file,"window",param->parameter_name, g_value_get_string(val)); + break; + case YON_TYPE_INT: + g_key_file_set_integer(__yon_window_config_file,"window",param->parameter_name, g_value_get_int(val)); + break; + case YON_TYPE_BOOLEAN: + g_key_file_set_boolean(__yon_window_config_file,"window",param->parameter_name, g_value_get_boolean(val)); + break; + case YON_TYPE_OTHER:printf("\033[0;31mCannot save %s property with %s key\033[0m\n",param->property_name,param->parameter_name);break; + } + } + if (__yon_main_window_config.custom_parameters) + for_dictionaries(dict,__yon_main_window_config.custom_parameters){ + __yon_custom_parameter *param = yon_dictionary_get_data(dict,__yon_custom_parameter*); + switch (param->containing_type){ + case YON_TYPE_STRING: + g_key_file_set_string(__yon_window_config_file,param->section,param->parameter_name, (char*)param->property); + break; + case YON_TYPE_INT: + g_key_file_set_integer(__yon_window_config_file,param->section,param->parameter_name, *(int*)param->property); + break; + case YON_TYPE_BOOLEAN: + g_key_file_set_boolean(__yon_window_config_file,param->section,param->parameter_name, *(gboolean*)param->property); + break; + default: + break; + } + } + if (__yon_main_window_config.deleted_parameters) + for_dictionaries(dict,__yon_main_window_config.deleted_parameters){ + __yon_custom_parameter *param = yon_dictionary_get_data(dict,__yon_custom_parameter*); + g_key_file_remove_key(__yon_window_config_file,param->section,param->parameter_name,NULL); + } + g_key_file_save_to_file(__yon_window_config_file,__yon_window_config_path,NULL); + } + + void yon_get_is_fullscreen(){ + gtk_window_is_maximized(__yon_window_config_target_window); + __yon_main_window_config.fullscreen = gtk_window_is_maximized(__yon_window_config_target_window); + if (!__yon_main_window_config.fullscreen) gtk_window_get_position(__yon_window_config_target_window,&__yon_main_window_config.x,&__yon_main_window_config.y); + } + + /**yon_on_configured_window_destroy(GtkWidget* self,GdkEvent* event) + * [EN] + * + * [RU] + * Сохраняет настройки основного окна. Вызывается когда основное окно уничтожается. + */ + void yon_on_configured_window_destroy(GtkWidget* self,GdkEvent* event){ + check_window_config_setup{ + yon_get_is_fullscreen(); + yon_window_config_save(); + } + gtk_main_quit(); + } + + void __yon_window_config_on_resize(){ + int max=0; + max=gtk_window_is_maximized(__yon_window_config_target_window); + if(max==0){ + gtk_window_get_size(__yon_window_config_target_window,&__yon_main_window_config.width,&__yon_main_window_config.height); + gtk_window_get_position(__yon_window_config_target_window,&__yon_main_window_config.x,&__yon_main_window_config.y); + } + } + + /**yon_window_config_setup(GtkWindow *window) + * [EN] + * + * [RU] + * Устанавливает указатель на окно для отслеживания его положения и размера + */ + void yon_window_config_setup(GtkWindow *window){ + __yon_window_config_target_window = window; + g_signal_connect(G_OBJECT(window),"delete-event",G_CALLBACK(yon_on_configured_window_destroy),NULL); + g_signal_connect(G_OBJECT(window),"check-resize"/*"configure-event"*/,G_CALLBACK(__yon_window_config_on_resize),NULL); + } + + void _yon_maximize(void *data){ + g_usleep(G_USEC_PER_SEC/10); + if(__yon_main_window_config.fullscreen ==1) gtk_window_maximize(__yon_window_config_target_window); + } + + /**yon_window_config_load(char *path) + * [EN] + * + * [RU] + * Загружает конфиг окна и инициализирует отслеживание его параметров + */ + int yon_window_config_load(char *path){ + __yon_window_config_file = g_key_file_new(); + __yon_window_config_path=yon_char_new(path); + if (!g_key_file_load_from_file(__yon_window_config_file,__yon_window_config_path,G_KEY_FILE_NONE,NULL)){ + struct stat st; + int size; + config_str conf = yon_char_parse(yon_char_new(__yon_window_config_path),&size,"/"); + char *path = yon_char_unite(conf[0],"/",conf[1],"/",conf[2],"/",conf[3],"/",conf[4],"/",NULL); + if (stat(path, &st) == -1) { + mkdir(path, 0777); + } + FILE *fp; + fp=fopen(__yon_window_config_path,"w"); + fclose(fp); + g_key_file_load_from_file(__yon_window_config_file,__yon_window_config_path,G_KEY_FILE_NONE,NULL); + } + __yon_main_window_config.x = g_key_file_get_integer(__yon_window_config_file,"window","WindowPosX",NULL); + __yon_main_window_config.y = g_key_file_get_integer(__yon_window_config_file,"window","WindowPosY",NULL); + __yon_main_window_config.width = g_key_file_get_integer(__yon_window_config_file,"window","WindowWidth",NULL); + __yon_main_window_config.height = g_key_file_get_integer(__yon_window_config_file,"window","WindowHeight",NULL); + __yon_main_window_config.fullscreen = g_key_file_get_integer(__yon_window_config_file,"window","fullscreen",NULL); + dictionary *dict=NULL; + if (__yon_main_window_config.custom_listeners) + for_dictionaries(dict,__yon_main_window_config.custom_listeners){ + __yon_listener_parameter *param = yon_dictionary_get_data(dict,__yon_listener_parameter*); + GValue *val = g_malloc0(sizeof(GValue)); + g_object_get_property(G_OBJECT(param->track_widget),param->property_name,val); + switch(param->containing_type){ + case YON_TYPE_STRING: + g_value_set_string(val,g_key_file_get_string(__yon_window_config_file,"window",param->parameter_name, NULL)); + break; + case YON_TYPE_INT: + g_value_set_int(val,g_key_file_get_integer(__yon_window_config_file,"window",param->parameter_name, NULL)); + break; + case YON_TYPE_BOOLEAN: + gboolean res = g_key_file_get_boolean(__yon_window_config_file,"window",param->parameter_name, NULL); + g_value_set_boolean(val,res); + break; + default:printf("\033[0;31mCannot load %s property with %s key\033[0m\n",param->property_name,param->parameter_name);break; + } + g_object_set_property(G_OBJECT(param->track_widget),param->property_name,val); + } + if (__yon_main_window_config.width==0) __yon_main_window_config.width=800; + if (__yon_main_window_config.height==0) __yon_main_window_config.height=600; + gtk_window_resize(__yon_window_config_target_window,__yon_main_window_config.width,__yon_main_window_config.height); + gtk_window_move(__yon_window_config_target_window,__yon_main_window_config.x,__yon_main_window_config.y); + pthread_t tid; + pthread_create(&tid,NULL,(void *)_yon_maximize,NULL); + return 1; + } + + void yon_window_config_apply(){ + dictionary *dict=NULL; + gtk_window_move(__yon_window_config_target_window,__yon_main_window_config.x,__yon_main_window_config.y); + gtk_window_resize(__yon_window_config_target_window,__yon_main_window_config.width,__yon_main_window_config.height); + } + + config_str yon_window_config_get_section(char *section, gsize *size){ + config_str key = g_key_file_get_keys(__yon_window_config_file,section,size,NULL); + return key; + } + + /**yon_window_config_add_custom_parameter(GtkWidget *widget, char *param_name, char *widget_property) + * [EN] + * + * [RU] + * Добавляет параметр виджета [widget] по названию [widget_property] для отслеживания и сохраняет его в конфиг под ключом [param_name]. + */ + void yon_window_config_add_listener(GtkWidget *widget, char *param_name, char *widget_property, enum YON_TYPE val_type){ + __yon_listener_parameter *param = NULL; + param = yon_remalloc(param,sizeof(__yon_listener_parameter)); + param->parameter_name = yon_char_new(param_name); + param->track_widget = widget; + param->property_name = yon_char_new(widget_property); + param->containing_type = val_type; + yon_dictionary_add_or_create_if_exists_with_data(__yon_main_window_config.custom_listeners,param->parameter_name,param); + } + + void yon_window_config_add_custom_parameter(char *param_name, char *section, void *tracked_value, enum YON_TYPE val_type){ + __yon_custom_parameter *param = NULL; + param = yon_remalloc(param,sizeof(__yon_custom_parameter)); + param->parameter_name = yon_char_new(param_name); + param->section=section; + param->property = tracked_value; + param->containing_type = val_type; + yon_dictionary_add_or_create_if_exists_with_data(__yon_main_window_config.custom_parameters,param->parameter_name,param); + } + + void yon_window_config_erase_custom_parameter(char *param_name, char *section){ + __yon_custom_parameter *param = NULL; + param = yon_remalloc(param,sizeof(__yon_custom_parameter)); + param->parameter_name=param_name; + param->section=section; + yon_dictionary_add_or_create_if_exists_with_data(__yon_main_window_config.deleted_parameters,param->parameter_name,param); + } + +GtkWidget *yon_ubl_menu_item_about_new(char *buttonname){ + GtkWidget *menu_item = gtk_menu_item_new(); + gtk_style_context_add_class(gtk_widget_get_style_context(menu_item),"menuitembottom"); + GtkWidget *box = gtk_box_new(GTK_ORIENTATION_HORIZONTAL,0); + GtkWidget *label = gtk_label_new(buttonname); + GtkWidget *image = gtk_image_new_from_icon_name("dialog-information-symbolic",GTK_ICON_SIZE_BUTTON); + gtk_label_set_xalign(GTK_LABEL(label),0.0); + gtk_box_pack_start(GTK_BOX(box),image,0,0,5); + gtk_box_pack_start(GTK_BOX(box),label,0,0,5); + gtk_container_add(GTK_CONTAINER(menu_item),box); + gtk_widget_show_all(menu_item); + return menu_item; +} + +GtkWidget *yon_ubl_menu_item_documentation_new(char *buttonname){ + GtkWidget *menu_item = gtk_menu_item_new(); + gtk_style_context_add_class(gtk_widget_get_style_context(menu_item),"menuitemtop"); + GtkWidget *box = gtk_box_new(GTK_ORIENTATION_HORIZONTAL,0); + GtkWidget *label = gtk_label_new(buttonname); + GtkWidget *image = gtk_image_new_from_icon_name("dialog-question-symbolic",GTK_ICON_SIZE_BUTTON); + gtk_label_set_xalign(GTK_LABEL(label),0.0); + gtk_box_pack_start(GTK_BOX(box),image,0,0,5); + gtk_box_pack_start(GTK_BOX(box),label,0,0,5); + gtk_container_add(GTK_CONTAINER(menu_item),box); + gtk_widget_show_all(menu_item); + return menu_item; +} + + +// other Gtk functions + +/**yon_gtk_combo_box_text_fill(GtkWidget *combo, config_str parameters,int size) + * [EN] + * + * [RU] + * Добавляет в Комбобокс [combo] все строки из массива строк [parameters] размера [size] +*/ +int yon_gtk_combo_box_text_fill(GtkWidget *combo, config_str parameters,int size){ + if (combo&¶meters){ + for (int i=0;imessage); + g_error_free(err); + } + if (type == BACKGROUND_IMAGE_SUCCESS_TYPE||! 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 (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 (text) + gtk_label_set_text(GTK_LABEL(data.label), text); +} + +void yon_ubl_status_box_render(char *text, BACKGROUND_IMAGE_TYPE type){ + _yon_ubl_status_box_render(text,type); +} + +/**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/ubl-utils/ubl-utils.h b/ubl-utils/ubl-utils.h new file mode 100644 index 0000000..6884893 --- /dev/null +++ b/ubl-utils/ubl-utils.h @@ -0,0 +1,364 @@ +#ifndef UBL_UTILS +#define UBL_UTILS +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "../utils-compile/ubl-cmake.h" +#ifdef WEBKIT_FOUND + #include +#endif +#define DesktopPath "/usr/share/applications/" + +#define for_dictionaries(obj, obj1) for (obj = obj1->first; obj != NULL; obj = obj->next) + +#define new(type) malloc(sizeof(type)) +#define new_arr(type,size) malloc(sizeof(type)*size) + +#define get_home_dir_command yon_char_unite("getent passwd \"",yon_ubl_root_user_get(),"\" | cut -d: -f6",NULL) + +typedef enum +{ + #ifdef __GTK_H__ + DICTIONARY_GTK_WIDGETS_TYPE, + #endif + DICTIONARY_OTHER_TYPE=0, + DICTIONARY_CHAR_TYPE, + DICTIONARY_INT_TYPE, + DICTIONARY_BOOL_TYPE, + +} DICT_TYPE; + +typedef struct dictionary +{ + char *key; + void *data; + struct dictionary *next; + struct dictionary *prev; + struct dictionary *first; + DICT_TYPE data_type; + int flag1; +} dictionary; + +typedef struct apps +{ + char *Name; + int Type; + char *Categories; + char *Exec; + char *Icon; + int Pluggable; + int DualPluggable; +} apps; + +typedef char** config_str; + +static dictionary *__yon__config__strings = NULL; +#define check_config if(__yon__config__strings&&__yon__config__strings->data_type==DICTIONARY_CHAR_TYPE) + +#define config(key) yon_config_get_by_key(key) + +#define for_config dictionary temp = NULL; for_dictionary(temp,__yon__config__strings) + +#define yon_remalloc(pointer, size) (!pointer) ? malloc(size) : realloc(pointer, size) +// 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) + +/**yon_dictionary_add_or_create_if_exists_with_data(dict,key,data) + * [EN] + * + * [RU] + * Добавляет элемент словаря в конец словаря [dict] c ключом [key] и данными [data]. + * Если словарь не существует, создаёт его +*/ +#define yon_dictionary_add_or_create_if_exists_with_data(dict,key,data) {if (!dict) dict=yon_dictionary_new_with_data(key,data); \ + else dict=yon_dictionary_append_with_data(dict,key,data);} + +dictionary *yon_dictionary_new(); + +dictionary *yon_dictionary_append(dictionary *targetdict); + +dictionary *yon_dictionary_get_last(dictionary *dict); + +dictionary *yon_dictionary_swap(dictionary *dict, int aim); + +void yon_dictionary_make_first(dictionary *dict); + +void yon_dictionary_make_nth(dictionary *dict, int nth); + +dictionary *yon_dictionary_new_with_data(char *key, void *data); + +dictionary *yon_dictionary_append_with_data(dictionary *dict, char *key, void *data); + +dictionary *yon_dictionary_connect(dictionary *old, dictionary *toconnect); + +dictionary *yon_dictionary_get(dictionary **dict, char *key); + +dictionary *yon_dictionary_rip(dictionary *dict); + +dictionary *yon_dictionary_get_nth(dictionary *dict, int place); + +void *yon_dictionary_free_all(dictionary *dictionary,void (data_manipulation)(void*)); + +// char functions + +int yon_char_find_last(char *source, char find); + +char *yon_char_append(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_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); + +char **yon_char_parsed_rip(char **char_string, int *size, int item_to_delete); + +int yon_char_parsed_check_exist(char **parameters, int size, char *param); + +int yon_char_find_count(char *source, char *find); + +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 (int *size, ...); + +void yon_char_parsed_copy(config_str *source, config_str *to_copy); + +config_str yon_char_parsed_append(config_str parsed, int *size, char *string); + +int yon_ubl_check_root(); + +char *yon_ubl_root_user_get(); + +char *yon_ubl_user_get_home_directory(); + +// parsing functions + +config_str philos_list_user(int* size); + +apps *yon_apps_scan_and_parse_desktops(int *sizef); + +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_config_save_registered(char *command); + +char *yon_config_get_parameter(config_str parameters, int size, char *param); + +int yon_config_load_register(char *command); + +int yon_config_remove_by_key(char *key); + +int yon_config_remove_by_data(void *data); + +int yon_config_remove_element(char *key, char *deleted); + +void *yon_config_get_by_key(char *key); + +char *yon_config_get_key_by_data(char *data); + +int yon_config_set(char *key, void *data); + +int yon_config_clean(); + +void yon_config_register(char *key, void *data); + +config_str yon_config_get_all(); + +// terminal-using functions + +int yon_launch_app_with_arguments(char *name, char *args); + +void yon_launch(char *command); + +// Gtk functions + +#ifdef __GTK_H__ +#ifdef VTE_TERMINAL +void yon_terminal_integrated_launch(GtkWidget *place_to_show, char* command, void *endwork_function, void* endwork_function_argument); + +void yon_terminal_integrated_start(GtkWidget *terminal, char* command, void *endwork_function, void* endwork_function_argument); + +#endif + +enum YON_TYPE{ + YON_TYPE_STRING, + YON_TYPE_INT, + YON_TYPE_BOOLEAN, + YON_TYPE_OTHER +}; + +GtkWidget *yon_ubl_menu_item_about_new(char *buttonname); +GtkWidget *yon_ubl_menu_item_documentation_new(char *buttonname); + +/**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 +{ + GtkWidget *Icon; + GtkWidget *Label; + GtkWidget *IconView; + GtkListStore *List; +} expander_icon_view; + +void yon_window_config_setup(GtkWindow *window); + +int yon_window_config_load(char *path); + +config_str yon_window_config_get_section(char *section, gsize *size); + +void yon_window_config_add_listener(GtkWidget *widget, char *param_name, char *widget_property, enum YON_TYPE val_type); + +void yon_window_config_add_custom_parameter(char *param_name, char *section, void *tracked_value, enum YON_TYPE val_type); + +void yon_window_config_erase_custom_parameter(char *param_name, char *section); + +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(GtkBox *destination, gboolean expand, gboolean fill, int padding, ...); + +int yon_dictionary_gtk_pack_end_multiple_widgets(GtkBox *destination, gboolean expand, gboolean fill, int padding, ...); + + + +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 в котором будет отображаться текст статусного сообщения; +*/ +int yon_ubl_status_box_setup(GtkWidget *icon, GtkWidget *box, GtkWidget *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 (Жёлтный фон, иконка - галка) +*/ +void yon_ubl_status_box_render(char *text, BACKGROUND_IMAGE_TYPE type); + +#ifdef __cplusplus + +/**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 + +/**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) +#define yon_ubl_header_setup_resource(overlay, head, image, imag_path) _yon_ubl_header_setup_resource(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_header_setup_resource(GtkWidget *Overlay, GtkWidget *Head, GtkWidget *Image, char *image_path); + +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-utils/ubl-utils.pc.in b/ubl-utils/ubl-utils.pc.in new file mode 100644 index 0000000..a170ac9 --- /dev/null +++ b/ubl-utils/ubl-utils.pc.in @@ -0,0 +1,10 @@ +prefix=@CMAKE_INSTALL_PREFIX@ +exec_prefix=@CMAKE_INSTALL_PREFIX@ +libdir=${exec_prefix}/@CMAKE_INSTALL_LIBDIR@ +includedir=${prefix}/@CMAKE_INSTALL_INCLUDEDIR@ +Name: @PROJECT_NAME@ +Description: @PROJECT_DESCRIPTION@ +Version: @PROJECT_VERSION@ +Requires: +Libs: -L${libdir} -l@PROJECT_NAME@ +Cflags: -I${includedir} \ No newline at end of file diff --git a/ublsettings-ui-banner.png b/ublsettings-ui-banner.png new file mode 100644 index 0000000000000000000000000000000000000000..8eb67cbc38babeaf498d981356cf7e77e2741f12 GIT binary patch literal 33872 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 { + 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: 3px 10px 3px 5px; + /* padding: 5px 0px 3px 5px; */ + border:transparent; + } + .menuitemmiddle>*{ + margin:0 2px 0 2px; + padding: 3px 10px 3px 5px; + /* padding: 3px 0px 3px 5px; */ + border:transparent; + } + .menuitembottom>*{ + margin:0 2px 2px 2px; + padding: 3px 10px 3px 5px; + /* padding: 3px 0px 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: 3px 10px 3px 5px; + /* padding: 5px 0 3px 5px; */ + background:@theme_selected_bg_color; + border-radius:2px; + } + .menuitemmiddle:hover>* { + margin:0 2px 0px 2px; + padding: 3px 10px 3px 5px; + /* padding: 3px 0px 3px 5px; */ + background:@theme_selected_bg_color; + border-radius:2px; + } + .menuitembottom:hover>* { + margin:0 2px 2px 2px; + padding: 3px 10px 3px 5px; + /* padding: 3px 0px 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/ublsettings-ui.desktop b/ublsettings-ui.desktop new file mode 100644 index 0000000..d82afc3 --- /dev/null +++ b/ublsettings-ui.desktop @@ -0,0 +1,15 @@ +[Desktop Entry] +Encoding=UTF-8 +Name=TEMPLATE Manager +Name[ru]=TEMPLATE +GenericName=ublsettings-ui +GenericName[ru]=TEMPLATE +Comment=TEMPLATE management app +Comment[ru]=Приложение для TEMPLATE +Type=Application +Exec=pkexec ublsettings-ui +Icon=com.ublinux.ublsettings-ui +Terminal=false +X-XfcePluggable=true +X-UBLPluggable=true +Categories=XFCE;GTK;Settings;DesktopSettings;X-XFCE-SettingsDialog;X-XFCE-SystemSettings;X-UBL-SettingsManager;X-UBL-Personal-Settings; diff --git a/ublsettings-ui.glade b/ublsettings-ui.glade new file mode 100644 index 0000000..fdaf89d --- /dev/null +++ b/ublsettings-ui.glade @@ -0,0 +1,766 @@ + + + + + + + + + + False + False + True + center + com.ublinux.ublsettings-ui + dialog + True + ublsettings-ui + 1.1 + Copyright © 2022 - 2023, UBSoft LLC + TEMPLATE Manager + https://wiki.ublinux.ru/ru/Программное_обеспечение/Программы_и_утилиты/Все/ublsettings-ui + Project Home Page + Это приложение распространяется без каких-либо гарантий. +Подробнее в <a href="https://www.gnu.org/licenses/old-licenses/gpl-2.0.html">GNU General Public License, версии 2 или позднее</a>. + UBGroup + UBGroup + com.ublinux.ublsettings-ui + True + gpl-2-0 + + + True + False + vertical + 2 + + + False + end + + + False + False + 1 + + + + + + + True + False + True + + + True + False + 5 + 5 + 5 + 5 + 2 + TEMPLATE Manager + + + + + + + + + + True + False + center + + + True + False + 5 + 5 + 5 + 5 + 6 + 6 + 64 + com.ublinux.ublsettings-ui + + + False + True + 0 + + + + + True + False + + + True + False + + + True + False + center + vertical + + + 255 + True + False + end + TEMPLATE Manager + 0 + + + + + + + + True + True + 0 + + + + + 255 + True + False + start + TEMPLATE management app + 0 + + + + + + + + True + True + 1 + + + + + False + True + 0 + + + + + True + True + 0 + + + + + True + True + 1 + + + + + True + False + process-stop-symbolic + + + True + False + emblem-ok-symbolic + + + False + False + 450 + dialog-question-symbolic + + + True + False + 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 + + + + + Open documentation + True + True + True + image9 + + + + True + True + 1 + + + + + False + True + 1 + + + + + + + True + False + True + + + True + False + TEMPLATE Manager + + + + + + + + + + True + False + False + + + True + False + Load global configuration + + + + + + True + False + Load local configuration + + + + + + True + False + False + False + + + True + False + False + + + True + False + Save configuration + + + + + + True + False + Save to global configuration + + + + + + True + False + Save to local configuration + + + + + + 800 + 600 + False + 800 + 600 + com.ublinux.ublsettings-ui + + + True + False + vertical + + + 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 + True + + + + + + + False + True + 1 + + + + + False + True + 0 + + + + + True + False + vertical + + + 81 + True + False + + + True + False + start + + + -1 + + + + + False + True + 0 + + + + + False + True + 1 + + + + + True + False + 5 + 5 + 5 + 5 + 5 + 5 + True + True + vertical + + + + + + False + True + 2 + + + + + True + True + 0 + + + + + + + True + False + True + + + True + False + 5 + 5 + 5 + 5 + 2 + TEMPLATE Manager + + + + + + + + True + False + 5 + 5 + 5 + 5 + 6 + 6 + 32 + com.ublinux.ublsettings-ui + + + + + True + False + + + True + True + False + True + menu3 + + + True + False + + + True + False + Save + + + False + True + 0 + + + + + True + False + pan-down-symbolic + + + False + True + 1 + + + + + + + False + True + 0 + + + + + True + True + True + False + True + True + menu2 + none + + + + + + + False + True + 1 + + + + + end + 1 + + + + + True + False + + + True + True + False + True + menu1 + + + True + False + + + True + False + Load + + + False + True + 0 + + + + + True + False + pan-down-symbolic + + + False + True + 1 + + + + + + + False + True + 0 + + + + + 2 + + + + + + + diff --git a/ublsettings-ui.pot b/ublsettings-ui.pot new file mode 100644 index 0000000..b516b52 --- /dev/null +++ b/ublsettings-ui.pot @@ -0,0 +1,174 @@ +# Language translations for ublsettings-ui package. +# Copyright (C) 2022, UBTech LLC +# This file is distributed under the same license as the ublsettings-ui package. +# UBLinux Team , 2022 +# +#, fuzzy +msgid "" +msgstr "" +"Project-Id-Version: ublsettings-ui 1.0\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2023-05-22 16:12+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-strings.h:1 +msgid "Version:" +msgstr "" + +#: source/ubl-strings.h:2 +msgid "ublsettings-ui version:" +msgstr "" + +#: source/ubl-strings.h:2 +msgid "TEMPLATE settings" +msgstr "" + +#: source/ubl-strings.h:2 +msgid "Usage:" +msgstr "" + +#: source/ubl-strings.h:2 +msgid "[OPTIONS]" +msgstr "" + +#: source/ubl-strings.h:2 +msgid "Options:" +msgstr "" + +#: source/ubl-strings.h:2 +msgid "Show this help" +msgstr "" + +#: source/ubl-strings.h:2 +msgid "Show package version" +msgstr "" + +#: source/ubl-strings.h:2 +msgid "Lock this help menu" +msgstr "" + +#: source/ubl-strings.h:2 +msgid "Lock configuration saving" +msgstr "" + +#: source/ubl-strings.h:2 +msgid "Lock local configration saving" +msgstr "" + +#: source/ubl-strings.h:2 +msgid "Lock global configration saving" +msgstr "" + +#: source/ubl-strings.h:2 +msgid "Lock global configration loading" +msgstr "" + +#: source/ubl-strings.h:4 +msgid "TEMPLATE Manager" +msgstr "" + +#: source/ubl-strings.h:5 +msgid "TEMPLATE management app" +msgstr "" + +#: source/ubl-strings.h:7 +msgid "Operation succeeded" +msgstr "" + +#: source/ubl-strings.h:8 +msgid "" +"Warning! Application was launched without root - root-dependent actions are " +"locked" +msgstr "" + +#: source/ubl-strings.h:10 +msgid "About" +msgstr "" + +#: source/ubl-strings.h:11 +msgid "Documentation" +msgstr "" + +#: source/ubl-strings.h:12 +msgid "Save to local configuration" +msgstr "" + +#: source/ubl-strings.h:13 +msgid "Save to global configuration" +msgstr "" + +#: source/ubl-strings.h:14 +msgid "Save configuration" +msgstr "" + +#: source/ubl-strings.h:15 +msgid "Save" +msgstr "" + +#: source/ubl-strings.h:16 +msgid "Load local configuration" +msgstr "" + +#: source/ubl-strings.h:17 +msgid "Load global configuration" +msgstr "" + +#: source/ubl-strings.h:18 +msgid "Load" +msgstr "" + +#: source/ubl-strings.h:20 +msgid "Cancel" +msgstr "" + +#: source/ubl-strings.h:22 +msgid "Would you like to read documentation in the Web?" +msgstr "" + +#: source/ubl-strings.h:23 +msgid "" +"You will be redirected to documentation website where documentation is\n" +"translated and supported by community." +msgstr "" + +#: source/ubl-strings.h:24 +msgid "Always redirect to online documentation" +msgstr "" + +#: source/ubl-strings.h:25 +msgid "Open documentation" +msgstr "" + +#: source/ubl-strings.h:26 +msgid "Project Home Page" +msgstr "" + +#: source/ubl-strings.h:27 +msgid "Nothing were chosen" +msgstr "" + +#: source/ubl-strings.h:30 +msgid "Global configuration loading succseeded." +msgstr "" + +#: source/ubl-strings.h:31 +msgid "Local configuration loading succseeded." +msgstr "" + +#: source/ubl-strings.h:33 +msgid "Local and global configuration saving succseeded." +msgstr "" + +#: source/ubl-strings.h:34 +msgid "Global configuration saving succseeded." +msgstr "" + +#: source/ubl-strings.h:35 +msgid "Local configuration saving succseeded." +msgstr "" diff --git a/ublsettings-ui_ru.po b/ublsettings-ui_ru.po new file mode 100644 index 0000000..1ff99b7 --- /dev/null +++ b/ublsettings-ui_ru.po @@ -0,0 +1,177 @@ +# Russian translations for ublsettings-ui package. +# Copyright (C) 2022, UBTech LLC +# This file is distributed under the same license as the ublsettings-ui package. +# UBLinux Team , 2022 +# +#, fuzzy +msgid "" +msgstr "" +"Project-Id-Version: ublsettings-ui 1.0\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2023-05-22 16:12+0600\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" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +#: source/ubl-strings.h:1 +msgid "Version:" +msgstr "Версия:" + +#: source/ubl-strings.h:2 +msgid "ublsettings-ui version:" +msgstr "Версия ublsettings-ui: " + +#: source/ubl-strings.h:2 +msgid "TEMPLATE settings" +msgstr "Настройки TEMPLATE" + +#: source/ubl-strings.h:2 +msgid "Usage:" +msgstr "Использование:" + +#: source/ubl-strings.h:2 +msgid "[OPTIONS]" +msgstr "[АРГУМЕНТЫ]" + +#: source/ubl-strings.h:2 +msgid "Options:" +msgstr "Аргументы:" + +#: source/ubl-strings.h:2 +msgid "Show this help" +msgstr "Показать параметры справки" + +#: source/ubl-strings.h:2 +msgid "Show package version" +msgstr "Показать текущую версию" + +#: source/ubl-strings.h:2 +msgid "Lock this help menu" +msgstr "Блокировка вызова справки" + +#: source/ubl-strings.h:2 +#, fuzzy +msgid "Lock configuration saving" +msgstr "Блокировка сохранения локальной и глобальной конфигурации" + +#: source/ubl-strings.h:2 +msgid "Lock local configration saving" +msgstr "Блокировка сохранения локальной конфигурации" + +#: source/ubl-strings.h:2 +msgid "Lock global configration saving" +msgstr "Блокировка сохранения глобальной конфигурации" + +#: source/ubl-strings.h:2 +msgid "Lock global configration loading" +msgstr "Блокировка загрузки глобальной конфигурации" + +#: source/ubl-strings.h:4 +msgid "TEMPLATE Manager" +msgstr "Настройки TEMPLATE" + +#: source/ubl-strings.h:5 +msgid "TEMPLATE management app" +msgstr "Настройки TEMPLATE" + +#: source/ubl-strings.h:7 +msgid "Operation succeeded" +msgstr "Операция завершена" + +#: source/ubl-strings.h:8 +msgid "" +"Warning! Application was launched without root - root-dependent actions are " +"locked" +msgstr "Внимание! Приложение было запущено без прав суперпользователя - действия, требующие их наличия заблокированы" + +#: source/ubl-strings.h:10 +msgid "About" +msgstr "О программе" + +#: source/ubl-strings.h:11 +msgid "Documentation" +msgstr "Справка" + +#: source/ubl-strings.h:12 +msgid "Save to local configuration" +msgstr "Сохранить в локальную конфигурацию" + +#: source/ubl-strings.h:13 +msgid "Save to global configuration" +msgstr "Сохранить в глобальную конфигурацию" + +#: source/ubl-strings.h:14 +msgid "Save configuration" +msgstr "Сохранить конфигурацию" + +#: source/ubl-strings.h:15 +msgid "Save" +msgstr "Сохранить" + +#: source/ubl-strings.h:16 +msgid "Load local configuration" +msgstr "Загрузить локальную конфигуруцию" + +#: source/ubl-strings.h:17 +msgid "Load global configuration" +msgstr "Загрузить глобальную конфигурацию" + +#: source/ubl-strings.h:18 +msgid "Load" +msgstr "Загрузить" + +#: source/ubl-strings.h:20 +msgid "Cancel" +msgstr "Отмена" + +#: source/ubl-strings.h:22 +msgid "Would you like to read documentation in the Web?" +msgstr "Вы хотите прочитать справку в Сети?" + +#: source/ubl-strings.h:23 +msgid "" +"You will be redirected to documentation website where documentation is\n" +"translated and supported by community." +msgstr "" +"Вы будете перенаправлены на сайт с документацией, где страницы помощи\n" +"переводятся и поддерживаются сообществом." + +#: source/ubl-strings.h:24 +msgid "Always redirect to online documentation" +msgstr "Всегда перенаправлять" + +#: source/ubl-strings.h:25 +msgid "Open documentation" +msgstr "Прочитать справку" + +#: source/ubl-strings.h:26 +msgid "Project Home Page" +msgstr "Домашняя страница проекта" + +#: source/ubl-strings.h:27 +msgid "Nothing were chosen" +msgstr "Ничего не было выбрано" + +#: source/ubl-strings.h:30 +msgid "Global configuration loading succseeded." +msgstr "Успешно загружена глобальная конфигурация" + +#: source/ubl-strings.h:31 +msgid "Local configuration loading succseeded." +msgstr "Успешно загружена локальная конфигурация" + +#: source/ubl-strings.h:33 +msgid "Local and global configuration saving succseeded." +msgstr "Успешно записаны локальная и глобальная конфигурация" + +#: source/ubl-strings.h:34 +msgid "Global configuration saving succseeded." +msgstr "Успешно записана глобальная конфигурация" + +#: source/ubl-strings.h:35 +msgid "Local configuration saving succseeded." +msgstr "Успешно записана локальная конфигурация" From 5f43294cbdae805374c6a8c222ee2bc163191df5 Mon Sep 17 00:00:00 2001 From: Ivan Yarcev Date: Thu, 3 Aug 2023 17:55:36 +0600 Subject: [PATCH 2/7] Lib update --- Makefile | 56 +++++++++++++++++++++++++++------------- source/CMakeLists.txt | 15 ++++++----- source/ublsettings-ui.c | 6 ++++- source/ublsettings-ui.h | 4 +-- ubl-utils/CMakeLists.txt | 2 ++ ubl-utils/ubl-utils.c | 32 ++++++++++++++++++++--- ubl-utils/ubl-utils.h | 5 +++- 7 files changed, 88 insertions(+), 32 deletions(-) diff --git a/Makefile b/Makefile index aae2afb..fdce4f1 100644 --- a/Makefile +++ b/Makefile @@ -46,8 +46,8 @@ depend: exit 1; \ fi; \ done; \ - $(CMAKE_UI_COMMAND) -S$(CMAKE_UI_SOURCE_DIR) -B${CMAKE_UI_BUILD_DIR} --check-build-system CMakeFiles/Makefile.cmake 1 || exit 1; \ - $(CMAKE_UTILS_COMMAND) -S$(CMAKE_UTILS_SOURCE_DIR) -B${CMAKE_UTILS_BUILD_DIR} --check-build-system CMakeFiles/Makefile.cmake 1 || exit 1; \ + $(CMAKE_UI_COMMAND) -DCMAKE_INSTALL_PREFIX=/usr -S$(CMAKE_UI_SOURCE_DIR) -B${CMAKE_UI_BUILD_DIR} --check-build-system CMakeFiles/Makefile.cmake 1 || exit 1; \ + $(CMAKE_UTILS_COMMAND) -DCMAKE_INSTALL_PREFIX=/usr -S$(CMAKE_UTILS_SOURCE_DIR) -B${CMAKE_UTILS_BUILD_DIR} --check-build-system CMakeFiles/Makefile.cmake 1 || exit 1; \ echo "Check depends: OK" debug: @@ -60,28 +60,37 @@ debug: prepare: @echo "Prepare ..."; \ if [ ! -d ${CMAKE_UI_BUILD_DIR} ]; then \ - $(CMAKE_UI_COMMAND) -S${CMAKE_UI_SOURCE_DIR} -B${CMAKE_UI_BUILD_DIR} -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX="${PREFIX}"; \ - $(CMAKE_UTILS_COMMAND) -S${CMAKE_UTILS_SOURCE_DIR} -B${CMAKE_UTILS_BUILD_DIR} -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX="${PREFIX}"; \ + $(CMAKE_UI_COMMAND) -DCMAKE_INSTALL_PREFIX=/usr -S${CMAKE_UI_SOURCE_DIR} -B${CMAKE_UI_BUILD_DIR} -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX="${PREFIX}"; \ + $(CMAKE_UTILS_COMMAND) -DCMAKE_INSTALL_PREFIX=/usr -S${CMAKE_UTILS_SOURCE_DIR} -B${CMAKE_UTILS_BUILD_DIR} -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX="${PREFIX}"; \ fi; \ echo "Prepare: OK" check: @echo "Check ..."; \ - if [ -f ${CMAKE_UI_BUILD_DIR}/lib${PKGNAME}.so ]; then \ + if [ -f ${CMAKE_UTILS_BUILD_DIR}/libubl-utils.so ]; then \ echo "Check: OK"; \ else \ - echo "Check: ${CMAKE_UI_BUILD_DIR}/lib${PKGNAME}.so not found !"; \ + echo "Check: ${CMAKE_UI_BUILD_DIR}/libubl-utils.so not found !"; \ exit 1; \ fi -build: depend prepare +build: depend prepare build-utils @echo "Build ..."; \ - $(MAKE_COMMAND) --directory=${CMAKE_UI_BUILD_DIR}; \ - $(MAKE_COMMAND) --directory=${CMAKE_UTILS_BUILD_DIR}; \ sed -r "s/^(string version_application).*/\1;/" -i ${FILE_VER}; \ echo "Build: OK" -uninstall: +build-ui: + @cd ./ubl-utils; \ + $(MAKE_COMMAND) --directory=${CMAKE_UI_BUILD_DIR}; \ + cd ../ + + +build-utils: + @cd ./source; \ + $(MAKE_COMMAND) --directory=${CMAKE_UTILS_BUILD_DIR}; \ + cd ../ + +uninstall: uninstall-ui uninstall-util @echo "Uninstall ..." @for FILE_PO in $(wildcard *.po); do \ LANG=$${FILE_PO##*_};LANG=$${LANG%.*}; \ @@ -98,10 +107,6 @@ uninstall: $(RM) "${DESTDIR}${PREFIX}/share/icons/hicolor/$${SIZE}/status/$${FILE_SVG%.*}".{svg,png,jpg}; \ done; \ done - @$(RM) -r /usr/local/lib/libubl-utils.so* - @$(RM) -r /usr/local/lib/libublsettings-ui.a* - @$(RM) -r /usr/local/include/*ubl-utils.h* - @$(RM) -r /usr/local/include/*ublsettings-ui.h* @$(RM) "${DESTDIR}${PREFIX}/share/applications/${PKGNAME}.desktop" @$(RM) "${DESTDIR}${PREFIX}/share/icons/hicolor/scalable/apps/com.ublinux.${PKGNAME}.svg" @$(RM) "${DESTDIR}/usr/share/polkit-1/actions/com.ublinux.${PKGNAME}${PKGIDENT}.policy" @@ -112,7 +117,17 @@ uninstall: fi @echo "Uninstall: OK" -install: check uninstall +uninstall-ui: + @echo "Uninstall ..."; \ + $(RM) -r /usr/local/lib/libublsettings-ui.a*; \ + $(RM) -r /usr/local/include/*ublsettings-ui.h* + +uninstall-util: + @echo "Uninstall ..."; \ + $(RM) -r /usr/local/lib/libubl-utils.so*; \ + $(RM) -r /usr/local/include/*ubl-utils.h* + +install: check install-util build-ui install-ui @echo "Install ..." @for FILE_PO in $(wildcard *.po); do \ LANG=$${FILE_PO##*_};LANG=$${LANG%.*}; \ @@ -128,9 +143,7 @@ install: check uninstall done @install -Dm644 -t "${DESTDIR}${PREFIX}/share/icons/hicolor/scalable/apps/" "com.ublinux.${PKGNAME}.svg" @install -Dm644 -t "${DESTDIR}${PREFIX}/share/icons/hicolor/scalable/status/" "com.ublinux.${PKGNAME}.checked.svg" - @install -Dm644 -t "${DESTDIR}${PREFIX}/share/icons/hicolor/scalable/status/" "com.ublinux.${PKGNAME}.warning.svg"; \ - $(MAKE_COMMAND) install --directory=${CMAKE_UI_BUILD_DIR}; \ - $(MAKE_COMMAND) install --directory=${CMAKE_UTILS_BUILD_DIR} + @install -Dm644 -t "${DESTDIR}${PREFIX}/share/icons/hicolor/scalable/status/" "com.ublinux.${PKGNAME}.warning.svg" @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; \ @@ -138,6 +151,13 @@ install: check uninstall fi @echo "Install: OK" + +install-ui: uninstall-ui + @$(MAKE_COMMAND) install --directory=${CMAKE_UI_BUILD_DIR} + +install-util: uninstall-util + @$(MAKE_COMMAND) install --directory=${CMAKE_UTILS_BUILD_DIR} + clean: @echo "Clean ..." @$(RM) -rd ${CMAKE_UI_BUILD_DIR} diff --git a/source/CMakeLists.txt b/source/CMakeLists.txt index 042a36a..a4d96b7 100644 --- a/source/CMakeLists.txt +++ b/source/CMakeLists.txt @@ -62,19 +62,22 @@ add_custom_target( 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") add_library(${PROJECT_NAME} SHARED ublsettings-ui.c - ublsettings-ui.h) + ublsettings-ui.h + ${CMAKE_CURRENT_BINARY_DIR}/${GRESOURCE_C}) set(LIBRARIES -${GTK_LIBRARIES} -${WEBKIT_LIBRARIES} -# ${VTE291_LIBRARIES} -pthread) + ${GTK_LIBRARIES} + ${WEBKIT_LIBRARIES} + ${VTE291_LIBRARIES} + ubl-utils + pthread) + message(${CMAKE_INSTALL_LIBDIR}) target_include_directories(${PROJECT_NAME} PUBLIC ${PROJECT_BINARY_DIR}) target_link_libraries(${PROJECT_NAME} PUBLIC ${LIBRARIES}) diff --git a/source/ublsettings-ui.c b/source/ublsettings-ui.c index 6062e11..2f79476 100644 --- a/source/ublsettings-ui.c +++ b/source/ublsettings-ui.c @@ -165,11 +165,13 @@ int yon_ubl_window_setup(GtkWidget *interface, char *app_name, char *app_descrip app_information.app_locale=locale; } -main_window *yon_ubl_window_init(){ +main_window *yon_ubl_window_init(int argc, char *argv[]){ local=setlocale(LC_ALL, ""); textdomain (app_information.app_locale); + gtk_init(&argc,&argv); + main_window *widgets = setup_window(); yon_ubl_header_setup_resource(widgets->HeadOverlay,widgets->HeadBox,widgets->HeadImage,ui_banner_path); @@ -186,5 +188,7 @@ main_window *yon_ubl_window_init(){ gtk_style_context_add_provider_for_screen(gdk_screen_get_default(), GTK_STYLE_PROVIDER(css), -1); + return widgets; + gtk_main(); } \ No newline at end of file diff --git a/source/ublsettings-ui.h b/source/ublsettings-ui.h index 5936f59..394542c 100644 --- a/source/ublsettings-ui.h +++ b/source/ublsettings-ui.h @@ -25,7 +25,7 @@ #define ui_LocalePath "/usr/share/locale" #define ui_LocaleName "ublsettings-ui" typedef char* string; -string version_application = "0.0"; +string version_application; char *local; @@ -105,5 +105,5 @@ typedef struct { #define SUCCESS_LABEL _("Operation succeeded") #define ROOT_WARNING_LABEL _("Warning! Application was launched without root - root-dependent actions are locked") -main_window *yon_ubl_window_init(); +main_window *yon_ubl_window_init(int argc, char *argv[]); int yon_ubl_window_setup(GtkWidget *interface, char *app_name, char *app_description, char *locale); \ No newline at end of file diff --git a/ubl-utils/CMakeLists.txt b/ubl-utils/CMakeLists.txt index 310149a..4656047 100644 --- a/ubl-utils/CMakeLists.txt +++ b/ubl-utils/CMakeLists.txt @@ -40,6 +40,8 @@ ${WEBKIT_LIBRARIES} # ${VTE291_LIBRARIES} pthread) +message(${CMAKE_INSTALL_LIBDIR}) + target_include_directories(${PROJECT_NAME} PUBLIC ${PROJECT_BINARY_DIR}) target_link_libraries(${PROJECT_NAME} PUBLIC ${LIBRARIES}) diff --git a/ubl-utils/ubl-utils.c b/ubl-utils/ubl-utils.c index 0810a44..de47801 100644 --- a/ubl-utils/ubl-utils.c +++ b/ubl-utils/ubl-utils.c @@ -645,19 +645,18 @@ char **yon_char_parse(char *parameters, int *size, char *divider){ string=malloc(sizeof(char*)); char *paramline=yon_char_new(parameters); char *param; + if (!strstr(parameters,divider)) return NULL; while ((param=yon_char_divide_search(paramline,divider,1))){ + if (strcmp(param,paramline)==0||param[0]=='\0') break; string=realloc(string,sizeof(char*)*i); string[i-1]=yon_char_new(param); i++; - if (strcmp(param,paramline)==0) break; } string=realloc(string,sizeof(char*)*i); string[i-1]=yon_char_new(paramline); i++; - // printf("%d\n",i); *size=i-1; return string; - } /**yon_char_parsed_rip(char **char_string, int *size, int item_to_delete) @@ -1582,7 +1581,7 @@ void yon_terminal_integrated_start(GtkWidget *terminal, char* command, void *end return key; } - /**yon_window_config_add_custom_parameter(GtkWidget *widget, char *param_name, char *widget_property) + /**yon_window_config_add_listener(GtkWidget *widget, char *param_name, char *widget_property, enum YON_TYPE val_type) * [EN] * * [RU] @@ -1616,6 +1615,31 @@ void yon_terminal_integrated_start(GtkWidget *terminal, char* command, void *end yon_dictionary_add_or_create_if_exists_with_data(__yon_main_window_config.deleted_parameters,param->parameter_name,param); } + int yon_window_config_get_parameter(char *section, char *config_parameter, void *return_value, enum YON_TYPE type){ + GError *err=NULL; + switch (type){ + case YON_TYPE_BOOLEAN: + *((int*)return_value) = g_key_file_get_boolean(__yon_window_config_file,section,config_parameter,&err); + if (err) return 0; else return 1; + break; + case YON_TYPE_INT: + *((int*)return_value) = g_key_file_get_integer(__yon_window_config_file,section,config_parameter,&err); + if (err) return 0; else return 1; + break; + case YON_TYPE_STRING: + *((char**)return_value) = g_key_file_get_string(__yon_window_config_file,section,config_parameter,&err); + if (err) return 0; else return 1; + break; + case YON_TYPE_STRING_LIST: + gsize size=0; + *((char***)return_value) = g_key_file_get_string_list(__yon_window_config_file,section,config_parameter,&size,&err); + *((char***)return_value)=yon_remalloc(return_value,size+1); + *((char***)return_value)[size]=NULL; + if (err) return 0; else return 1; + break; + } + } + GtkWidget *yon_ubl_menu_item_about_new(char *buttonname){ GtkWidget *menu_item = gtk_menu_item_new(); gtk_style_context_add_class(gtk_widget_get_style_context(menu_item),"menuitembottom"); diff --git a/ubl-utils/ubl-utils.h b/ubl-utils/ubl-utils.h index 6884893..1e845f1 100644 --- a/ubl-utils/ubl-utils.h +++ b/ubl-utils/ubl-utils.h @@ -15,7 +15,7 @@ #include #include -#include "../utils-compile/ubl-cmake.h" +#include "ubl-cmake.h" #ifdef WEBKIT_FOUND #include #endif @@ -218,6 +218,7 @@ void yon_terminal_integrated_start(GtkWidget *terminal, char* command, void *end enum YON_TYPE{ YON_TYPE_STRING, + YON_TYPE_STRING_LIST, YON_TYPE_INT, YON_TYPE_BOOLEAN, YON_TYPE_OTHER @@ -254,6 +255,8 @@ void yon_window_config_add_custom_parameter(char *param_name, char *section, voi void yon_window_config_erase_custom_parameter(char *param_name, char *section); +int yon_window_config_get_parameter(char *section, char *config_parameter, void *return_value, enum YON_TYPE type); + 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); From b8000f21f5a9786fde98dbaa1384dc4c695f870b Mon Sep 17 00:00:00 2001 From: Ivan Yarcev Date: Fri, 4 Aug 2023 10:36:44 +0600 Subject: [PATCH 3/7] Fixed config folder creation --- ubl-utils/ubl-utils.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/ubl-utils/ubl-utils.c b/ubl-utils/ubl-utils.c index de47801..2403ef2 100644 --- a/ubl-utils/ubl-utils.c +++ b/ubl-utils/ubl-utils.c @@ -1525,8 +1525,7 @@ void yon_terminal_integrated_start(GtkWidget *terminal, char* command, void *end if (!g_key_file_load_from_file(__yon_window_config_file,__yon_window_config_path,G_KEY_FILE_NONE,NULL)){ struct stat st; int size; - config_str conf = yon_char_parse(yon_char_new(__yon_window_config_path),&size,"/"); - char *path = yon_char_unite(conf[0],"/",conf[1],"/",conf[2],"/",conf[3],"/",conf[4],"/",NULL); + char *path = yon_char_divide(yon_char_new(__yon_window_config_path),yon_char_find_last(__yon_window_config_path,'/')); if (stat(path, &st) == -1) { mkdir(path, 0777); } From 9bb41c67d349682de1537a904079a05e44fb9498 Mon Sep 17 00:00:00 2001 From: Ivan Yarcev Date: Thu, 30 Nov 2023 16:21:47 +0600 Subject: [PATCH 4/7] 1.0 Library version --- .gitignore | 4 +- gresource.xml | 3 + source/CMakeLists.txt | 10 +- source/ublsettings-ui.c | 137 ++--- source/ublsettings-ui.h | 165 ++++-- ubl-utils/CMakeLists.txt | 7 +- ubl-utils/ubl-utils.c | 785 +++++++++++++++++++++---- ubl-utils/ubl-utils.h | 77 ++- ublsettings-ui-about.glade | 64 ++ ublsettings-ui-documentation.glade | 208 +++++++ ublsettings-ui-save-confirmation.glade | 145 +++++ ublsettings-ui.glade | 264 --------- ublsettings-ui.pot | 124 ++-- ublsettings-ui_ru.po | 131 ++--- 14 files changed, 1445 insertions(+), 679 deletions(-) create mode 100644 ublsettings-ui-about.glade create mode 100644 ublsettings-ui-documentation.glade create mode 100644 ublsettings-ui-save-confirmation.glade diff --git a/.gitignore b/.gitignore index 4a609ef..e11513c 100644 --- a/.gitignore +++ b/.gitignore @@ -9,4 +9,6 @@ source/ubl-cmake.h vgcore* .BUILD.md .updatebuild.sh -.install.sh \ No newline at end of file +.install.sh +ublsettings-ui-debug +.install-debug.sh \ No newline at end of file diff --git a/gresource.xml b/gresource.xml index 7861abe..f24a0e6 100644 --- a/gresource.xml +++ b/gresource.xml @@ -2,6 +2,9 @@ ublsettings-ui.glade + ublsettings-ui-about.glade + ublsettings-ui-documentation.glade + ublsettings-ui-save-confirmation.glade ublsettings-ui.css diff --git a/source/CMakeLists.txt b/source/CMakeLists.txt index a4d96b7..2a6b49a 100644 --- a/source/CMakeLists.txt +++ b/source/CMakeLists.txt @@ -9,6 +9,11 @@ include_directories(${GTK_INCLUDE_DIRS}) link_directories(${GTK_LIBRARY_DIRS}) add_definitions(${GTK_CFLAGS_OTHER}) +pkg_check_modules(VTE291 REQUIRED vte-2.91) +include_directories(${VTE291_INCLUDE_DIRS}) +link_directories(${VTE291_LIBRARY_DIRS}) +add_definitions(${VTE291_CFLAGS_OTHER}) + find_library(WEBKIT_LIBRARIES_FOUND webkit2gtk-4.0 webkit2gtk-web-extension-4.0) option(WEBKIT_FOUND "No" OFF) @@ -32,6 +37,9 @@ add_custom_target(GLADE ublsettings-ui.glade) set(DEPENDFILES ../ublsettings-ui.glade + ../ublsettings-ui-about.glade + ../ublsettings-ui-documentation.glade + ../ublsettings-ui-save-confirmation.glade ../gresource.xml ../ublsettings-ui-banner.png ../ublsettings-ui.css @@ -62,7 +70,7 @@ add_custom_target( 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") add_library(${PROJECT_NAME} SHARED ublsettings-ui.c diff --git a/source/ublsettings-ui.c b/source/ublsettings-ui.c index 2f79476..983cd19 100644 --- a/source/ublsettings-ui.c +++ b/source/ublsettings-ui.c @@ -4,48 +4,28 @@ //signal emmit handlers - no header initialization -/**on_close_subwindow(GtkWidget *self) - * [EN] - * Closes window in which [self] is contained. - * [RU] - * Закрывает окно, в котором расположен виджет [self]. -*/ -void on_close_subwindow(GtkWidget *self){ +void on_subwindow_close(GtkWidget *self){ gtk_widget_destroy(gtk_widget_get_toplevel(self)); } -/**yon_open_browser(GtkWidget *self, char *link) - * [EN] - * Opens browser with [link] link. - * [RU] - * Открывает браузер с [link] ссылкой. -*/ void yon_open_browser(GtkWidget *self, char *link){ - yon_ubl_browser_window_open(link,app_information.app_name); + yon_ubl_browser_window_open(link,template_app_information.app_title); } -/**on_open_documentation_confirmation(GtkWidget *self, char *link) - * [EN] - * Opens confirmation window for [link] link. - * [RU] - * Открывает окно подтверждение перехода по ссылке [link]. -*/ void on_open_documentation_confirmation(GtkWidget *self, char *link){ - if (app_information.always_open_documentation==0){ - GtkBuilder *builder = gtk_builder_new_from_resource(ui_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),app_information.app_name); - 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); + if (template_app_information.always_open_documentation==0){ + GtkBuilder *builder = gtk_builder_new_from_resource(ui_glade_path_documentation); + template_documentation_confirmation_window *window = malloc(sizeof(template_documentation_confirmation_window)); + window->Window = yon_gtk_builder_get_widget(builder,"helpConfirmationWindow"); + window->AcceptButton = yon_gtk_builder_get_widget(builder,"ReadHelpButton"); + window->CloseButton = yon_gtk_builder_get_widget(builder,"CancelHelpButton"); + window->HeaderLabel = yon_gtk_builder_get_widget(builder,"webHeaderNameLabel"); + window->AlwaysOpenCheck = yon_gtk_builder_get_widget(builder,"AlwaysOpenDocumentationCheckbox"); + gtk_label_set_text(GTK_LABEL(window->HeaderLabel),template_app_information.app_title); + gtk_widget_show_all(window->Window); + g_signal_connect(G_OBJECT(window->CloseButton),"clicked",G_CALLBACK(on_subwindow_close),NULL); + g_signal_connect(G_OBJECT(window->AcceptButton),"clicked",G_CALLBACK(yon_open_browser),yon_char_new(link)); + g_signal_connect(G_OBJECT(window->AcceptButton),"clicked",G_CALLBACK(on_subwindow_close),NULL); } else { @@ -72,22 +52,14 @@ void on_link(GtkWidget *self, char* uri, gpointer user_data){ on_open_documentation_confirmation(self,uri); } -/**on_about() - * [EN] - * Function for setting up and showing AboutDialog. - * Connect it to "activate" signal of Documentation MenuItem. - * [RU] - * Функиця для настройки и показа окна AboutDialog. - * Присоединять к сигналу "activate" кнопки справки типа MenuItem. -*/ -void on_about(){ - GtkBuilder *builder=gtk_builder_new_from_resource(ui_glade_path); +void on_about(GtkWidget *self, char *version_application){ + GtkBuilder *builder=gtk_builder_new_from_resource(ui_glade_path_about); 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_version(GTK_ABOUT_DIALOG(window),version_application); - gtk_about_dialog_set_comments(GTK_ABOUT_DIALOG(window),app_information.app_name); - gtk_label_set_text(GTK_LABEL(title),app_information.app_name); + gtk_about_dialog_set_comments(GTK_ABOUT_DIALOG(window),template_app_information.app_title); + gtk_label_set_text(GTK_LABEL(title),template_app_information.app_title); g_signal_connect(G_OBJECT(window),"activate-link",G_CALLBACK(on_link),NULL); gtk_widget_set_visible(hideButtonBox,0); gtk_widget_destroy(hideButtonBox); @@ -97,22 +69,28 @@ void on_about(){ //functions void yon_load_proceed(char *command){ - if (yon_config_load_register(command)) - yon_ubl_status_box_render(LOCAL_SAVE_SUCCESS_LABEL,BACKGROUND_IMAGE_SUCCESS_TYPE); - else - yon_ubl_status_box_render(LOAD_FAILED_LABEL,BACKGROUND_IMAGE_FAIL_TYPE); + yon_ubl_status_box_render(LOCAL_LOAD_SUCCESS_LABEL,BACKGROUND_IMAGE_SUCCESS_TYPE); } // standard functions +int yon_ubl_connect_config(_template_config *config){ + int replaces; + if(!template_config) + replaces=0; + else + replaces=1; + template_config = config; + return replaces; +} -main_window *setup_window(){ +template_main_window *setup_window(){ /* Widgets getting | Получение виджетов */ - main_window *widgets = malloc(sizeof(main_window)); + template_main_window *widgets = malloc(sizeof(template_main_window)); GtkBuilder *builder = gtk_builder_new_from_resource(ui_glade_path); widgets->Window = yon_gtk_builder_get_widget(builder,"MainWindow"); - widgets->HatLabel = yon_gtk_builder_get_widget(builder,"headerTopic"); + widgets->HeadLabel = yon_gtk_builder_get_widget(builder,"headerTopic"); widgets->PlugBox = yon_gtk_builder_get_widget(builder,"plugBox"); widgets->HeadOverlay = yon_gtk_builder_get_widget(builder,"HeadOverlay"); @@ -125,13 +103,11 @@ main_window *setup_window(){ widgets->StatusIcon = yon_gtk_builder_get_widget(builder,"mainStatusIcon"); widgets->StatusLabel = yon_gtk_builder_get_widget(builder,"mainStatusLabel"); - widgets->SaveLabel = yon_gtk_builder_get_widget(builder,"headerSaveConfigLabel"); widgets->SaveMenuItem = yon_gtk_builder_get_widget(builder,"SaveGlobalLocalConfigurationMenuItem"); widgets->SaveGlobalMenuItem = yon_gtk_builder_get_widget(builder,"SaveGlobalConfigurationMenuItem"); widgets->SaveLocalMenuItem = yon_gtk_builder_get_widget(builder,"SaveLocalConfigurationMenuItem"); widgets->RightBox = yon_gtk_builder_get_widget(builder,"HeaderRightBox"); - widgets->LoadLabel = yon_gtk_builder_get_widget(builder,"headerLoadConfigLabel"); widgets->LoadGlobalMenuItem = yon_gtk_builder_get_widget(builder,"LoadGlobalConfigurationMenuItem"); widgets->LoadLocalMenuItem = yon_gtk_builder_get_widget(builder,"LoadLocalConfigurationMenuItem"); widgets->LeftBox = yon_gtk_builder_get_widget(builder,"HeaderLeftBox"); @@ -139,7 +115,10 @@ main_window *setup_window(){ widgets->DocumentationMenuItem = yon_ubl_menu_item_documentation_new(DOCUMENTATION_LABEL); widgets->AboutMenuItem = yon_ubl_menu_item_about_new(ABOUT_LABEL); - gtk_window_set_title(GTK_WINDOW(widgets->Window),app_information.app_name); + gtk_window_set_title(GTK_WINDOW(widgets->Window),template_app_information.app_title); + gtk_label_set_text(GTK_LABEL(widgets->HeadLabel),template_app_information.app_title); + gtk_label_set_text(GTK_LABEL(widgets->HeadTitleLabel),template_app_information.app_title); + gtk_label_set_text(GTK_LABEL(widgets->HeadInfoLabel),template_app_information.app_description); GtkWidget *menu = yon_gtk_builder_get_widget(builder,"menu2"); gtk_menu_shell_append(GTK_MENU_SHELL(menu),widgets->DocumentationMenuItem); @@ -150,7 +129,7 @@ main_window *setup_window(){ /* Signal connection | Присоединение сигналов */ g_signal_connect(G_OBJECT(widgets->Window), "destroy", G_CALLBACK(gtk_main_quit), NULL); - g_signal_connect(G_OBJECT(widgets->DocumentationMenuItem),"activate",G_CALLBACK(on_open_documentation_confirmation),app_information.wiki_link); + g_signal_connect(G_OBJECT(widgets->DocumentationMenuItem),"activate",G_CALLBACK(on_open_documentation_confirmation),template_app_information.wiki_link); g_signal_connect(G_OBJECT(widgets->AboutMenuItem),"activate",G_CALLBACK(on_about),NULL); @@ -158,29 +137,36 @@ main_window *setup_window(){ return widgets; } -int yon_ubl_window_setup(GtkWidget *interface, char *app_name, char *app_description, char *locale){ - app_information.interface=interface; - app_information.app_name=app_name; - app_information.app_description=app_description; - app_information.app_locale=locale; +int yon_ubl_window_setup(GtkWidget *interface, char *app_title, char *app_description, char *locale, char *css, char *tech_name, char *version, char *wiki){ + template_app_information.interface=interface; + template_app_information.app_title=app_title; + template_app_information.css_path=css; + template_app_information.app_tech_name=tech_name; + template_app_information.app_version=version; + template_app_information.wiki_link=wiki; + template_app_information.app_description=app_description; + + template_app_information.app_locale=locale; } -main_window *yon_ubl_window_init(int argc, char *argv[]){ - local=setlocale(LC_ALL, ""); - textdomain (app_information.app_locale); +template_main_window *yon_ubl_window_init(int argc, char *argv[]){ + textdomain (template_ui_LocaleName); + setlocale(LC_ALL,""); - gtk_init(&argc,&argv); + // gtk_init(&argc,&argv); - main_window *widgets = setup_window(); + template_main_window *widgets = setup_window(); yon_ubl_header_setup_resource(widgets->HeadOverlay,widgets->HeadBox,widgets->HeadImage,ui_banner_path); - yon_ubl_status_box_setup(widgets->StatusIcon,widgets->StatusBox,widgets->StatusLabel); - if (getuid()!=0) - yon_ubl_status_box_render(ROOT_WARNING_LABEL,BACKGROUND_IMAGE_FAIL_TYPE); - else - yon_ubl_status_box_render(app_information.app_name,BACKGROUND_IMAGE_SUCCESS_TYPE); - yon_ubl_setup_sockets(widgets->PlugBox,widgets->LeftBox,widgets->RightBox,app_information.socket_id,app_information.load_socket_id,app_information.save_socket_id); + if (yon_ubl_status_box_setup(widgets->StatusIcon,widgets->StatusBox,widgets->StatusLabel)){ + if (getuid()!=0) + yon_ubl_status_box_render(ROOT_WARNING_LABEL,BACKGROUND_IMAGE_FAIL_TYPE); + else + yon_ubl_status_box_render(LOCAL_LOAD_SUCCESS_LABEL,BACKGROUND_IMAGE_SUCCESS_TYPE); + } + if(template_config) + yon_ubl_setup_sockets(widgets->PlugBox,widgets->LeftBox,widgets->RightBox,template_config->socket_id,template_config->load_socket_id,template_config->save_socket_id); yon_window_config_setup(GTK_WINDOW(widgets->Window)); yon_window_config_load(ui_config_path); GtkCssProvider *css=gtk_css_provider_new(); @@ -190,5 +176,4 @@ main_window *yon_ubl_window_init(int argc, char *argv[]){ -1); return widgets; - gtk_main(); -} \ No newline at end of file +} diff --git a/source/ublsettings-ui.h b/source/ublsettings-ui.h index 394542c..ca189c7 100644 --- a/source/ublsettings-ui.h +++ b/source/ublsettings-ui.h @@ -18,37 +18,85 @@ #define _(String) gettext(String) #define ui_glade_path "/com/ublinux/ui/ublsettings-ui.glade" +#define ui_glade_path_documentation "/com/ublinux/ui/ublsettings-ui-documentation.glade" +#define ui_glade_path_about "/com/ublinux/ui/ublsettings-ui-about.glade" #define ui_banner_path "/com/ublinux/images/ublsettings-ui-banner.png" #define ui_CssPath "/com/ublinux/css/ublsettings-ui.css" -#define ui_config_path yon_char_unite(yon_ubl_user_get_home_directory(),"/.config/",app_information.app_locale,"/",app_information.app_locale,".conf",NULL) +#define ui_config_path yon_char_unite(yon_ubl_user_get_home_directory(),"/.config/",template_app_information.app_tech_name,"/",template_app_information.app_tech_name,".conf",NULL) -#define ui_LocalePath "/usr/share/locale" -#define ui_LocaleName "ublsettings-ui" -typedef char* string; -string version_application; +#ifndef UBL_UI + #define template_ui_LocalePath "/usr/share/locale" + #define template_ui_LocaleName "ublsettings-ui" -char *local; + #define SUCCESS_LABEL _("Operation succeeded") + #define ROOT_WARNING_LABEL _("Warning! Application was launched without root - root-dependent actions are locked") + #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 CANCEL_LABEL _("Cancel") + #define ACCEPT_LABEL _("Accept") + + #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_LABEL _("Global configuration loading succeeded.") + #define LOCAL_LOAD_SUCCESS_LABEL _("Local configuration loading succeeded.") + #define LOAD_FAILED_LABEL _("Config loading failed") + + #define GLOBAL_LOCAL_SAVE_SUCCESS_LABEL _("Local and global configuration saving succeeded.") + #define GLOBAL_SAVE_SUCCESS_LABEL _("Global configuration saving succeeded.") + #define LOCAL_SAVE_SUCCESS_LABEL _("Local configuration saving succeeded.") +#endif typedef struct { GtkWidget *interface; - char *app_name; - char *app_description; + char *app_locale; + char *css_path; + char *app_title; + char *app_description; + + char *app_tech_name; + char *app_version; char *wiki_link; + gboolean always_open_documentation; +} template_app_info; +static template_app_info template_app_information; + +typedef struct { int socket_id; int load_socket_id; int save_socket_id; -} app_info; + + int lock_help; + int lock_save_local; + int lock_save_global; + int lock_load_global; -static app_info app_information; + int always_open_documentation; +} _template_config; +static _template_config *template_config; typedef struct { - //Standard GtkWidget *Window; - GtkWidget *HatLabel; + GtkWidget *HeadLabel; GtkWidget *PlugBox; GtkWidget *HeadOverlay; @@ -61,49 +109,90 @@ typedef struct { GtkWidget *StatusIcon; GtkWidget *StatusLabel; - GtkWidget *SaveLabel; GtkWidget *SaveMenuItem; GtkWidget *SaveGlobalMenuItem; GtkWidget *SaveLocalMenuItem; GtkWidget *RightBox; - GtkWidget *LoadLabel; GtkWidget *LoadGlobalMenuItem; GtkWidget *LoadLocalMenuItem; GtkWidget *LeftBox; GtkWidget *DocumentationMenuItem; GtkWidget *AboutMenuItem; - // Custom -} main_window; +} template_main_window; typedef struct { GtkWidget *Window; + GtkWidget *HeaderLabel; - GtkWidget *HatText; - GtkWidget *HeaderText; - GtkWidget *InfoText; GtkWidget *AlwaysOpenCheck; GtkWidget *CloseButton; GtkWidget *AcceptButton; -} documentation_confirmation_window; - - -#define GLOBAL_LOAD_SUCCESS_LABEL _("Global configuration loading succseeded.") -#define LOCAL_LOAD_SUCCESS_LABEL _("Local configuration loading succseeded.") -#define LOAD_FAILED_LABEL _("Config loading failed") - -#define GLOBAL_LOCAL_SAVE_SUCCESS_LABEL _("Local and global configuration saving succseeded.") -#define GLOBAL_SAVE_SUCCESS_LABEL _("Global configuration saving succseeded.") -#define LOCAL_SAVE_SUCCESS_LABEL _("Local configuration saving succseeded.") - -#define ABOUT_LABEL _("About") -#define DOCUMENTATION_LABEL _("Documentation") - -#define SUCCESS_LABEL _("Operation succeeded") -#define ROOT_WARNING_LABEL _("Warning! Application was launched without root - root-dependent actions are locked") - -main_window *yon_ubl_window_init(int argc, char *argv[]); -int yon_ubl_window_setup(GtkWidget *interface, char *app_name, char *app_description, char *locale); \ No newline at end of file +} template_documentation_confirmation_window; + +/**yon_open_browser(GtkWidget *self, char *link) + * [EN] + * Opens browser with [link] link. + * [RU] + * Открывает браузер с [link] ссылкой. +*/ +void yon_open_browser(GtkWidget *self, char *link); + +/**yon_ubl_connect_config(_template_config *config) + * [EN] + * + * [RU] + * Присоединяет конфиг основной утилиты (struct config) к стандартному интерфейсу. +*/ +int yon_ubl_connect_config(_template_config *config); + +/**yon_ubl_window_init(int argc, char *argv[]) + * [EN] + * + * [RU] + * Создаёт и настраивает основное окно приложения. +*/ +template_main_window *yon_ubl_window_init(int argc, char *argv[]); + +/**yon_ubl_window_setup(GtkWidget *interface, char *app_title, char *app_description, char *locale, char *css, char *tech_name, char *version, char *wiki) + * [EN] + * + * [RU] + * Установить важные значения для конфига; + * [app_title] - оботражаемое имя утилиты; + * [app_description] - отображаемое описание утилиты; + * [css] - путь к ресурсу css файла; + * [tech_name] - техническое имя утилиты (ubl-settings-) + * [version] - строка с версией приложения; + * [wiki] - ссылка на вики страницу; +*/ +int yon_ubl_window_setup(GtkWidget *interface, char *app_title, char *app_description, char *locale, char *css, char *tech_name, char *version, char *wiki); + +/**on_about() + * [EN] + * Function for setting up and showing AboutDialog. + * Connect it to "activate" signal of Documentation MenuItem. + * [RU] + * Функиця для настройки и показа окна AboutDialog. + * Присоединять к сигналу "activate" кнопки справки типа MenuItem. +*/ +void on_about(GtkWidget *self, char *version_application); + +/**on_open_documentation_confirmation(GtkWidget *self, char *link) + * [EN] + * Opens confirmation window for [link] link. + * [RU] + * Открывает окно подтверждения перехода по ссылке [link]. +*/ +void on_open_documentation_confirmation(GtkWidget *self, char *link); + +/**on_subwindow_close(GtkWidget *self) + * [EN] + * Closes window in which [self] is contained. + * [RU] + * Закрывает окно, в котором расположен виджет [self]. +*/ +void on_subwindow_close(GtkWidget *self); \ No newline at end of file diff --git a/ubl-utils/CMakeLists.txt b/ubl-utils/CMakeLists.txt index 4656047..9286eef 100644 --- a/ubl-utils/CMakeLists.txt +++ b/ubl-utils/CMakeLists.txt @@ -9,6 +9,11 @@ include_directories(${GTK_INCLUDE_DIRS}) link_directories(${GTK_LIBRARY_DIRS}) add_definitions(${GTK_CFLAGS_OTHER}) +pkg_check_modules(VTE291 REQUIRED vte-2.91) +include_directories(${VTE291_INCLUDE_DIRS}) +link_directories(${VTE291_LIBRARY_DIRS}) +add_definitions(${VTE291_CFLAGS_OTHER}) + find_library(WEBKIT_LIBRARIES_FOUND webkit2gtk-4.0 webkit2gtk-web-extension-4.0) option(WEBKIT_FOUND "No" OFF) @@ -37,7 +42,7 @@ add_library(${PROJECT_NAME} SHARED set(LIBRARIES ${GTK_LIBRARIES} ${WEBKIT_LIBRARIES} -# ${VTE291_LIBRARIES} +${VTE291_LIBRARIES} pthread) message(${CMAKE_INSTALL_LIBDIR}) diff --git a/ubl-utils/ubl-utils.c b/ubl-utils/ubl-utils.c index 2403ef2..0e8b853 100644 --- a/ubl-utils/ubl-utils.c +++ b/ubl-utils/ubl-utils.c @@ -455,9 +455,9 @@ char *yon_char_append(char *source, char *append) int size = strlen(source) + strlen(append) + 1; char *final = malloc(size); memset(final, 0, size); - if (strstr(source, "%%")) - sprintf(final, source, append); - else + // if (strstr(source, "%%")) + // sprintf(final, source, append); + // else sprintf(final, "%s%s", source, append); return final; } @@ -522,15 +522,18 @@ char *yon_cut(char *source, int size, int startpos) */ 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; + if (source){ + 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; + } + return NULL; } /**yon_char_find_count(char *source, char *find) @@ -607,6 +610,46 @@ char *yon_char_from_int(int int_to_convert) return ch; } +/**yon_char_from_float(int int_to_convert) + * [EN] + * converts float to char*. + * + * [RU] + * Конвертирует float в char* + */ +char *yon_char_from_float(float int_to_convert) +{ + int i = 1; + float convert_check = (float)int_to_convert; + for (i = 1; convert_check >= 10; i++) + { + convert_check = convert_check / 10; + } + char *ch = g_malloc0((i + 9)* sizeof(char)); + sprintf(ch, "%.2f", int_to_convert); + return ch; +} + +/**yon_char_from_long(int int_to_convert) + * [EN] + * converts long to char*. + * + * [RU] + * Конвертирует long в char* + */ +char *yon_char_from_long(long int_to_convert) +{ + int i = 1; + double convert_check = (double)int_to_convert; + for (i = 1; convert_check >= 10; i++) + { + convert_check = convert_check / 10; + } + char *ch = g_malloc0(i * sizeof(char) + 1); + sprintf(ch, "%ld", int_to_convert); + return ch; +} + /**yon_char_replace(char *source, char *find, char*replace) * [EN] * @@ -621,11 +664,11 @@ char *yon_char_replace(char *source, char *find, char*replace){ char *temp=NULL; if(!strstr(replace,find)){ while ((final=strstr(source,find))){ - temp=malloc(strlen(source)-strlen(final)); + temp=malloc(strlen(source)-strlen(final)+strlen(replace)); memset(temp,0,strlen(source)-strlen(final)+strlen(replace)); memcpy(temp,source,strlen(source)-strlen(final)); temp=yon_char_append(temp,replace); - source=yon_char_append(temp,final+1); + source=yon_char_append(temp,final+strlen(find)); } } @@ -640,23 +683,22 @@ char *yon_char_replace(char *source, char *find, char*replace){ * size of returned array */ char **yon_char_parse(char *parameters, int *size, char *divider){ - char **string=NULL; - int i=1; - string=malloc(sizeof(char*)); - char *paramline=yon_char_new(parameters); - char *param; - if (!strstr(parameters,divider)) return NULL; - while ((param=yon_char_divide_search(paramline,divider,1))){ - if (strcmp(param,paramline)==0||param[0]=='\0') break; - string=realloc(string,sizeof(char*)*i); - string[i-1]=yon_char_new(param); - i++; - } - string=realloc(string,sizeof(char*)*i); - string[i-1]=yon_char_new(paramline); - i++; - *size=i-1; - return string; + if (parameters){ + char **string=NULL; + *size=0; + char *paramline=yon_char_new(parameters); + char *param = strstr(paramline,divider); + for (;param;param=strstr(paramline,divider)){ + string = yon_remalloc(string,sizeof(char*)*((*size)+1)); + string[(*size)]=yon_char_divide(paramline,strlen(paramline)-strlen(param)); + *size=(*size)+1; + } + string = yon_remalloc(string,sizeof(char*)*((*size)+1)); + string[(*size)]=paramline; + (*size)+=1; + return string; + } + return NULL; } /**yon_char_parsed_rip(char **char_string, int *size, int item_to_delete) @@ -705,6 +747,30 @@ int yon_char_parsed_check_exist(char **parameters, int size, char *param){ return -1; } +/**yon_char_parsed_check_repeats(char **parameters, int size) + * [EN] + * Checks if [parameters] string array of length [size] + * has repeated elements; + * [RU] + * Проверяет есть ли в массиве строк [parameters], размера [size] + * повторения +*/ +int yon_char_parsed_check_repeats(char **parameters, int size, int *first_overlap, int *second_overlap){ + if (parameters){ + *first_overlap=0; + *second_overlap=0; + for ((*first_overlap)=0;(*first_overlap)pw_name,NULL); + else { + user_list = yon_char_parsed_append(user_list,user_size,user->pw_name); + } + } + endpwent(); + return user_list; +} + // parsing functions +/** yon_size_convert_automatic(int bytes, int *size) + * [EN] + * + * [RU] + * +*/ +float yon_size_convert_automatic(int bytes, int *size){ + float byte_float=bytes; + for (*size=-1;byte_float>1024;*size=*size+1){ + byte_float=byte_float/1024; + } + if (*size==-1) { + *size=0; + byte_float=byte_float/1024; + } + return byte_float; +} apps *yon_apps_scan_and_parse_desktops(int *sizef) { @@ -941,8 +1045,73 @@ apps *yon_apps_get_by_name(apps *applist, char *name, int size) return NULL; }; + +/** + * yon_dir_get_contents(char *dir_path, int *size) + * [EN] + * + * [RU] + * Проверяет существует ли папка [dir_path] и + * возвращает список всех вложенных файлов и папок, + * передавая в [size] длину списка. +*/ +config_str yon_dir_get_contents(char *dir_path, int *size){ + config_str dir = NULL; + *size=0; + if (!access(dir_path,F_OK)){ + DIR *directory = opendir(dir_path); + struct dirent *de; + while ((de = readdir(directory))){ + if (dir) yon_char_parsed_append(dir,size,de->d_name); + else dir = yon_char_parsed_new(size,de->d_name,NULL); + } + closedir(directory); + } + return dir; +} + //config functions +typedef struct yon_config_parameter +{ + char *key; + void *data; + struct yon_config_parameter *next; + struct yon_config_parameter *prev; + struct yon_config_parameter *first; + DICT_TYPE data_type; + int flag1; + char *section; +} yon_config_parameter; + +yon_config_parameter *yon_config_parameter_new_with_data(char *key, void *data){ + yon_config_parameter *param = yon_remalloc(NULL,sizeof(yon_config_parameter)); + param->data=data; + param->data_type=DICTIONARY_CHAR_TYPE; + param->first=param; + param->flag1=0; + param->key=yon_char_new(key); + param->next=NULL; + param->prev=NULL; + param->section=NULL; + return param; +} + +yon_config_parameter *yon_config_parameter_append_with_data(yon_config_parameter *dict, char *key, void *data){ + yon_config_parameter *param = yon_config_parameter_new_with_data(key,data); + param->first=dict->first; + (param->prev)=(yon_config_parameter*)yon_dictionary_get_last((dictionary*)dict); + dict->next=param; + return param; +} + + +static yon_config_parameter *__yon__config__strings = NULL; +#define check_config if(__yon__config__strings&&__yon__config__strings->data_type==DICTIONARY_CHAR_TYPE) +#define for_config dictionary temp = NULL; for_dictionary(temp,(dictionary*)__yon__config__strings) +#define yon_config_parameter_add_or_create_if_exists_with_data(dict,key,data) {if (!dict) dict=yon_config_parameter_new_with_data(key,data); \ + else dict=yon_config_parameter_append_with_data(dict,key,data);} + /**yon_config_load_register(char *command) * [EN] * @@ -950,28 +1119,48 @@ apps *yon_apps_get_by_name(apps *applist, char *name, int size) * Выполняет команду [command]. * Полученные данные парсятся и регистрируются в конфиг. */ -int yon_config_load_register(char *command){ +int yon_config_load_register(YON_CONFIG_TYPE config_type,char *section,char *parameter, ...){ if (__yon__config__strings){ - __yon__config__strings = yon_dictionary_free_all(__yon__config__strings,NULL); + __yon__config__strings = yon_dictionary_free_all((dictionary*)__yon__config__strings,NULL); } - FILE *output = popen(command, "r"); - char **output_strings = NULL; - output_strings = malloc(sizeof(char)); - int i = 0; - char str[4096]; - memset(str, 0, 4096); - while (fgets(str, 4096, output)) + va_list args; + va_start(args,parameter); + char *arg; + dictionary *sections = NULL; { - if (strcmp(str, "") != 0&& strcmp(str,"(null)\n")!=0) + if (sections&&yon_dictionary_get(§ions,section)) sections->data=(void*)yon_char_unite(yon_dictionary_get_data(sections,char*)," ",parameter,NULL); + else yon_dictionary_add_or_create_if_exists_with_data(sections,section,parameter); + } + while (arg=va_arg(args,char*)){ + char *key = va_arg(args,char*); + if (sections&&yon_dictionary_get(§ions,arg)) sections->data=(void*)yon_char_unite(yon_dictionary_get_data(sections,char*)," ",key,NULL); + else yon_dictionary_add_or_create_if_exists_with_data(sections,arg,key); + } + char *command=NULL; + dictionary *dict; + for_dictionaries(dict,sections){ + command = yon_char_unite(ubconfig_load_command,config_type==YON_CONFIG_GLOBAL ? " global get " : " system get ", dict->key," ", yon_dictionary_get_data(dict,char*),NULL); + FILE *output = popen(command, "r"); + char **output_strings = NULL; + output_strings = malloc(sizeof(char*)); + int i = 0; + char str[4096]; + memset(str, 0, 4096); + while (fgets(str, 4096, output)) { - char *key = yon_char_divide_search(str,"=",-1); - yon_dictionary_add_or_create_if_exists_with_data(__yon__config__strings,key,str); - __yon__config__strings->data_type=DICTIONARY_CHAR_TYPE; + if (strcmp(str, "") != 0&& strcmp(str,"(null)\n")!=0) + { + char *key = yon_char_divide_search(str,"=",-1); + char *final_str=yon_char_divide_search(str,"\n",-1); + yon_config_parameter_add_or_create_if_exists_with_data(__yon__config__strings,key,yon_char_new(final_str)); + __yon__config__strings->data_type=DICTIONARY_CHAR_TYPE; + __yon__config__strings->section=dict->key; + } } } check_config - return 0; - else return 1; + return 1; + else return 0; } /**yon_config_remove_by_key(char *key) @@ -982,35 +1171,15 @@ int yon_config_load_register(char *command){ */ int yon_config_remove_by_key(char *key){ check_config{ - dictionary *dict = yon_dictionary_get(&__yon__config__strings,key); + dictionary *dict = yon_dictionary_get((dictionary**)&__yon__config__strings,key); if (dict){ - yon_dictionary_rip(dict); + ((yon_config_parameter*)dict)->flag1=-1; return 1; }else return 0; } return 0; } -/**yon_config_remove_by_data(void *data) - * [EN] - * - * [RU] - * Производит поиск по конфигу на наличие параметра со значением [data] и удаляет найденное значение из конфига. -*/ -int yon_config_remove_by_data(void *data){ - check_config{ - dictionary *dict = NULL; - for_dictionaries(dict,__yon__config__strings){ - if (dict->data==data){ - yon_dictionary_rip(dict); - return 1; - } - } - return 0; - } - return 0; -} - /**yon_config_remove_element(char *key, char *deleted) * [EN] * @@ -1019,7 +1188,7 @@ int yon_config_remove_by_data(void *data){ */ int yon_config_remove_element(char *key, char *deleted){ check_config{ - dictionary *dict = yon_dictionary_get(&__yon__config__strings,key); + yon_config_parameter *dict = (yon_config_parameter*)yon_dictionary_get((dictionary**)&__yon__config__strings,key); char *data = (char*)dict->data; char *found = strstr(data,deleted); int size=strlen(data)-strlen(found)+1; @@ -1033,7 +1202,6 @@ int yon_config_remove_element(char *key, char *deleted){ new_data = yon_char_append(new_data,found+strlen(deleted)); } dict->data=(void*)(new_data); - free(data); dict->flag1=1; return 1; } else return 0; @@ -1048,8 +1216,8 @@ int yon_config_remove_element(char *key, char *deleted){ void *yon_config_get_by_key(char *key){ check_config{ dictionary *dict = NULL; - for_dictionaries(dict, __yon__config__strings){ - if (strcmp(dict->key,key)==0){ + for_dictionaries(dict, (dictionary*)__yon__config__strings){ + if (strcmp(dict->key,key)==0&&((yon_config_parameter*)dict)->flag1!=-1){ return dict->data; } } @@ -1057,6 +1225,21 @@ void *yon_config_get_by_key(char *key){ return NULL; } +void *yon_config_get_all_by_key(char *key, int *size){ + check_config{ + config_str ret_data=NULL; + dictionary *dict = NULL; + for_dictionaries(dict, (dictionary*)__yon__config__strings){ + if (strstr(dict->key,key)&&((yon_config_parameter*)dict)->flag1!=-1) { + char *ret_string = yon_char_unite(dict->key,"=",(char*)dict->data,NULL); + if (ret_data) ret_data = yon_char_parsed_append(ret_data,size,ret_string); + else ret_data = yon_char_parsed_new(size,ret_string,NULL); + } + } + return ret_data; + } +} + /**yon_config_get_key_by_data(char *data) * [EN] * @@ -1067,7 +1250,7 @@ void *yon_config_get_by_key(char *key){ char *yon_config_get_key_by_data(char *data){ check_config{ dictionary *dict = NULL; - for_dictionaries(dict, __yon__config__strings){ + for_dictionaries(dict, (dictionary*)__yon__config__strings){ if (strcmp(((char*)dict->data),data)==0){ return dict->key; } @@ -1084,12 +1267,32 @@ char *yon_config_get_key_by_data(char *data){ */ int yon_config_set(char *key, void *data){ check_config{ - dictionary *dict = yon_dictionary_get(&__yon__config__strings,key); + yon_config_parameter *dict = (yon_config_parameter*)yon_dictionary_get((dictionary**)&__yon__config__strings,key); dict->data=data; + dict->flag1=1; return 1; } else return 0; } + +/**yon_config_append(char *key, void *data) + * [EN] + * + * [RU] + * Производит поиск по конфигу и дополняет значение параметра с ключом [key] значением [data]; +*/ +int yon_config_append(char *key, char *data){ + check_config{ + yon_config_parameter *dict = (yon_config_parameter*)yon_dictionary_get((dictionary**)&__yon__config__strings,key); + if (strcmp(((char*)dict->data),"")!=0) + dict->data=(void*)(yon_char_unite((char*)dict->data," ",data,NULL)); + else dict->data=(void*)data; + dict->flag1=1; + return 1; + } else return 0; +} + + /**yon_config_clean() * [EN] * Erase all parameters from config; @@ -1098,7 +1301,7 @@ int yon_config_set(char *key, void *data){ */ int yon_config_clean(){ check_config{ - __yon__config__strings = yon_dictionary_free_all(__yon__config__strings, NULL); + __yon__config__strings = (yon_config_parameter*)yon_dictionary_free_all((dictionary*)__yon__config__strings, NULL); return 1; } else return 0; @@ -1112,9 +1315,14 @@ int yon_config_clean(){ * [key] - ключ параметра; * [data] - значение параметра; */ -void yon_config_register(char *key, void *data){ - yon_dictionary_add_or_create_if_exists_with_data(__yon__config__strings,key,data); +void yon_config_register(char *key, char *config_section, void *data){ + if (!__yon__config__strings||!yon_dictionary_get((dictionary**)&__yon__config__strings,key)){ + yon_config_parameter_add_or_create_if_exists_with_data(__yon__config__strings,key,data); + } + else if (yon_dictionary_get((dictionary**)&__yon__config__strings,key)) __yon__config__strings->data=data; __yon__config__strings->data_type=DICTIONARY_CHAR_TYPE; + __yon__config__strings->flag1=1; + __yon__config__strings->section=yon_char_new(config_section); } /**yon_config_load(char *command, int *str_len) @@ -1136,7 +1344,6 @@ config_str yon_config_load(char *command, int *str_len){ if (strcmp(str, "") != 0) { output_strings = realloc(output_strings, sizeof(char *) * (i + 1)); - // printf("%s\n", str); output_strings[i] = NULL; output_strings[i] = yon_char_new(str); memset(str, 0, 4096); @@ -1152,22 +1359,93 @@ config_str yon_config_load(char *command, int *str_len){ } } -/**int yon_config_save(char *command) +/**int yon_config_save_registered(char *path) * [EN] - * Saves config with [command] + * Saves config at [path] config. + * [path] can be: + * system + * global * [RU] - * Выполняет команду [command], добавляя в конец все записи конфига в таком виде: - * [ПАРАМЕТР1]="[значения1]" [ПАРАМЕТР2]="[значения2]" + * Сохраняет конфигурацию в [path] конфиг. + * [path] может быть + * system - локальный конфиг + * global - глобальный конфиг */ -int yon_config_save_registered(char *command){ +int yon_config_save_registered(char *path){ check_config{ - dictionary *dict = NULL; - for_dictionaries(dict,__yon__config__strings){ - command = yon_char_unite(command, " ", yon_dictionary_get_data(dict,char*), NULL); + dictionary *dct; + dictionary *sections_add=NULL; + dictionary *sections_remove=NULL; + for_dictionaries(dct,(dictionary*)__yon__config__strings){ + if (dct->data&&strcmp(yon_dictionary_get_data(dct,char*),"")!=0){ + if (((yon_config_parameter*)dct)->flag1==1){ + ((yon_config_parameter*)dct)->flag1=0; + if (sections_add&&yon_dictionary_get(§ions_add,((yon_config_parameter*)dct)->section)) sections_add->data=(void*)yon_char_unite(yon_dictionary_get_data(sections_add,char*)," ",dct->key,"=\"",yon_dictionary_get_data(dct,char*),"\"",NULL); + else yon_dictionary_add_or_create_if_exists_with_data(sections_add,((yon_config_parameter*)dct)->section,yon_char_unite (ubconfig_save_command,path ? yon_char_append(" --target ",path):"", " set ", ((yon_config_parameter*)dct)->section, " ",dct->key,"=\"",yon_dictionary_get_data(dct,char*),"\"",NULL)); + } else if (((yon_config_parameter*)dct)->flag1==-1){ + ((yon_config_parameter*)dct)->flag1=0; + if (sections_remove&&yon_dictionary_get(§ions_remove,((yon_config_parameter*)dct)->section)) sections_remove->data=(void*)yon_char_unite(yon_dictionary_get_data(sections_remove,char*)," ",dct->key,NULL); + else yon_dictionary_add_or_create_if_exists_with_data(sections_remove,((yon_config_parameter*)dct)->section,yon_char_unite (ubconfig_save_command,path ? yon_char_append(" --target ",path):"", " remove ", ((yon_config_parameter*)dct)->section, " ",dct->key,NULL)); + yon_dictionary_rip(dct); + } + } } - if (popen(command, "r")) return 1; - else return 0; - } else return 0; + if (sections_add) + for_dictionaries(dct,sections_add){ + char *command = yon_dictionary_get_data(dct,char*); + yon_launch(command); + } + if (sections_remove) + for_dictionaries(dct,sections_remove){ + char *command = yon_dictionary_get_data(dct,char*); + yon_launch(command); + } + return 1; + } else return 1; +} + +/**int yon_config_force_save_registered(char *path, char *section) + * [EN] + * Force config to save at [path] config ignoring parameter save status. + * [path] can be: + * system + * global + * [RU] + * Принудительно сохраняет конфигурацию в [path] конфиг игнорируя статус параметра. + * [path] может быть + * system - локальный конфиг + * global - глобальный конфиг +*/ +int yon_config_force_save_registered(char *path){ + check_config{ + dictionary *dct; + dictionary *sections_add=NULL; + dictionary *sections_remove=NULL; + for_dictionaries(dct,(dictionary*)__yon__config__strings){ + if (dct->data&&strcmp(yon_dictionary_get_data(dct,char*),"")!=0){ + if (((yon_config_parameter*)dct)->flag1==1||((yon_config_parameter*)dct)->flag1==0){ + if (sections_add&&yon_dictionary_get(§ions_add,((yon_config_parameter*)dct)->section)) sections_add->data=(void*)yon_char_unite(yon_dictionary_get_data(sections_add,char*)," ",dct->key,"=\"",yon_dictionary_get_data(dct,char*),"\"",NULL); + else yon_dictionary_add_or_create_if_exists_with_data(sections_add,((yon_config_parameter*)dct)->section,yon_char_unite (ubconfig_save_command,path ? yon_char_append(" --target ",path):"", " set ", ((yon_config_parameter*)dct)->section, " ",dct->key,"=\"",yon_dictionary_get_data(dct,char*),"\"",NULL)); + } else if (((yon_config_parameter*)dct)->flag1==-1){ + if (sections_remove&&yon_dictionary_get(§ions_remove,((yon_config_parameter*)dct)->section)) sections_remove->data=(void*)yon_char_unite(yon_dictionary_get_data(sections_remove,char*)," ",dct->key,NULL); + else yon_dictionary_add_or_create_if_exists_with_data(sections_remove,((yon_config_parameter*)dct)->section,yon_char_unite (ubconfig_save_command,path ? yon_char_append(" --target ",path):"", " remove ", ((yon_config_parameter*)dct)->section, " ",dct->key,NULL)); + } + } + } + if (sections_add) + for_dictionaries(dct,sections_add){ + char *command = yon_dictionary_get_data(dct,char*); + yon_launch(command); + } + if (sections_remove) + for_dictionaries(dct,sections_remove){ + char *command = yon_dictionary_get_data(dct,char*); + yon_launch(command); + } + + + return 1; + } else return 1; } /**yon_config_get_all(int *size) @@ -1182,13 +1460,14 @@ config_str yon_config_get_all(int *size){ *size = 1; config_str conf = NULL; dictionary *dict = NULL; - for_dictionaries(dict,__yon__config__strings){ + for_dictionaries(dict,(dictionary*)__yon__config__strings){ conf = yon_remalloc(conf,sizeof(char*)*(*size)); conf[(*size)-1] = yon_char_unite(dict->key,"=",(char*)dict->data,NULL); - size++; + (*size)++; } - conf = yon_remalloc(conf,sizeof(char*)*(*size+1)); - conf[*size] = NULL; + conf = yon_remalloc(conf,sizeof(char*)*(*size)); + conf[*size-1] = NULL; + (*size)=(*size)-1; return conf; } else return NULL; } @@ -1226,7 +1505,71 @@ char *yon_config_get_parameter(config_str parameters, int size, char *param) return NULL; } +config_str yon_file_open(char *file_path, int *size){ + *size=0; + FILE *file = fopen(file_path,"r"); + if (file){ + char str_loaded[4098]; + config_str final_string = NULL; + while (fgets(str_loaded,4098,file)){ + final_string = final_string ? yon_char_parsed_append(final_string,size,str_loaded) : yon_char_parsed_new(size,str_loaded,NULL); + } + return final_string; + } +} + +/**yon_file_create(char *path, char *name, int rules) + * [EN] + * + * [RU] + * Создать файл с названием [name], находящимся по пути [path] + * С правами доступа [rules] (от 0000 до 0777) +*/ +int yon_file_create(char *path, char *name, int rules){ + if (path&&name){ + char *full_path = yon_char_unite(path,"/",name,NULL); + if (access(full_path,F_OK)){ + FILE *fl = fopen(full_path,"w"); + if (fl){ + chmod(full_path,rules); + fclose(fl); + return 1; + } else { + return 0; + } + } else { + return -1; + } + } else { + return 0; + } +} +/**yon_file_create_full_path(char *path, char *name, int rules) + * [EN] + * + * [RU] + * Создать файл по пути [path] + * С правами доступа [rules] (от 0000 до 0777) +*/ +int yon_file_create_full_path(char *path, int rules){ + if (path){ + if (access(path,F_OK)){ + FILE *fl = fopen(path,"w"); + if (fl){ + chmod(path,rules); + fclose(fl); + return 1; + } else { + return 0; + } + } else { + return -1; + } + } else { + return 0; + } +} // terminal-using functions @@ -1297,8 +1640,7 @@ void yon_terminal_integrated_launch(GtkWidget *place_to_show, char* command, voi VtePty *pty = vte_pty_new_sync(VTE_PTY_DEFAULT,NULL,NULL); vte_terminal_set_pty(VTE_TERMINAL(terminal),pty); gtk_container_add(GTK_CONTAINER(place_to_show),terminal); - char *install_command=yon_char_unite("tput cup 0 0 && tput ed; ",command," ; sleep 5;exit 0","\n",NULL); - printf("%s\n",install_command); + char *install_command=yon_char_unite("clear;tput cup 0 0 && tput ed; ",command," ; sleep 5;exit 0","\n",NULL); if(endwork_function) g_signal_connect(G_OBJECT(terminal), "child-exited", G_CALLBACK(endwork_function), endwork_function_argument); vte_terminal_spawn_async(VTE_TERMINAL(terminal), @@ -1351,7 +1693,7 @@ void yon_terminal_integrated_start(GtkWidget *terminal, char* command, void *end 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); + char *install_command=yon_char_unite("clear;tput cup 0 0 && tput ed; ",command," ; sleep 5; stty -echo; unset PS1","\n",NULL); if(endwork_function) g_signal_connect(G_OBJECT(terminal), "child-exited", G_CALLBACK(endwork_function), endwork_function_argument); vte_terminal_spawn_async(VTE_TERMINAL(terminal), @@ -1377,7 +1719,7 @@ void yon_terminal_integrated_start(GtkWidget *terminal, char* command, void *end NULL, NULL, NULL); - vte_terminal_set_scrollback_lines(VTE_TERMINAL(terminal), 100); + vte_terminal_set_scrollback_lines(VTE_TERMINAL(terminal), -1); vte_terminal_set_scroll_on_output(VTE_TERMINAL(terminal), TRUE); vte_terminal_set_scroll_on_keystroke(VTE_TERMINAL(terminal), TRUE); gtk_widget_show_all(terminal); @@ -1424,6 +1766,11 @@ void yon_terminal_integrated_start(GtkWidget *terminal, char* command, void *end g_key_file_set_integer(__yon_window_config_file,"window","WindowHeight",__yon_main_window_config.height); g_key_file_set_integer(__yon_window_config_file,"window","fullscreen",__yon_main_window_config.fullscreen); dictionary *dict=NULL; + if (__yon_main_window_config.deleted_parameters) + for_dictionaries(dict,__yon_main_window_config.deleted_parameters){ + __yon_custom_parameter *param = yon_dictionary_get_data(dict,__yon_custom_parameter*); + g_key_file_remove_key(__yon_window_config_file,param->section,param->parameter_name,NULL); + } if (__yon_main_window_config.custom_listeners) for_dictionaries(dict,__yon_main_window_config.custom_listeners){ __yon_listener_parameter *param = yon_dictionary_get_data(dict,__yon_listener_parameter*); @@ -1459,11 +1806,7 @@ void yon_terminal_integrated_start(GtkWidget *terminal, char* command, void *end break; } } - if (__yon_main_window_config.deleted_parameters) - for_dictionaries(dict,__yon_main_window_config.deleted_parameters){ - __yon_custom_parameter *param = yon_dictionary_get_data(dict,__yon_custom_parameter*); - g_key_file_remove_key(__yon_window_config_file,param->section,param->parameter_name,NULL); - } + g_key_file_save_to_file(__yon_window_config_file,__yon_window_config_path,NULL); } @@ -1525,12 +1868,14 @@ void yon_terminal_integrated_start(GtkWidget *terminal, char* command, void *end if (!g_key_file_load_from_file(__yon_window_config_file,__yon_window_config_path,G_KEY_FILE_NONE,NULL)){ struct stat st; int size; - char *path = yon_char_divide(yon_char_new(__yon_window_config_path),yon_char_find_last(__yon_window_config_path,'/')); + config_str conf = yon_char_parse(yon_char_new(__yon_window_config_path),&size,"/"); + char *path = yon_char_unite(conf[0],"/",conf[1],"/",conf[2],"/",conf[3],"/",conf[4],"/",NULL); if (stat(path, &st) == -1) { mkdir(path, 0777); } FILE *fp; fp=fopen(__yon_window_config_path,"w"); + chmod(__yon_window_config_path,0777); fclose(fp); g_key_file_load_from_file(__yon_window_config_file,__yon_window_config_path,G_KEY_FILE_NONE,NULL); } @@ -1580,7 +1925,7 @@ void yon_terminal_integrated_start(GtkWidget *terminal, char* command, void *end return key; } - /**yon_window_config_add_listener(GtkWidget *widget, char *param_name, char *widget_property, enum YON_TYPE val_type) + /**yon_window_config_add_custom_parameter(GtkWidget *widget, char *param_name, char *widget_property) * [EN] * * [RU] @@ -1604,6 +1949,23 @@ void yon_terminal_integrated_start(GtkWidget *terminal, char* command, void *end param->property = tracked_value; param->containing_type = val_type; yon_dictionary_add_or_create_if_exists_with_data(__yon_main_window_config.custom_parameters,param->parameter_name,param); + dictionary *dict=NULL; + if (__yon_main_window_config.deleted_parameters) + for_dictionaries(dict,__yon_main_window_config.deleted_parameters){ + if (strcmp(dict->key,param->parameter_name)) + yon_dictionary_rip(dict); + } + } + + void yon_window_config_add_instant_parameter(char *param_name, char *section, void *tracked_value, enum YON_TYPE val_type){ + switch (val_type){ + case YON_TYPE_BOOLEAN: g_key_file_set_boolean(__yon_window_config_file,section,param_name,*((gboolean*)tracked_value)); + break; + case YON_TYPE_INT: g_key_file_set_integer(__yon_window_config_file,section,param_name,*((int*)tracked_value)); + break; + case YON_TYPE_STRING: g_key_file_set_string(__yon_window_config_file,section,param_name,(char*)tracked_value); + break; + } } void yon_window_config_erase_custom_parameter(char *param_name, char *section){ @@ -1613,7 +1975,7 @@ void yon_terminal_integrated_start(GtkWidget *terminal, char* command, void *end param->section=section; yon_dictionary_add_or_create_if_exists_with_data(__yon_main_window_config.deleted_parameters,param->parameter_name,param); } - + int yon_window_config_get_parameter(char *section, char *config_parameter, void *return_value, enum YON_TYPE type){ GError *err=NULL; switch (type){ @@ -1639,6 +2001,81 @@ void yon_terminal_integrated_start(GtkWidget *terminal, char* command, void *end } } + void yon_on_window_config_custom_window_destroy(GtkWindow *window, char *window_name){ + if (!gtk_window_is_maximized(window)){ + int height=0; + int width=0; + int X=0; + int Y=0; + gtk_window_get_position(window,&X,&Y); + yon_window_config_add_instant_parameter(yon_char_append(window_name,"PosX"),"window",&X,YON_TYPE_INT); + yon_window_config_add_instant_parameter(yon_char_append(window_name,"PosY"),"window",&Y,YON_TYPE_INT); + + } + } + + void yon_on_window_config_custom_window_resize(GtkWindow *window, char *window_name){ + if (!gtk_window_is_maximized(window)){ + int height=0; + int width=0; + int X=0; + int Y=0; + gtk_window_get_size(window,&width,&height); + gtk_window_get_position(window,&X,&Y); + yon_window_config_add_instant_parameter(yon_char_append(window_name,"Width"),"window",&width,YON_TYPE_INT); + yon_window_config_add_instant_parameter(yon_char_append(window_name,"Height"),"window",&height,YON_TYPE_INT); + yon_window_config_add_instant_parameter(yon_char_append(window_name,"PosX"),"window",&X,YON_TYPE_INT); + yon_window_config_add_instant_parameter(yon_char_append(window_name,"PosY"),"window",&Y,YON_TYPE_INT); + } + + } + + void yon_window_config_custom_window_setup(GtkWindow *window, char *window_name){ + int height=0; + int width=0; + int X=0; + int Y=0; + yon_window_config_get_parameter("window",yon_char_append(window_name,"Width"),&width,YON_TYPE_INT); + yon_window_config_get_parameter("window",yon_char_append(window_name,"Height"),&height,YON_TYPE_INT); + yon_window_config_get_parameter("window",yon_char_append(window_name,"PosX"),&X,YON_TYPE_INT); + yon_window_config_get_parameter("window",yon_char_append(window_name,"PosY"),&Y,YON_TYPE_INT); + if (width&&height) + gtk_window_resize(window,width,height); + if (X&&Y) + gtk_window_move(window,X,Y); + char *signals_window_name = yon_char_new(window_name); + g_signal_connect(G_OBJECT(window),"check-resize",G_CALLBACK(yon_on_window_config_custom_window_resize),signals_window_name); + g_signal_connect(G_OBJECT(window),"delete-event",G_CALLBACK(yon_on_window_config_custom_window_destroy),signals_window_name); + } + + void yon_window_config_custom_window_get(GtkWindow *window, char *window_name){ + int height=0; + int width=0; + int X=0; + int Y=0; + yon_window_config_get_parameter("window",yon_char_append(window_name,"Width"),&width,YON_TYPE_INT); + yon_window_config_get_parameter("window",yon_char_append(window_name,"Height"),&height,YON_TYPE_INT); + yon_window_config_get_parameter("window",yon_char_append(window_name,"PosX"),&X,YON_TYPE_INT); + yon_window_config_get_parameter("window",yon_char_append(window_name,"PosY"),&Y,YON_TYPE_INT); + if (width&&height) + gtk_window_resize(window,width,height); + if (X&&Y) + gtk_window_move(window,X,Y); + } + + void yon_window_config_custom_window_set(GtkWindow *window, char *window_name){ + int height=0; + int width=0; + int X=0; + int Y=0; + gtk_window_get_size(window,&width,&height); + gtk_window_get_position(window,&X,&Y); + yon_window_config_add_instant_parameter(yon_char_append(window_name,"Width"),"window",&width,YON_TYPE_INT); + yon_window_config_add_instant_parameter(yon_char_append(window_name,"Height"),"window",&height,YON_TYPE_INT); + yon_window_config_add_instant_parameter(yon_char_append(window_name,"PosX"),"window",&X,YON_TYPE_INT); + yon_window_config_add_instant_parameter(yon_char_append(window_name,"PosY"),"window",&Y,YON_TYPE_INT); + } + GtkWidget *yon_ubl_menu_item_about_new(char *buttonname){ GtkWidget *menu_item = gtk_menu_item_new(); gtk_style_context_add_class(gtk_widget_get_style_context(menu_item),"menuitembottom"); @@ -1655,7 +2092,7 @@ GtkWidget *yon_ubl_menu_item_about_new(char *buttonname){ GtkWidget *yon_ubl_menu_item_documentation_new(char *buttonname){ GtkWidget *menu_item = gtk_menu_item_new(); - gtk_style_context_add_class(gtk_widget_get_style_context(menu_item),"menuitemtop"); + gtk_style_context_add_class(gtk_widget_get_style_context(menu_item),"menuitemmiddle"); GtkWidget *box = gtk_box_new(GTK_ORIENTATION_HORIZONTAL,0); GtkWidget *label = gtk_label_new(buttonname); GtkWidget *image = gtk_image_new_from_icon_name("dialog-question-symbolic",GTK_ICON_SIZE_BUTTON); @@ -1670,13 +2107,13 @@ GtkWidget *yon_ubl_menu_item_documentation_new(char *buttonname){ // other Gtk functions -/**yon_gtk_combo_box_text_fill(GtkWidget *combo, config_str parameters,int size) +/**yon_gtk_combo_box_fill(GtkWidget *combo, config_str parameters,int size) * [EN] * * [RU] * Добавляет в Комбобокс [combo] все строки из массива строк [parameters] размера [size] */ -int yon_gtk_combo_box_text_fill(GtkWidget *combo, config_str parameters,int size){ +int yon_gtk_combo_box_fill(GtkWidget *combo, config_str parameters,int size){ if (combo&¶meters){ for (int i=0;i0 ? 1 : 0); +} + +void yon_gtk_widget_set_sensitive_from_combo_box_inversed(GtkComboBox *toggle, GtkWidget *target){ + gtk_widget_set_sensitive(target,!gtk_combo_box_get_active(toggle)>0 ? 0 : 1); +} void _yon_ubl_header_setup(GtkWidget *Overlay, GtkWidget *Head, GtkWidget *Image, char *image_path) { @@ -1799,6 +2257,115 @@ void yon_ubl_status_box_render(char *text, BACKGROUND_IMAGE_TYPE type){ _yon_ubl_status_box_render(text,type); } +void _yon_ubl_status_highlight_incorrect(GtkWidget *widget){ + gtk_style_context_add_class(gtk_widget_get_style_context(widget),"errorBox"); + sleep(5); + gtk_style_context_remove_class(gtk_widget_get_style_context(widget),"errorBox"); +} + +void yon_ubl_status_highlight_incorrect(GtkWidget *widget){ + GThread *thread = g_thread_new(NULL,(GThreadFunc)_yon_ubl_status_highlight_incorrect,widget); +} + +void _yon_ubl_status_list_store_highlight_incorrect(GtkWidget **widget_pack){ + GtkListStore *list = (GtkListStore*)widget_pack[0]; + GtkTreeIter *iter = (GtkTreeIter*)widget_pack[1]; + GdkRGBA rgba,rgba2; + rgba.alpha=1; + rgba.blue=153.0/255.0; + rgba.green=153.0/255.0; + rgba.red=234.0/255.0; + rgba2.alpha=1; + rgba2.blue=0; + rgba2.green=0; + rgba2.red=0; + gtk_list_store_set(list,iter,1,gdk_rgba_to_string(&rgba2),2,gdk_rgba_to_string(&rgba),-1); + sleep(5); + gtk_list_store_set(list,iter,1,NULL,2,NULL,-1); +} + +void yon_ubl_status_list_store_highlight_incorrect(GtkListStore *list, GtkTreeIter *iter){ + GtkWidget **pack = malloc(sizeof(GtkWidget *)*2); + pack[0]=(GtkWidget*)list; + pack[1]=(GtkWidget*)iter; + GThread *thread = g_thread_new(NULL,(GThreadFunc)_yon_ubl_status_list_store_highlight_incorrect,pack); +} + +struct temp_statusbox { + int times; + GtkWidget *revealer; + }; + +void _yon_ubl_status_box_timed_remove(struct temp_statusbox *statusstruct){ + sleep(statusstruct->times); + if (status_thread_busy){ + gtk_revealer_set_reveal_child(GTK_REVEALER(statusstruct->revealer),0); + sleep(1); + gtk_widget_destroy(statusstruct->revealer); + + } + status_thread_busy=0; +} + +void __yon_ubl_status_box_destroyed(){ + status_thread_busy=0; +} + +void yon_ubl_status_box_spawn(GtkContainer *container,char *display_text, int timeout,BACKGROUND_IMAGE_TYPE type){ + if (!status_thread_busy){ + GtkWidget *box = gtk_box_new(GTK_ORIENTATION_HORIZONTAL,5); + GtkWidget *revealer = gtk_revealer_new(); + GtkWidget *label = gtk_label_new(""); + GtkWidget *icon = gtk_image_new(); + gtk_container_add(GTK_CONTAINER(revealer),box); + gtk_box_pack_start(GTK_BOX(box),icon,0,0,5); + gtk_box_pack_start(GTK_BOX(box),label,0,0,5); + gtk_container_add(container,revealer); + + gtk_widget_show_all(revealer); + gtk_revealer_set_reveal_child(GTK_REVEALER(revealer),1); + g_signal_connect(G_OBJECT(revealer),"destroy", G_CALLBACK(__yon_ubl_status_box_destroyed),NULL); + + gtk_widget_set_margin_bottom(label,9); + gtk_widget_set_margin_top(label,9); + gtk_label_set_xalign(GTK_LABEL(label),0.0); + PangoAttrList *attributes = pango_attr_list_new(); + PangoAttribute *boldAttr = pango_attr_weight_new(PANGO_WEIGHT_BOLD); + pango_attr_list_insert(attributes, boldAttr); + gtk_label_set_attributes(GTK_LABEL(label),attributes); + + GdkRGBA textColor; + gdk_rgba_parse(&textColor, "#4d4d4d4d4d4d"); + PangoAttribute *colorAttr = pango_attr_foreground_new( + (int)(textColor.red * 65535), + (int)(textColor.green * 65535), + (int)(textColor.blue * 65535) + ); + pango_attr_list_insert(attributes, colorAttr); + + GtkIconTheme *ictheme = gtk_icon_theme_get_default(); + if (type == BACKGROUND_IMAGE_SUCCESS_TYPE||! type) + { + gtk_style_context_remove_class(gtk_widget_get_style_context(box), "boxInfoMessError"); + gtk_style_context_add_class(gtk_widget_get_style_context(box), "boxInfoMessOK"); + gtk_image_set_from_pixbuf(GTK_IMAGE(icon), gtk_icon_theme_load_icon_for_scale(ictheme, "com.ublinux.ubl-settings-logging.checked", 25, 1, GTK_ICON_LOOKUP_FORCE_SIZE, NULL)); + } + else if (type == BACKGROUND_IMAGE_FAIL_TYPE) + { + gtk_style_context_remove_class(gtk_widget_get_style_context(box), "boxInfoMessOK"); + gtk_style_context_add_class(gtk_widget_get_style_context(box), "boxInfoMessError"); + gtk_image_set_from_pixbuf(GTK_IMAGE(icon), gtk_icon_theme_load_icon_for_scale(ictheme, "com.ublinux.ubl-settings-logging.warning", 25, 1, GTK_ICON_LOOKUP_FORCE_SIZE, NULL)); + } + if (display_text) + gtk_label_set_text(GTK_LABEL(label),display_text); + struct temp_statusbox *statusstruct = malloc(sizeof(struct temp_statusbox)); + statusstruct->revealer = revealer; + statusstruct->times = timeout; + GThread *thread = g_thread_new("StatusThread",(GThreadFunc)_yon_ubl_status_box_timed_remove,statusstruct); + status_thread_busy=1; + } +} + /**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. diff --git a/ubl-utils/ubl-utils.h b/ubl-utils/ubl-utils.h index 1e845f1..2fef789 100644 --- a/ubl-utils/ubl-utils.h +++ b/ubl-utils/ubl-utils.h @@ -14,8 +14,10 @@ #include #include #include +#include +#include -#include "ubl-cmake.h" +#include "../compile/ubl-cmake.h" #ifdef WEBKIT_FOUND #include #endif @@ -48,9 +50,11 @@ typedef struct dictionary struct dictionary *prev; struct dictionary *first; DICT_TYPE data_type; - int flag1; } dictionary; + + + typedef struct apps { char *Name; @@ -64,13 +68,8 @@ typedef struct apps typedef char** config_str; -static dictionary *__yon__config__strings = NULL; -#define check_config if(__yon__config__strings&&__yon__config__strings->data_type==DICTIONARY_CHAR_TYPE) - #define config(key) yon_config_get_by_key(key) -#define for_config dictionary temp = NULL; for_dictionary(temp,__yon__config__strings) - #define yon_remalloc(pointer, size) (!pointer) ? malloc(size) : realloc(pointer, size) // dictionary functions @@ -124,6 +123,10 @@ void *yon_dictionary_free_all(dictionary *dictionary,void (data_manipulation)(vo // char functions +#define yon_char_divide_search_self(str,find,delete_divider) {char *temp = str; str = yon_char_divide_search(str,find,delete_divider); free(temp);} + +#define yon_char_is_empty(string) !(string&&strcmp(string,"")) + int yon_char_find_last(char *source, char find); char *yon_char_append(char *source, char *append); @@ -140,6 +143,10 @@ char *yon_char_divide_search(char *source, char *dividepos, int delete_divider); char *yon_char_from_int(int int_to_convert); +char *yon_char_from_float(float int_to_convert); + +char *yon_char_from_long(long int_to_convert); + char *yon_char_replace(char *source, char *find, char*replace); char **yon_char_parse(char *parameters, int *size, char *divider); @@ -148,12 +155,16 @@ char **yon_char_parsed_rip(char **char_string, int *size, int item_to_delete); int yon_char_parsed_check_exist(char **parameters, int size, char *param); +int yon_char_parsed_check_repeats(char **parameters, int size, int *first_overlap, int *second_overlap); + int yon_char_find_count(char *source, char *find); 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 (int *size, ...); +void yon_char_parsed_free(config_str source, int size); + void yon_char_parsed_copy(config_str *source, config_str *to_copy); config_str yon_char_parsed_append(config_str parsed, int *size, char *string); @@ -164,8 +175,12 @@ char *yon_ubl_root_user_get(); char *yon_ubl_user_get_home_directory(); +config_str yon_ubl_get_all_users(int *user_size); + // parsing functions +float yon_size_convert_automatic(int bytes, int *size); + config_str philos_list_user(int* size); apps *yon_apps_scan_and_parse_desktops(int *sizef); @@ -174,13 +189,34 @@ void yon_apps_sort(apps *applist, int size); apps *yon_apps_get_by_name(apps *applist, char *name, int size); +config_str yon_file_open(char *file_path, int *size); + +int yon_file_create(char *path, char *name, int rules); + +int yon_file_create_full_path(char *path, int rules); + +config_str yon_dir_get_contents(char *dir_path, int *size); + +//config functions + +#define ubconfig_save_command "ubconfig" +#define ubconfig_load_command "ubconfig --source" + +typedef enum { + YON_CONFIG_LOCAL=0, + YON_CONFIG_GLOBAL, + YON_CONFIG_BOTH +} YON_CONFIG_TYPE; + config_str yon_config_load(char *command, int *str_len); -int yon_config_save_registered(char *command); +int yon_config_save_registered(char *path); + +int yon_config_force_save_registered(char *path); char *yon_config_get_parameter(config_str parameters, int size, char *param); -int yon_config_load_register(char *command); +int yon_config_load_register(YON_CONFIG_TYPE config_type,char *section,char *parameter, ...); int yon_config_remove_by_key(char *key); @@ -190,13 +226,15 @@ int yon_config_remove_element(char *key, char *deleted); void *yon_config_get_by_key(char *key); +void *yon_config_get_all_by_key(char *key, int *size); + char *yon_config_get_key_by_data(char *data); int yon_config_set(char *key, void *data); int yon_config_clean(); -void yon_config_register(char *key, void *data); +void yon_config_register(char *key, char* config_section, void *data); config_str yon_config_get_all(); @@ -257,10 +295,18 @@ void yon_window_config_erase_custom_parameter(char *param_name, char *section); int yon_window_config_get_parameter(char *section, char *config_parameter, void *return_value, enum YON_TYPE type); +void yon_window_config_custom_window_setup(GtkWindow *window, char *window_name); + +void yon_window_config_custom_window_get(GtkWindow *window, char *window_name); + +void yon_window_config_custom_window_set(GtkWindow *window, char *window_name); + 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); +void yon_gtk_column_minimal_fixed_size_set(GtkTreeViewColumn *column); + int yon_gtk_icon_view_hide_empty(dictionary *icon_view_segment); int yon_dictionary_gtk_pack_start_multiple_widgets(GtkBox *destination, gboolean expand, gboolean fill, int padding, ...); @@ -268,6 +314,10 @@ int yon_dictionary_gtk_pack_start_multiple_widgets(GtkBox *destination, gboolean int yon_dictionary_gtk_pack_end_multiple_widgets(GtkBox *destination, gboolean expand, gboolean fill, int padding, ...); +void yon_gtk_widget_set_sensitive_from_toggle_button(GtkToggleButton *toggle, GtkWidget *target); +void yon_gtk_widget_set_sensitive_from_toggle_button_inversed(GtkToggleButton *toggle, GtkWidget *target); +void yon_gtk_widget_set_sensitive_from_combo_box(GtkComboBox *toggle, GtkWidget *target); +void yon_gtk_widget_set_sensitive_from_combo_box_inversed(GtkComboBox *toggle, GtkWidget *target); typedef enum { @@ -315,6 +365,13 @@ int yon_ubl_status_box_setup(GtkWidget *icon, GtkWidget *box, GtkWidget *label); */ void yon_ubl_status_box_render(char *text, BACKGROUND_IMAGE_TYPE type); +void yon_ubl_status_highlight_incorrect(GtkWidget *widget); + +void yon_ubl_status_list_store_highlight_incorrect(GtkListStore *list, GtkTreeIter *iter); + +static int status_thread_busy; +void yon_ubl_status_box_spawn(GtkContainer *container,char *display_text, int timeout,BACKGROUND_IMAGE_TYPE type); + #ifdef __cplusplus /**yon_ubl_header_setup(overlay, head, image, imag_path) diff --git a/ublsettings-ui-about.glade b/ublsettings-ui-about.glade new file mode 100644 index 0000000..cf83633 --- /dev/null +++ b/ublsettings-ui-about.glade @@ -0,0 +1,64 @@ + + + + + + False + False + True + center + com.ublinux.ublsettings-ui + dialog + True + ublsettings-ui + 1.1 + Copyright © 2022 - 2023, UBSoft LLC + TEMPLATE Manager + https://wiki.ublinux.ru/ru/Программное_обеспечение/Программы_и_утилиты/Все/ublsettings-ui + Project Home Page + Это приложение распространяется без каких-либо гарантий. +Подробнее в <a href="https://www.gnu.org/licenses/old-licenses/gpl-2.0.html">GNU General Public License, версии 2 или позднее</a>. + UBGroup + UBGroup + com.ublinux.ublsettings-ui + True + gpl-2-0 + + + False + + + False + + + False + False + 0 + + + + + + + True + False + True + + + True + False + 5 + 5 + 5 + 5 + 2 + TEMPLATE Manager + + + + + + + + + diff --git a/ublsettings-ui-documentation.glade b/ublsettings-ui-documentation.glade new file mode 100644 index 0000000..8629012 --- /dev/null +++ b/ublsettings-ui-documentation.glade @@ -0,0 +1,208 @@ + + + + + + False + False + 450 + dialog-question-symbolic + + + True + False + 5 + 5 + 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 + + + + + Open documentation + True + True + True + image9 + + + + True + True + 1 + + + + + False + True + 1 + + + + + + + True + False + True + + + True + False + TEMPLATE Manager + + + + + + + + + + True + False + process-stop-symbolic + + + True + False + emblem-ok-symbolic + + diff --git a/ublsettings-ui-save-confirmation.glade b/ublsettings-ui-save-confirmation.glade new file mode 100644 index 0000000..168da42 --- /dev/null +++ b/ublsettings-ui-save-confirmation.glade @@ -0,0 +1,145 @@ + + + + + + True + False + process-stop-symbolic + + + True + False + emblem-ok-symbolic + + + + + + + + + + + False + False + 450 + dialog-question-symbolic + + + True + False + 5 + 5 + 5 + 5 + 5 + 5 + vertical + 10 + + + True + True + liststore1 + + + + + + Parameter + + + + 0 + + + + + + + Save + + + + 1 + + + + + + + True + True + 0 + + + + + True + False + end + 5 + True + + + Cancel + True + True + True + image8 + + + + True + True + 0 + + + + + Accept + True + True + True + image9 + + + + True + True + 1 + + + + + False + True + 1 + + + + + + + True + False + True + + + True + False + ubl-settings-TEMPLATES + + + + + + + + + diff --git a/ublsettings-ui.glade b/ublsettings-ui.glade index fdaf89d..4c0777b 100644 --- a/ublsettings-ui.glade +++ b/ublsettings-ui.glade @@ -25,69 +25,6 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - - False - False - True - center - com.ublinux.ublsettings-ui - dialog - True - ublsettings-ui - 1.1 - Copyright © 2022 - 2023, UBSoft LLC - TEMPLATE Manager - https://wiki.ublinux.ru/ru/Программное_обеспечение/Программы_и_утилиты/Все/ublsettings-ui - Project Home Page - Это приложение распространяется без каких-либо гарантий. -Подробнее в <a href="https://www.gnu.org/licenses/old-licenses/gpl-2.0.html">GNU General Public License, версии 2 или позднее</a>. - UBGroup - UBGroup - com.ublinux.ublsettings-ui - True - gpl-2-0 - - - True - False - vertical - 2 - - - False - end - - - False - False - 1 - - - - - - - True - False - True - - - True - False - 5 - 5 - 5 - 5 - 2 - TEMPLATE Manager - - - - - - - - True False @@ -191,207 +128,6 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - - True - False - process-stop-symbolic - - - True - False - emblem-ok-symbolic - - - False - False - 450 - dialog-question-symbolic - - - True - False - 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 - - - - - Open documentation - True - True - True - image9 - - - - True - True - 1 - - - - - False - True - 1 - - - - - - - True - False - True - - - True - False - TEMPLATE Manager - - - - - - - - True False diff --git a/ublsettings-ui.pot b/ublsettings-ui.pot index b516b52..f12d952 100644 --- a/ublsettings-ui.pot +++ b/ublsettings-ui.pot @@ -17,158 +17,106 @@ msgstr "" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -#: source/ubl-strings.h:1 -msgid "Version:" -msgstr "" - -#: source/ubl-strings.h:2 -msgid "ublsettings-ui version:" -msgstr "" - -#: source/ubl-strings.h:2 -msgid "TEMPLATE settings" -msgstr "" - -#: source/ubl-strings.h:2 -msgid "Usage:" -msgstr "" - -#: source/ubl-strings.h:2 -msgid "[OPTIONS]" -msgstr "" - -#: source/ubl-strings.h:2 -msgid "Options:" -msgstr "" - -#: source/ubl-strings.h:2 -msgid "Show this help" -msgstr "" - -#: source/ubl-strings.h:2 -msgid "Show package version" -msgstr "" - -#: source/ubl-strings.h:2 -msgid "Lock this help menu" -msgstr "" - -#: source/ubl-strings.h:2 -msgid "Lock configuration saving" -msgstr "" - -#: source/ubl-strings.h:2 -msgid "Lock local configration saving" -msgstr "" - -#: source/ubl-strings.h:2 -msgid "Lock global configration saving" -msgstr "" - -#: source/ubl-strings.h:2 -msgid "Lock global configration loading" -msgstr "" - -#: source/ubl-strings.h:4 -msgid "TEMPLATE Manager" -msgstr "" - -#: source/ubl-strings.h:5 -msgid "TEMPLATE management app" -msgstr "" - -#: source/ubl-strings.h:7 +#: source/ublsettings-ui.h:31 msgid "Operation succeeded" msgstr "" -#: source/ubl-strings.h:8 +#: source/ublsettings-ui.h:32 msgid "" "Warning! Application was launched without root - root-dependent actions are " "locked" msgstr "" -#: source/ubl-strings.h:10 +#: source/ublsettings-ui.h:34 msgid "About" msgstr "" -#: source/ubl-strings.h:11 +#: source/ublsettings-ui.h:35 msgid "Documentation" msgstr "" -#: source/ubl-strings.h:12 +#: source/ublsettings-ui.h:37 msgid "Save to local configuration" msgstr "" -#: source/ubl-strings.h:13 +#: source/ublsettings-ui.h:38 msgid "Save to global configuration" msgstr "" -#: source/ubl-strings.h:14 +#: source/ublsettings-ui.h:39 msgid "Save configuration" msgstr "" -#: source/ubl-strings.h:15 +#: source/ublsettings-ui.h:40 msgid "Save" msgstr "" -#: source/ubl-strings.h:16 +#: source/ublsettings-ui.h:42 msgid "Load local configuration" msgstr "" -#: source/ubl-strings.h:17 +#: source/ublsettings-ui.h:43 msgid "Load global configuration" msgstr "" -#: source/ubl-strings.h:18 +#: source/ublsettings-ui.h:44 msgid "Load" msgstr "" -#: source/ubl-strings.h:20 +#: source/ublsettings-ui.h:46 msgid "Cancel" msgstr "" -#: source/ubl-strings.h:22 +#: source/ublsettings-ui.h:47 +msgid "Accept" +msgstr "" + +#: source/ublsettings-ui.h:49 msgid "Would you like to read documentation in the Web?" msgstr "" -#: source/ubl-strings.h:23 +#: source/ublsettings-ui.h:50 msgid "" "You will be redirected to documentation website where documentation is\n" "translated and supported by community." msgstr "" -#: source/ubl-strings.h:24 +#: source/ublsettings-ui.h:51 msgid "Always redirect to online documentation" msgstr "" -#: source/ubl-strings.h:25 +#: source/ublsettings-ui.h:52 msgid "Open documentation" msgstr "" -#: source/ubl-strings.h:26 +#: source/ublsettings-ui.h:53 msgid "Project Home Page" msgstr "" -#: source/ubl-strings.h:27 +#: source/ublsettings-ui.h:54 msgid "Nothing were chosen" msgstr "" -#: source/ubl-strings.h:30 -msgid "Global configuration loading succseeded." +#: source/ublsettings-ui.h:57 +msgid "Global configuration loading succeeded." +msgstr "" + +#: source/ublsettings-ui.h:58 +msgid "Local configuration loading succeeded." msgstr "" -#: source/ubl-strings.h:31 -msgid "Local configuration loading succseeded." +#: source/ublsettings-ui.h:59 +msgid "Config loading failed" msgstr "" -#: source/ubl-strings.h:33 -msgid "Local and global configuration saving succseeded." +#: source/ublsettings-ui.h:61 +msgid "Local and global configuration saving succeeded." msgstr "" -#: source/ubl-strings.h:34 -msgid "Global configuration saving succseeded." +#: source/ublsettings-ui.h:62 +msgid "Global configuration saving succeeded." msgstr "" -#: source/ubl-strings.h:35 -msgid "Local configuration saving succseeded." +#: source/ublsettings-ui.h:63 +msgid "Local configuration saving succeeded." msgstr "" diff --git a/ublsettings-ui_ru.po b/ublsettings-ui_ru.po index 1ff99b7..a2719cf 100644 --- a/ublsettings-ui_ru.po +++ b/ublsettings-ui_ru.po @@ -17,122 +17,67 @@ msgstr "" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -#: source/ubl-strings.h:1 -msgid "Version:" -msgstr "Версия:" - -#: source/ubl-strings.h:2 -msgid "ublsettings-ui version:" -msgstr "Версия ublsettings-ui: " - -#: source/ubl-strings.h:2 -msgid "TEMPLATE settings" -msgstr "Настройки TEMPLATE" - -#: source/ubl-strings.h:2 -msgid "Usage:" -msgstr "Использование:" - -#: source/ubl-strings.h:2 -msgid "[OPTIONS]" -msgstr "[АРГУМЕНТЫ]" - -#: source/ubl-strings.h:2 -msgid "Options:" -msgstr "Аргументы:" - -#: source/ubl-strings.h:2 -msgid "Show this help" -msgstr "Показать параметры справки" - -#: source/ubl-strings.h:2 -msgid "Show package version" -msgstr "Показать текущую версию" - -#: source/ubl-strings.h:2 -msgid "Lock this help menu" -msgstr "Блокировка вызова справки" - -#: source/ubl-strings.h:2 -#, fuzzy -msgid "Lock configuration saving" -msgstr "Блокировка сохранения локальной и глобальной конфигурации" - -#: source/ubl-strings.h:2 -msgid "Lock local configration saving" -msgstr "Блокировка сохранения локальной конфигурации" - -#: source/ubl-strings.h:2 -msgid "Lock global configration saving" -msgstr "Блокировка сохранения глобальной конфигурации" - -#: source/ubl-strings.h:2 -msgid "Lock global configration loading" -msgstr "Блокировка загрузки глобальной конфигурации" - -#: source/ubl-strings.h:4 -msgid "TEMPLATE Manager" -msgstr "Настройки TEMPLATE" - -#: source/ubl-strings.h:5 -msgid "TEMPLATE management app" -msgstr "Настройки TEMPLATE" - -#: source/ubl-strings.h:7 +#: source/ublsettings-ui.h:31 msgid "Operation succeeded" msgstr "Операция завершена" -#: source/ubl-strings.h:8 +#: source/ublsettings-ui.h:32 msgid "" "Warning! Application was launched without root - root-dependent actions are " "locked" -msgstr "Внимание! Приложение было запущено без прав суперпользователя - действия, требующие их наличия заблокированы" +msgstr "" +"Внимание! Приложение было запущено без прав суперпользователя - действия, " +"требующие их наличия заблокированы" -#: source/ubl-strings.h:10 +#: source/ublsettings-ui.h:34 msgid "About" msgstr "О программе" -#: source/ubl-strings.h:11 +#: source/ublsettings-ui.h:35 msgid "Documentation" msgstr "Справка" -#: source/ubl-strings.h:12 +#: source/ublsettings-ui.h:37 msgid "Save to local configuration" msgstr "Сохранить в локальную конфигурацию" -#: source/ubl-strings.h:13 +#: source/ublsettings-ui.h:38 msgid "Save to global configuration" msgstr "Сохранить в глобальную конфигурацию" -#: source/ubl-strings.h:14 +#: source/ublsettings-ui.h:39 msgid "Save configuration" msgstr "Сохранить конфигурацию" -#: source/ubl-strings.h:15 +#: source/ublsettings-ui.h:40 msgid "Save" msgstr "Сохранить" -#: source/ubl-strings.h:16 +#: source/ublsettings-ui.h:42 msgid "Load local configuration" msgstr "Загрузить локальную конфигуруцию" -#: source/ubl-strings.h:17 +#: source/ublsettings-ui.h:43 msgid "Load global configuration" msgstr "Загрузить глобальную конфигурацию" -#: source/ubl-strings.h:18 +#: source/ublsettings-ui.h:44 msgid "Load" msgstr "Загрузить" -#: source/ubl-strings.h:20 +#: source/ublsettings-ui.h:46 msgid "Cancel" msgstr "Отмена" -#: source/ubl-strings.h:22 +#: source/ublsettings-ui.h:47 +msgid "Accept" +msgstr "Принять" + +#: source/ublsettings-ui.h:49 msgid "Would you like to read documentation in the Web?" msgstr "Вы хотите прочитать справку в Сети?" -#: source/ubl-strings.h:23 +#: source/ublsettings-ui.h:50 msgid "" "You will be redirected to documentation website where documentation is\n" "translated and supported by community." @@ -140,38 +85,42 @@ msgstr "" "Вы будете перенаправлены на сайт с документацией, где страницы помощи\n" "переводятся и поддерживаются сообществом." -#: source/ubl-strings.h:24 +#: source/ublsettings-ui.h:51 msgid "Always redirect to online documentation" msgstr "Всегда перенаправлять" -#: source/ubl-strings.h:25 +#: source/ublsettings-ui.h:52 msgid "Open documentation" msgstr "Прочитать справку" -#: source/ubl-strings.h:26 +#: source/ublsettings-ui.h:53 msgid "Project Home Page" msgstr "Домашняя страница проекта" -#: source/ubl-strings.h:27 +#: source/ublsettings-ui.h:54 msgid "Nothing were chosen" msgstr "Ничего не было выбрано" -#: source/ubl-strings.h:30 -msgid "Global configuration loading succseeded." +#: source/ublsettings-ui.h:57 +msgid "Global configuration loading succeeded." msgstr "Успешно загружена глобальная конфигурация" -#: source/ubl-strings.h:31 -msgid "Local configuration loading succseeded." +#: source/ublsettings-ui.h:58 +msgid "Local configuration loading succeeded." msgstr "Успешно загружена локальная конфигурация" -#: source/ubl-strings.h:33 -msgid "Local and global configuration saving succseeded." +#: source/ublsettings-ui.h:59 +msgid "Config loading failed" +msgstr "" + +#: source/ublsettings-ui.h:61 +msgid "Local and global configuration saving succeeded." msgstr "Успешно записаны локальная и глобальная конфигурация" -#: source/ubl-strings.h:34 -msgid "Global configuration saving succseeded." +#: source/ublsettings-ui.h:62 +msgid "Global configuration saving succeeded." msgstr "Успешно записана глобальная конфигурация" -#: source/ubl-strings.h:35 -msgid "Local configuration saving succseeded." -msgstr "Успешно записана локальная конфигурация" +#: source/ublsettings-ui.h:63 +msgid "Local configuration saving succeeded." +msgstr "Успешно записана локальная конфигурация" \ No newline at end of file From ba217e33ea0c4883b27dd9fd38aef4a00f737797 Mon Sep 17 00:00:00 2001 From: Ivan Yarcev Date: Thu, 30 Nov 2023 16:28:13 +0600 Subject: [PATCH 5/7] Changed gitignore --- .gitignore | 133 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 133 insertions(+) diff --git a/.gitignore b/.gitignore index e11513c..370ce61 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,136 @@ +# ---> C +# Prerequisites +*.d + +# Object files +*.o +*.ko +*.obj +*.elf + +# Linker output +*.ilk +*.map +*.exp + +# Precompiled Headers +*.gch +*.pch + +# Libraries +*.lib +*.a +*.la +*.lo + +# Shared objects (inc. Windows DLLs) +*.dll +*.so +*.so.* +*.dylib + +# Executables +*.exe +*.out +*.app +*.i*86 +*.x86_64 +*.hex + +# Debug files +*.dSYM/ +*.su +*.idb +*.pdb + +# Kernel Module Compile Results +*.mod* +*.cmd +.tmp_versions/ +modules.order +Module.symvers +Mkfile.old +dkms.conf + +# Ubl projects output +.vscode/ +ubl-settings-TEMPLATE +*~ +build/ +*compile/ +*# +terminal-commands/ +source/ubl-cmake.h +vgcore* +.BUILD.md +.updatebuild.sh +.install.sh +ublsettings-ui-debug +.install-debug.sh + +# ---> C++ +# Prerequisites +*.d + +# Compiled Object files +*.slo +*.lo +*.o +*.obj + +# Precompiled Headers +*.gch +*.pch + +# Compiled Dynamic libraries +*.so +*.dylib +*.dll + +# Fortran module files +*.mod +*.smod + +# Compiled Static libraries +*.lai +*.la +*.a +*.lib + +# Executables +*.exe +*.out +*.app + +# ---> CMake +CMakeLists.txt.user +CMakeCache.txt +CMakeFiles +CMakeScripts +Testing +Makefile +cmake_install.cmake +install_manifest.txt +compile_commands.json +CTestTestfile.cmake +_deps + +# ---> ArchLinuxPackages +*.tar +*.tar.* +*.jar +*.exe +*.msi +*.zip +*.tgz +*.log +*.log.* +*.sig + +pkg/ +src/ + +# Ubl project output .vscode/ ubl-settings-TEMPLATE *~ From 497d5e677ba0cefffe14922d81077e3f72f8785a Mon Sep 17 00:00:00 2001 From: Ivan Yarcev Date: Fri, 1 Dec 2023 16:11:34 +0600 Subject: [PATCH 6/7] Descriptions has been updated --- README.md | 64 ++++ source/ublsettings-ui.c | 8 +- source/ublsettings-ui.h | 4 +- ubl-utils/ubl-utils.c | 534 ---------------------------- ubl-utils/ubl-utils.h | 750 ++++++++++++++++++++++++++++++++++++++-- 5 files changed, 788 insertions(+), 572 deletions(-) diff --git a/README.md b/README.md index 578fcb3..a81545b 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,66 @@ # libublsettings-ui +# ubl-settings-logging +# Выполнить +# Build +In order to build ubl-settings-logging you will need: + +- CMake +- C compiler +- GTK+ 3 & dependencies +- webkit2gtk (optional) +- vte-2.91 + +Once you have all the necessary dependencies, you can use: +```sh +$ make +``` + +# Installation +After a successful build, just use: +```sh +$ sudo make install clean +``` + +# Uninstallation +After a successful build, just use: +```sh +$ sudo make uninstall +``` +# Library usage +Libublsettings-ui provides 2 libraries: +```C + #include + #include +``` +## ublsettings-ui +Ublsettings-ui provides API to use ubl-settings- applications shared interface: main window, about dialog, confirmation window. +First of all, you need to connect config structure to standard interface: +```C + _template_config config; + yon_ubl_connect_config(config); +``` +Next step you should initialize all necceccary information for standard interface: +```C +yon_ubl_window_init("Title of util","Description of util",".po file name","path to css file (must be connected as resource)","filename of your util","Version of util","About dialog wiki link"); +``` +And finaly you get interface structure: +```C + template_main_window *widgets = yon_ubl_window_setup(); +``` + +## ubl-utils +Ubl-utils provides various utility functions used in ubl-settings- applications. They are divided into sections as: +**Dictionary functions** yon_dictionary; +**String functions** yon_char; +**String array functions** yon_char_parsed; +**UBL misc functions** yon_ubl +**Parsing functions** +**File manipulating functions** yon_file +**UBconfig manipulation functions** yon_config +**Terminal functions** yon_launch +**GTK functions** yon_gtk and yon_ubl_gtk +**GTK VTE functions** yon_terminal +**GTK Webkit functions** yon_ubl_browser +**GTK window configuration manipulation and saving functions** yon_window_config +**GTK status line renderer functions** yon_ubl_status \ No newline at end of file diff --git a/source/ublsettings-ui.c b/source/ublsettings-ui.c index 983cd19..ee7681f 100644 --- a/source/ublsettings-ui.c +++ b/source/ublsettings-ui.c @@ -137,8 +137,7 @@ template_main_window *setup_window(){ return widgets; } -int yon_ubl_window_setup(GtkWidget *interface, char *app_title, char *app_description, char *locale, char *css, char *tech_name, char *version, char *wiki){ - template_app_information.interface=interface; +int yon_ubl_window_init(char *app_title, char *app_description, char *locale, char *css, char *tech_name, char *version, char *wiki){ template_app_information.app_title=app_title; template_app_information.css_path=css; template_app_information.app_tech_name=tech_name; @@ -149,12 +148,9 @@ int yon_ubl_window_setup(GtkWidget *interface, char *app_title, char *app_descri template_app_information.app_locale=locale; } -template_main_window *yon_ubl_window_init(int argc, char *argv[]){ +template_main_window *yon_ubl_window_setup(){ textdomain (template_ui_LocaleName); setlocale(LC_ALL,""); - - - // gtk_init(&argc,&argv); template_main_window *widgets = setup_window(); yon_ubl_header_setup_resource(widgets->HeadOverlay,widgets->HeadBox,widgets->HeadImage,ui_banner_path); diff --git a/source/ublsettings-ui.h b/source/ublsettings-ui.h index ca189c7..2da844a 100644 --- a/source/ublsettings-ui.h +++ b/source/ublsettings-ui.h @@ -155,7 +155,7 @@ int yon_ubl_connect_config(_template_config *config); * [RU] * Создаёт и настраивает основное окно приложения. */ -template_main_window *yon_ubl_window_init(int argc, char *argv[]); +template_main_window *yon_ubl_window_setup(); /**yon_ubl_window_setup(GtkWidget *interface, char *app_title, char *app_description, char *locale, char *css, char *tech_name, char *version, char *wiki) * [EN] @@ -169,7 +169,7 @@ template_main_window *yon_ubl_window_init(int argc, char *argv[]); * [version] - строка с версией приложения; * [wiki] - ссылка на вики страницу; */ -int yon_ubl_window_setup(GtkWidget *interface, char *app_title, char *app_description, char *locale, char *css, char *tech_name, char *version, char *wiki); +int yon_ubl_window_init(char *app_title, char *app_description, char *locale, char *css, char *tech_name, char *version, char *wiki); /**on_about() * [EN] diff --git a/ubl-utils/ubl-utils.c b/ubl-utils/ubl-utils.c index 0e8b853..dccd9cf 100644 --- a/ubl-utils/ubl-utils.c +++ b/ubl-utils/ubl-utils.c @@ -2,12 +2,6 @@ // dictionary functions -/**yon_dictionary_new(): - * [EN] - * Creates and returns empty dictionary - * [RU] - * Создаёт и возвращает пустой словарь. - */ dictionary *yon_dictionary_new() { dictionary *dict = malloc(sizeof(dictionary)); @@ -20,24 +14,12 @@ dictionary *yon_dictionary_new() return dict; } -/**yon_dictionary_copy(dictionary *dict) - * [EN] - * - * [RU] - * Создаёт и возвращает копию элемента словаря [dict] -*/ dictionary *yon_dictinoary_copy(dictionary *dict){ dictionary *dct = yon_dictionary_new_with_data(dict->key,dict->data); dct->data_type= dict->data_type; return dct; } -/**yon_dictionary_copy_deep(dictionary *dict) - * [EN] - * - * [RU] - * Создаёт полную копию словаря [dict] и возвращает первый элемент -*/ dictionary *yon_dictionary_copy_deep(dictionary *dict){ dictionary *dct = NULL; dictionary *newone=NULL; @@ -48,69 +30,33 @@ dictionary *yon_dictionary_copy_deep(dictionary *dict){ return newone->first; } -/**int yon_dictionary_set_data(dictionary *dict, void *data) - * [EN] - * - * [RU] - * Установить элементу словаря [dict] значение [data] -*/ int yon_dictionary_set_data(dictionary *dict, void *data){ dict->data=data; } -/**int yon_dictionary_set_key(dictionary *dict, char *key) - * [EN] - * - * [RU] - * Изменяет ключ элемента словаря [dict] на [key] -*/ int yon_dictionary_set_key(dictionary *dict, char *key){ dict->key=key; return 1; } -/** int yon_dictionary_set(dictionary *dict, char *key, void *data) - * [EN] - * - * [RU] -* Устанавливает значение ключа элемента словаря [dict] на [key] и его данные на [data] -*/ int yon_dictionary_set(dictionary *dict, char *key, void *data){ dict->key=key; dict->data=data; return 1; } -/**int yon_dictionary_empty(dictionary *dict) - * [EN] - * - * [RU] - * Очищает элемент словаря [dict] от данных -*/ int yon_dictionary_empty(dictionary *dict){ dict->data=NULL; dict->data_type=DICTIONARY_OTHER_TYPE; return 1; } -/**yon_dictionary_switch_to_last(dictionary **dict) - * [EN] - * - * [RU] - * Переключает словарь [dict] на последний элемент. -*/ void yon_dictionary_switch_to_last(dictionary **dict) { dictionary *dct=NULL, *dact=*dict; for_dictionaries(dct,dact); } -/**yon_dictionary_create_conneced(dictionary *targetdict) - * [EN] - * - * [RU] - * Создаёт новый элемент словаря [targetdict] -*/ dictionary *yon_dictionary_append(dictionary *targetdict) { targetdict = yon_dictionary_get_last(targetdict); @@ -121,14 +67,6 @@ dictionary *yon_dictionary_append(dictionary *targetdict) return targetdict->next; } -/**yon_dictionary_get_last(dictionary *dict) - * [EN] - * - * [RU] - * Возвращает последний элемент словаря [dict]. - * В отличае от yon_dictionary_switch_to_last() - * словарь [dict] остаётся на прежнем элементе. -*/ dictionary *yon_dictionary_get_last(dictionary *dict) { if (dict->next){ @@ -138,14 +76,6 @@ dictionary *yon_dictionary_get_last(dictionary *dict) } else return dict; } -/**yon_dictionary_switch_places(dictionary *dict, int aim) - * [EN] - * - * [RU] - * Меняет элемент словаря [dict] местами с другим элементом. - * если [aim]<0 элемент меняется местами с левым элементом; - * если [aim]>0 элемент меняется местами с правым элементом; -*/ dictionary *yon_dictionary_swap(dictionary *dict, int aim) { if (aim < 0) @@ -247,13 +177,6 @@ dictionary *yon_dictionary_swap(dictionary *dict, int aim) } } -/**yon_dictionary_make_first(dictionary *dict) - * [EN] - * - * [RU] - * Устанавливает указатель первого элемента словаря [dict] - * на текущий элемент. Не использовать. -*/ void yon_dictionary_make_first(dictionary *dict) { for (dictionary *dct = dict->first; dct != NULL; dct = dct->next) @@ -262,12 +185,6 @@ void yon_dictionary_make_first(dictionary *dict) } } -/**yon_dictionary_make_nth(dictionary *dict, int nth) - * [EN] - * - * [RU] - * Перемещает элемент словаря [dict] на позицию [nth]. -*/ void yon_dictionary_make_nth(dictionary *dict, int nth) { dictionary *dct = dict->first; @@ -286,12 +203,6 @@ void yon_dictionary_make_nth(dictionary *dict, int nth) dct->prev = dict; } -/**yon_dictionary_create_with_data(char *key, void *data) - * [EN] - * - * [RU] - * Создаёт новый словарь с ключом [key] и указателем на данные [data] -*/ dictionary *yon_dictionary_new_with_data(char *key, void *data) { dictionary *dct = yon_dictionary_new(); @@ -301,12 +212,6 @@ dictionary *yon_dictionary_new_with_data(char *key, void *data) return dct; } -/** 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){ @@ -319,13 +224,6 @@ void *yon_dictionary_free_all(dictionary *dictionary_to_free,void (*data_manipul return NULL; } -/**yon_dictionary_create_with_data_connected(dictionary *dict, char *key, void *data) - * [EN] - * - * [RU] - * Создаёт новый элемент словаря, присоединяемый в конец словаря [dict] - * с ключом [key] и указателем на данные [data] -*/ dictionary *yon_dictionary_append_with_data(dictionary *dict, char *key, void *data) { dictionary *dct = yon_dictionary_append(dict); @@ -335,12 +233,6 @@ dictionary *yon_dictionary_append_with_data(dictionary *dict, char *key, void *d return dct; } -/**yon_dictionary_connect(dictionary *old, dictionary *toconnect) - * [EN] - * - * [RU] - * Присоединяет словарь [toconnect] в конец словаря [old]. -*/ dictionary *yon_dictionary_connect(dictionary *old, dictionary *toconnect) { dictionary *dict = yon_dictionary_get_last(old); @@ -350,13 +242,6 @@ dictionary *yon_dictionary_connect(dictionary *old, dictionary *toconnect) return toconnect; } -/**yon_dictionary_get(dictionary **dict, char *key) - * [EN] - * - * [RU] - * Возвращает элемент словаря [dict] с ключом [key]. - * Если такого элемента не было обнаружено, возвращается NULL -*/ dictionary *yon_dictionary_get(dictionary **dict, char *key) { dictionary *dct = *dict; @@ -371,12 +256,6 @@ dictionary *yon_dictionary_get(dictionary **dict, char *key) return NULL; } -/**yon_dictionary_rip(dictionary *dict) - * [EN] - * - * [RU] - * Вырезает элемент из словаря и возвращает вырезанный элемент. -*/ dictionary *yon_dictionary_rip(dictionary *dict) { if (!dict->next&&!dict->prev) return NULL; @@ -412,12 +291,6 @@ dictionary *yon_dictionary_rip(dictionary *dict) } } -/**yon_dictionary_get_nth(dictionary *dict, int place) - * [EN] - * - * [RU] - * Возвращает [place]-й элемент словаря [dict] -*/ dictionary *yon_dictionary_get_nth(dictionary *dict, int place) { if (dict){ @@ -444,10 +317,6 @@ int yon_char_find_last(char *source, char find){ return i; } -/**[EN] - * - * creates new char string by combining two char strings. - */ char *yon_char_append(char *source, char *append) { if (source && append) @@ -465,10 +334,6 @@ char *yon_char_append(char *source, char *append) return NULL; } -/**[EN] - * - * creates new char string by copying another char. - */ char *yon_char_new(char *chr) { if (chr){ @@ -480,12 +345,6 @@ char *yon_char_new(char *chr) return NULL; } -/**yon_char_unite(char *source, ...) - * [En] - * - * [RU] - * Объединяет строку [source] со всеми строками, написанными в [...] -*/ char *yon_char_unite(char *source, ...){ va_list arglist; char *new_char=NULL; @@ -501,10 +360,6 @@ char *yon_char_unite(char *source, ...){ return new_char; } -/**yon_cut(char *source, int size, int startpos) - * [EN] - * cuts source string by size length from startpos position. - */ char *yon_cut(char *source, int size, int startpos) { char *cut = NULL; @@ -514,12 +369,6 @@ char *yon_cut(char *source, int size, int startpos) return cut; } -/**yon_char_divide(char *source, int dividepos) - * [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) { if (source){ @@ -536,12 +385,6 @@ char *yon_char_divide(char *source, int dividepos) return NULL; } -/**yon_char_find_count(char *source, char *find) - * [EN] - * - * [RU] - * Считает количество символов [find] в строке [source] -*/ int yon_char_find_count(char *source, char *find){ char *working_string=yon_char_new(source); int i=0; @@ -556,24 +399,6 @@ int yon_char_find_count(char *source, char *find){ return i; } -/**yon_char_divide_search(char *source, char *dividepos, int delete_divider) - * [EN] - * char *yon_char_divide_search(char *source, char *dividepos, int delete_divider) - * searches string [dividepos] in [source] string and divides it, - * returning left part of divided string and - * inserting right part to [source] string. - * if [delete_divider] is 0, left part will contain [delete_divider] substring, else - * if [delete_divider] is 1 it will stay in right part, else - * if [delete_divider] is -1 it will be deleted from string. - * - * [RU] - * char *yon_char_divide_search(char *source, char *dividepos, int delete_divider) - * Ищет строку [dividepos] в строке [source] и делит её в этом месте, - * возвращая левую часть разделённой строки и устанавливает в [source] правую часть. - * Если [delete_divider] равен 0, [dividepos] останется в левой строке, иначе - * если [delete_divider] равен 1, [dividepos] останется в правой строке, иначе - * если [delete_divider] равен -1, [dividepos] удаляется из строки. - */ char *yon_char_divide_search(char *source, char *dividepos, int delete_divider) { if (source&÷pos){ @@ -588,15 +413,6 @@ char *yon_char_divide_search(char *source, char *dividepos, int delete_divider) return source; } -/**yon_char_from_int(int int_to_convert) - * [EN] - * char *yon_char_from_int(int int_to_convert) - * converts int to char*. - * - * [RU] - * char *yon_char_from_int(int int_to_convert) - * Конвертирует int в char* - */ char *yon_char_from_int(int int_to_convert) { int i = 1; @@ -610,13 +426,6 @@ char *yon_char_from_int(int int_to_convert) return ch; } -/**yon_char_from_float(int int_to_convert) - * [EN] - * converts float to char*. - * - * [RU] - * Конвертирует float в char* - */ char *yon_char_from_float(float int_to_convert) { int i = 1; @@ -630,13 +439,6 @@ char *yon_char_from_float(float int_to_convert) return ch; } -/**yon_char_from_long(int int_to_convert) - * [EN] - * converts long to char*. - * - * [RU] - * Конвертирует long в char* - */ char *yon_char_from_long(long int_to_convert) { int i = 1; @@ -650,12 +452,6 @@ char *yon_char_from_long(long int_to_convert) return ch; } -/**yon_char_replace(char *source, char *find, char*replace) - * [EN] - * - * [RU] - * Заменяет в строке [source] все вхождения строки [find] на [replace] -*/ char *yon_char_replace(char *source, char *find, char*replace){ if (!strstr(replace,find)){ @@ -676,12 +472,6 @@ char *yon_char_replace(char *source, char *find, char*replace){ return source; } -/**yon_char_parse(char *parameters, int *size, char *divider) - * [EN] - * Parses string [parameters], divided by [divider], - * then returns parsed string array and sets [size] to - * size of returned array -*/ char **yon_char_parse(char *parameters, int *size, char *divider){ if (parameters){ char **string=NULL; @@ -701,13 +491,6 @@ char **yon_char_parse(char *parameters, int *size, char *divider){ return NULL; } -/**yon_char_parsed_rip(char **char_string, int *size, int item_to_delete) - * [EN] - * - * [RU] - * Удаляет элемент [item_to_delete] из массива строк [char_string], размера [size] - * Возвращает получившийся массив, в [size] загружается размер нового массива. -*/ char **yon_char_parsed_rip(char **char_string, int *size, int item_to_delete){ char **new_char_parsed=NULL; new_char_parsed=malloc(sizeof(char*)*((*size)-1)); @@ -727,14 +510,6 @@ char **yon_char_parsed_rip(char **char_string, int *size, int item_to_delete){ return new_char_parsed; } -/**yon_char_parsed_check_exist(char **parameters, int size, char *param) - * [EN] - * Checks if [parameters] string array of length [size] - * has [param] element; - * [RU] - * Проверяет есть ли в массиве строк [parameters], размера [size] - * элемент [param] -*/ int yon_char_parsed_check_exist(char **parameters, int size, char *param){ for (int i=0;i1024;*size=*size+1){ @@ -1045,16 +767,6 @@ apps *yon_apps_get_by_name(apps *applist, char *name, int size) return NULL; }; - -/** - * yon_dir_get_contents(char *dir_path, int *size) - * [EN] - * - * [RU] - * Проверяет существует ли папка [dir_path] и - * возвращает список всех вложенных файлов и папок, - * передавая в [size] длину списка. -*/ config_str yon_dir_get_contents(char *dir_path, int *size){ config_str dir = NULL; *size=0; @@ -1112,13 +824,6 @@ static yon_config_parameter *__yon__config__strings = NULL; #define yon_config_parameter_add_or_create_if_exists_with_data(dict,key,data) {if (!dict) dict=yon_config_parameter_new_with_data(key,data); \ else dict=yon_config_parameter_append_with_data(dict,key,data);} -/**yon_config_load_register(char *command) - * [EN] - * - * [RU] - * Выполняет команду [command]. - * Полученные данные парсятся и регистрируются в конфиг. -*/ int yon_config_load_register(YON_CONFIG_TYPE config_type,char *section,char *parameter, ...){ if (__yon__config__strings){ __yon__config__strings = yon_dictionary_free_all((dictionary*)__yon__config__strings,NULL); @@ -1163,12 +868,6 @@ int yon_config_load_register(YON_CONFIG_TYPE config_type,char *section,char *par else return 0; } -/**yon_config_remove_by_key(char *key) - * [EN] - * - * [RU] - * Удаляет параметр конфига по ключу [key] -*/ int yon_config_remove_by_key(char *key){ check_config{ dictionary *dict = yon_dictionary_get((dictionary**)&__yon__config__strings,key); @@ -1180,12 +879,6 @@ int yon_config_remove_by_key(char *key){ return 0; } -/**yon_config_remove_element(char *key, char *deleted) - * [EN] - * - * [RU] - * Удаляет элемент [deleted] из массива параметров с ключом [key] -*/ int yon_config_remove_element(char *key, char *deleted){ check_config{ yon_config_parameter *dict = (yon_config_parameter*)yon_dictionary_get((dictionary**)&__yon__config__strings,key); @@ -1207,12 +900,6 @@ int yon_config_remove_element(char *key, char *deleted){ } else return 0; } -/**yon_config_get_by_key(char *key) - * [EN] - * - * [RU] - * Возвращает значение параметра конфига с ключом [key] -*/ void *yon_config_get_by_key(char *key){ check_config{ dictionary *dict = NULL; @@ -1240,31 +927,6 @@ void *yon_config_get_all_by_key(char *key, int *size){ } } -/**yon_config_get_key_by_data(char *data) - * [EN] - * - * [RU] - * Возвращает ключ параметра конфига со значением [data]. - * Если параметр с таким значением не найден, возвращается NULL -*/ -char *yon_config_get_key_by_data(char *data){ - check_config{ - dictionary *dict = NULL; - for_dictionaries(dict, (dictionary*)__yon__config__strings){ - if (strcmp(((char*)dict->data),data)==0){ - return dict->key; - } - } - } - return NULL; -} - -/**yon_config_set(char *key, void *data) - * [EN] - * - * [RU] - * Производит поиск по конфигу и заменяет значение параметра с ключом [key] на новое значение [data]; -*/ int yon_config_set(char *key, void *data){ check_config{ yon_config_parameter *dict = (yon_config_parameter*)yon_dictionary_get((dictionary**)&__yon__config__strings,key); @@ -1274,13 +936,6 @@ int yon_config_set(char *key, void *data){ } else return 0; } - -/**yon_config_append(char *key, void *data) - * [EN] - * - * [RU] - * Производит поиск по конфигу и дополняет значение параметра с ключом [key] значением [data]; -*/ int yon_config_append(char *key, char *data){ check_config{ yon_config_parameter *dict = (yon_config_parameter*)yon_dictionary_get((dictionary**)&__yon__config__strings,key); @@ -1292,13 +947,6 @@ int yon_config_append(char *key, char *data){ } else return 0; } - -/**yon_config_clean() - * [EN] - * Erase all parameters from config; - * [RU] - * Удаляет все параметры из конфига; -*/ int yon_config_clean(){ check_config{ __yon__config__strings = (yon_config_parameter*)yon_dictionary_free_all((dictionary*)__yon__config__strings, NULL); @@ -1307,14 +955,6 @@ int yon_config_clean(){ else return 0; } -/**yon_config_register(char *key, void *data) - * [EN] - * - * [RU] - * Регистрирует новый параметр конфига. - * [key] - ключ параметра; - * [data] - значение параметра; -*/ void yon_config_register(char *key, char *config_section, void *data){ if (!__yon__config__strings||!yon_dictionary_get((dictionary**)&__yon__config__strings,key)){ yon_config_parameter_add_or_create_if_exists_with_data(__yon__config__strings,key,data); @@ -1325,13 +965,6 @@ void yon_config_register(char *key, char *config_section, void *data){ __yon__config__strings->section=yon_char_new(config_section); } -/**yon_config_load(char *command, int *str_len) - * [EN] - * - * [RU] - * Выполняет команду [command] и возвращает распаршеный результат выполнения команды. - * В [str_len] возвращается длина возвращаемого массива -*/ config_str yon_config_load(char *command, int *str_len){ FILE *output = popen(command, "r"); char **output_strings = NULL; @@ -1359,18 +992,6 @@ config_str yon_config_load(char *command, int *str_len){ } } -/**int yon_config_save_registered(char *path) - * [EN] - * Saves config at [path] config. - * [path] can be: - * system - * global - * [RU] - * Сохраняет конфигурацию в [path] конфиг. - * [path] может быть - * system - локальный конфиг - * global - глобальный конфиг -*/ int yon_config_save_registered(char *path){ check_config{ dictionary *dct; @@ -1404,18 +1025,6 @@ int yon_config_save_registered(char *path){ } else return 1; } -/**int yon_config_force_save_registered(char *path, char *section) - * [EN] - * Force config to save at [path] config ignoring parameter save status. - * [path] can be: - * system - * global - * [RU] - * Принудительно сохраняет конфигурацию в [path] конфиг игнорируя статус параметра. - * [path] может быть - * system - локальный конфиг - * global - глобальный конфиг -*/ int yon_config_force_save_registered(char *path){ check_config{ dictionary *dct; @@ -1448,13 +1057,6 @@ int yon_config_force_save_registered(char *path){ } else return 1; } -/**yon_config_get_all(int *size) - * [EN] - * - * [RU] - * Возвращает массив со всеми параметрами конфига, оканчивающаяся NULL - * [size] - указатель, в который выгружается длина массива -*/ config_str yon_config_get_all(int *size){ check_config{ *size = 1; @@ -1472,14 +1074,6 @@ config_str yon_config_get_all(int *size){ } else return NULL; } -/**char *yon_config_get_parameter(config parameters, int size, char *param) - * [EN] - * Gets parameter [param] from parameter list [parameters] of size [size]; - * or NULL if nothing were found - * [RU] - * Возвращает параметр [param] из массива строк [parameters] размером [size] - * или NULL если такой не был найден -*/ char *yon_config_get_parameter(config_str parameters, int size, char *param) { if (param[0]==' ') @@ -1518,13 +1112,6 @@ config_str yon_file_open(char *file_path, int *size){ } } -/**yon_file_create(char *path, char *name, int rules) - * [EN] - * - * [RU] - * Создать файл с названием [name], находящимся по пути [path] - * С правами доступа [rules] (от 0000 до 0777) -*/ int yon_file_create(char *path, char *name, int rules){ if (path&&name){ char *full_path = yon_char_unite(path,"/",name,NULL); @@ -1545,13 +1132,6 @@ int yon_file_create(char *path, char *name, int rules){ } } -/**yon_file_create_full_path(char *path, char *name, int rules) - * [EN] - * - * [RU] - * Создать файл по пути [path] - * С правами доступа [rules] (от 0000 до 0777) -*/ int yon_file_create_full_path(char *path, int rules){ if (path){ if (access(path,F_OK)){ @@ -1573,12 +1153,6 @@ int yon_file_create_full_path(char *path, int rules){ // terminal-using functions -/**yon_launch_app_with_arguments(char *name, char *args) - * [EN] - * Execute [command] in separate thread; - * [RU] - * Выполнить команду [command] в отдельном потоке; -*/ int yon_launch_app_with_arguments(char *name, char *args) { char *path = yon_char_unite("/usr/bin/", name, " ", args,NULL); @@ -1588,12 +1162,6 @@ int yon_launch_app_with_arguments(char *name, char *args) pthread_create(&thread_id, NULL, (void *)yon_launch, command); }; -/**yon_launch(char *command) - * [EN] - * Execute command [command] - * [RU] - * Выполнить команду [command] -*/ void yon_launch(char *command) { system(command); @@ -1616,17 +1184,6 @@ static void child_ready(VteTerminal *terminal, GPid pid, GError *error, gpointer else vte_terminal_feed_child(VTE_TERMINAL(terminal),(char*)user_data,strlen((char*)user_data)); } -/** - * 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]. -*/ void yon_terminal_integrated_launch(GtkWidget *place_to_show, char* command, void *endwork_function, void* endwork_function_argument){ char **commands=new_arr(char*,2); gchar **envp = g_get_environ(); @@ -1672,16 +1229,6 @@ void yon_terminal_integrated_launch(GtkWidget *place_to_show, char* command, voi gtk_widget_show_all(terminal); } -/**yon_terminal_integrated_start(GtkWidget *terminal, char* command, 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]. -*/ void yon_terminal_integrated_start(GtkWidget *terminal, char* command, void *endwork_function, void* endwork_function_argument){ char **commands=new_arr(char*,2); gchar **envp = g_get_environ(); @@ -1839,12 +1386,6 @@ void yon_terminal_integrated_start(GtkWidget *terminal, char* command, void *end } } - /**yon_window_config_setup(GtkWindow *window) - * [EN] - * - * [RU] - * Устанавливает указатель на окно для отслеживания его положения и размера - */ void yon_window_config_setup(GtkWindow *window){ __yon_window_config_target_window = window; g_signal_connect(G_OBJECT(window),"delete-event",G_CALLBACK(yon_on_configured_window_destroy),NULL); @@ -1856,12 +1397,6 @@ void yon_terminal_integrated_start(GtkWidget *terminal, char* command, void *end if(__yon_main_window_config.fullscreen ==1) gtk_window_maximize(__yon_window_config_target_window); } - /**yon_window_config_load(char *path) - * [EN] - * - * [RU] - * Загружает конфиг окна и инициализирует отслеживание его параметров - */ int yon_window_config_load(char *path){ __yon_window_config_file = g_key_file_new(); __yon_window_config_path=yon_char_new(path); @@ -1925,12 +1460,6 @@ void yon_terminal_integrated_start(GtkWidget *terminal, char* command, void *end return key; } - /**yon_window_config_add_custom_parameter(GtkWidget *widget, char *param_name, char *widget_property) - * [EN] - * - * [RU] - * Добавляет параметр виджета [widget] по названию [widget_property] для отслеживания и сохраняет его в конфиг под ключом [param_name]. - */ void yon_window_config_add_listener(GtkWidget *widget, char *param_name, char *widget_property, enum YON_TYPE val_type){ __yon_listener_parameter *param = NULL; param = yon_remalloc(param,sizeof(__yon_listener_parameter)); @@ -2107,12 +1636,6 @@ GtkWidget *yon_ubl_menu_item_documentation_new(char *buttonname){ // other Gtk functions -/**yon_gtk_combo_box_fill(GtkWidget *combo, config_str parameters,int size) - * [EN] - * - * [RU] - * Добавляет в Комбобокс [combo] все строки из массива строк [parameters] размера [size] -*/ int yon_gtk_combo_box_fill(GtkWidget *combo, config_str parameters,int size){ if (combo&¶meters){ for (int i=0;i-1){ gtk_widget_hide(gtk_widget_get_toplevel(main_window)); @@ -2447,12 +1927,6 @@ void yon_ubl_setup_sockets(GtkWidget *main_window, GtkWidget *left_window, GtkWi #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); @@ -2471,14 +1945,6 @@ void yon_ubl_browser_window_open(char *link, char *browser_window_name){ } #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) diff --git a/ubl-utils/ubl-utils.h b/ubl-utils/ubl-utils.h index 2fef789..61edb75 100644 --- a/ubl-utils/ubl-utils.h +++ b/ubl-utils/ubl-utils.h @@ -23,7 +23,13 @@ #endif #define DesktopPath "/usr/share/applications/" -#define for_dictionaries(obj, obj1) for (obj = obj1->first; obj != NULL; obj = obj->next) +/**for_dictionaries(element, stack) + * [EN] + * + * [RU] + * Работает как for, но нужен для перечисления элементов словаря типа dictioary [stack]. Каждый цикл текущий элемент попадает в [element] +*/ +#define for_dictionaries(element, stack) for (element = stack->first; element != NULL; element = element->next) #define new(type) malloc(sizeof(type)) #define new_arr(type,size) malloc(sizeof(type)*size) @@ -42,6 +48,15 @@ typedef enum } DICT_TYPE; +/** + * Структура именованого списка. + * [key] - ключ элемента + * [data] - хранимое значение + * [next] - следующий элемент списка + * [prev] - предыдущий элемент списка + * [first] - первый элемент списка + * [data_type] - Тип значения в словаре +*/ typedef struct dictionary { char *key; @@ -68,6 +83,9 @@ typedef struct apps typedef char** config_str; +/**config(key) + * Возвращает элемент конфигурации ubconfig с ключом [key] или NULL если такого нет +*/ #define config(key) yon_config_get_by_key(key) #define yon_remalloc(pointer, size) (!pointer) ? malloc(size) : realloc(pointer, size) @@ -95,30 +113,171 @@ typedef char** config_str; #define yon_dictionary_add_or_create_if_exists_with_data(dict,key,data) {if (!dict) dict=yon_dictionary_new_with_data(key,data); \ else dict=yon_dictionary_append_with_data(dict,key,data);} +/**yon_dictionary_new(): + * [EN] + * Creates and returns empty dictionary + * [RU] + * Создаёт и возвращает пустой словарь. + */ dictionary *yon_dictionary_new(); +/**yon_dictionary_copy(dictionary *dict) + * [EN] + * + * [RU] + * Создаёт и возвращает копию элемента словаря [dict] +*/ +dictionary *yon_dictinoary_copy(dictionary *dict); + +/**yon_dictionary_copy_deep(dictionary *dict) + * [EN] + * + * [RU] + * Создаёт полную копию словаря [dict] и возвращает первый элемент +*/ +dictionary *yon_dictionary_copy_deep(dictionary *dict); + +/**int yon_dictionary_set_data(dictionary *dict, void *data) + * [EN] + * + * [RU] + * Установить элементу словаря [dict] значение [data] +*/ +int yon_dictionary_set_data(dictionary *dict, void *data); + +/**int yon_dictionary_set_key(dictionary *dict, char *key) + * [EN] + * + * [RU] + * Изменяет ключ элемента словаря [dict] на [key] +*/ +int yon_dictionary_set_key(dictionary *dict, char *key); + +/** int yon_dictionary_set(dictionary *dict, char *key, void *data) + * [EN] + * + * [RU] +* Устанавливает значение ключа элемента словаря [dict] на [key] и его данные на [data] +*/ +int yon_dictionary_set(dictionary *dict, char *key, void *data); + +/**int yon_dictionary_empty(dictionary *dict) + * [EN] + * + * [RU] + * Очищает элемент словаря [dict] от данных +*/ +int yon_dictionary_empty(dictionary *dict); + +/**yon_dictionary_switch_to_last(dictionary **dict) + * [EN] + * + * [RU] + * Переключает словарь [dict] на последний элемент. +*/ +void yon_dictionary_switch_to_last(dictionary **dict); + +/**yon_dictionary_create_conneced(dictionary *targetdict) + * [EN] + * + * [RU] + * Создаёт новый элемент словаря [targetdict] +*/ dictionary *yon_dictionary_append(dictionary *targetdict); +/**yon_dictionary_get_last(dictionary *dict) + * [EN] + * + * [RU] + * Возвращает последний элемент словаря [dict]. + * В отличае от yon_dictionary_switch_to_last() + * словарь [dict] остаётся на прежнем элементе. +*/ dictionary *yon_dictionary_get_last(dictionary *dict); +/**yon_dictionary_switch_places(dictionary *dict, int aim) + * [EN] + * + * [RU] + * Меняет элемент словаря [dict] местами с другим элементом. + * если [aim]<0 элемент меняется местами с левым элементом; + * если [aim]>0 элемент меняется местами с правым элементом; +*/ dictionary *yon_dictionary_swap(dictionary *dict, int aim); +/**yon_dictionary_make_first(dictionary *dict) + * [EN] + * + * [RU] + * Устанавливает указатель первого элемента словаря [dict] + * на текущий элемент. Не использовать. +*/ void yon_dictionary_make_first(dictionary *dict); +/**yon_dictionary_make_nth(dictionary *dict, int nth) + * [EN] + * + * [RU] + * Перемещает элемент словаря [dict] на позицию [nth]. +*/ void yon_dictionary_make_nth(dictionary *dict, int nth); +/**yon_dictionary_create_with_data(char *key, void *data) + * [EN] + * + * [RU] + * Создаёт новый словарь с ключом [key] и указателем на данные [data] +*/ dictionary *yon_dictionary_new_with_data(char *key, void *data); +/**yon_dictionary_create_with_data_connected(dictionary *dict, char *key, void *data) + * [EN] + * + * [RU] + * Создаёт новый элемент словаря, присоединяемый в конец словаря [dict] + * с ключом [key] и указателем на данные [data] +*/ dictionary *yon_dictionary_append_with_data(dictionary *dict, char *key, void *data); +/**yon_dictionary_connect(dictionary *old, dictionary *toconnect) + * [EN] + * + * [RU] + * Присоединяет словарь [toconnect] в конец словаря [old]. +*/ dictionary *yon_dictionary_connect(dictionary *old, dictionary *toconnect); +/**yon_dictionary_get(dictionary **dict, char *key) + * [EN] + * + * [RU] + * Возвращает элемент словаря [dict] с ключом [key]. + * Если такого элемента не было обнаружено, возвращается NULL +*/ dictionary *yon_dictionary_get(dictionary **dict, char *key); +/**yon_dictionary_rip(dictionary *dict) + * [EN] + * + * [RU] + * Вырезает элемент из словаря и возвращает вырезанный элемент. +*/ dictionary *yon_dictionary_rip(dictionary *dict); +/**yon_dictionary_get_nth(dictionary *dict, int place) + * [EN] + * + * [RU] + * Возвращает [place]-й элемент словаря [dict] +*/ dictionary *yon_dictionary_get_nth(dictionary *dict, int place); +/** 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,void (data_manipulation)(void*)); // char functions @@ -129,72 +288,263 @@ void *yon_dictionary_free_all(dictionary *dictionary,void (data_manipulation)(vo int yon_char_find_last(char *source, char find); +/**[EN] + * + * creates new char string by combining two char strings. + */ char *yon_char_append(char *source, char *append); +/**[EN] + * + * creates new char string by copying another char. + */ char *yon_char_new(char *chr); +/**yon_char_unite(char *source, ...) + * [En] + * + * [RU] + * Объединяет строку [source] со всеми строками, написанными в [...]. Последний элемент должен быть NULL +*/ char *yon_char_unite(char *source, ...); +/**yon_cut(char *source, int size, int startpos) + * [EN] + * cuts source string by size length from startpos position. + */ char *yon_cut(char *source, int size, int startpos); +/**yon_char_divide(char *source, int dividepos) + * [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); +/**yon_char_divide_search(char *source, char *dividepos, int delete_divider) + * [EN] + * char *yon_char_divide_search(char *source, char *dividepos, int delete_divider) + * searches string [dividepos] in [source] string and divides it, + * returning left part of divided string and + * inserting right part to [source] string. + * if [delete_divider] is 0, left part will contain [delete_divider] substring, else + * if [delete_divider] is 1 it will stay in right part, else + * if [delete_divider] is -1 it will be deleted from string. + * + * [RU] + * char *yon_char_divide_search(char *source, char *dividepos, int delete_divider) + * Ищет строку [dividepos] в строке [source] и делит её в этом месте, + * возвращая левую часть разделённой строки и устанавливает в [source] правую часть. + * Если [delete_divider] равен 0, [dividepos] останется в левой строке, иначе + * если [delete_divider] равен 1, [dividepos] останется в правой строке, иначе + * если [delete_divider] равен -1, [dividepos] удаляется из строки. + */ char *yon_char_divide_search(char *source, char *dividepos, int delete_divider); +/**yon_char_from_int(int int_to_convert) + * [EN] + * char *yon_char_from_int(int int_to_convert) + * converts int to char*. + * + * [RU] + * char *yon_char_from_int(int int_to_convert) + * Конвертирует int в char* + */ char *yon_char_from_int(int int_to_convert); +/**yon_char_from_float(int int_to_convert) + * [EN] + * converts float to char*. + * + * [RU] + * Конвертирует float в char* + */ char *yon_char_from_float(float int_to_convert); +/**yon_char_from_long(int int_to_convert) + * [EN] + * converts long to char*. + * + * [RU] + * Конвертирует long в char* + */ char *yon_char_from_long(long int_to_convert); +/**yon_char_replace(char *source, char *find, char*replace) + * [EN] + * + * [RU] + * Заменяет в строке [source] все вхождения строки [find] на [replace] +*/ char *yon_char_replace(char *source, char *find, char*replace); +/**yon_char_parse(char *parameters, int *size, char *divider) + * [EN] + * Parses string [parameters], divided by [divider], + * then returns parsed string array and sets [size] to + * size of returned array +*/ char **yon_char_parse(char *parameters, int *size, char *divider); +/**yon_char_parsed_rip(char **char_string, int *size, int item_to_delete) + * [EN] + * + * [RU] + * Удаляет элемент [item_to_delete] из массива строк [char_string], размера [size] + * Возвращает получившийся массив, в [size] загружается размер нового массива. +*/ char **yon_char_parsed_rip(char **char_string, int *size, int item_to_delete); +/**yon_char_parsed_check_exist(char **parameters, int size, char *param) + * [EN] + * Checks if [parameters] string array of length [size] + * has [param] element; + * [RU] + * Проверяет есть ли в массиве строк [parameters], размера [size] + * элемент [param] +*/ int yon_char_parsed_check_exist(char **parameters, int size, char *param); +/**yon_char_parsed_check_repeats(char **parameters, int size) + * [EN] + * Checks if [parameters] string array of length [size] + * has repeated elements; + * [RU] + * Проверяет есть ли в массиве строк [parameters], размера [size] + * повторения +*/ int yon_char_parsed_check_repeats(char **parameters, int size, int *first_overlap, int *second_overlap); +/**yon_char_find_count(char *source, char *find) + * [EN] + * + * [RU] + * Считает количество символов [find] в строке [source] +*/ int yon_char_find_count(char *source, char *find); +/**yon_char_parsed_includes_char_parsed (config_str source, config_str to_check, int source_size, int check_size) + * [EN] + * + * [RU] + * Проверяет, включает ли в себя [source] размера [source_size] + * массив строк [to_check] размера [check_size] +*/ int yon_char_parsed_includes_char_parsed (config_str source, config_str to_check, int source_size, int check_size); +/**yon_char_parsed_new (config_str old, int *old_size, ...) + * [EN] + * + * [RU] + * Создаёт новый массив строк. В [size] выгружается его размер + * [...] - неограниченное количество строк. +*/ config_str yon_char_parsed_new (int *size, ...); void yon_char_parsed_free(config_str source, int size); +/**yon_char_parsed_copy(config_str *source, config_str *to_copy) + * [EN] + * + * [RU] + * Копирует массив строк [to_copy] в [source] +*/ void yon_char_parsed_copy(config_str *source, config_str *to_copy); +/**config_str yon_char_parsed_append(config_str parsed, int *size, char *string) + * [EN] + * Adds [string] at the end of [parsed] string array of [size] length. + * [RU] + * Добавляет строку [string] в конец массива строк [parsed] с длинной [size]. +*/ config_str yon_char_parsed_append(config_str parsed, int *size, char *string); +/**yon_ubl_check_root() + * [EN] + * + * [RU] + * Возвращает 1 если приложение было запущено от root +*/ int yon_ubl_check_root(); +/**yon_ubl_root_user_get() + * [EN] + * + * [RU] + * Возвращает имя пользователя. + * Если пользователь запустил приложение через root, выводится имя пользователя, запустившего приложение через root +*/ char *yon_ubl_root_user_get(); +/** yon_ubl_user_get_home_directory() + * [EN] + * + * [RU] + * Возвращает домашний каталог пользователя. + * Если пользователь открыл утилиту с правами суперпользователя, всё равно возвращает каталог пользователя, а не root +*/ char *yon_ubl_user_get_home_directory(); +/** yon_ubl_get_all_users(int *user_size) + * [EN] + * + * [RU] + * Возвращает массив всех пользователей в системе и записывает его размер в [user_size] +*/ config_str yon_ubl_get_all_users(int *user_size); // parsing functions +/** yon_size_convert_automatic(int bytes, int *size) + * [EN] + * + * [RU] + * Делит число [bytes] на 1024 пока оно не станет меньше 1024. + * Возвращает получившееся число и устанавливает [size] равным количеству делений. +*/ float yon_size_convert_automatic(int bytes, int *size); -config_str philos_list_user(int* size); - apps *yon_apps_scan_and_parse_desktops(int *sizef); void yon_apps_sort(apps *applist, int size); apps *yon_apps_get_by_name(apps *applist, char *name, int size); +/**yon_file_open(char *file_path, int *size) + * [EN] + * + * [RU] + * Открывает файл [file_path], возвращает содержимое в виде массива строк размера [size] +*/ config_str yon_file_open(char *file_path, int *size); +/**yon_file_create(char *path, char *name, int rules) + * [EN] + * + * [RU] + * Создать файл с названием [name], находящимся по пути [path] + * С правами доступа [rules] (от 0000 до 0777) +*/ int yon_file_create(char *path, char *name, int rules); +/**yon_file_create_full_path(char *path, char *name, int rules) + * [EN] + * + * [RU] + * Создать файл по пути [path] + * С правами доступа [rules] (от 0000 до 0777) +*/ int yon_file_create_full_path(char *path, int rules); +/** yon_dir_get_contents(char *dir_path, int *size) + * [EN] + * + * [RU] + * Проверяет существует ли папка [dir_path] и + * возвращает список всех вложенных файлов и папок, + * передавая в [size] длину списка. +*/ config_str yon_dir_get_contents(char *dir_path, int *size); //config functions @@ -202,58 +552,204 @@ config_str yon_dir_get_contents(char *dir_path, int *size); #define ubconfig_save_command "ubconfig" #define ubconfig_load_command "ubconfig --source" +/** + * Типы конфигураций ubconfig-а +*/ typedef enum { YON_CONFIG_LOCAL=0, YON_CONFIG_GLOBAL, YON_CONFIG_BOTH } YON_CONFIG_TYPE; +/**yon_config_load(char *command, int *str_len) + * [EN] + * + * [RU] + * Выполняет команду [command] и возвращает результат выполнения команды, разделяя на строки. + * В [str_len] возвращается длина возвращаемого массива +*/ config_str yon_config_load(char *command, int *str_len); +/**int yon_config_save_registered(char *path) + * [EN] + * Saves config at [path] config. + * [path] can be: + * system + * global + * [RU] + * Сохраняет конфигурацию в [path] конфиг. + * [path] может быть + * system - локальный конфиг + * global - глобальный конфиг +*/ int yon_config_save_registered(char *path); -int yon_config_force_save_registered(char *path); - +/**char *yon_config_get_parameter(config parameters, int size, char *param) + * [EN] + * Gets parameter [param] from parameter list [parameters] of size [size]; + * or NULL if nothing were found + * [RU] + * Возвращает параметр [param] из массива строк [parameters] размером [size] + * или NULL если такой не был найден +*/ char *yon_config_get_parameter(config_str parameters, int size, char *param); +/**yon_config_load_register(char *command) + * [EN] + * + * [RU] + * Выполняет команду [command]. + * Полученные данные парсятся и регистрируются в конфиг. +*/ int yon_config_load_register(YON_CONFIG_TYPE config_type,char *section,char *parameter, ...); +/**yon_config_remove_by_key(char *key) + * [EN] + * + * [RU] + * Удаляет параметр конфига по ключу [key] +*/ int yon_config_remove_by_key(char *key); -int yon_config_remove_by_data(void *data); - +/**yon_config_remove_element(char *key, char *deleted) + * [EN] + * + * [RU] + * Удаляет элемент [deleted] из массива параметров с ключом [key] +*/ int yon_config_remove_element(char *key, char *deleted); +/**yon_config_get_key_by_key(char *data) + * [EN] + * + * [RU] + * Возвращает значение параметра конфига с ключом [key]. + * Если параметр с таким значением не найден, возвращается NULL +*/ void *yon_config_get_by_key(char *key); +/**yon_config_get_all_by_key(char *data) + * [EN] + * + * [RU] + * Возвращает значение всех параметров конфига с ключом включающем строку [key]. + * Если параметр с таким значением не найден, возвращается NULL +*/ void *yon_config_get_all_by_key(char *key, int *size); -char *yon_config_get_key_by_data(char *data); - +/**yon_config_set(char *key, void *data) + * [EN] + * + * [RU] + * Производит поиск по конфигу и заменяет значение параметра с ключом [key] на новое значение [data]; +*/ int yon_config_set(char *key, void *data); +/**yon_config_append(char *key, void *data) + * [EN] + * + * [RU] + * Производит поиск по конфигу и дополняет значение параметра с ключом [key] значением [data]; +*/ +int yon_config_append(char *key, char *data) + +/**yon_config_clean() + * [EN] + * Erase all parameters from config; + * [RU] + * Удаляет все параметры из конфига; +*/ int yon_config_clean(); +/**yon_config_register(char *key, void *data) + * [EN] + * + * [RU] + * Регистрирует новый параметр конфига. + * [key] - ключ параметра; + * [data] - значение параметра; +*/ void yon_config_register(char *key, char* config_section, void *data); +/**int yon_config_force_save_registered(char *path, char *section) + * [EN] + * Force config to save at [path] config ignoring parameter save status. + * [path] can be: + * system + * global + * [RU] + * Принудительно сохраняет конфигурацию в [path] конфиг игнорируя статус параметра. + * [path] может быть + * system - локальный конфиг + * global - глобальный конфиг +*/ +int yon_config_force_save_registered(char *path); + +/**yon_config_get_all(int *size) + * [EN] + * + * [RU] + * Возвращает массив со всеми параметрами конфига, оканчивающаяся NULL + * [size] - указатель, в который выгружается длина массива +*/ config_str yon_config_get_all(); // terminal-using functions +/**yon_launch_app_with_arguments(char *name, char *args) + * [EN] + * Execute [command] in separate thread; + * [RU] + * Выполнить команду [command] в отдельном потоке; +*/ int yon_launch_app_with_arguments(char *name, char *args); +/**yon_launch(char *command) + * [EN] + * Execute command [command] + * [RU] + * Выполнить команду [command] +*/ void yon_launch(char *command); // Gtk functions #ifdef __GTK_H__ #ifdef VTE_TERMINAL + +/** + * 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]. +*/ void yon_terminal_integrated_launch(GtkWidget *place_to_show, char* command, void *endwork_function, void* endwork_function_argument); +/**yon_terminal_integrated_start(GtkWidget *terminal, char* command, 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]. +*/ void yon_terminal_integrated_start(GtkWidget *terminal, char* command, void *endwork_function, void* endwork_function_argument); #endif +/**YON_TYPE + * [EN] + * + * [RU] + * Типы, поддерживаемые функциями сохранения/загрузки конфигурации утилиты +*/ enum YON_TYPE{ YON_TYPE_STRING, YON_TYPE_STRING_LIST, @@ -262,61 +758,204 @@ enum YON_TYPE{ YON_TYPE_OTHER }; -GtkWidget *yon_ubl_menu_item_about_new(char *buttonname); -GtkWidget *yon_ubl_menu_item_documentation_new(char *buttonname); - /**yon_gtk_builder_get_widget(builder, widget_name) * [EN] * Returns GtkWidget from GtkBuilder *[builder]. * [builder] is GtkBuilder*; * [widget_name] is id of widget; + * [RU] + * Возвращает виджет GtkWidget c id [widget_name] из [builder] */ #define yon_gtk_builder_get_widget(builder, widget_name) GTK_WIDGET(gtk_builder_get_object(builder, widget_name)) -typedef struct -{ - GtkWidget *Icon; - GtkWidget *Label; - GtkWidget *IconView; - GtkListStore *List; -} expander_icon_view; - +/**yon_window_config_setup(GtkWindow *window) + * [EN] + * + * [RU] + * Устанавливает указатель на окно для отслеживания его положения и размера +*/ void yon_window_config_setup(GtkWindow *window); +/**yon_window_config_load(char *path) + * [EN] + * + * [RU] + * Загружает конфиг окна и инициализирует отслеживание его параметров +*/ int yon_window_config_load(char *path); +/**yon_window_config_get_section(char *section, gsize *size) + * [EN] + * + * [RU] + * Возвращает все параметры раздела [section] конфига утилиты и записывает в [size] количество считанных параметров. +*/ config_str yon_window_config_get_section(char *section, gsize *size); +/**yon_window_config_add_custom_parameter(GtkWidget *widget, char *param_name, char *widget_property) + * [EN] + * + * [RU] + * Добавляет параметр виджета [widget] по названию [widget_property] для отслеживания и сохраняет его в конфиг под ключом [param_name]. +*/ void yon_window_config_add_listener(GtkWidget *widget, char *param_name, char *widget_property, enum YON_TYPE val_type); +/**yon_window_config_add_custom_parameter(char *param_name, char *section, void *tracked_value, enum YON_TYPE val_type) + * [EN] + * + * [RU] + * Добавить параметр в конфиг утилиты. + * Параметр [param_name] добавляется в раздел [section] конфига утилиты со значением [tracked value]. + * Тип указывается в [type] +*/ void yon_window_config_add_custom_parameter(char *param_name, char *section, void *tracked_value, enum YON_TYPE val_type); +/**yon_window_config_erase_custom_parameter(char *param_name, char *section) + * [EN] + * + * [RU] + * Удаляет параметр из конфига утилиты. + * Удаляет параметр [param_name] из раздела [section] конфига утилиты. +*/ void yon_window_config_erase_custom_parameter(char *param_name, char *section); +/**yon_window_config_get_parameter(char *section, char *config_parameter, void *return_value, enum YON_TYPE type) + * [EN] + * + * [RU] + * Возвращает параметр из конфига утилиты. + * Параметр [config_parameter] из раздела [section] возвращается в [return_value] + * Возвращаемый тип указывается в [type] +*/ int yon_window_config_get_parameter(char *section, char *config_parameter, void *return_value, enum YON_TYPE type); +/**yon_window_config_custom_window_setup(GtkWindow *window, char *window_name) + * [EN] + * + * [RU] + * Зарегистрировать окно [window] в конфиге утилиты под именем [window_name] +*/ void yon_window_config_custom_window_setup(GtkWindow *window, char *window_name); +/**yon_window_config_custom_window_set(GtkWindow *window, char *window_name) + * [EN] + * + * [RU] + * Загрузить и применить параметры окна [window], сохранёнными в конфигурации утилиты под именем [window_name] +*/ void yon_window_config_custom_window_get(GtkWindow *window, char *window_name); +/**yon_window_config_custom_window_set(GtkWindow *window, char *window_name) + * [EN] + * + * [RU] + * Сохранить параметры окна [window] в конфигурацию утилиты под именем [window_name] +*/ void yon_window_config_custom_window_set(GtkWindow *window, char *window_name); +int yon_gtk_icon_view_hide_empty(dictionary *icon_view_segment); + +/**yon_ubl_menu_item_documentation_new(char *buttonname) + * [EN] + * + * [RU] + * Создаёт элемент меню GtkMenu с текстом [buttonname]. Кнопка настроена для отображения диалогового окна информации об утилите +*/ +GtkWidget *yon_ubl_menu_item_about_new(char *buttonname); + +/**yon_ubl_menu_item_documentation_new(char *buttonname) + * [EN] + * + * [RU] + * Создаёт элемент меню GtkMenu с текстом [buttonname]. Кнопка настроена для отображения диалогового окна подтверждения перехода на страницу wiki +*/ +GtkWidget *yon_ubl_menu_item_documentation_new(char *buttonname); + +// other Gtk functions + +/**yon_gtk_combo_box_fill(GtkWidget *combo, config_str parameters,int size) + * [EN] + * + * [RU] + * Добавляет в Комбобокс [combo] все строки из массива строк [parameters] размера [size] +*/ int yon_gtk_combo_box_fill(GtkWidget *combo, char **parameters,int size); +/**yon_gtk_combo_box_text_find(GtkWidget *combo_box, char *text_to_find) + * [EN] + * + * [RU] + * Проивзодит поиск по GtkComboBoxText [combo_box] + * возвращает 1 если элемент [text_to_find] найден, иначе возвращает 0 +*/ int yon_gtk_combo_box_text_find(GtkWidget *combo_box, char *text_to_find); +/**yon_gtk_column_minimal_fixed_size_set(GtkTreeViewColumn *column) + * [EN] + * + * [RU] + * Установить минимальный размер колонки [column] равным размеру заголовка. +*/ void yon_gtk_column_minimal_fixed_size_set(GtkTreeViewColumn *column); -int yon_gtk_icon_view_hide_empty(dictionary *icon_view_segment); - +/**yon_dictionary_gtk_pack_start_multiple_widgets(GtkBox *destination, gboolean expand, gboolean fill, int padding, ...) + * [EN] + * + * [RU] + * Добвляет [destination] все виджеты, прописанные после [padding]. Добавление происходит с начала контейнера. + * [expand] - расширяемость выделенного для виджетов места + * [fill] - заполнять ли виджетом всё ему выделенное место + * [padding] - отступ од других элементов +*/ int yon_dictionary_gtk_pack_start_multiple_widgets(GtkBox *destination, gboolean expand, gboolean fill, int padding, ...); +/**yon_dictionary_gtk_pack_end_multiple_widgets(GtkBox *destination, gboolean expand, gboolean fill, int padding, ...) + * [EN] + * + * [RU] + * Добвляет в [destination] все виджеты, прописанные после [padding]. Добавление происходит с конца контейнера. + * [expand] - расширяемость выделенного для виджетов места + * [fill] - заполнять ли виджетом всё ему выделенное место + * [padding] - отступ од других элементов +*/ int yon_dictionary_gtk_pack_end_multiple_widgets(GtkBox *destination, gboolean expand, gboolean fill, int padding, ...); + +/**yon_gtk_widget_set_sensitive_from_toggle_button(GtkToggleButton *toggle, GtkWidget *target) + * [EN] + * + * [RU] + * Выставляет чуствительность виджета [target] в зависимости от состояния комбобокса [toggle]. + * Чувствительность виджета [target] повторяет статус чекбоска. +*/ void yon_gtk_widget_set_sensitive_from_toggle_button(GtkToggleButton *toggle, GtkWidget *target); + +/**yon_gtk_widget_set_sensitive_from_toggle_button_inversed(GtkToggleButton *toggle, GtkWidget *target) + * [EN] + * + * [RU] + * Выставляет чуствительность виджета [target] в зависимости от состояния чекбоска [toggle]. + * Если чекбокс вктивен, [target] становится нечувствительным и наоборот. +*/ void yon_gtk_widget_set_sensitive_from_toggle_button_inversed(GtkToggleButton *toggle, GtkWidget *target); + +/**yon_gtk_widget_set_sensitive_from_combo_box(GtkComboBox *toggle, GtkWidget *target); + * [EN] + * + * [RU] + * Выставляет чуствительность виджета [target] в зависимости от состояния комбобокса [toggle]. + * Если выбран первый элемент списка, [target] становится чувствительным, любое другое значение сделает его нечувствительным. +*/ void yon_gtk_widget_set_sensitive_from_combo_box(GtkComboBox *toggle, GtkWidget *target); + +/**yon_gtk_widget_set_sensitive_from_combo_box_inversed(GtkComboBox *toggle, GtkWidget *target); + * [EN] + * + * [RU] + * Выставляет чуствительность виджета [target] в зависимости от состояния комбобокса [toggle]. + * Если выбран первый элемент списка, [target] становится нечувствительным, любое другое значение сделает его чувствительным. +*/ void yon_gtk_widget_set_sensitive_from_combo_box_inversed(GtkComboBox *toggle, GtkWidget *target); typedef enum @@ -365,14 +1004,36 @@ int yon_ubl_status_box_setup(GtkWidget *icon, GtkWidget *box, GtkWidget *label); */ void yon_ubl_status_box_render(char *text, BACKGROUND_IMAGE_TYPE type); +/**yon_ubl_status_list_store_highlight_incorrect(GtkListStore *list, GtkTreeIter *iter) + * [EN] + * + * [RU] + * Подсвечивает красным цветом [widget] на 5 секунд +*/ void yon_ubl_status_highlight_incorrect(GtkWidget *widget); +/**yon_ubl_status_list_store_highlight_incorrect(GtkListStore *list, GtkTreeIter *iter) + * [EN] + * + * [RU] + * Подсвечивает красным цветом [iter] элемент списка [list] на 5 секунд +*/ void yon_ubl_status_list_store_highlight_incorrect(GtkListStore *list, GtkTreeIter *iter); static int status_thread_busy; -void yon_ubl_status_box_spawn(GtkContainer *container,char *display_text, int timeout,BACKGROUND_IMAGE_TYPE type); -#ifdef __cplusplus +/**yon_ubl_status_box_spawn(GtkContainer *container,char *display_text, int timeout,BACKGROUND_IMAGE_TYPE type); + * [EN] + * + * [RU] + * Создаёт статусную строку в контейнере [container], отображая текст [display_text]. + * Строка удаляется через [timeout] секунд. + * [type] - тип сообщения. Может быть: + * BACKGROUND_IMAGE_FAIL_TYPE (красный фон,иконка - восклицательный знак) + * или + * BACKGROUND_IMAGE_SUCCESS_TYPE (Жёлтный фон, иконка - галка) +*/ +void yon_ubl_status_box_spawn(GtkContainer *container,char *display_text, int timeout,BACKGROUND_IMAGE_TYPE type); /**yon_ubl_header_setup(overlay, head, image, imag_path) * [EN] @@ -388,10 +1049,9 @@ void yon_ubl_status_box_spawn(GtkContainer *container,char *display_text, int ti * [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) -/**yon_ubl_header_setup(overlay, head, image, imag_path) +/**yon_ubl_header_setup_resource(overlay, head, image, imag_path) * [EN] * Sets up header of app. * [overlay] is overlay for app header; @@ -403,21 +1063,51 @@ void yon_ubl_status_box_spawn(GtkContainer *container,char *display_text, int ti * [overlay] - оверлей заголовка приложения; * [head] - шапка заголовка, присоединяемая к [overlay] * [image] - виджет картинки для заднего фона; - * [imag_path] - путь до картинки, загружаемой в [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) #define yon_ubl_header_setup_resource(overlay, head, image, imag_path) _yon_ubl_header_setup_resource(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_header_setup_resource(GtkWidget *Overlay, GtkWidget *Head, GtkWidget *Image, char *image_path); +/**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); #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); #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); #endif #endif From 3d8c7b2bafb45726c040c6b1c65b002a62718189 Mon Sep 17 00:00:00 2001 From: Ivan Yarcev Date: Mon, 4 Dec 2023 16:06:23 +0600 Subject: [PATCH 7/7] deletion of old files --- Makefile | 2 -- com.ublinux.ublsettings-ui.policy | 24 ------------------------ gresource.xml | 2 ++ source/CMakeLists.txt | 12 +++--------- source/ubl-cmake.in | 1 - source/ublsettings-ui.h | 3 --- source/ublsettings-ui.pc.in | 10 ---------- ubl-utils/CMakeLists.txt | 7 +------ ubl-utils/ubl-cmake.in | 1 - ubl-utils/ubl-utils.c | 23 +---------------------- ubl-utils/ubl-utils.h | 30 +++--------------------------- ubl-utils/ubl-utils.pc.in | 10 ---------- ublsettings-ui.desktop | 15 --------------- 13 files changed, 10 insertions(+), 130 deletions(-) delete mode 100644 com.ublinux.ublsettings-ui.policy delete mode 100644 source/ubl-cmake.in delete mode 100644 source/ublsettings-ui.pc.in delete mode 120000 ubl-utils/ubl-cmake.in delete mode 100644 ubl-utils/ubl-utils.pc.in delete mode 100644 ublsettings-ui.desktop diff --git a/Makefile b/Makefile index fdce4f1..3b68851 100644 --- a/Makefile +++ b/Makefile @@ -142,8 +142,6 @@ install: check install-util build-ui install-ui rsvg-convert -w $${SIZE} -h $${SIZE} -f svg --keep-image-data "com.ublinux.${PKGNAME}.svg" -o "${DESTDIR}${PREFIX}/share/icons/hicolor/$${SIZE}x$${SIZE}/apps/com.ublinux.${PKGNAME}.svg"; \ done @install -Dm644 -t "${DESTDIR}${PREFIX}/share/icons/hicolor/scalable/apps/" "com.ublinux.${PKGNAME}.svg" - @install -Dm644 -t "${DESTDIR}${PREFIX}/share/icons/hicolor/scalable/status/" "com.ublinux.${PKGNAME}.checked.svg" - @install -Dm644 -t "${DESTDIR}${PREFIX}/share/icons/hicolor/scalable/status/" "com.ublinux.${PKGNAME}.warning.svg" @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; \ diff --git a/com.ublinux.ublsettings-ui.policy b/com.ublinux.ublsettings-ui.policy deleted file mode 100644 index eaa2b92..0000000 --- a/com.ublinux.ublsettings-ui.policy +++ /dev/null @@ -1,24 +0,0 @@ - - - - - UBLinux - https://ublinux.ru - - - Run ublsettings-ui as root - Запуск утилиты ublsettings-ui с правами root - Authentication is required to run ublsettings-ui - Требуется авторизация для запуска утилиты ublsettings-ui с правами root - - auth_admin - auth_admin - auth_admin - - /usr/bin/ublsettings-ui - true - - - diff --git a/gresource.xml b/gresource.xml index f24a0e6..ce32b3b 100644 --- a/gresource.xml +++ b/gresource.xml @@ -11,5 +11,7 @@ ublsettings-ui-banner.png + com.ublinux.ublsettings-ui.checked.svg + com.ublinux.ublsettings-ui.warning.svg \ No newline at end of file diff --git a/source/CMakeLists.txt b/source/CMakeLists.txt index 2a6b49a..495d810 100644 --- a/source/CMakeLists.txt +++ b/source/CMakeLists.txt @@ -25,10 +25,6 @@ if(WEBKIT_LIBRARIES_FOUND) add_definitions(${WEBKIT_CFLAGS_OTHER}) endif() -configure_file(ubl-cmake.in ubl-cmake.h) - -file(COPY ${CMAKE_CURRENT_BINARY_DIR}/ubl-cmake.h DESTINATION ../compile) - set(GRESOURCE_C resources.c) set(GRESOURCE_XML gresource.xml) @@ -43,6 +39,8 @@ set(DEPENDFILES ../gresource.xml ../ublsettings-ui-banner.png ../ublsettings-ui.css + ../com.ublinux.ublsettings-ui.checked.svg + ../com.ublinux.ublsettings-ui.warning.svg ) file(COPY ${DEPENDFILES} DESTINATION ${CMAKE_CURRENT_BINARY_DIR}) @@ -99,8 +97,4 @@ install(TARGETS ${PROJECT_NAME} LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} PUBLIC_HEADER DESTINATION ${CMAKE_INSTALL_INCLUDEDIR} ) -configure_file(${PROJECT_NAME}.pc.in ${CMAKE_BINARY_DIR}/${PROJECT_NAME}.pc @ONLY) -# Set pkg-config file to install. -install(FILES ${CMAKE_BINARY_DIR}/${PROJECT_NAME}.pc - DESTINATION ${CMAKE_INSTALL_LIBDIR}/pkgconfig -) \ No newline at end of file +# Set pkg-config file to install. \ No newline at end of file diff --git a/source/ubl-cmake.in b/source/ubl-cmake.in deleted file mode 100644 index d4623a7..0000000 --- a/source/ubl-cmake.in +++ /dev/null @@ -1 +0,0 @@ -#cmakedefine WEBKIT_FOUND diff --git a/source/ublsettings-ui.h b/source/ublsettings-ui.h index 2da844a..debdfb3 100644 --- a/source/ublsettings-ui.h +++ b/source/ublsettings-ui.h @@ -8,10 +8,7 @@ #include #include #include -#include "../compile/ubl-cmake.h" -#ifdef WEBKIT_FOUND #include -#endif #define ui_WIKI_LINK "https://wiki.ublinux.ru/ru/Программное_обеспечение/Программы_и_утилиты/Все/ublsettings-ui" diff --git a/source/ublsettings-ui.pc.in b/source/ublsettings-ui.pc.in deleted file mode 100644 index a170ac9..0000000 --- a/source/ublsettings-ui.pc.in +++ /dev/null @@ -1,10 +0,0 @@ -prefix=@CMAKE_INSTALL_PREFIX@ -exec_prefix=@CMAKE_INSTALL_PREFIX@ -libdir=${exec_prefix}/@CMAKE_INSTALL_LIBDIR@ -includedir=${prefix}/@CMAKE_INSTALL_INCLUDEDIR@ -Name: @PROJECT_NAME@ -Description: @PROJECT_DESCRIPTION@ -Version: @PROJECT_VERSION@ -Requires: -Libs: -L${libdir} -l@PROJECT_NAME@ -Cflags: -I${includedir} \ No newline at end of file diff --git a/ubl-utils/CMakeLists.txt b/ubl-utils/CMakeLists.txt index 9286eef..def0f63 100644 --- a/ubl-utils/CMakeLists.txt +++ b/ubl-utils/CMakeLists.txt @@ -25,7 +25,6 @@ if(WEBKIT_LIBRARIES_FOUND) add_definitions(${WEBKIT_CFLAGS_OTHER}) endif() -file(COPY ${CMAKE_CURRENT_BINARY_DIR}/../ui-compile/ubl-cmake.h DESTINATION ./) #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") @@ -60,8 +59,4 @@ install(TARGETS ${PROJECT_NAME} LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} PUBLIC_HEADER DESTINATION ${CMAKE_INSTALL_INCLUDEDIR} ) -configure_file(${PROJECT_NAME}.pc.in ${CMAKE_BINARY_DIR}/${PROJECT_NAME}.pc @ONLY) -# Set pkg-config file to install. -install(FILES ${CMAKE_BINARY_DIR}/${PROJECT_NAME}.pc - DESTINATION ${CMAKE_INSTALL_LIBDIR}/pkgconfig -) \ No newline at end of file +# Set pkg-config file to install. \ No newline at end of file diff --git a/ubl-utils/ubl-cmake.in b/ubl-utils/ubl-cmake.in deleted file mode 120000 index 393ccdb..0000000 --- a/ubl-utils/ubl-cmake.in +++ /dev/null @@ -1 +0,0 @@ -/home/superadmin/Документы/libublsettings-ui/source/ubl-cmake.in \ No newline at end of file diff --git a/ubl-utils/ubl-utils.c b/ubl-utils/ubl-utils.c index dccd9cf..95c5662 100644 --- a/ubl-utils/ubl-utils.c +++ b/ubl-utils/ubl-utils.c @@ -1169,14 +1169,8 @@ void yon_launch(char *command) // Gtk functions - -#ifdef __GTK_H__ - - static render_data render; -#ifdef VTE_TERMINAL - static void child_ready(VteTerminal *terminal, GPid pid, GError *error, gpointer user_data) { if (!terminal) return; @@ -1271,7 +1265,6 @@ void yon_terminal_integrated_start(GtkWidget *terminal, char* command, void *end vte_terminal_set_scroll_on_keystroke(VTE_TERMINAL(terminal), TRUE); gtk_widget_show_all(terminal); } -#endif // Window config functions @@ -1925,8 +1918,6 @@ void yon_ubl_setup_sockets(GtkWidget *main_window, GtkWidget *left_window, GtkWi } } -#ifdef WEBKIT_FOUND - 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); @@ -1942,16 +1933,4 @@ void yon_ubl_browser_window_open(char *link, char *browser_window_name){ 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 - -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 +} \ No newline at end of file diff --git a/ubl-utils/ubl-utils.h b/ubl-utils/ubl-utils.h index 61edb75..059aaf1 100644 --- a/ubl-utils/ubl-utils.h +++ b/ubl-utils/ubl-utils.h @@ -17,10 +17,7 @@ #include #include -#include "../compile/ubl-cmake.h" -#ifdef WEBKIT_FOUND - #include -#endif + #include #define DesktopPath "/usr/share/applications/" /**for_dictionaries(element, stack) @@ -38,9 +35,7 @@ typedef enum { - #ifdef __GTK_H__ DICTIONARY_GTK_WIDGETS_TYPE, - #endif DICTIONARY_OTHER_TYPE=0, DICTIONARY_CHAR_TYPE, DICTIONARY_INT_TYPE, @@ -651,7 +646,7 @@ int yon_config_set(char *key, void *data); * [RU] * Производит поиск по конфигу и дополняет значение параметра с ключом [key] значением [data]; */ -int yon_config_append(char *key, char *data) +int yon_config_append(char *key, char *data); /**yon_config_clean() * [EN] @@ -714,9 +709,6 @@ void yon_launch(char *command); // Gtk functions -#ifdef __GTK_H__ -#ifdef VTE_TERMINAL - /** * void yon_terminal_integrated_launch(GtkWidget *place_to_show, void *endwork_function, void* endwork_function_argument) * [EN] @@ -742,8 +734,6 @@ void yon_terminal_integrated_launch(GtkWidget *place_to_show, char* command, voi */ void yon_terminal_integrated_start(GtkWidget *terminal, char* command, void *endwork_function, void* endwork_function_argument); -#endif - /**YON_TYPE * [EN] * @@ -755,8 +745,7 @@ enum YON_TYPE{ YON_TYPE_STRING_LIST, YON_TYPE_INT, YON_TYPE_BOOLEAN, - YON_TYPE_OTHER -}; + YON_TYPE_OTHER}; /**yon_gtk_builder_get_widget(builder, widget_name) * [EN] @@ -1090,7 +1079,6 @@ void _yon_ubl_header_setup_resource(GtkWidget *Overlay, GtkWidget *Head, GtkWidg * [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); -#ifdef WEBKIT_FOUND /**yon_ubl_browser_window_open(char *link, char *browser_window_name) * [EN] @@ -1099,16 +1087,4 @@ void yon_ubl_setup_sockets(GtkWidget *main_window, GtkWidget *left_window, GtkWi * Открывает встроенный браузер с именем [browser_window_name] и показываемой страницей по ссылке [link] */ void yon_ubl_browser_window_open(char *link, char *browser_window_name); -#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); -#endif -#endif #endif \ No newline at end of file diff --git a/ubl-utils/ubl-utils.pc.in b/ubl-utils/ubl-utils.pc.in deleted file mode 100644 index a170ac9..0000000 --- a/ubl-utils/ubl-utils.pc.in +++ /dev/null @@ -1,10 +0,0 @@ -prefix=@CMAKE_INSTALL_PREFIX@ -exec_prefix=@CMAKE_INSTALL_PREFIX@ -libdir=${exec_prefix}/@CMAKE_INSTALL_LIBDIR@ -includedir=${prefix}/@CMAKE_INSTALL_INCLUDEDIR@ -Name: @PROJECT_NAME@ -Description: @PROJECT_DESCRIPTION@ -Version: @PROJECT_VERSION@ -Requires: -Libs: -L${libdir} -l@PROJECT_NAME@ -Cflags: -I${includedir} \ No newline at end of file diff --git a/ublsettings-ui.desktop b/ublsettings-ui.desktop deleted file mode 100644 index d82afc3..0000000 --- a/ublsettings-ui.desktop +++ /dev/null @@ -1,15 +0,0 @@ -[Desktop Entry] -Encoding=UTF-8 -Name=TEMPLATE Manager -Name[ru]=TEMPLATE -GenericName=ublsettings-ui -GenericName[ru]=TEMPLATE -Comment=TEMPLATE management app -Comment[ru]=Приложение для TEMPLATE -Type=Application -Exec=pkexec ublsettings-ui -Icon=com.ublinux.ublsettings-ui -Terminal=false -X-XfcePluggable=true -X-UBLPluggable=true -Categories=XFCE;GTK;Settings;DesktopSettings;X-XFCE-SettingsDialog;X-XFCE-SystemSettings;X-UBL-SettingsManager;X-UBL-Personal-Settings;