Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
T
tuneit
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Registry
Registry
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Ximper Linux
tuneit
Commits
3da4c51e
Commit
3da4c51e
authored
2 months ago
by
Roman Alifanov
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
big refactoring
parent
d1dc212d
Expand all
Show whitespace changes
Inline
Side-by-side
Showing
12 changed files
with
298 additions
and
4 deletions
+298
-4
meson.build
src/meson.build
+4
-0
__init__.py
src/settings/__init__.py
+141
-0
backends.py
src/settings/backends.py
+45
-0
__init__.py
src/settings/tools/__init__.py
+0
-0
yml_tools.py
src/settings/tools/yml_tools.py
+31
-0
BaseWidget.py
src/settings/widgets/BaseWidget.py
+6
-0
BooleanWidget.py
src/settings/widgets/BooleanWidget.py
+14
-0
ChoiceWidget.py
src/settings/widgets/ChoiceWidget.py
+14
-0
EntryWidget.py
src/settings/widgets/EntryWidget.py
+13
-0
__init__.py
src/settings/widgets/__init__.py
+19
-0
window.blp
src/window.blp
+11
-4
window.py
src/window.py
+0
-0
No files found.
src/meson.build
View file @
3da4c51e
...
@@ -42,3 +42,6 @@ tuneit_sources = [
...
@@ -42,3 +42,6 @@ tuneit_sources = [
]
]
install_data(tuneit_sources, install_dir: moduledir)
install_data(tuneit_sources, install_dir: moduledir)
install_subdir('settings', install_dir: moduledir, strip_directory : false)
install_subdir('shop', install_dir: moduledir, strip_directory : false)
\ No newline at end of file
This diff is collapsed.
Click to expand it.
src/settings/__init__.py
0 → 100644
View file @
3da4c51e
from
gi.repository
import
Adw
,
Gtk
from
.backends
import
backend_factory
from
.tools.yml_tools
import
load_yaml_files_from_directory
,
merge_categories_by_name
from
.widgets
import
WidgetFactory
class
Setting
:
def
__init__
(
self
,
setting_data
):
self
.
name
=
setting_data
[
'name'
]
self
.
type
=
setting_data
[
'type'
]
self
.
help
=
setting_data
.
get
(
'help'
,
""
)
self
.
backend
=
setting_data
.
get
(
'backend'
)
self
.
key
=
setting_data
.
get
(
'key'
)
self
.
default
=
setting_data
.
get
(
'default'
)
self
.
map
=
setting_data
.
get
(
'map'
,
self
.
_default_map
())
if
setting_data
.
get
(
'gtype'
):
self
.
gtype
=
setting_data
.
get
(
'gtype'
)[
0
]
self
.
data
=
setting_data
.
get
(
'data'
,
{})
def
_default_map
(
self
):
if
self
.
type
==
'boolean'
:
# Дефолтная карта для булевых настроек
return
{
True
:
True
,
False
:
False
}
return
{}
def
create_row
(
self
):
widget
=
WidgetFactory
.
create_widget
(
self
)
return
widget
.
create_row
()
if
widget
else
None
def
_get_selected_row_index
(
self
):
current_value
=
self
.
_get_backend_value
()
return
list
(
self
.
map
.
values
())
.
index
(
current_value
)
if
current_value
in
self
.
map
.
values
()
else
0
def
_get_backend_value
(
self
):
backend
=
self
.
_get_backend
()
if
backend
:
return
backend
.
get_value
(
self
.
key
,
self
.
gtype
)
return
self
.
default
def
_set_backend_value
(
self
,
value
):
backend
=
self
.
_get_backend
()
if
backend
:
backend
.
set_value
(
self
.
key
,
value
,
self
.
gtype
)
def
_get_backend
(
self
):
backend
=
backend_factory
.
get_backend
(
self
.
backend
)
if
not
backend
:
print
(
f
"Бекенд {self.backend} не зарегистрирован."
)
return
backend
class
Section
:
def
__init__
(
self
,
section_data
,
strategy
):
self
.
name
=
section_data
[
'name'
]
self
.
weight
=
section_data
.
get
(
'weight'
,
0
)
self
.
settings
=
[
Setting
(
s
)
for
s
in
section_data
.
get
(
'settings'
,
[])]
self
.
strategy
=
strategy
def
create_preferences_group
(
self
):
return
self
.
strategy
.
create_preferences_group
(
self
)
class
SectionStrategy
:
def
create_preferences_group
(
self
,
section
):
raise
NotImplementedError
(
"Метод create_preferences_group должен быть реализован"
)
class
ClassicSectionStrategy
(
SectionStrategy
):
def
create_preferences_group
(
self
,
section
):
group
=
Adw
.
PreferencesGroup
(
title
=
section
.
name
)
for
setting
in
section
.
settings
:
row
=
setting
.
create_row
()
if
row
:
print
(
f
"Добавление строки для настройки: {setting.name}"
)
group
.
add
(
row
)
else
:
print
(
f
"Не удалось создать строку для настройки: {setting.name}"
)
return
group
class
NewSectionStrategy
(
SectionStrategy
):
def
create_preferences_group
(
self
,
section
):
group
=
Adw
.
PreferencesGroup
(
title
=
section
.
name
)
print
(
f
"Создание секции нового типа: {section.name}"
)
for
setting
in
section
.
settings
:
row
=
setting
.
create_row
()
group
.
add
(
row
)
return
group
class
SectionFactory
:
def
__init__
(
self
):
self
.
strategies
=
{
'classic'
:
ClassicSectionStrategy
(),
}
def
create_section
(
self
,
section_data
):
section_type
=
section_data
.
get
(
'type'
,
'classic'
)
strategy
=
self
.
strategies
.
get
(
section_type
)
if
not
strategy
:
raise
ValueError
(
f
"Неизвестный тип секции: {section_type}"
)
return
Section
(
section_data
,
strategy
)
class
Category
:
def
__init__
(
self
,
category_data
,
section_factory
:
SectionFactory
):
self
.
name
=
category_data
[
'name'
]
self
.
weight
=
category_data
.
get
(
'weight'
,
0
)
self
.
sections
=
[
section_factory
.
create_section
(
s
)
for
s
in
category_data
.
get
(
'sections'
,
[])]
def
create_stack_page
(
self
,
stack
):
box
=
Gtk
.
ScrolledWindow
()
pref_page
=
Adw
.
PreferencesPage
()
clamp
=
Adw
.
Clamp
()
clamp
.
set_child
(
pref_page
)
box
.
set_child
(
clamp
)
for
section
in
self
.
sections
:
preferences_group
=
section
.
create_preferences_group
()
if
preferences_group
:
pref_page
.
add
(
preferences_group
)
else
:
print
(
f
"Секция {section.name} не создала виджетов."
)
stack
.
add_child
(
box
)
.
set_title
(
self
.
name
)
def
init_settings_stack
(
stack
):
yaml_files_directory
=
"/usr/share/ximper-tuneit/modules"
# Укажите путь к папке с YAML файлами
yaml_data
=
load_yaml_files_from_directory
(
yaml_files_directory
)
merged_data
=
merge_categories_by_name
(
yaml_data
)
section_factory
=
SectionFactory
()
categories
=
[
Category
(
c
,
section_factory
)
for
c
in
merged_data
]
for
category
in
categories
:
category
.
create_stack_page
(
stack
)
if
not
stack
:
print
(
"Ошибка: settings_pagestack не найден."
)
This diff is collapsed.
Click to expand it.
src/settings/backends.py
0 → 100644
View file @
3da4c51e
from
gi.repository
import
Gio
,
GLib
class
Backend
:
def
get_value
(
self
,
key
,
gtype
):
raise
NotImplementedError
(
"Метод get_value должен быть реализован"
)
def
set_value
(
self
,
key
,
value
,
gtype
):
raise
NotImplementedError
(
"Метод set_value должен быть реализован"
)
class
GSettingsBackend
(
Backend
):
def
get_value
(
self
,
key
,
gtype
):
schema_name
,
key_name
=
key
.
rsplit
(
'.'
,
1
)
schema
=
Gio
.
Settings
.
new
(
schema_name
)
print
(
f
"[DEBUG] Получение значения: schema={schema_name}, key={key_name}, gtype={gtype}"
)
try
:
value
=
schema
.
get_value
(
key_name
)
return
value
.
unpack
()
except
Exception
as
e
:
print
(
f
"[ERROR] Ошибка при получении значения {key}: {e}"
)
return
None
def
set_value
(
self
,
schema_key
,
value
,
gtype
):
schema_name
,
key_name
=
schema_key
.
rsplit
(
'.'
,
1
)
schema
=
Gio
.
Settings
.
new
(
schema_name
)
print
(
f
"[DEBUG] Установка значения: schema={schema_name}, key={key_name}, value={value}, gtype={gtype}"
)
try
:
schema
.
set_value
(
key_name
,
GLib
.
Variant
(
gtype
,
value
))
except
Exception
as
e
:
print
(
f
"[ERROR] Ошибка при установке значения {schema_key}: {e}"
)
class
BackendFactory
:
def
__init__
(
self
):
self
.
backends
=
{
'gsettings'
:
GSettingsBackend
(),
}
def
get_backend
(
self
,
name
):
return
self
.
backends
.
get
(
name
)
backend_factory
=
BackendFactory
()
This diff is collapsed.
Click to expand it.
src/settings/tools/__init__.py
0 → 100644
View file @
3da4c51e
This diff is collapsed.
Click to expand it.
src/settings/tools/yml_tools.py
0 → 100644
View file @
3da4c51e
import
os
import
yaml
def
load_yaml_files_from_directory
(
directory
):
yaml_data
=
[]
for
root
,
_
,
files
in
os
.
walk
(
directory
):
for
file
in
files
:
if
file
.
endswith
(
".yml"
)
or
file
.
endswith
(
".yaml"
):
file_path
=
os
.
path
.
join
(
root
,
file
)
with
open
(
file_path
,
'r'
,
encoding
=
'utf-8'
)
as
f
:
try
:
data
=
yaml
.
safe_load
(
f
)
if
data
:
yaml_data
.
extend
(
data
)
except
yaml
.
YAMLError
as
e
:
print
(
f
"Ошибка при чтении файла {file_path}: {e}"
)
return
yaml_data
def
merge_categories_by_name
(
categories_data
):
categories_dict
=
{}
for
category_data
in
categories_data
:
category_name
=
category_data
[
'name'
]
if
category_name
not
in
categories_dict
:
categories_dict
[
category_name
]
=
category_data
else
:
categories_dict
[
category_name
][
'sections'
]
.
extend
(
category_data
[
'sections'
])
return
list
(
categories_dict
.
values
())
This diff is collapsed.
Click to expand it.
src/settings/widgets/BaseWidget.py
0 → 100644
View file @
3da4c51e
class
BaseWidget
:
def
__init__
(
self
,
setting
):
self
.
setting
=
setting
def
create_row
(
self
):
raise
NotImplementedError
(
"Метод create_row должен быть реализован в подклассе"
)
This diff is collapsed.
Click to expand it.
src/settings/widgets/BooleanWidget.py
0 → 100644
View file @
3da4c51e
from
gi.repository
import
Adw
from
.BaseWidget
import
BaseWidget
class
BooleanWidget
(
BaseWidget
):
def
create_row
(
self
):
row
=
Adw
.
SwitchRow
(
title
=
self
.
setting
.
name
,
subtitle
=
self
.
setting
.
help
)
current_value
=
self
.
setting
.
_get_backend_value
()
row
.
set_active
(
current_value
==
self
.
setting
.
map
.
get
(
True
))
row
.
connect
(
"notify::active"
,
self
.
_on_boolean_toggled
)
return
row
def
_on_boolean_toggled
(
self
,
switch
,
_
):
value
=
self
.
setting
.
map
.
get
(
True
)
if
switch
.
get_active
()
else
self
.
setting
.
map
.
get
(
False
)
self
.
setting
.
_set_backend_value
(
value
)
This diff is collapsed.
Click to expand it.
src/settings/widgets/ChoiceWidget.py
0 → 100644
View file @
3da4c51e
from
gi.repository
import
Adw
,
Gtk
from
.BaseWidget
import
BaseWidget
class
ChoiceWidget
(
BaseWidget
):
def
create_row
(
self
):
row
=
Adw
.
ComboRow
(
title
=
self
.
setting
.
name
,
subtitle
=
self
.
setting
.
help
)
row
.
set_model
(
Gtk
.
StringList
.
new
(
list
(
self
.
setting
.
map
.
keys
())))
row
.
set_selected
(
self
.
setting
.
_get_selected_row_index
())
row
.
connect
(
"notify::selected"
,
self
.
_on_choice_changed
)
return
row
def
_on_choice_changed
(
self
,
combo_row
,
_
):
selected_value
=
list
(
self
.
setting
.
map
.
values
())[
combo_row
.
get_selected
()]
self
.
setting
.
_set_backend_value
(
selected_value
)
This diff is collapsed.
Click to expand it.
src/settings/widgets/EntryWidget.py
0 → 100644
View file @
3da4c51e
from
gi.repository
import
Adw
from
.BaseWidget
import
BaseWidget
class
EntryWidget
(
BaseWidget
):
def
create_row
(
self
):
row
=
Adw
.
EntryRow
(
title
=
self
.
setting
.
name
)
row
.
set_show_apply_button
(
True
)
row
.
set_text
(
self
.
setting
.
_get_backend_value
())
row
.
connect
(
"apply"
,
self
.
_on_text_changed
)
return
row
def
_on_text_changed
(
self
,
entry_row
):
self
.
setting
.
_set_backend_value
(
entry_row
.
get_text
())
This diff is collapsed.
Click to expand it.
src/settings/widgets/__init__.py
0 → 100644
View file @
3da4c51e
from
.BooleanWidget
import
BooleanWidget
from
.ChoiceWidget
import
ChoiceWidget
from
.EntryWidget
import
EntryWidget
class
WidgetFactory
:
widget_map
=
{
'choice'
:
ChoiceWidget
,
'boolean'
:
BooleanWidget
,
'entry'
:
EntryWidget
}
@staticmethod
def
create_widget
(
setting
):
widget_class
=
WidgetFactory
.
widget_map
.
get
(
setting
.
type
)
if
widget_class
:
return
widget_class
(
setting
)
else
:
print
(
f
"Неизвестный тип виджета: {setting.type}"
)
return
None
This diff is collapsed.
Click to expand it.
src/window.blp
View file @
3da4c51e
...
@@ -25,7 +25,7 @@ template $TuneitWindow: Adw.ApplicationWindow {
...
@@ -25,7 +25,7 @@ template $TuneitWindow: Adw.ApplicationWindow {
child: Box {
child: Box {
Adw.NavigationSplitView {
Adw.NavigationSplitView {
content: Adw.NavigationPage {
content: Adw.NavigationPage {
Stack
main
_pagestack {}
Stack
settings
_pagestack {}
};
};
hexpand: true;
hexpand: true;
...
@@ -38,7 +38,7 @@ template $TuneitWindow: Adw.ApplicationWindow {
...
@@ -38,7 +38,7 @@ template $TuneitWindow: Adw.ApplicationWindow {
margin-top: 8;
margin-top: 8;
StackSidebar {
StackSidebar {
stack:
main
_pagestack;
stack:
settings
_pagestack;
}
}
}
}
};
};
...
@@ -46,8 +46,15 @@ template $TuneitWindow: Adw.ApplicationWindow {
...
@@ -46,8 +46,15 @@ template $TuneitWindow: Adw.ApplicationWindow {
};
};
icon-name: "preferences-system";
icon-name: "preferences-system";
name: "main";
name: "settings";
title: "main";
title: _("Settings");
}
Adw.ViewStackPage {
child: Box {};
icon-name: "preferences-system";
name: "shop";
title: _("Shop");
}
}
}
}
};
};
...
...
This diff is collapsed.
Click to expand it.
src/window.py
View file @
3da4c51e
This diff is collapsed.
Click to expand it.
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment