diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..e992b39
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,12 @@
+.vscode/
+ubl-settings-logging
+*~
+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..1399ffb
--- /dev/null
+++ b/Makefile
@@ -0,0 +1,163 @@
+#!/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_COMMAND = cmake
+CMAKE_SOURCE_DIR = $(MAKEFILE_PATH)source
+CMAKE_BUILD_DIR = $(MAKEFILE_PATH)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_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_COMMAND) -S$(CMAKE_SOURCE_DIR) -B${CMAKE_BUILD_DIR} --check-build-system CMakeFiles/Makefile.cmake 1 || exit 1; \
+ echo "Check depends: OK"
+
+debug:
+ @echo "Debug ..."
+ if [ ! -d ${CMAKE_BUILD_DIR} ]; then \
+ $(CMAKE_COMMAND) -S${CMAKE_SOURCE_DIR} -B${CMAKE_BUILD_DIR} -DCMAKE_BUILD_TYPE=Debug -DCMAKE_INSTALL_PREFIX="${PREFIX}"; \
+ fi; \
+ echo "Debug: OK"
+
+prepare:
+ @echo "Prepare ..."; \
+ if [ ! -d ${CMAKE_BUILD_DIR} ]; then \
+ $(CMAKE_COMMAND) -S${CMAKE_SOURCE_DIR} -B${CMAKE_BUILD_DIR} -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX="${PREFIX}"; \
+ fi; \
+ echo "Prepare: OK"
+
+check:
+ @echo "Check ..."; \
+ if [ -f ${CMAKE_BUILD_DIR}/${PKGNAME} ]; then \
+ echo "Check: OK"; \
+ else \
+ echo "Check: ${CMAKE_BUILD_DIR}/${PKGNAME} not found !"; \
+ exit 1; \
+ fi
+
+build: depend prepare
+ @echo "Build ..."; \
+ $(MAKE_COMMAND) --directory=${CMAKE_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) "${DESTDIR}${PREFIX}/bin/${PKGNAME}"
+ @$(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"
+ @cp ./com.ublinux.${PKGNAME}.policy ./compile/com.ublinux.${PKGNAME}${PKGIDENT}.policy
+ @sed -e 's+/usr/bin+${PREFIX}/bin+' -e 's+.run+${PKGIDENT}.run+g' ./compile/com.ublinux.${PKGNAME}${PKGIDENT}.policy -i
+ @install -Dm755 -t "${DESTDIR}${PREFIX}/bin/" "${CMAKE_BUILD_DIR}/${PKGNAME}"
+ @install -Dm644 -t "${DESTDIR}${PREFIX}/share/applications/" "${PKGNAME}.desktop"
+ @install -Dm644 -t "${DESTDIR}/usr/share/icons/hicolor/scalable/status/" "icons/com.ublinux.${PKGNAME}.checked.svg"
+ @install -Dm644 -t "${DESTDIR}/usr/share/icons/hicolor/scalable/status/" "icons/com.ublinux.${PKGNAME}.warning.svg"
+ @install -Dm644 -t "${DESTDIR}/usr/share/icons/hicolor/scalable/actions/" "icons/com.ublinux.${PKGNAME}.view-symbolic.svg"
+ @install -Dm644 -t "${DESTDIR}/usr/share/icons/hicolor/scalable/actions/" "icons/com.ublinux.${PKGNAME}.play-symbolic.svg"
+ @install -Dm644 -t "${DESTDIR}/usr/share/icons/hicolor/scalable/actions/" "icons/com.ublinux.${PKGNAME}.stop-symbolic.svg"
+ @install -Dm644 -t "${DESTDIR}/usr/share/icons/hicolor/scalable/actions/" "icons/com.ublinux.${PKGNAME}.zoom-symbolic.svg"
+ @install -Dm644 -t "${DESTDIR}/usr/share/icons/hicolor/scalable/actions/" "icons/com.ublinux.${PKGNAME}.back-symbolic.svg"
+ @install -Dm644 -t "${DESTDIR}/usr/share/icons/hicolor/scalable/actions/" "icons/com.ublinux.${PKGNAME}.increase-symbolic.svg"
+ @install -Dm644 -t "${DESTDIR}/usr/share/icons/hicolor/scalable/actions/" "icons/com.ublinux.${PKGNAME}.decrease-symbolic.svg"
+ @install -Dm644 -t "${DESTDIR}/usr/share/icons/hicolor/scalable/actions/" "icons/com.ublinux.${PKGNAME}.profile-symbolic.svg"
+ @install -Dm644 -t "${DESTDIR}/usr/share/${PKGNAME}/csv/" "journals_list.csv"
+ @install -Dm644 -t "${DESTDIR}/usr/share/${PKGNAME}/csv/" "logging_services.csv"
+ @install -Dm644 -t "${DESTDIR}/usr/share/polkit-1/actions/" "${CMAKE_BUILD_DIR}/com.ublinux.${PKGNAME}${PKGIDENT}.policy"
+ @if [ -z ${DESTDIR} ]; then \
+ [ -d "${DESTDIR}/usr/share/icons/hicolor/" ] && gtk-update-icon-cache -fiq "${DESTDIR}/usr/share/icons/hicolor/" &>/dev/null || true; \
+ update-desktop-database --quiet &>/dev/null || true; \
+ [ -d "${DESTDIR}$/usr/share/applications" ] && touch "${DESTDIR}/usr/share/applications" &>/dev/null || true; \
+ fi
+ @echo "Install: OK"
+
+clean:
+ @echo "Clean ..."
+ @$(RM) -rd ${CMAKE_BUILD_DIR}
+ @if [ -d ${CMAKE_BUILD_DIR} ]; then \
+ echo "Clean: error, compile directory exist ${CMAKE_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/README.md b/README.md
index 3134f1e..389e5a2 100644
--- a/README.md
+++ b/README.md
@@ -1,2 +1,29 @@
# ubl-settings-logging
+# Выполнить
+# Build
+In order to build ubl-settings-logging you will need:
+
+- CMake
+- C compiler
+- GTK+ 3 & dependencies
+- webkit2gtk (optional)
+
+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
+```
+
+
diff --git a/com.ublinux.ubl-settings-logging.policy b/com.ublinux.ubl-settings-logging.policy
new file mode 100644
index 0000000..daa7152
--- /dev/null
+++ b/com.ublinux.ubl-settings-logging.policy
@@ -0,0 +1,24 @@
+
+
+
+
+ UBLinux
+ https://ublinux.ru
+
+
+ Run ubl-settings-logging as root
+ Запуск утилиты ubl-settings-logging с правами root
+ Authentication is required to run ubl-settings-logging
+ Требуется авторизация для запуска утилиты ubl-settings-logging с правами root
+
+ auth_admin
+ auth_admin
+ auth_admin
+
+ /usr/bin/ubl-settings-logging
+ true
+
+
+
diff --git a/com.ublinux.ubl-settings-logging.svg b/com.ublinux.ubl-settings-logging.svg
new file mode 100644
index 0000000..4dc1dc4
--- /dev/null
+++ b/com.ublinux.ubl-settings-logging.svg
@@ -0,0 +1,3633 @@
+
+
diff --git a/gresource.xml b/gresource.xml
new file mode 100644
index 0000000..1914fde
--- /dev/null
+++ b/gresource.xml
@@ -0,0 +1,17 @@
+
+
+
+ ubl-settings-logging.glade
+ ubl-settings-logging-add.glade
+ ubl-settings-logging-inspector.glade
+ ubl-settings-logging-logrotate.glade
+ ubl-settings-logging-journald.glade
+ ubl-settings-logging-logrotate-table.glade
+
+
+ ubl-settings-logging.css
+
+
+ ubl-settings-logging-banner.png
+
+
\ No newline at end of file
diff --git a/icons/com.ublinux.ubl-settings-logging.back-symbolic.svg b/icons/com.ublinux.ubl-settings-logging.back-symbolic.svg
new file mode 100644
index 0000000..3e0225a
--- /dev/null
+++ b/icons/com.ublinux.ubl-settings-logging.back-symbolic.svg
@@ -0,0 +1,47 @@
+
+
diff --git a/icons/com.ublinux.ubl-settings-logging.checked.svg b/icons/com.ublinux.ubl-settings-logging.checked.svg
new file mode 100644
index 0000000..e3cab42
--- /dev/null
+++ b/icons/com.ublinux.ubl-settings-logging.checked.svg
@@ -0,0 +1,327 @@
+
+
diff --git a/icons/com.ublinux.ubl-settings-logging.decrease-symbolic.svg b/icons/com.ublinux.ubl-settings-logging.decrease-symbolic.svg
new file mode 100644
index 0000000..1413e10
--- /dev/null
+++ b/icons/com.ublinux.ubl-settings-logging.decrease-symbolic.svg
@@ -0,0 +1,40 @@
+
+
diff --git a/icons/com.ublinux.ubl-settings-logging.increase-symbolic.svg b/icons/com.ublinux.ubl-settings-logging.increase-symbolic.svg
new file mode 100644
index 0000000..800b264
--- /dev/null
+++ b/icons/com.ublinux.ubl-settings-logging.increase-symbolic.svg
@@ -0,0 +1,40 @@
+
+
diff --git a/icons/com.ublinux.ubl-settings-logging.play-symbolic.svg b/icons/com.ublinux.ubl-settings-logging.play-symbolic.svg
new file mode 100644
index 0000000..3ebe8f3
--- /dev/null
+++ b/icons/com.ublinux.ubl-settings-logging.play-symbolic.svg
@@ -0,0 +1,169 @@
+
+
+
+
diff --git a/icons/com.ublinux.ubl-settings-logging.profile-symbolic.svg b/icons/com.ublinux.ubl-settings-logging.profile-symbolic.svg
new file mode 100644
index 0000000..4bc7b0c
--- /dev/null
+++ b/icons/com.ublinux.ubl-settings-logging.profile-symbolic.svg
@@ -0,0 +1,49 @@
+
+
+
+
diff --git a/icons/com.ublinux.ubl-settings-logging.stop-symbolic.svg b/icons/com.ublinux.ubl-settings-logging.stop-symbolic.svg
new file mode 100644
index 0000000..91f45bc
--- /dev/null
+++ b/icons/com.ublinux.ubl-settings-logging.stop-symbolic.svg
@@ -0,0 +1,185 @@
+
+
+
+
diff --git a/icons/com.ublinux.ubl-settings-logging.view-symbolic.svg b/icons/com.ublinux.ubl-settings-logging.view-symbolic.svg
new file mode 100644
index 0000000..86197b6
--- /dev/null
+++ b/icons/com.ublinux.ubl-settings-logging.view-symbolic.svg
@@ -0,0 +1,49 @@
+
+
+
+
diff --git a/icons/com.ublinux.ubl-settings-logging.warning.svg b/icons/com.ublinux.ubl-settings-logging.warning.svg
new file mode 100644
index 0000000..9a90dba
--- /dev/null
+++ b/icons/com.ublinux.ubl-settings-logging.warning.svg
@@ -0,0 +1,55 @@
+
+
diff --git a/icons/com.ublinux.ubl-settings-logging.zoom-symbolic.svg b/icons/com.ublinux.ubl-settings-logging.zoom-symbolic.svg
new file mode 100644
index 0000000..c5011ec
--- /dev/null
+++ b/icons/com.ublinux.ubl-settings-logging.zoom-symbolic.svg
@@ -0,0 +1,160 @@
+
+
+
+
diff --git a/journals_list.csv b/journals_list.csv
new file mode 100644
index 0000000..be0612f
--- /dev/null
+++ b/journals_list.csv
@@ -0,0 +1,12 @@
+Журнал Acpid;/var/log/acpid;Журнал работы и обращений к Acpid
+Журнал веб-сервера;/var/log/apache2/error.log,/var/log/apache2/access.log;Журнал работы и обращений к веб-серверу
+Журнал аудита;/var/log/audit/audit.log;Журнал аудита (audit)
+Журнал авторизации;/var/log/auth.log;Журнал процедур авторизации
+Журнал планировщика заданий;/var/log/syslog;Журнал работы планировщика заданий (cron)
+Журнал сервера печати;/var/log/cups/access_log,/var/log/cups/page_log,/var/log/cups/cups-pdf_log;Журнал работы и обращений к серверу печати (cups)
+Журналы служб;/var/log/daemon.log;Журнал работы и обращения к службам системы
+Журнал Samba;/var/log/samba/log.smbd,/var/log/samba/log.localhost,/var/log/samba/log.127.0.0.1,/var/log/samba/log.nmbd;Журнал работы и обращения к Samba
+Журнал почтового сервера;/var/log/mail.log,/var/log/mail.info,/var/log/mail.warn,/var/log/mail.err;Журнал почтового сервера Postfix
+Системный журнал;/var/log/syslog;Системный журнал
+Журнал дисплейного сервера;/var/log/Xorg.0.log;Журнал работы дисплейного сервера X.org
+Журнал сеансов графической системы X;~/.xsession-errors/;Журнал сеансов графической системы X
\ No newline at end of file
diff --git a/logging_services.csv b/logging_services.csv
new file mode 100644
index 0000000..ccc34a9
--- /dev/null
+++ b/logging_services.csv
@@ -0,0 +1,4 @@
+journald;Системный журнал событий;systemctl start;systemctl start systemd-journald.service;systemctl stop systemd-journald.service;ubconfig set config SERVICESSTART+=systemd-journald.service;ubconfig set config SERVICESSTART-=systemd-journald.service;systemctl status systemd-journald.service
+logrotate;Служба ротации системных журналов событий;systemctl start logrotate.service;systemctl stop logrotate.service;ubconfig set config SERVICESSTART+=logrotate.service;ubconfig set config SERVICESSTART-=logrotate.service;systemctl status logrotate.service
+metalog;Системный журнал событий;systemctl start metalog.service;systemctl stop metalog.service;ubconfig set config SERVICESSTART+=metalog.service;ubconfig set config SERVICESSTART-=metalog.service;systemctl status metalog.service
+syslog-ng;Сервис сбора сообщений системных событий активных сетевых устройств;systemctl start syslog-ng.service;systemctl stop syslog-ng.service;ubconfig set config SERVICESSTART+=syslog-ng.service;ubconfig set config SERVICESSTART-=syslog-ng.service;systemctl status syslog-ng.service
\ No newline at end of file
diff --git a/source/CMakeLists.txt b/source/CMakeLists.txt
new file mode 100644
index 0000000..c9220c0
--- /dev/null
+++ b/source/CMakeLists.txt
@@ -0,0 +1,101 @@
+cmake_minimum_required(VERSION 3.7)
+project(ubl-settings-logging)
+
+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})
+
+#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)
+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 ./)
+
+set(GRESOURCE_C resources.c)
+set(GRESOURCE_XML gresource.xml)
+
+find_program(GLIB_COMPILE_RESOURCES NAMES glib-compile-resources REQUIRED)
+add_custom_target(GLADE ubl-settings-logging.glade)
+
+set(DEPENDFILES
+ ../ubl-settings-logging.glade
+ ../ubl-settings-logging-add.glade
+ ../ubl-settings-logging-inspector.glade
+ ../ubl-settings-logging-journald.glade
+ ../ubl-settings-logging-logrotate.glade
+ ../ubl-settings-logging-logrotate-table.glade
+ ../gresource.xml
+ ../ubl-settings-logging-banner.png
+ ../ubl-settings-logging.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")
+
+
+set(SOURCE_FILES
+ ubl-settings-logging.c
+ ubl-settings-logging.h
+ ubl-strings.h
+ ubl-utils.h
+ ubl-utils.c
+ ${CMAKE_CURRENT_BINARY_DIR}/ubl-cmake.h
+ )
+
+set(LIBRARIES
+ ${GTK_LIBRARIES}
+ ${WEBKIT_LIBRARIES}
+# ${VTE291_LIBRARIES}
+ pthread)
+
+
+add_executable(${PROJECT_NAME} ${SOURCE_FILES} ${CMAKE_CURRENT_BINARY_DIR}/${GRESOURCE_C})
+target_link_libraries(${PROJECT_NAME} PUBLIC ${LIBRARIES})
+target_include_directories(${PROJECT_NAME} PUBLIC ${PROJECT_BINARY_DIR})
+set_source_files_properties(
+ ${CMAKE_CURRENT_BINARY_DIR}/${GRESOURCE_C}
+ PROPERTIES GENERATED TRUE
+)
+install(TARGETS ${PROJECT_NAME} DESTINATION bin)
+add_dependencies(${PROJECT_NAME} dummy-resource)
\ 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/ubl-settings-logging.c b/source/ubl-settings-logging.c
new file mode 100644
index 0000000..3b35ba2
--- /dev/null
+++ b/source/ubl-settings-logging.c
@@ -0,0 +1,718 @@
+#include "ubl-settings-logging.h"
+
+config main_config;
+
+//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,TITLE_LABEL);
+}
+
+/**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 (main_config.always_open_documentation==0){
+ GtkBuilder *builder = gtk_builder_new_from_resource(glade_path);
+ documentation_confirmation_window *widgets = malloc(sizeof(documentation_confirmation_window));
+ widgets->Window = yon_gtk_builder_get_widget(builder,"helpConfirmationWindow");
+ widgets->AcceptButton = yon_gtk_builder_get_widget(builder,"ReadHelpButton");
+ widgets->CloseButton = yon_gtk_builder_get_widget(builder,"CancelHelpButton");
+ widgets->HatText = yon_gtk_builder_get_widget(builder,"webHeaderNameLabel");
+ widgets->HeaderText = yon_gtk_builder_get_widget(builder,"helpHeader");
+ widgets->InfoText = yon_gtk_builder_get_widget(builder,"helpText");
+ widgets->AlwaysOpenCheck = yon_gtk_builder_get_widget(builder,"AlwaysOpenDocumentationCheckbox");
+ gtk_label_set_text(GTK_LABEL(widgets->HatText),TITLE_LABEL);
+ gtk_label_set_text(GTK_LABEL(widgets->HeaderText),HELP_TITLE_LABEL);
+ gtk_label_set_text(GTK_LABEL(widgets->InfoText),HELP_INFO_LABEL);
+ gtk_button_set_label(GTK_BUTTON(widgets->AcceptButton),OPEN_HELP_LABEL);
+ gtk_button_set_label(GTK_BUTTON(widgets->AlwaysOpenCheck),HELP_ALWAYS_OPEN_LABEL);
+ gtk_button_set_label(GTK_BUTTON(widgets->CloseButton),CANCEL_LABEL);
+ gtk_widget_show_all(widgets->Window);
+ g_signal_connect(G_OBJECT(widgets->CloseButton),"clicked",G_CALLBACK(on_close_subwindow),NULL);
+ g_signal_connect(G_OBJECT(widgets->AcceptButton),"clicked",G_CALLBACK(yon_open_browser),yon_char_new(link));
+ g_signal_connect(G_OBJECT(widgets->AcceptButton),"clicked",G_CALLBACK(on_close_subwindow),NULL);
+
+
+ } else {
+ yon_open_browser(self,link);
+ }
+}
+
+/**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(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_website_label(GTK_ABOUT_DIALOG(window),PROJECT_HOME_LABEL);
+ gtk_about_dialog_set_comments(GTK_ABOUT_DIALOG(window),TITLE_LABEL);
+ gtk_label_set_text(GTK_LABEL(title),TITLE_LABEL);
+ g_signal_connect(G_OBJECT(window),"activate-link",G_CALLBACK(on_link),NULL);
+ gtk_widget_set_visible(hideButtonBox,0);
+ gtk_widget_destroy(hideButtonBox);
+ gtk_widget_show(window);
+}
+
+//functions
+
+void yon_load_proceed(char *command){
+ yon_ubl_status_box_render(LOCAL_SAVE_SUCCESS_LABEL,BACKGROUND_IMAGE_SUCCESS_TYPE);
+
+}
+
+add_log_window *on_add_open(){
+ add_log_window *window = malloc(sizeof(add_log_window));
+ GtkBuilder *builder = gtk_builder_new_from_resource(glade_add_path);
+ window->MainWindow=yon_gtk_builder_get_widget(builder,"MainWindow");
+ window->CancelButton=yon_gtk_builder_get_widget(builder,"CancelButton");
+ window->SaveButton=yon_gtk_builder_get_widget(builder,"SaveButton");
+ window->LogAddingBox=yon_gtk_builder_get_widget(builder,"LogAddingBox");
+ window->LogTypeCombo=yon_gtk_builder_get_widget(builder,"LogTypeCombo");
+ window->LogPathEntry=yon_gtk_builder_get_widget(builder,"LogPathEntry");
+ window->LogFindButton=yon_gtk_builder_get_widget(builder,"LogFindButton");
+ window->LogDescriptionEntry=yon_gtk_builder_get_widget(builder,"LogDescriptionEntry");
+ window->LogrotateButton=yon_gtk_builder_get_widget(builder,"LogrotateButton");
+ window->MetalogButton=yon_gtk_builder_get_widget(builder,"MetalogButton");
+ window->SyslogButton=yon_gtk_builder_get_widget(builder,"SyslogButton");
+ window->JournaldButton=yon_gtk_builder_get_widget(builder,"JournaldButton");
+ window->LogSizeLabel=yon_gtk_builder_get_widget(builder,"LogSizeLabel");
+ window->StatisticsFrame=yon_gtk_builder_get_widget(builder,"StatisticsFrame");
+ gtk_window_set_title(GTK_WINDOW(window->MainWindow),TITLE_LABEL);
+ g_signal_connect(G_OBJECT(window->CancelButton),"clicked", G_CALLBACK(on_close_subwindow),NULL);
+ return window;
+}
+
+void on_inspector_update(GtkWidget *self, inspector_window *window){
+ int size;
+ GtkTextIter titer,titerend;
+ gtk_text_buffer_get_bounds(window->textbuffer1,&titer,&titerend);
+ gtk_text_buffer_delete(window->textbuffer1,&titer,&titerend);
+ config_str output;
+ if (self==window->UpdateButton){
+ switch(window->last_mode){
+ case 0: output = yon_config_load(get_journal_output_command, &size);
+ break;
+ case 1: output = yon_config_load(get_journal_output_since_boot_command, &size);
+ break;
+ case 2: output = yon_config_load(get_journal_output_followed_command, &size);
+ break;
+ case 3: output = yon_config_load(get_journal_output_kernel_command, &size);
+ break;
+ case 4: output = yon_config_load(get_journal_output_prioritied_command, &size);
+ break;
+ }
+ }
+ if (self==window->ShowSinceBootButton){
+ window->last_mode=1;
+ output = yon_config_load(get_journal_output_since_boot_command, &size);
+ }
+ if (self==window->NewMessagesButton){
+ window->last_mode=2;
+ output = yon_config_load(get_journal_output_followed_command, &size);
+ }
+ if (self==window->ShowKernelButton){
+ window->last_mode=3;
+ output = yon_config_load(get_journal_output_kernel_command, &size);
+ }
+ if (self==window->ShowPriorityButton){
+ window->last_mode=4;
+ output = yon_config_load(get_journal_output_prioritied_command, &size);
+ }
+ if (output){
+ for (int i=0;itextbuffer1,&titer);
+ gtk_text_buffer_insert(window->textbuffer1,&titer,output[i],-1);
+ }
+ gtk_text_buffer_get_end_iter(window->textbuffer1,&titer);
+ gtk_text_view_scroll_to_iter(GTK_TEXT_VIEW(window->LoggingTextView),&titer,0.25,0,1,0);
+ }
+}
+
+void on_inspector_open(GtkWidget *self, main_window *widgets){
+ inspector_window *window = malloc(sizeof(inspector_window));
+ GtkBuilder *builder = gtk_builder_new_from_resource(glade_inspector_path);
+ window->textbuffer1=GTK_TEXT_BUFFER(gtk_builder_get_object(builder,"textbuffer1"));
+ window->MainWindow=yon_gtk_builder_get_widget(builder,"MainWindow");
+ window->ShowSinceBootButton=yon_gtk_builder_get_widget(builder,"ShowSinceBootButton");
+ window->NewMessagesButton=yon_gtk_builder_get_widget(builder,"NewMessagesButton");
+ window->ShowKernelButton=yon_gtk_builder_get_widget(builder,"ShowKernelButton");
+ window->ShowPriorityButton=yon_gtk_builder_get_widget(builder,"ShowPriorityButton");
+ window->UpdateButton=yon_gtk_builder_get_widget(builder,"UpdateButton");
+ window->LoggingTextView=yon_gtk_builder_get_widget(builder,"LoggingTextView");
+ window->JournalActionsBox=yon_gtk_builder_get_widget(builder,"JournalActionsBox");
+ GtkTreeModel *model = GTK_TREE_MODEL(widgets->list);
+ GtkTreeIter iter;
+ char *name;
+ g_signal_connect(G_OBJECT(window->UpdateButton),"clicked", G_CALLBACK(on_inspector_update),window);
+ g_signal_connect(G_OBJECT(window->ShowKernelButton),"clicked", G_CALLBACK(on_inspector_update),window);
+ g_signal_connect(G_OBJECT(window->NewMessagesButton),"clicked", G_CALLBACK(on_inspector_update),window);
+ g_signal_connect(G_OBJECT(window->ShowPriorityButton),"clicked", G_CALLBACK(on_inspector_update),window);
+ g_signal_connect(G_OBJECT(window->ShowSinceBootButton),"clicked", G_CALLBACK(on_inspector_update),window);
+ if (gtk_tree_selection_get_selected(gtk_tree_view_get_selection(GTK_TREE_VIEW(widgets->MainTree)),&model,&iter)){
+ gtk_tree_model_get(model,&iter,0,&name,-1);
+ if (strcmp(name,"journald")){
+ window->last_mode=-1;
+ gtk_widget_hide(window->JournalActionsBox);
+ } else {
+ window->last_mode=0;
+ }
+ on_inspector_update(window->UpdateButton,window);
+ gtk_widget_show(window->MainWindow);
+ }
+}
+
+void on_log_choose(GtkWidget *self,add_log_window *window){
+ GtkWidget *dialog = gtk_file_chooser_dialog_new(TITLE_LABEL,GTK_WINDOW(window->MainWindow),GTK_FILE_CHOOSER_ACTION_OPEN,CANCEL_LABEL,GTK_RESPONSE_CANCEL,ACCEPT_LABEL,GTK_RESPONSE_ACCEPT,NULL);
+ gtk_file_chooser_add_shortcut_folder(GTK_FILE_CHOOSER(dialog),yon_ubl_user_get_home_directory(),NULL);
+ gtk_file_chooser_add_shortcut_folder(GTK_FILE_CHOOSER(dialog),"/var/",NULL);
+ gtk_file_chooser_set_current_folder(GTK_FILE_CHOOSER(dialog),"/var/");
+ GtkFileFilter *filter = gtk_file_filter_new();
+ gtk_file_filter_add_pattern(filter,"*.log");
+ gtk_file_filter_set_name(filter,".log");
+ gtk_file_chooser_add_filter(GTK_FILE_CHOOSER(dialog),filter);
+ int responce = gtk_dialog_run(GTK_DIALOG(dialog));
+ if (responce == GTK_RESPONSE_ACCEPT){
+ char *filename = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(dialog));
+ gtk_entry_set_text(GTK_ENTRY(window->LogPathEntry),filename);
+ }
+ gtk_widget_destroy(dialog);
+}
+
+logrotate_configure_window *yon_logrotate_window_new(){
+ logrotate_configure_window *window = malloc(sizeof(logrotate_configure_window));
+ GtkBuilder *builder = gtk_builder_new_from_resource(glade_logrotate_path);
+ window->MainWindow=yon_gtk_builder_get_widget(builder,"MainWindow");
+ window->CancelButton=yon_gtk_builder_get_widget(builder,"CancelButton");
+ window->SaveButton=yon_gtk_builder_get_widget(builder,"SaveButton");
+ window->LogNamelabel=yon_gtk_builder_get_widget(builder,"LogNamelabel");
+ window->LogNameButton=yon_gtk_builder_get_widget(builder,"LogNameButton");
+ window->RotationPeriodCheck=yon_gtk_builder_get_widget(builder,"RotationPeriodCheck");
+ window->RotationPeriodMainCombo=yon_gtk_builder_get_widget(builder,"RotationPeriodMainCombo");
+ window->RotationPeriodAdditionalCombo=yon_gtk_builder_get_widget(builder,"RotationPeriodAdditionalCombo");
+ window->JournalMaxSizeCheck=yon_gtk_builder_get_widget(builder,"JournalMaxSizeCheck");
+ window->JournalMaxSizeSpin=yon_gtk_builder_get_widget(builder,"JournalMaxSizeSpin");
+ window->JournalMaxSizeCombo=yon_gtk_builder_get_widget(builder,"JournalMaxSizeCombo");
+ window->FileAmountCheck=yon_gtk_builder_get_widget(builder,"FileAmountCheck");
+ window->FileAmountSpin=yon_gtk_builder_get_widget(builder,"FileAmountSpin");
+ window->FileAmountCombo=yon_gtk_builder_get_widget(builder,"FileAmountCombo");
+ window->FileAmountEntry=yon_gtk_builder_get_widget(builder,"FileAmountEntry");
+ window->FileAmountButton=yon_gtk_builder_get_widget(builder,"FileAmountButton");
+ window->RotationAtUserCombo=yon_gtk_builder_get_widget(builder,"RotationAtUserCombo");
+ window->RotationAtGroupCombo=yon_gtk_builder_get_widget(builder,"RotationAtGroupCombo");
+ window->ErrorProcessingCombo=yon_gtk_builder_get_widget(builder,"ErrorProcessingCombo");
+ window->JournalEmptyCombo=yon_gtk_builder_get_widget(builder,"JournalEmptyCombo");
+ window->DoNotRotateYoungerCheck=yon_gtk_builder_get_widget(builder,"DoNotRotateYoungerCheck");
+ window->DoNotRotateYoungerSpin=yon_gtk_builder_get_widget(builder,"DoNotRotateYoungerSpin");
+ window->DeleteOlderCheck=yon_gtk_builder_get_widget(builder,"DeleteOlderCheck");
+ window->DeleteOlderSpin=yon_gtk_builder_get_widget(builder,"DeleteOlderSpin");
+ window->RotateSizeMaxAfterTimeCheck=yon_gtk_builder_get_widget(builder,"RotateSizeMaxAfterTimeCheck");
+ window->RotateSizeMaxAfterTimeSpin=yon_gtk_builder_get_widget(builder,"RotateSizeMaxAfterTimeSpin");
+ window->RotateSizeMaxAfterTimeCombo=yon_gtk_builder_get_widget(builder,"RotateSizeMaxAfterTimeCombo");
+ window->RotateSizeMaxBeforeTimeCheck=yon_gtk_builder_get_widget(builder,"RotateSizeMaxBeforeTimeCheck");
+ window->RotateSizeMaxBeforeTimeSpin=yon_gtk_builder_get_widget(builder,"RotateSizeMaxBeforeTimeSpin");
+ window->RotateSizeMaxBeforeTimeCombo=yon_gtk_builder_get_widget(builder,"RotateSizeMaxBeforeTimeCombo");
+ window->CreateLogCombo=yon_gtk_builder_get_widget(builder,"CreateLogCombo");
+ window->CreateLogUserCombo=yon_gtk_builder_get_widget(builder,"CreateLogUserCombo");
+ window->CreateGroupCombo=yon_gtk_builder_get_widget(builder,"CreateGroupCombo");
+ window->CreateLogEntry=yon_gtk_builder_get_widget(builder,"CreateLogEntry");
+ window->CreateLogButton=yon_gtk_builder_get_widget(builder,"CreateLogButton");
+ window->CutCheck=yon_gtk_builder_get_widget(builder,"CutCheck");
+ window->CompressionCombo=yon_gtk_builder_get_widget(builder,"CompressionCombo");
+ window->QueueCombo=yon_gtk_builder_get_widget(builder,"QueueCombo");
+ window->SaveOriginalCombo=yon_gtk_builder_get_widget(builder,"SaveOriginalCombo");
+ window->SaveOriginalEntry=yon_gtk_builder_get_widget(builder,"SaveOriginalEntry");
+ window->AddDateCombo=yon_gtk_builder_get_widget(builder,"AddDateCombo");
+ window->OldNumberCombo=yon_gtk_builder_get_widget(builder,"OldNumberCombo");
+ window->OldNumberEntry=yon_gtk_builder_get_widget(builder,"OldNumberEntry");
+ window->EmailCombo=yon_gtk_builder_get_widget(builder,"EmailCombo");
+ window->EmailEntry=yon_gtk_builder_get_widget(builder,"EmailEntry");
+ window->EmailContentsCombo=yon_gtk_builder_get_widget(builder,"EmailContentsCombo");
+ window->ManualInputEntry=yon_gtk_builder_get_widget(builder,"ManualInputEntry");
+ window->LogSizeLabel=yon_gtk_builder_get_widget(builder,"LogSizeLabel");
+ window->headerTopic=yon_gtk_builder_get_widget(builder,"headerTopic");
+ window->LogNameDescriptionLabel=yon_gtk_builder_get_widget(builder,"LogNameDescriptionLabel");
+ window->list=GTK_LIST_STORE(gtk_builder_get_object(builder,"liststore1"));
+ g_signal_connect(G_OBJECT(window->CancelButton),"clicked",G_CALLBACK(on_close_subwindow),NULL);
+ g_signal_connect(G_OBJECT(window->SaveButton),"clicked",G_CALLBACK(on_close_subwindow),NULL);
+
+ return window;
+}
+
+void on_logrotate_add(GtkWidget *self, main_window *widgets){
+ logrotate_configure_window *window = yon_logrotate_window_new();
+ gtk_widget_show(window->MainWindow);
+ add_log_window *dialog = on_add_open();
+ gtk_widget_hide(dialog->StatisticsFrame);
+ gtk_widget_hide(dialog->JournaldButton);
+ gtk_label_set_text(GTK_LABEL(window->LogNamelabel),"");
+ gtk_label_set_text(GTK_LABEL(window->LogNameDescriptionLabel),"");
+ gtk_label_set_text(GTK_LABEL(window->LogSizeLabel),"");
+ gtk_window_present(GTK_WINDOW(dialog->MainWindow));
+}
+
+void on_logrotate_edit(GtkWidget *self, logrotate_tab_window *window){
+ GtkTreeModel *model = GTK_TREE_MODEL(main_config.logrotate_list);
+ GtkTreeIter iter;
+ if (gtk_tree_selection_get_selected(gtk_tree_view_get_selection(GTK_TREE_VIEW(window->MainTree)),&model, &iter)){
+ logrotate_configure_window *dialog = yon_logrotate_window_new();
+
+ gtk_widget_show(dialog->MainWindow);
+ }
+
+}
+
+void on_logrotate_remove(GtkWidget *self, logrotate_tab_window *window){
+ GtkTreeModel *model = GTK_TREE_MODEL(main_config.logrotate_list);
+ GtkTreeIter iter;
+ if (gtk_tree_selection_get_selected(gtk_tree_view_get_selection(GTK_TREE_VIEW(window->MainTree)),&model, &iter)){
+ gtk_list_store_remove(main_config.logrotate_list,&iter);
+ }
+}
+
+void on_logrotate_apps_configure(){
+
+}
+
+void on_logrotate_tab_open(GtkWidget *self, main_window *widgets){
+ logrotate_window *window = malloc(sizeof(logrotate_window));
+ GtkBuilder *builder = gtk_builder_new_from_resource(glade_logrotate_table_path);
+ window->Window=yon_gtk_builder_get_widget(builder,"MainWindow");
+ window->AppsMainTree=yon_gtk_builder_get_widget(builder,"AppsMainTree");
+ window->MainTree=yon_gtk_builder_get_widget(builder,"MainTree");
+ window->AppsConfigureButton=yon_gtk_builder_get_widget(builder,"AppsConfigureButton");
+ window->CancelButton=yon_gtk_builder_get_widget(builder,"CancelButton");
+ window->SaveButton=yon_gtk_builder_get_widget(builder,"SaveButton");
+ window->ConfigureButton = yon_gtk_builder_get_widget(builder,"ConfigureButton");
+ window->AddButton = yon_gtk_builder_get_widget(builder,"AddButton");
+ window->RemoveButton = yon_gtk_builder_get_widget(builder,"RemoveButton");
+ gtk_window_set_title(GTK_WINDOW(window->Window),TITLE_LABEL);
+
+ gtk_tree_view_set_model(GTK_TREE_VIEW(window->MainTree),GTK_TREE_MODEL(main_config.logrotate_list));
+ gtk_tree_view_set_model(GTK_TREE_VIEW(window->AppsMainTree),GTK_TREE_MODEL(main_config.logrotate_apps_list));
+
+ g_signal_connect(G_OBJECT(window->CancelButton),"clicked",G_CALLBACK(on_close_subwindow),NULL);
+ g_signal_connect(G_OBJECT(window->SaveButton),"clicked",G_CALLBACK(on_close_subwindow),NULL);
+ g_signal_connect(G_OBJECT(window->AddButton),"clicked",G_CALLBACK(on_logrotate_add),window);
+ g_signal_connect(G_OBJECT(window->RemoveButton),"clicked",G_CALLBACK(on_logrotate_remove),window);
+ g_signal_connect(G_OBJECT(window->ConfigureButton),"clicked",G_CALLBACK(on_logrotate_edit),window);
+ g_signal_connect(G_OBJECT(window->AppsConfigureButton),"clicked",G_CALLBACK(on_logrotate_apps_configure),NULL);
+ gtk_widget_show(window->Window);
+}
+
+void on_journald_open(GtkWidget *self, main_window *widgets){
+ journald_window *window = malloc(sizeof(journald_window));
+ GtkBuilder *builder = gtk_builder_new_from_resource(glade_journald_path);
+ window->MainWindow=yon_gtk_builder_get_widget(builder,"MainWindow");
+ window->CancelButton=yon_gtk_builder_get_widget(builder,"CancelButton");
+ window->SaveButton=yon_gtk_builder_get_widget(builder,"SaveButton");
+ window->LogNameLabel=yon_gtk_builder_get_widget(builder,"LogNameLabel");
+ window->LogDescriptionLabel=yon_gtk_builder_get_widget(builder,"LogDescriptionLabel");
+ window->LogStorageCombo=yon_gtk_builder_get_widget(builder,"LogStorageCombo");
+ window->LogCompressionCombo=yon_gtk_builder_get_widget(builder,"LogCompressionCombo");
+ window->LogCompressionEntry=yon_gtk_builder_get_widget(builder,"LogCompressionEntry");
+ window->LogCompressionSizeCombo=yon_gtk_builder_get_widget(builder,"LogCompressionSizeCombo");
+ window->DivideJournalFilesCombo=yon_gtk_builder_get_widget(builder,"DivideJournalFilesCombo");
+ window->LogIntervalCheck=yon_gtk_builder_get_widget(builder,"LogIntervalCheck");
+ window->LogIntervalSpin=yon_gtk_builder_get_widget(builder,"LogIntervalSpin");
+ window->LogIntervalAmountCheck=yon_gtk_builder_get_widget(builder,"LogIntervalAmountCheck");
+ window->LogIntervalAmountSpin=yon_gtk_builder_get_widget(builder,"LogIntervalAmountSpin");
+ window->LogSizeMaxCheck=yon_gtk_builder_get_widget(builder,"LogSizeMaxCheck");
+ window->LogSizeMaxSpin=yon_gtk_builder_get_widget(builder,"LogSizeMaxSpin");
+ window->LogSizeMaxCombo=yon_gtk_builder_get_widget(builder,"LogSizeMaxCombo");
+ window->RotationSizeMaxCheck=yon_gtk_builder_get_widget(builder,"RotationSizeMaxCheck");
+ window->RotationSizeMaxSpin=yon_gtk_builder_get_widget(builder,"RotationSizeMaxSpin");
+ window->RotationSizeMaxCombo=yon_gtk_builder_get_widget(builder,"RotationSizeMaxCombo");
+ window->LogFreeSpaceCheck=yon_gtk_builder_get_widget(builder,"LogFreeSpaceCheck");
+ window->LogFreeSpaceSpin=yon_gtk_builder_get_widget(builder,"LogFreeSpaceSpin");
+ window->LogFreeSpaceCombo=yon_gtk_builder_get_widget(builder,"LogFreeSpaceCombo");
+ window->RedirectCombo=yon_gtk_builder_get_widget(builder,"RedirectCombo");
+ window->RedirectTTYEntry=yon_gtk_builder_get_widget(builder,"RedirectTTYEntry");
+ window->ForwardedTypeCombo=yon_gtk_builder_get_widget(builder,"ForwardedTypeCombo");
+ window->LogSizeLabel=yon_gtk_builder_get_widget(builder,"LogSizeLabel");
+ window->LowerSizeEntry=yon_gtk_builder_get_widget(builder,"LowerSizeEntry");
+ window->LowerSizeCombo=yon_gtk_builder_get_widget(builder,"LowerSizeCombo");
+ window->LowerSizeButton=yon_gtk_builder_get_widget(builder,"LowerSizeButton");
+ window->LowerTimeEntry=yon_gtk_builder_get_widget(builder,"LowerTimeEntry");
+ window->LowerTimeCombo=yon_gtk_builder_get_widget(builder,"LowerTimeCombo");
+ window->LowerTimeButton=yon_gtk_builder_get_widget(builder,"LowerTimeButton");
+ window->headerTopic=yon_gtk_builder_get_widget(builder,"headerTopic");
+
+ gtk_window_set_title(GTK_WINDOW(window->MainWindow),TITLE_LABEL);
+
+ g_signal_connect(G_OBJECT(window->CancelButton),"clicked",G_CALLBACK(on_close_subwindow),NULL);
+ g_signal_connect(G_OBJECT(window->SaveButton),"clicked",G_CALLBACK(on_close_subwindow),NULL);
+ gtk_widget_show(window->MainWindow);
+}
+
+void on_serivces_open(GtkWidget *self,main_window *widgets){
+ GtkTreeModel *model = GTK_TREE_MODEL(widgets->list);
+ GtkTreeIter iter;
+ if (gtk_tree_selection_get_selected(gtk_tree_view_get_selection(GTK_TREE_VIEW(widgets->MainTree)),&model, &iter)){
+ char *service_name;
+ gtk_tree_model_get(model,&iter,1,&service_name,-1);
+ if (!strcmp(service_name,"journald")){
+ on_journald_open(NULL,widgets);
+ } else {
+ on_logrotate_tab_open(NULL,widgets);
+ }
+ }
+
+}
+
+void on_log_add(GtkWidget *self, main_window *widgets){
+ GtkTreeModel *model = GTK_TREE_MODEL(widgets->list);
+ GtkTreeIter iter;
+ add_log_window *window = on_add_open();
+ gtk_widget_show(window->MainWindow);
+ gtk_widget_hide(window->StatisticsFrame);
+ gtk_widget_hide(window->JournaldButton);
+ g_signal_connect(G_OBJECT(window->SaveButton),"clicked", G_CALLBACK(on_close_subwindow),NULL);
+}
+
+void on_log_edit(GtkWidget *self,main_window *widgets){
+ GtkTreeModel *model = GTK_TREE_MODEL(widgets->list);
+ GtkTreeIter iter;
+ if (gtk_tree_selection_get_selected(gtk_tree_view_get_selection(GTK_TREE_VIEW(widgets->MainTree)),&model,&iter)){
+ add_log_window *window = on_add_open();
+ gtk_widget_show(window->MainWindow);
+ gtk_widget_hide(window->StatisticsFrame);
+ char *name;
+ gtk_tree_model_get(model,&iter,0,&name,-1);
+ if (!strcmp(name,"journald")){
+ gtk_widget_hide(window->LogrotateButton);
+ gtk_widget_hide(window->MetalogButton);
+ gtk_widget_hide(window->SyslogButton);
+ g_signal_connect(G_OBJECT(window->JournaldButton),"clicked", G_CALLBACK(on_journald_open),widgets);
+ } else {
+ gtk_widget_hide(window->JournaldButton);
+ // g_signal_connect(G_OBJECT(window->JournaldButton),"clicked", G_CALLBACK(on_journald_open),widgets);
+ // g_signal_connect(G_OBJECT(window->JournaldButton),"clicked", G_CALLBACK(on_log),widgets);
+ // g_signal_connect(G_OBJECT(window->JournaldButton),"clicked", G_CALLBACK(on_journald_open),widgets);
+ }
+ gtk_widget_set_sensitive(window->LogAddingBox,0);
+ g_signal_connect(G_OBJECT(window->SaveButton),"clicked", G_CALLBACK(on_close_subwindow),NULL);
+ }
+}
+
+void on_log_remove(GtkWidget *self, main_window *widgets){
+ GtkTreeModel *model = GTK_TREE_MODEL(widgets->list);
+ GtkTreeIter iter;
+ if (gtk_tree_selection_get_selected(gtk_tree_view_get_selection(GTK_TREE_VIEW(widgets->MainTree)),&model, &iter)){
+ gtk_list_store_remove(widgets->list,&iter);
+ }
+}
+
+void on_service_edit(GtkWidget *self,main_window *widgets){
+ GtkTreeModel *model = GTK_TREE_MODEL(widgets->ServicesList);
+ GtkTreeIter iter;
+ if (gtk_tree_selection_get_selected(gtk_tree_view_get_selection(GTK_TREE_VIEW(widgets->ServicesTree)),&model,&iter)){
+ char *name;
+ gtk_tree_model_get(model,&iter,1,&name,-1);
+ if (!strcmp(name,"journald")){
+ on_journald_open(NULL,widgets);
+ } else {
+ on_logrotate_tab_open(NULL,widgets);
+ }
+ }
+}
+
+// standard functions
+
+void config_init(){
+ main_config.always_open_documentation=0;
+ main_config.win_height=0;
+ main_config.win_width=0;
+ main_config.win_pos_x=0;
+ main_config.win_pos_y=0;
+ main_config.socket_id=-1;
+ main_config.save_socket_id=-1;
+ main_config.load_socket_id=-1;
+ main_config.lock_help=0;
+ main_config.lock_help=0;
+ main_config.lock_load_global=0;
+ main_config.lock_save_global=0;
+ main_config.lock_save_local=0;
+ main_config.logrotate_list = gtk_list_store_new(3,G_TYPE_STRING,G_TYPE_STRING,G_TYPE_STRING);
+ main_config.logrotate_apps_list = gtk_list_store_new(3,G_TYPE_STRING,G_TYPE_STRING,G_TYPE_STRING);
+}
+
+main_window *setup_window(){
+ /* Widgets getting | Получение виджетов */
+ main_window *widgets = malloc(sizeof(main_window));
+ GtkBuilder *builder = gtk_builder_new_from_resource(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);
+
+ widgets->InspectButton = yon_gtk_builder_get_widget(builder,"MainInspectButton");
+ widgets->ConfigureButton = yon_gtk_builder_get_widget(builder,"MainConfigureButton");
+ widgets->AddButton = yon_gtk_builder_get_widget(builder,"MainAddButton");
+ widgets->RemoveButton = yon_gtk_builder_get_widget(builder,"MainRemoveButton");
+ widgets->Notebook = yon_gtk_builder_get_widget(builder,"MainNotebook");
+ widgets->ServicesEditButton = yon_gtk_builder_get_widget(builder,"ServicesEditButton");
+ widgets->ServicesTree = yon_gtk_builder_get_widget(builder,"ServicesTree");
+ widgets->list = GTK_LIST_STORE(gtk_builder_get_object(builder,"liststore1"));
+ widgets->ServicesList = GTK_LIST_STORE(gtk_builder_get_object(builder,"ServicesList"));
+
+ widgets->MainTree = yon_gtk_builder_get_widget(builder,"MainTree");
+
+ gtk_window_set_title(GTK_WINDOW(widgets->Window),TITLE_LABEL);
+
+ 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);
+
+ if (main_config.lock_load_global == 1){
+ gtk_widget_set_sensitive(widgets->LoadGlobalMenuItem,0);
+ }
+ if (main_config.lock_save_global == 1){
+ gtk_widget_set_sensitive(widgets->SaveGlobalMenuItem,0);
+ gtk_widget_set_sensitive(widgets->SaveMenuItem,0);
+ }
+ if (main_config.lock_save_local == 1){
+ gtk_widget_set_sensitive(widgets->SaveLocalMenuItem,0);
+ gtk_widget_set_sensitive(widgets->SaveMenuItem,0);
+ }
+ int size;
+ int service_size;
+ int dirs_size;
+ char *cname=NULL;
+ char *cparams="";
+ GtkTreeIter iter;
+ config_str journals = yon_file_open(journals_list_path,&size);
+ for (int i=0;ilist,&iter);
+ gtk_list_store_set(widgets->list,&iter,0,log[0],1,log[1],2,log[2],3,-1,4,-1,5,-1,6,-1,7,-1,-1);
+ }
+ config_str services = yon_file_open(services_list_path,&service_size);
+ for (int i=0;iServicesList,&iter);
+ gtk_list_store_set(widgets->ServicesList,&iter,0,0,1,log[0],2,log[1],-1);
+ // yon_char_parsed_free(log,log_size);
+ }
+ // yon_char_parsed_free(services,service_size);
+ config_str dirs = yon_config_load(logrotate_config_command,&dirs_size);
+ for (int i=0;iHeadInfoLabel,"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),WIKI_LINK);
+ g_signal_connect(G_OBJECT(widgets->AboutMenuItem),"activate",G_CALLBACK(on_about),NULL);
+ g_signal_connect(G_OBJECT(widgets->InspectButton),"clicked",G_CALLBACK(on_inspector_open),widgets);
+ g_signal_connect(G_OBJECT(widgets->AddButton),"clicked",G_CALLBACK(on_log_add),widgets);
+ g_signal_connect(G_OBJECT(widgets->ConfigureButton),"clicked",G_CALLBACK(on_log_edit),widgets);
+ g_signal_connect(G_OBJECT(widgets->RemoveButton),"clicked",G_CALLBACK(on_log_remove),widgets);
+ g_signal_connect(G_OBJECT(widgets->ServicesEditButton),"clicked",G_CALLBACK(on_service_edit),widgets);
+
+
+ gtk_widget_show(widgets->Window);
+ return widgets;
+}
+
+int main(int argc, char *argv[]){
+ local=setlocale(LC_ALL, "");
+ textdomain (LocaleName);
+ config_init();
+ int option_index=0;
+ int show_help=0;
+ int debug_mode=0;
+ {
+ struct option long_options[] = {
+ {"help", 0, 0, 'h'},
+ {"version", 0, 0, 'V'},
+ {"lock-help", 0,0, 1},
+ {"lock-save", 0,0, 2},
+ {"lock-save-local", 0,0, 3},
+ {"lock-save-global", 0,0, 4},
+ {"lock-load-global", 0,0, 5},
+ {"socket-id", 1, 0, 's'},
+ {"socket-ext-id", 1,0, 'e'},
+ {"socket-trd-id", 1,0, 't'},
+ {"clear-config", 0,0, 'c'},
+ { NULL, 0, NULL, 0 }
+ };
+ for (int i=0;iHeadOverlay,widgets->HeadBox,widgets->HeadImage,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(TITLE_LABEL,BACKGROUND_IMAGE_SUCCESS_TYPE);
+ yon_ubl_setup_sockets(widgets->PlugBox,widgets->LeftBox,widgets->RightBox,main_config.socket_id,main_config.load_socket_id,main_config.save_socket_id);
+ yon_window_config_setup(GTK_WINDOW(widgets->Window));
+ yon_window_config_load(config_path);
+ GtkCssProvider *css=gtk_css_provider_new();
+ gtk_css_provider_load_from_resource(css,CssPath);
+ gtk_style_context_add_provider_for_screen(gdk_screen_get_default(),
+ GTK_STYLE_PROVIDER(css),
+ -1);
+ gtk_main();
+}
\ No newline at end of file
diff --git a/source/ubl-settings-logging.h b/source/ubl-settings-logging.h
new file mode 100644
index 0000000..68bfa6a
--- /dev/null
+++ b/source/ubl-settings-logging.h
@@ -0,0 +1,294 @@
+#include
+#include
+#include "ubl-utils.h"
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include "../compile/ubl-cmake.h"
+#ifdef WEBKIT_FOUND
+ #include
+#endif
+#include "ubl-strings.h"
+
+#define WIKI_LINK "https://wiki.ublinux.ru/ru/Программное_обеспечение/Программы_и_утилиты/Все/ubl-settings-logging"
+
+#define _(String) gettext(String)
+
+#define glade_path "/com/ublinux/ui/ubl-settings-logging.glade"
+#define glade_add_path "/com/ublinux/ui/ubl-settings-logging-add.glade"
+#define glade_inspector_path "/com/ublinux/ui/ubl-settings-logging-inspector.glade"
+#define glade_journald_path "/com/ublinux/ui/ubl-settings-logging-journald.glade"
+#define glade_logrotate_path "/com/ublinux/ui/ubl-settings-logging-logrotate.glade"
+#define glade_logrotate_table_path "/com/ublinux/ui/ubl-settings-logging-logrotate-table.glade"
+#define banner_path "/com/ublinux/images/ubl-settings-logging-banner.png"
+#define CssPath "/com/ublinux/css/ubl-settings-logging.css"
+#define config_path yon_char_unite(yon_ubl_user_get_home_directory(),"/.config/",LocaleName,"/",LocaleName,".conf",NULL)
+#define journals_list_path "/usr/share/ubl-settings-logging/csv/journals_list.csv"
+#define services_list_path "/usr/share/ubl-settings-logging/csv/logging_services.csv"
+#define logrotate_config_command "ls /etc/logrotate.d/ |sed -e 's/ */\\n/g'"
+#define logrotate_config_path "/etc/logrotate.d/"
+
+#define LocalePath "/usr/share/locale"
+#define LocaleName "ubl-settings-logging"
+
+
+#define get_journal_output_command "journalctl --no-pager"
+#define get_journal_output_since_boot_command "journalctl --no-pager -b"
+#define get_journal_output_followed_command "journalctl --no-pager -f"
+#define get_journal_output_kernel_command "journalctl --no-pager -k"
+#define get_journal_output_prioritied_command "journalctl --no-pager -p err..alert"
+typedef char* string;
+string version_application;
+
+char *local;
+
+typedef struct {
+ int always_open_documentation;
+ int win_pos_x;
+ int win_pos_y;
+ int win_width;
+ int win_height;
+
+ int socket_id;
+ int load_socket_id;
+ int save_socket_id;
+
+ int lock_help;
+ int lock_save_local;
+ int lock_save_global;
+ int lock_load_global;
+
+ GtkListStore *logrotate_list;
+ GtkListStore *logrotate_apps_list;
+} config;
+
+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;
+
+ GtkWidget *MainTree;
+ GtkWidget *InspectButton;
+ GtkWidget *ConfigureButton;
+ GtkWidget *AddButton;
+ GtkWidget *RemoveButton;
+
+ GtkWidget *Notebook;
+ GtkWidget *ServicesTree;
+ GtkWidget *ServicesEditButton;
+ GtkListStore *list;
+ GtkListStore *ServicesList;
+ // Custom
+} main_window;
+
+
+typedef struct {
+ GtkWidget *Window;
+
+ GtkWidget *HatText;
+ GtkWidget *HeaderText;
+ GtkWidget *InfoText;
+ GtkWidget *AlwaysOpenCheck;
+
+ GtkWidget *CloseButton;
+ GtkWidget *AcceptButton;
+} documentation_confirmation_window;
+
+typedef struct {
+ GtkWidget *MainWindow;
+ GtkWidget *adjustment1;
+ GtkWidget *adjustment2;
+ GtkWidget *CancelButton;
+ GtkWidget *SaveButton;
+ GtkWidget *LogTypeCombo;
+ GtkWidget *LogPathEntry;
+ GtkWidget *LogFindButton;
+ GtkWidget *LogDescriptionEntry;
+ GtkWidget *editingBox;
+ GtkWidget *FileAmountCheck;
+ GtkWidget *FileAmountSpin;
+ GtkWidget *FileSizeCheck;
+ GtkWidget *FileSizeSpin;
+ GtkWidget *FileSizeCombo;
+ GtkWidget *RotationPeriodCheck;
+ GtkWidget *RotationPeriodCombo;
+ GtkWidget *JournalSizeCheck;
+ GtkWidget *JournalSizeSpin;
+ GtkWidget *JournalSizeCombo;
+ GtkWidget *JournalGatheringPeriodCheck;
+ GtkWidget *JournalGatheringPeriodCombo;
+ GtkWidget *logSizeLabel;
+ GtkWidget *diskSizeLabel;
+ GtkWidget *headerBar;
+ GtkWidget *headerTopic;
+ GtkWidget *LogSettingsBox;
+ GtkWidget *JournalSettingsBox;
+ GtkWidget *LogEditingBox;
+ GtkWidget *LogAddingBox;
+ GtkWidget *LogNameLabel;
+ GtkWidget *LogrotateButton;
+ GtkWidget *MetalogButton;
+ GtkWidget *SyslogButton;
+ GtkWidget *JournaldButton;
+ GtkWidget *LogSizeLabel;
+ GtkWidget *StatisticsFrame;
+} add_log_window;
+
+typedef struct {
+GtkTextBuffer *textbuffer1;
+GtkWidget *MainWindow;
+GtkWidget *plugBox;
+GtkWidget *ShowSinceBootButton;
+GtkWidget *NewMessagesButton;
+GtkWidget *ShowKernelButton;
+GtkWidget *ShowPriorityButton;
+GtkWidget *UpdateButton;
+GtkWidget *LoggingTextView;
+GtkWidget *JournalActionsBox;
+int last_mode;
+
+} inspector_window;
+
+typedef struct {
+ GtkWidget *Window;
+
+ GtkWidget *MainTree;
+ GtkWidget *ConfiguraButton;
+ GtkWidget *CancelButton;
+ GtkWidget *SaveButton;
+ GtkListStore *list;
+} logrotate_tab_window;
+
+typedef struct {
+ GtkWidget *Window;
+ GtkWidget *AppsMainTree;
+ GtkWidget *AppsConfigureButton;
+ GtkWidget *MainTree;
+ GtkWidget *AddButton;
+ GtkWidget *RemoveButton;
+ GtkWidget *ConfigureButton;
+ GtkWidget *CancelButton;
+ GtkWidget *SaveButton;
+} logrotate_window;
+
+typedef struct {
+ GtkWidget *MainWindow;
+ GtkWidget *CancelButton;
+ GtkWidget *SaveButton;
+ GtkWidget *LogNameLabel;
+ GtkWidget *LogDescriptionLabel;
+ GtkWidget *LogStorageCombo;
+ GtkWidget *LogCompressionCombo;
+ GtkWidget *LogCompressionEntry;
+ GtkWidget *LogCompressionSizeCombo;
+ GtkWidget *DivideJournalFilesCombo;
+ GtkWidget *LogIntervalCheck;
+ GtkWidget *LogIntervalSpin;
+ GtkWidget *LogIntervalAmountCheck;
+ GtkWidget *LogIntervalAmountSpin;
+ GtkWidget *LogSizeMaxCheck;
+ GtkWidget *LogSizeMaxSpin;
+ GtkWidget *LogSizeMaxCombo;
+ GtkWidget *RotationSizeMaxCheck;
+ GtkWidget *RotationSizeMaxSpin;
+ GtkWidget *RotationSizeMaxCombo;
+ GtkWidget *LogFreeSpaceCheck;
+ GtkWidget *LogFreeSpaceSpin;
+ GtkWidget *LogFreeSpaceCombo;
+ GtkWidget *RedirectCombo;
+ GtkWidget *RedirectTTYEntry;
+ GtkWidget *ForwardedTypeCombo;
+ GtkWidget *LogSizeLabel;
+ GtkWidget *LowerSizeEntry;
+ GtkWidget *LowerSizeCombo;
+ GtkWidget *LowerSizeButton;
+ GtkWidget *LowerTimeEntry;
+ GtkWidget *LowerTimeCombo;
+ GtkWidget *LowerTimeButton;
+ GtkWidget *headerTopic;
+} journald_window;
+
+typedef struct {
+ GtkWidget *MainWindow;
+ GtkWidget *CancelButton;
+ GtkWidget *SaveButton;
+ GtkWidget *LogNamelabel;
+ GtkWidget *LogNameButton;
+ GtkWidget *LogNameDescriptionLabel;
+ GtkWidget *RotationPeriodCheck;
+ GtkWidget *RotationPeriodMainCombo;
+ GtkWidget *RotationPeriodAdditionalCombo;
+ GtkWidget *JournalMaxSizeCheck;
+ GtkWidget *JournalMaxSizeSpin;
+ GtkWidget *JournalMaxSizeCombo;
+ GtkWidget *FileAmountCheck;
+ GtkWidget *FileAmountSpin;
+ GtkWidget *FileAmountCombo;
+ GtkWidget *FileAmountEntry;
+ GtkWidget *FileAmountButton;
+ GtkWidget *RotationAtUserCombo;
+ GtkWidget *RotationAtGroupCombo;
+ GtkWidget *ErrorProcessingCombo;
+ GtkWidget *JournalEmptyCombo;
+ GtkWidget *DoNotRotateYoungerCheck;
+ GtkWidget *DoNotRotateYoungerSpin;
+ GtkWidget *DeleteOlderCheck;
+ GtkWidget *DeleteOlderSpin;
+ GtkWidget *RotateSizeMaxAfterTimeCheck;
+ GtkWidget *RotateSizeMaxAfterTimeSpin;
+ GtkWidget *RotateSizeMaxAfterTimeCombo;
+ GtkWidget *RotateSizeMaxBeforeTimeCheck;
+ GtkWidget *RotateSizeMaxBeforeTimeSpin;
+ GtkWidget *RotateSizeMaxBeforeTimeCombo;
+ GtkWidget *CreateLogCombo;
+ GtkWidget *CreateLogUserCombo;
+ GtkWidget *CreateGroupCombo;
+ GtkWidget *CreateLogEntry;
+ GtkWidget *CreateLogButton;
+ GtkWidget *CutCheck;
+ GtkWidget *CompressionCombo;
+ GtkWidget *QueueCombo;
+ GtkWidget *SaveOriginalCombo;
+ GtkWidget *SaveOriginalEntry;
+ GtkWidget *AddDateCombo;
+ GtkWidget *OldNumberCombo;
+ GtkWidget *OldNumberEntry;
+ GtkWidget *EmailCombo;
+ GtkWidget *EmailEntry;
+ GtkWidget *EmailContentsCombo;
+ GtkWidget *ManualInputEntry;
+ GtkWidget *LogSizeLabel;
+ GtkWidget *headerTopic;
+ GtkListStore *list;
+} logrotate_configure_window;
+
+main_window *setup_window();
\ No newline at end of file
diff --git a/source/ubl-strings.h b/source/ubl-strings.h
new file mode 100644
index 0000000..58c1749
--- /dev/null
+++ b/source/ubl-strings.h
@@ -0,0 +1,39 @@
+#define VERSION_LABEL yon_char_unite(_("Version:")," ",version_application,"\n",NULL)
+#define HELP_LABEL yon_char_unite(_("ubl-settings-loggign version:")," ", version_application,"\n",_("Logs and events"),"\n",_("Usage:"), " ubl-settings-loggign ",_("[OPTIONS]"),"\n",_("Options:"),"\n\t--help, -h\t\t\t",_("Show this help"),"\n\t--version, -V\t\t\t",_("Show package version"),"\n\t--lock-help\t\t\t",_("Lock this help menu"),"\n\t--lock-save\t\t\t",_("Lock configuration saving"),"\n\t--lock-save-local\t\t",_("Lock local configration saving"),"\n\t--lock-save-global\t\t",_("Lock global configration saving"),"\n\t--lock-load-global\t\t",_("Lock global configration loading"),"\n",NULL)
+
+#define TITLE_LABEL _("Logs and events")
+#define TITLE_INFO_LABEL _("Logs and events configuration")
+
+#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 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 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 ACCEPT_LABEL _("Accept")
\ No newline at end of file
diff --git a/source/ubl-utils.c b/source/ubl-utils.c
new file mode 100644
index 0000000..8cc0436
--- /dev/null
+++ b/source/ubl-utils.c
@@ -0,0 +1,2110 @@
+#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))){
+ if (strcmp(param,paramline)==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++;
+ // 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_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_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]
+ *
+ * [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);
+ }
+ va_list args;
+ va_start(args,parameter);
+ char *arg;
+ dictionary *sections = NULL;
+ {
+ 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))
+ {
+ 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 1;
+ 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);
+ if (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,(dictionary*)__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{
+ 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;
+ 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);
+ 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, (dictionary*)__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, (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);
+ 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;
+ * [RU]
+ * Удаляет все параметры из конфига;
+*/
+int yon_config_clean(){
+ check_config{
+ __yon__config__strings = (yon_config_parameter*)yon_dictionary_free_all((dictionary*)__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, 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)
+ * [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));
+ 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_registered(char *path, char *section)
+ * [EN]
+ * Saves config with [command]
+ * [RU]
+ * Выполняет команду [command], добавляя в конец все записи конфига в таком виде:
+ * [ПАРАМЕТР1]="[значения1]" [ПАРАМЕТР2]="[значения2]"
+*/
+int yon_config_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){
+ ((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));
+ }
+ }
+ }
+ 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);
+ }
+
+
+ // char *command = yon_char_unite(ubconfig_save_command,path ? yon_char_append(" --target ",path):"", " set ", section, " ", yon_dictionary_get_data(dct,char*),NULL);
+ // char *remove_command = yon_char_unite(ubconfig_save_command, path ? yon_char_append(" --target ",path):"", " remove "," ", yon_dictionary_get_data(dct,char*), section,NULL);
+ // dictionary *dict = NULL;
+ // int any_add = 0;
+ // int any_remove = 0;
+ // for_dictionaries(dict,(dictionary*)__yon__config__strings){
+ // char *data = yon_dictionary_get_data(dict,char*);
+ // if (((yon_config_parameter*)dict)->flag1==1&&strcmp(data,"")!=0){
+ // command = yon_char_unite(command, " ", dict->key,"=\"", yon_dictionary_get_data(dict,char*),"\"", NULL);
+ // any_add=1;
+ // }
+ // if (strcmp(data,"")==0){
+ // remove_command = yon_char_unite(remove_command, " ", dict->key, NULL);
+ // any_remove=1;
+ // }
+ // }
+ // if (any_add) yon_launch(command);
+ // if (any_remove) yon_launch(remove_command);
+ return 1;
+ } 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;
+ config_str conf = NULL;
+ dictionary *dict = NULL;
+ 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)++;
+ }
+ conf = yon_remalloc(conf,sizeof(char*)*(*size));
+ conf[*size-1] = 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);
+ }
+
+ 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");
+ 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;i=0 ? 1 : 0);
+}
+
+void yon_gtk_widget_set_sensitive_from_toggle_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)
+{
+ gtk_overlay_add_overlay(GTK_OVERLAY(Overlay), Head);
+ gtk_image_set_from_file(GTK_IMAGE(Image), image_path);
+}
+
+void _yon_ubl_header_setup_resource(GtkWidget *Overlay, GtkWidget *Head, GtkWidget *Image, char *image_path)
+{
+ gtk_overlay_add_overlay(GTK_OVERLAY(Overlay), Head);
+ gtk_image_set_from_resource(GTK_IMAGE(Image), image_path);
+}
+
+int yon_ubl_status_box_setup(GtkWidget *icon, GtkWidget *box, GtkWidget *label)
+{
+ if(icon&&box&&label){
+ render.icon=icon;
+ render.box=box;
+ render.label=label;
+ return 1;
+ } else return 0;
+}
+
+void _yon_ubl_status_box_render(char *text, BACKGROUND_IMAGE_TYPE type)
+{
+ render_data data = render;
+ GtkIconTheme *ictheme = gtk_icon_theme_get_default();
+ GError *err = NULL;
+ if (err)
+ {
+ printf("%s\n", err->message);
+ 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/source/ubl-utils.h b/source/ubl-utils.h
new file mode 100644
index 0000000..db8ade7
--- /dev/null
+++ b/source/ubl-utils.h
@@ -0,0 +1,387 @@
+#ifndef UBL_UTILS
+#define UBL_UTILS
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+#include "../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;
+} dictionary;
+
+
+
+
+typedef struct apps
+{
+ char *Name;
+ int Type;
+ char *Categories;
+ char *Exec;
+ char *Icon;
+ int Pluggable;
+ int DualPluggable;
+} apps;
+
+typedef char** config_str;
+
+#define config(key) yon_config_get_by_key(key)
+
+#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
+
+#define yon_char_divide_search_self(str,find,delete_divider) {char *temp = str; str = yon_char_divide_search(str,find,delete_divider); free(temp);}
+
+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_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);
+
+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_file_open(char *file_path, int *size);
+
+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 *path);
+
+char *yon_config_get_parameter(config_str parameters, int size, char *param);
+
+int yon_config_load_register(YON_CONFIG_TYPE config_type,char *section,char *parameter, ...);
+
+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, char* config_section, 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_STRING_LIST,
+ 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_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);
+
+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, ...);
+
+
+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
+{
+ 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-settings-logging-add.glade b/ubl-settings-logging-add.glade
new file mode 100644
index 0000000..dcba07a
--- /dev/null
+++ b/ubl-settings-logging-add.glade
@@ -0,0 +1,525 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ True
+ False
+ com.ublinux.ubl-settings-logging.decrease-symbolic
+
+
diff --git a/ubl-settings-logging-banner.png b/ubl-settings-logging-banner.png
new file mode 100644
index 0000000..8eb67cb
Binary files /dev/null and b/ubl-settings-logging-banner.png differ
diff --git a/ubl-settings-logging-inspector.glade b/ubl-settings-logging-inspector.glade
new file mode 100644
index 0000000..33f25fa
--- /dev/null
+++ b/ubl-settings-logging-inspector.glade
@@ -0,0 +1,318 @@
+
+
+
+
+
+
+ 100
+ 1
+ 10
+
+
+ 100
+ 1
+ 10
+
+
+ True
+ False
+ system-shutdown-symbolic
+
+
+ True
+ False
+ document-open-recent-symbolic
+
+
+ True
+ False
+ emblem-system-symbolic
+
+
+ True
+ False
+ starred-symbolic
+
+
+ True
+ False
+ emblem-synchronizing-symbolic
+
+
+ True
+ False
+ emblem-documents-symbolic
+
+
+ True
+ False
+ emblem-synchronizing-symbolic
+
+
+ True
+ False
+ emblem-shared-symbolic
+
+
+
+ 800
+ 600
+ False
+ 800
+ 600
+ com.ublinux.ubl-settings-logging
+
+
+ True
+ False
+ 5
+ 5
+ 5
+ 5
+ vertical
+
+
+ True
+ False
+ 5
+
+
+ True
+ False
+ vertical
+ 5
+
+
+ True
+ False
+ vertical
+ 5
+
+
+ True
+ True
+ True
+ Show messages since the current system boot
+ image1
+
+
+
+ False
+ True
+ 0
+
+
+
+
+ True
+ True
+ True
+ Follow for new messages
+ image2
+
+
+
+ False
+ True
+ 1
+
+
+
+
+ True
+ True
+ True
+ Show kernel ring buffer
+ image3
+
+
+
+ False
+ True
+ 2
+
+
+
+
+ True
+ True
+ True
+ Show only priority error messages, critical messages and warnings
+ image4
+
+
+
+ False
+ True
+ 3
+
+
+
+
+ True
+ True
+ True
+ Show only priority error messages, critical messages and warnings
+ image7
+
+
+
+ False
+ True
+ 4
+
+
+
+
+ True
+ True
+ True
+ Show only priority error messages, critical messages and warnings
+ image6
+
+
+
+ False
+ True
+ 5
+
+
+
+
+ True
+ True
+ True
+ Show only priority error messages, critical messages and warnings
+ image8
+
+
+
+ False
+ True
+ 6
+
+
+
+
+ False
+ True
+ 4
+
+
+
+
+ True
+ True
+ True
+ Update
+ image5
+
+
+
+ False
+ True
+ 5
+
+
+
+
+ False
+ True
+ 0
+
+
+
+
+ True
+ True
+ adjustment1
+ adjustment2
+ in
+
+
+ True
+ True
+ 5
+ 5
+ 5
+ 5
+ adjustment1
+ adjustment2
+ False
+ textbuffer1
+ terminal
+
+
+
+
+ True
+ True
+ 1
+
+
+
+
+ True
+ True
+ 0
+
+
+
+
+
+
+
+
+
diff --git a/ubl-settings-logging-journald.glade b/ubl-settings-logging-journald.glade
new file mode 100644
index 0000000..28c9956
--- /dev/null
+++ b/ubl-settings-logging-journald.glade
@@ -0,0 +1,978 @@
+
+
+
+
+
+
+
+ 1024
+ 1
+ 10
+
+
+ 1024
+ 1
+ 10
+
+
+ 100
+ 1
+ 10
+
+
+ 100
+ 1
+ 10
+
+
+ 100
+ 1
+ 10
+
+
+ 100
+ 1
+ 10
+
+
+ 100
+ 1
+ 10
+
+
+ 100
+ 1
+ 10
+
+
+ True
+ False
+ process-stop-symbolic
+
+
+ True
+ False
+ emblem-ok-symbolic
+
+
+ True
+ False
+ emblem-ok-symbolic
+
+
+ True
+ False
+ emblem-ok-symbolic
+
+
+ 450
+ 450
+ False
+ True
+ com.ublinux.ubl-settings-logging
+ dialog
+
+
+ False
+ 5
+ 5
+ 5
+ 5
+ vertical
+ 5
+
+
+ False
+ end
+
+
+ Cancel
+ True
+ True
+ True
+ image1
+
+
+ True
+ True
+ 0
+
+
+
+
+ Save
+ True
+ True
+ True
+ image2
+
+
+ True
+ True
+ 1
+
+
+
+
+ False
+ False
+ 2
+
+
+
+
+ True
+ False
+ vertical
+
+
+ True
+ False
+
+
+ True
+ False
+ 5
+
+
+ True
+ False
+ Log/Journal:
+
+
+ False
+ True
+ 0
+
+
+
+
+ True
+ False
+ logname
+
+
+ False
+ True
+ 1
+
+
+
+
+ False
+ True
+ 0
+
+
+
+
+ True
+ False
+ 5
+
+
+ True
+ False
+ Description:
+
+
+ False
+ True
+ 0
+
+
+
+
+ True
+ False
+ logdescription
+
+
+ False
+ True
+ 1
+
+
+
+
+ False
+ True
+ end
+ 1
+
+
+
+
+ False
+ True
+ 0
+
+
+
+
+ True
+ False
+ 0
+ in
+
+
+ True
+ False
+ 5
+ 5
+ 5
+
+
+ True
+ False
+ vertical
+ 5
+
+
+ True
+ False
+ 5
+
+
+ True
+ False
+ Journal storage place:
+
+
+ False
+ True
+ 0
+
+
+
+
+ True
+ False
+ 0
+
+ - Default
+
+
+
+ False
+ True
+ 1
+
+
+
+
+ False
+ True
+ 0
+
+
+
+
+ True
+ False
+ 5
+
+
+ True
+ False
+ Use compression:
+
+
+ False
+ True
+ 0
+
+
+
+
+ True
+ False
+ 0
+
+ - Default
+
+
+
+ False
+ True
+ 1
+
+
+
+
+ True
+ True
+
+
+ False
+ True
+ 2
+
+
+
+
+ True
+ False
+ 0
+
+ - Kb
+ - Mb
+ - Gb
+ - Tb
+
+
+
+ False
+ True
+ 3
+
+
+
+
+ False
+ True
+ 1
+
+
+
+
+ True
+ False
+ 5
+
+
+ True
+ False
+ Divide journal files:
+
+
+ False
+ True
+ 0
+
+
+
+
+ True
+ False
+ 0
+
+ - Default
+
+
+
+ False
+ True
+ 1
+
+
+
+
+ False
+ True
+ 2
+
+
+
+
+ True
+ False
+ 5
+
+
+ Log recording journal interval:
+ True
+ True
+ False
+ True
+
+
+ False
+ True
+ 0
+
+
+
+
+ True
+ True
+ adjustment4
+
+
+ False
+ True
+ 1
+
+
+
+
+ Records amount:
+ True
+ True
+ False
+ True
+
+
+ False
+ True
+ 2
+
+
+
+
+ True
+ True
+ adjustment5
+
+
+ False
+ True
+ 3
+
+
+
+
+ False
+ True
+ 3
+
+
+
+
+ True
+ False
+ 5
+
+
+ Maximum size of all logs:
+ True
+ True
+ False
+ True
+
+
+ False
+ True
+ 0
+
+
+
+
+ True
+ True
+ adjustment6
+
+
+ False
+ True
+ 1
+
+
+
+
+ True
+ False
+ 0
+
+ - Kb
+ - Mb
+ - Gb
+ - Tb
+
+
+
+ False
+ True
+ 2
+
+
+
+
+ False
+ True
+ 4
+
+
+
+
+ True
+ False
+ 5
+
+
+ Maximum size of rotation journal:
+ True
+ True
+ False
+ True
+
+
+ False
+ True
+ 0
+
+
+
+
+ True
+ True
+ adjustment7
+
+
+ False
+ True
+ 1
+
+
+
+
+ True
+ False
+
+ - Kb
+ - Mb
+ - Gb
+ - Tb
+
+
+
+ False
+ True
+ 2
+
+
+
+
+ False
+ True
+ 5
+
+
+
+
+ True
+ False
+ 5
+
+
+ Leave free space at storage:
+ True
+ True
+ False
+ True
+
+
+ False
+ True
+ 0
+
+
+
+
+ True
+ True
+ adjustment8
+
+
+ False
+ True
+ 1
+
+
+
+
+ True
+ False
+
+ - Kb
+ - Mb
+ - Gb
+ - Tb
+
+
+
+ False
+ True
+ 2
+
+
+
+
+ False
+ True
+ 6
+
+
+
+
+ True
+ False
+ 5
+
+
+ True
+ False
+ Redirect to console:
+
+
+ False
+ True
+ 0
+
+
+
+
+ True
+ False
+
+ - Default
+
+
+
+ False
+ True
+ 1
+
+
+
+
+ True
+ False
+ TTY:
+
+
+ False
+ True
+ 2
+
+
+
+
+ True
+ True
+
+
+ False
+ True
+ 3
+
+
+
+
+ False
+ True
+ 7
+
+
+
+
+ True
+ False
+ 5
+
+
+ True
+ False
+ Type of forwarded messages:
+
+
+ False
+ True
+ 0
+
+
+
+
+ True
+ False
+
+ - Default
+
+
+
+ False
+ True
+ 1
+
+
+
+
+ False
+ True
+ 8
+
+
+
+
+
+
+
+
+ True
+ False
+ Journal configuration
+
+
+
+
+ False
+ True
+ 1
+
+
+
+
+ True
+ False
+ 0
+ in
+
+
+ True
+ False
+ 5
+ 5
+ 5
+
+
+ True
+ False
+ vertical
+ 5
+
+
+ True
+ False
+ 5
+
+
+ True
+ False
+ Total log size:
+
+
+ False
+ True
+ 0
+
+
+
+
+ True
+ False
+ 0.0 Mb
+
+
+ True
+ True
+ 1
+
+
+
+
+ False
+ True
+ 0
+
+
+
+
+ True
+ False
+ 5
+
+
+ True
+ False
+ Lower size to:
+
+
+ False
+ True
+ 0
+
+
+
+
+ True
+ True
+
+
+ False
+ True
+ 1
+
+
+
+
+ True
+ False
+
+ - Kb
+ - Mb
+ - Gb
+ - Tb
+
+
+
+ False
+ True
+ 2
+
+
+
+
+ Apply
+ True
+ True
+ True
+ image4
+
+
+ False
+ True
+ 3
+
+
+
+
+ False
+ True
+ 1
+
+
+
+
+ True
+ False
+ 5
+
+
+ True
+ False
+ Lower size to:
+
+
+ False
+ True
+ 0
+
+
+
+
+ True
+ True
+
+
+ False
+ True
+ 1
+
+
+
+
+ True
+ False
+
+ - Minutes
+ - Hours
+ - Days
+ - Weeks
+ - Months
+
+
+
+ False
+ True
+ 2
+
+
+
+
+ Apply
+ True
+ True
+ True
+ image3
+
+
+ False
+ True
+ 3
+
+
+
+
+ False
+ True
+ 2
+
+
+
+
+
+
+
+
+ True
+ False
+ Statistics
+
+
+
+
+ False
+ True
+ 2
+
+
+
+
+ False
+ True
+ 1
+
+
+
+
+
+
+
+
+
diff --git a/ubl-settings-logging-logrotate-table.glade b/ubl-settings-logging-logrotate-table.glade
new file mode 100644
index 0000000..5eeb2c1
--- /dev/null
+++ b/ubl-settings-logging-logrotate-table.glade
@@ -0,0 +1,386 @@
+
+
+
+
+
+
+
+ 1024
+ 1
+ 10
+
+
+ 1024
+ 1
+ 10
+
+
+ 100
+ 1
+ 10
+
+
+ True
+ False
+ process-stop-symbolic
+
+
+ True
+ False
+ emblem-ok-symbolic
+
+
+ True
+ False
+ document-edit-symbolic
+
+
+ True
+ False
+ com.ublinux.ubl-settings-logging.decrease-symbolic
+
+
+ True
+ False
+ com.ublinux.ubl-settings-logging.increase-symbolic
+
+
+ True
+ False
+ com.ublinux.ubl-settings-logging.back-symbolic
+
+
+ 450
+ 450
+ False
+ True
+ com.ublinux.ubl-settings-logging
+ dialog
+
+
+ False
+ 5
+ 5
+ 5
+ 5
+ vertical
+ 5
+
+
+ False
+ end
+
+
+ Cancel
+ True
+ True
+ True
+ image1
+
+
+ True
+ True
+ 0
+
+
+
+
+ Save
+ True
+ True
+ True
+ image2
+
+
+ True
+ True
+ 1
+
+
+
+
+ False
+ False
+ 2
+
+
+
+
+ True
+ True
+
+
+ True
+ False
+ 5
+ 5
+ 5
+ 5
+ 5
+
+
+ True
+ False
+ vertical
+ 5
+
+
+ True
+ True
+ True
+ image5
+
+
+
+ False
+ True
+ 0
+
+
+
+
+ True
+ True
+ True
+ image4
+
+
+
+ False
+ True
+ 1
+
+
+
+
+ True
+ True
+ True
+ image3
+
+
+
+ False
+ True
+ 2
+
+
+
+
+ False
+ True
+ 0
+
+
+
+
+ True
+ True
+ in
+
+
+ True
+ True
+
+
+
+
+
+ Log/Journal
+
+
+
+
+
+
+
+ Path
+
+
+
+
+
+
+
+ Description
+
+
+
+
+
+
+
+
+
+ True
+ True
+ 1
+
+
+
+
+
+
+ True
+ False
+ System configuration
+
+
+ False
+
+
+
+
+ True
+ False
+ 5
+ 5
+ 5
+ 5
+ 5
+ 5
+ 5
+
+
+ True
+ False
+ vertical
+ 5
+
+
+ True
+ True
+ True
+ image8
+
+
+
+ False
+ True
+ 2
+
+
+
+
+ False
+ True
+ 0
+
+
+
+
+ True
+ True
+ in
+
+
+ True
+ True
+
+
+
+
+
+ Log/Journal
+
+
+
+ 0
+
+
+
+
+
+
+ Path
+
+
+
+ 1
+
+
+
+
+
+
+
+
+ True
+ True
+ 1
+
+
+
+
+ 1
+
+
+
+
+ True
+ False
+ Applications configuration
+
+
+ 1
+ False
+
+
+
+
+ True
+ True
+ 0
+
+
+
+
+
+
+
+
+
diff --git a/ubl-settings-logging-logrotate.glade b/ubl-settings-logging-logrotate.glade
new file mode 100644
index 0000000..ce37634
--- /dev/null
+++ b/ubl-settings-logging-logrotate.glade
@@ -0,0 +1,1700 @@
+
+
+
+
+
+
+
+ 1024
+ 1
+ 10
+
+
+ 1024
+ 1
+ 10
+
+
+ 100
+ 1
+ 10
+
+
+ 100
+ 1
+ 10
+
+
+ 100
+ 1
+ 10
+
+
+ 100
+ 1
+ 10
+
+
+ 100
+ 1
+ 10
+
+
+ 100
+ 1
+ 10
+
+
+ 100
+ 1
+ 10
+
+
+ True
+ False
+ process-stop-symbolic
+
+
+ True
+ False
+ emblem-ok-symbolic
+
+
+ True
+ False
+ document-edit-symbolic
+
+
+ True
+ False
+ com.ublinux.ubl-settings-logging.zoom-symbolic
+
+
+ True
+ False
+ com.ublinux.ubl-settings-logging.profile-symbolic
+
+
+ 800
+ 600
+ False
+ True
+ com.ublinux.ubl-settings-logging
+ dialog
+
+
+ False
+ 5
+ 5
+ 5
+ 5
+ vertical
+ 5
+
+
+ False
+ end
+
+
+ Cancel
+ True
+ True
+ True
+ image1
+
+
+ True
+ True
+ 0
+
+
+
+
+ Save
+ True
+ True
+ True
+ image2
+
+
+ True
+ True
+ 1
+
+
+
+
+ False
+ False
+ 2
+
+
+
+
+ True
+ True
+ in
+
+
+ True
+ False
+ 5
+ 5
+ 5
+ 5
+
+
+ True
+ False
+ vertical
+ 5
+
+
+ True
+ False
+ vertical
+ 5
+
+
+ True
+ False
+ 5
+
+
+ True
+ False
+ Log/Journal:
+
+
+ False
+ True
+ 0
+
+
+
+
+ True
+ False
+ Logname
+
+
+ False
+ True
+ 1
+
+
+
+
+ True
+ True
+ True
+ image3
+
+
+ False
+ True
+ 2
+
+
+
+
+ False
+ True
+ 0
+
+
+
+
+ True
+ False
+ 5
+
+
+ True
+ False
+ Description:
+
+
+ False
+ True
+ 0
+
+
+
+
+ True
+ False
+ logdescription
+
+
+ False
+ True
+ 1
+
+
+
+
+ False
+ True
+ 1
+
+
+
+
+ False
+ True
+ 0
+
+
+
+
+ True
+ False
+ 0
+ in
+
+
+ True
+ False
+ 5
+ 5
+ 5
+
+
+ True
+ False
+ vertical
+ 5
+
+
+ True
+ False
+ 0
+ in
+
+
+ True
+ False
+ 5
+ 5
+ 5
+
+
+ True
+ False
+ vertical
+ 5
+
+
+ True
+ False
+ 5
+
+
+ Rotation period:
+ True
+ True
+ False
+ True
+
+
+ False
+ True
+ 0
+
+
+
+
+ True
+ False
+
+ - Week
+ - Month
+ - Year
+
+
+
+ False
+ True
+ 1
+
+
+
+
+ True
+ False
+
+
+ False
+ True
+ 2
+
+
+
+
+ False
+ True
+ 0
+
+
+
+
+ True
+ False
+ 5
+
+
+ Maximum size of file:
+ True
+ True
+ False
+ True
+
+
+ False
+ True
+ 0
+
+
+
+
+ True
+ True
+ adjustment4
+
+
+ False
+ True
+ 1
+
+
+
+
+ True
+ False
+
+ - Kb
+ - Mb
+ - Gb
+ - Tb
+
+
+
+ False
+ True
+ 2
+
+
+
+
+ False
+ True
+ 1
+
+
+
+
+
+
+
+
+ True
+ False
+ Checking frequency configuration
+
+
+
+
+ False
+ True
+ 0
+
+
+
+
+ True
+ False
+ 0
+ in
+
+
+ True
+ False
+ 5
+ 5
+ 5
+
+
+ True
+ False
+ vertical
+ 5
+
+
+ True
+ False
+ 5
+
+
+ File amount:
+ True
+ True
+ False
+ True
+
+
+ False
+ True
+ 0
+
+
+
+
+ True
+ True
+ adjustment6
+
+
+ False
+ True
+ 1
+
+
+
+
+ True
+ False
+ Store at:
+
+
+ False
+ True
+ 2
+
+
+
+
+ True
+ False
+
+ - Default
+
+
+
+ False
+ True
+ 3
+
+
+
+
+ True
+ True
+
+
+ False
+ True
+ 4
+
+
+
+
+ True
+ True
+ True
+ image4
+
+
+ False
+ True
+ 5
+
+
+
+
+ False
+ True
+ 0
+
+
+
+
+ True
+ False
+ 5
+
+
+ True
+ False
+ Rotation as user:
+
+
+ False
+ True
+ 0
+
+
+
+
+ True
+ False
+
+
+ False
+ True
+ 1
+
+
+
+
+ True
+ False
+ Rotation as group:
+
+
+ False
+ True
+ 2
+
+
+
+
+ True
+ False
+
+
+ False
+ True
+ 3
+
+
+
+
+ False
+ True
+ 1
+
+
+
+
+
+
+
+
+ True
+ False
+ Rotation configuration
+
+
+
+
+ False
+ True
+ 1
+
+
+
+
+ True
+ False
+ 0
+ in
+
+
+ True
+ False
+ 5
+ 5
+ 5
+
+
+ True
+ False
+ vertical
+ 5
+
+
+ True
+ False
+ 5
+
+
+ True
+ False
+ Error processing:
+
+
+ False
+ True
+ 0
+
+
+
+
+ True
+ False
+
+ - Output errors if log file does not exist
+
+
+
+ False
+ True
+ 1
+
+
+
+
+ False
+ True
+ 0
+
+
+
+
+ True
+ False
+ 5
+
+
+ True
+ False
+ Rotation of jurnal even when it is empty:
+
+
+ False
+ True
+ 0
+
+
+
+
+ True
+ False
+
+
+ False
+ True
+ 1
+
+
+
+
+ False
+ True
+ 1
+
+
+
+
+ True
+ False
+ 5
+
+
+ Do not rotate journal younger than
+ True
+ True
+ False
+ True
+
+
+ False
+ True
+ 0
+
+
+
+
+ True
+ True
+ adjustment7
+
+
+ False
+ True
+ 1
+
+
+
+
+ True
+ False
+ days
+
+
+ False
+ True
+ 2
+
+
+
+
+ False
+ True
+ 2
+
+
+
+
+ True
+ False
+ 5
+
+
+ Delete rotated journals older than
+ True
+ True
+ False
+ True
+
+
+ False
+ True
+ 0
+
+
+
+
+ True
+ True
+ adjustment5
+
+
+ False
+ True
+ 1
+
+
+
+
+ True
+ False
+ days
+
+
+ False
+ True
+ 2
+
+
+
+
+ False
+ True
+ 3
+
+
+
+
+ True
+ False
+ 5
+
+
+ Rotate journals if size more than
+ True
+ True
+ False
+ True
+
+
+ False
+ True
+ 0
+
+
+
+
+ True
+ True
+ adjustment8
+
+
+ False
+ True
+ 1
+
+
+
+
+ True
+ False
+
+ - Kb
+ - Mb
+ - Gb
+
+
+
+ False
+ True
+ 2
+
+
+
+
+ True
+ False
+ but not earlier than the specified time interval
+
+
+ False
+ True
+ 3
+
+
+
+
+ False
+ True
+ 4
+
+
+
+
+ True
+ False
+ 5
+
+
+ Rotate journals if size more than
+ True
+ True
+ False
+ True
+
+
+ False
+ True
+ 0
+
+
+
+
+ True
+ True
+ adjustment9
+
+
+ False
+ True
+ 1
+
+
+
+
+ True
+ False
+
+ - Kb
+ - Mb
+ - Gb
+
+
+
+ False
+ True
+ 2
+
+
+
+
+ True
+ False
+ before specified time interval
+
+
+ False
+ True
+ 3
+
+
+
+
+ False
+ True
+ 5
+
+
+
+
+
+
+
+
+ True
+ False
+ File choosing configuration
+
+
+
+
+ False
+ True
+ 2
+
+
+
+
+ True
+ False
+ 0
+ in
+
+
+ True
+ False
+ 5
+ 5
+ 5
+
+
+ True
+ False
+ vertical
+ 5
+
+
+ True
+ False
+ 5
+
+
+ True
+ False
+ Create log
+
+
+ False
+ True
+ 0
+
+
+
+
+ True
+ False
+
+ - Default
+
+
+
+ False
+ True
+ 1
+
+
+
+
+ True
+ False
+ as user:
+
+
+ False
+ True
+ 2
+
+
+
+
+ True
+ False
+
+ - Default
+
+
+
+ False
+ True
+ 3
+
+
+
+
+ True
+ False
+ as group:
+
+
+ False
+ True
+ 4
+
+
+
+
+ True
+ False
+
+ - Default
+
+
+
+ False
+ True
+ 5
+
+
+
+
+ True
+ False
+ rules:
+
+
+ False
+ True
+ 6
+
+
+
+
+ True
+ True
+
+
+ False
+ True
+ 7
+
+
+
+
+ True
+ True
+ True
+ image5
+
+
+ False
+ True
+ 8
+
+
+
+
+ False
+ True
+ 0
+
+
+
+
+ True
+ False
+ 5
+
+
+ Cut source journal fileafter copy creating instead of moving old journal file and creating new one
+ True
+ True
+ False
+ True
+
+
+ False
+ True
+ 0
+
+
+
+
+ False
+ True
+ 1
+
+
+
+
+
+
+
+
+ True
+ False
+ Files and directories configuration
+
+
+
+
+ False
+ True
+ 3
+
+
+
+
+ True
+ False
+ 0
+ in
+
+
+ True
+ False
+ 5
+ 5
+ 5
+
+
+ True
+ False
+ vertical
+ 5
+
+
+ True
+ False
+ 5
+
+
+ True
+ False
+ Use compression:
+
+
+ False
+ True
+ 0
+
+
+
+
+ True
+ False
+ 0
+
+ - On
+ - Off
+
+
+
+ False
+ True
+ 1
+
+
+
+
+ True
+ False
+ Delay compressin by one journal in queue:
+
+
+ False
+ True
+ 2
+
+
+
+
+ True
+ False
+ 0
+
+ - Default
+
+
+
+ False
+ True
+ 3
+
+
+
+
+ False
+ True
+ 0
+
+
+
+
+
+
+
+
+ True
+ False
+ Compression configuration
+
+
+
+
+ False
+ True
+ 4
+
+
+
+
+ True
+ False
+ 0
+ in
+
+
+ True
+ False
+ 5
+ 5
+ 5
+
+
+ True
+ False
+ vertical
+ 5
+
+
+ True
+ False
+ 5
+
+
+ True
+ False
+ Save original log file after rotation if it has specified extension:
+
+
+ False
+ True
+ 0
+
+
+
+
+ True
+ False
+ 0
+
+ - Default
+
+
+
+ False
+ True
+ 1
+
+
+
+
+ True
+ True
+
+
+ False
+ True
+ 2
+
+
+
+
+ False
+ True
+ 0
+
+
+
+
+ True
+ False
+ 5
+
+
+ True
+ False
+ Add date of rotation before log header
+
+
+ False
+ True
+ 0
+
+
+
+
+ True
+ False
+ 0
+
+ - Default
+
+
+
+ False
+ True
+ 1
+
+
+
+
+ False
+ True
+ 1
+
+
+
+
+ True
+ False
+ 5
+
+
+ True
+ False
+ Number from which numbering of old logs will begin
+
+
+ False
+ True
+ 0
+
+
+
+
+ True
+ False
+ 0
+
+ - Default
+
+
+
+ False
+ True
+ 1
+
+
+
+
+ True
+ True
+
+
+ False
+ True
+ 2
+
+
+
+
+ False
+ True
+ 2
+
+
+
+
+
+
+
+
+ True
+ False
+ Filename configuration
+
+
+
+
+ False
+ True
+ 5
+
+
+
+
+ True
+ False
+ 0
+ in
+
+
+ True
+ False
+ 5
+ 5
+ 5
+
+
+ True
+ False
+ vertical
+ 5
+
+
+ True
+ False
+ 5
+
+
+ True
+ False
+ Email after rotation:
+
+
+ False
+ True
+ 0
+
+
+
+
+ True
+ False
+ 0
+
+ - Default
+
+
+
+ False
+ True
+ 1
+
+
+
+
+ True
+ False
+ adress:
+
+
+ False
+ True
+ 2
+
+
+
+
+ True
+ True
+
+
+ False
+ True
+ 3
+
+
+
+
+ True
+ False
+ contents:
+
+
+ False
+ True
+ 4
+
+
+
+
+ True
+ False
+ 0
+
+ - Default
+
+
+
+ False
+ True
+ 5
+
+
+
+
+ False
+ True
+ 0
+
+
+
+
+
+
+
+
+ True
+ False
+ Message configuration
+
+
+
+
+ False
+ True
+ 6
+
+
+
+
+ True
+ False
+ 5
+
+
+ True
+ False
+ Manual input:
+
+
+ False
+ True
+ 0
+
+
+
+
+ True
+ True
+
+
+ True
+ True
+ 1
+
+
+
+
+ False
+ True
+ 7
+
+
+
+
+
+
+
+
+ True
+ False
+ Rotation configuration
+
+
+
+
+ False
+ True
+ 1
+
+
+
+
+ True
+ False
+ 0
+ in
+
+
+ True
+ False
+ 5
+ 5
+ 5
+
+
+ True
+ False
+ 5
+
+
+ True
+ False
+ Log size:
+
+
+ False
+ True
+ 0
+
+
+
+
+ True
+ False
+ loglize
+
+
+ True
+ True
+ 1
+
+
+
+
+
+
+
+
+ True
+ False
+ Statistics
+
+
+
+
+ False
+ True
+ 2
+
+
+
+
+
+
+
+
+ True
+ True
+ 1
+
+
+
+
+
+
+
+
+
+
diff --git a/ubl-settings-logging.css b/ubl-settings-logging.css
new file mode 100644
index 0000000..88e8c57
--- /dev/null
+++ b/ubl-settings-logging.css
@@ -0,0 +1,114 @@
+
+.thin {
+ margin:0px;
+ padding:0px;
+}
+.noborder {
+ border:none;
+}
+.nobackground {
+background:transparent;
+}
+.nobackground:active {
+background:transparent;
+}
+.textHead{
+ text-shadow: 2px 2px @theme_bg_color;
+ color: @theme_text_color;
+}
+
+.inherited>* {
+ border:none;
+ background:inherit;
+}
+.workingbg {
+ background:@theme_base_color;
+}
+.menuitembottom{
+ margin-top:0px;
+ margin-bottom:3px;
+ border-color:inherit;
+ border-left-width:inherit;
+ border-right-width:inherit;
+ }
+ .menuitemmiddle{
+ margin-top:0px;
+ margin-bottom:0px;
+ border-color:inherit;
+ border-left-width:inherit;
+ border-right-width:inherit;
+ }
+
+ .menuitemtop{
+ margin-bottom:0px;
+ border-color:inherit;
+ border-top-width:inherit;
+ border-left-width:inherit;
+ border-right-width:inherit;
+ }
+ .menuitemtop>*{
+ margin:2px 2px 0 2px;
+ padding: 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/ubl-settings-logging.desktop b/ubl-settings-logging.desktop
new file mode 100644
index 0000000..65bec5b
--- /dev/null
+++ b/ubl-settings-logging.desktop
@@ -0,0 +1,15 @@
+[Desktop Entry]
+Encoding=UTF-8
+Name=Logs and events
+Name[ru]=Логи и журналы событий
+GenericName=ubl-settings-logging
+GenericName[ru]=ubl-settings-logging
+Comment=Logs and events configuration
+Comment[ru]=Настройка логов и журналов событий
+Type=Application
+Exec=pkexec ubl-settings-logging
+Icon=com.ublinux.ubl-settings-logging
+Terminal=false
+X-XfcePluggable=true
+X-UBLPluggable=true
+Categories=GTK;X-UBL-SettingsManager;X-UBL-Personal-Settings;
diff --git a/ubl-settings-logging.glade b/ubl-settings-logging.glade
new file mode 100644
index 0000000..2247491
--- /dev/null
+++ b/ubl-settings-logging.glade
@@ -0,0 +1,1170 @@
+
+
+
+
+
+
+
+
+
+ False
+ False
+ True
+ center
+ com.ublinux.ubl-settings-logging
+ dialog
+ True
+ ubl-settings-logging
+ 1.1
+ Copyright © 2022 - 2023, UBSoft LLC
+ Logs and events
+ https://wiki.ublinux.ru/ru/Программное_обеспечение/Программы_и_утилиты/Все/ubl-settings-logging
+ 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.ubl-settings-logging
+ True
+ gpl-2-0
+
+
+ True
+ False
+ vertical
+ 2
+
+
+ False
+ end
+
+
+ False
+ False
+ 1
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ True
+ False
+ com.ublinux.ubl-settings-logging.view-symbolic
+
+
+ True
+ False
+ document-edit-symbolic
+
+
+ True
+ False
+ value-increase-symbolic
+
+
+ True
+ False
+ user-trash-symbolic
+
+
+ True
+ False
+ com.ublinux.ubl-settings-logging.stop-symbolic
+
+
+ True
+ False
+ com.ublinux.ubl-settings-logging.play-symbolic
+
+
+ True
+ False
+ document-edit-symbolic
+
+
+ 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
+
+
+
+ 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
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ journald
+ /var/log/journal/
+ System events journal
+ 0
+ 0
+ 0
+ 0
+ 0
+
+
+
+
+
+
+
+ 800
+ 600
+ False
+ 800
+ 600
+ com.ublinux.ubl-settings-logging
+
+
+ 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
+
+
+ True
+ True
+
+
+ True
+ False
+ 5
+ 5
+ 5
+ 5
+ 5
+
+
+ True
+ False
+ vertical
+ 5
+
+
+ True
+ True
+ True
+ image1
+
+
+
+ False
+ True
+ 0
+
+
+
+
+ True
+ True
+ True
+ image2
+
+
+
+ False
+ True
+ 1
+
+
+
+
+ True
+ True
+ True
+ image3
+
+
+
+ False
+ True
+ 2
+
+
+
+
+ True
+ True
+ True
+ image4
+
+
+
+ False
+ True
+ 3
+
+
+
+
+ False
+ True
+ 0
+
+
+
+
+ True
+ True
+ in
+
+
+ True
+ True
+ liststore1
+ 2
+
+
+
+
+
+ True
+ fixed
+ 30
+ Log/Journal
+
+
+ end
+ 100
+
+
+ 0
+
+
+
+
+
+
+ True
+ fixed
+ 30
+ Path
+
+
+ end
+ 100
+
+
+ 1
+
+
+
+
+
+
+ True
+ fixed
+ 30
+ Description
+
+
+ end
+ 100
+
+
+ 2
+
+
+
+
+
+
+
+
+ True
+ True
+ 1
+
+
+
+
+
+
+ True
+ False
+ Journals
+
+
+ False
+
+
+
+
+ True
+ False
+ 5
+ 5
+ 5
+ 5
+ 5
+
+
+ True
+ False
+ vertical
+ 5
+
+
+ True
+ True
+ True
+ image5
+
+
+
+ False
+ True
+ 0
+
+
+
+
+ True
+ True
+ True
+ image6
+
+
+
+ False
+ True
+ 1
+
+
+
+
+ True
+ True
+ True
+ image7
+
+
+
+ False
+ True
+ 2
+
+
+
+
+ False
+ True
+ 0
+
+
+
+
+ True
+ True
+ in
+
+
+ True
+ True
+ ServicesList
+
+
+
+
+
+ Status
+
+
+
+ 0
+
+
+
+
+
+
+ Service
+
+
+
+ 1
+
+
+
+
+
+
+ Description
+
+
+
+ 2
+
+
+
+
+
+
+
+
+ True
+ True
+ 1
+
+
+
+
+ 1
+
+
+
+
+ True
+ False
+ Services
+
+
+ 1
+ False
+
+
+
+
+ True
+ True
+ 1
+
+
+
+
+ False
+ True
+ 2
+
+
+
+
+ True
+ True
+ 0
+
+
+
+
+
+
+
+
+
diff --git a/ubl-settings-logging.pot b/ubl-settings-logging.pot
new file mode 100644
index 0000000..85c7978
--- /dev/null
+++ b/ubl-settings-logging.pot
@@ -0,0 +1,174 @@
+# Language translations for ubl-settings-logging package.
+# Copyright (C) 2022, UBTech LLC
+# This file is distributed under the same license as the ubl-settings-logging package.
+# UBLinux Team , 2022
+#
+#, fuzzy
+msgid ""
+msgstr ""
+"Project-Id-Version: ubl-settings-logging 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 "ubl-settings-logging version:"
+msgstr ""
+
+#: source/ubl-strings.h:2
+msgid "logging 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 "Logs and events"
+msgstr ""
+
+#: source/ubl-strings.h:5
+msgid "Logs and events configuration"
+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/ubl-settings-logging_ru.po b/ubl-settings-logging_ru.po
new file mode 100644
index 0000000..51aaa12
--- /dev/null
+++ b/ubl-settings-logging_ru.po
@@ -0,0 +1,177 @@
+# Russian translations for ubl-settings-logging package.
+# Copyright (C) 2022, UBTech LLC
+# This file is distributed under the same license as the ubl-settings-logging package.
+# UBLinux Team , 2022
+#
+#, fuzzy
+msgid ""
+msgstr ""
+"Project-Id-Version: ubl-settings-logging 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 "ubl-settings-logging version:"
+msgstr "Версия ubl-settings-logging: "
+
+#: source/ubl-strings.h:2
+msgid "logging settings"
+msgstr "Настройки logging"
+
+#: 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 "Logs and events"
+msgstr "Настройки logging"
+
+#: source/ubl-strings.h:5
+msgid "Logs and events configuration"
+msgstr "Настройки logging"
+
+#: 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 "Успешно записана локальная конфигурация"