Start migration to MVVM
This commit is contained in:
1 parent
fe1cea9e2b
commit
8acc18c7fe
115 files changed
+942
-820
No files matched your search
@@ -1 +1 @@
|
|||||||
icons/icon.svg
|
res/icons/icon.svg
|
||||||
@@ -1,642 +0,0 @@
|
|||||||
#!/usr/bin/python3
|
|
||||||
|
|
||||||
############################################################
|
|
||||||
# Imports #
|
|
||||||
############################################################
|
|
||||||
|
|
||||||
# Packages
|
|
||||||
import gi, os, subprocess, time
|
|
||||||
from datetime import timedelta
|
|
||||||
|
|
||||||
# Local scripts
|
|
||||||
from scripts import cinnamon_pref_handler, dialogs, display, images, location, suntimes, time_bar_chart, ui
|
|
||||||
from loop import *
|
|
||||||
from enums.ImageSourceEnum import ImageSourceEnum
|
|
||||||
from enums.PeriodSourceEnum import PeriodSourceEnum
|
|
||||||
|
|
||||||
gi.require_version("Gtk", "3.0")
|
|
||||||
from gi.repository import Gtk, GdkPixbuf
|
|
||||||
|
|
||||||
|
|
||||||
# Global definitions
|
|
||||||
PREFERENCES_URI = os.path.dirname(os.path.abspath(__file__))
|
|
||||||
GLADE_URI = PREFERENCES_URI + "/preferences.glade"
|
|
||||||
|
|
||||||
|
|
||||||
class Preferences:
|
|
||||||
""" Preference window class
|
|
||||||
"""
|
|
||||||
|
|
||||||
############################################################
|
|
||||||
# Lifecycle #
|
|
||||||
############################################################
|
|
||||||
|
|
||||||
def __init__(self) -> None:
|
|
||||||
# Objects from external scripts
|
|
||||||
self.prefs = cinnamon_pref_handler.Cinnamon_Pref_Handler()
|
|
||||||
self.dialogs = dialogs.Dialogs()
|
|
||||||
self.display = display.Display()
|
|
||||||
self.images = images.Images()
|
|
||||||
self.location = location.Location()
|
|
||||||
self.suntimes = suntimes.Suntimes()
|
|
||||||
self.time_bar_chart = time_bar_chart.Time_Bar_Chart()
|
|
||||||
|
|
||||||
# Glade
|
|
||||||
self.builder = Gtk.Builder()
|
|
||||||
self.builder.add_from_file(GLADE_URI)
|
|
||||||
self.builder.connect_signals(self)
|
|
||||||
|
|
||||||
self.ui = ui.UI(self.builder)
|
|
||||||
|
|
||||||
|
|
||||||
# Local Config
|
|
||||||
self.smaller_ui_height = 1000
|
|
||||||
|
|
||||||
|
|
||||||
def show(self):
|
|
||||||
""" Display the window to the screen
|
|
||||||
"""
|
|
||||||
window = self.builder.get_object("window_main")
|
|
||||||
window.show_all()
|
|
||||||
|
|
||||||
# Load from preferences
|
|
||||||
if self.prefs.image_source == ImageSourceEnum.IMAGESET:
|
|
||||||
self.ui.tb_image_set.set_active(True)
|
|
||||||
elif self.prefs.image_source == ImageSourceEnum.HEICFILE:
|
|
||||||
self.ui.tb_heic_file.set_active(True)
|
|
||||||
elif self.prefs.image_source == ImageSourceEnum.SOURCEFOLDER:
|
|
||||||
self.ui.tb_source_folder.set_active(True)
|
|
||||||
|
|
||||||
|
|
||||||
# Remove icons in the ToggleButtons if the screen height resolution < 1000 px
|
|
||||||
if self.display.get_screen_height() < self.smaller_ui_height:
|
|
||||||
self.ui.img_tb_image_set.clear()
|
|
||||||
self.ui.img_tb_heic_file.clear()
|
|
||||||
self.ui.img_tb_source_folder.clear()
|
|
||||||
self.ui.img_tb_network_location.clear()
|
|
||||||
self.ui.img_tb_custom_location.clear()
|
|
||||||
self.ui.img_tb_time_periods.clear()
|
|
||||||
|
|
||||||
|
|
||||||
picture_aspects = ["centered", "scaled", "stretched", "zoom", "spanned"]
|
|
||||||
self.ui.add_items_to_combo_box(self.ui.cb_picture_aspect, picture_aspects)
|
|
||||||
self.ui.set_active_combobox_item(self.ui.cb_picture_aspect, self.prefs.picture_aspect)
|
|
||||||
|
|
||||||
self.ui.sw_dynamic_background_color.set_active(self.prefs.dynamic_background_color)
|
|
||||||
|
|
||||||
|
|
||||||
if self.prefs.period_source == PeriodSourceEnum.NETWORKLOCATION:
|
|
||||||
self.ui.tb_network_location.set_active(True)
|
|
||||||
elif self.prefs.period_source == PeriodSourceEnum.CUSTOMLOCATION:
|
|
||||||
self.ui.tb_custom_location.set_active(True)
|
|
||||||
elif self.prefs.period_source == PeriodSourceEnum.CUSTOMTIMEPERIODS:
|
|
||||||
self.ui.tb_time_periods.set_active(True)
|
|
||||||
|
|
||||||
|
|
||||||
# Time diagram
|
|
||||||
try:
|
|
||||||
self.refresh_chart()
|
|
||||||
except:
|
|
||||||
pass
|
|
||||||
|
|
||||||
# Show the main window
|
|
||||||
Gtk.main()
|
|
||||||
|
|
||||||
|
|
||||||
def on_destroy(self, *args):
|
|
||||||
""" Lifecycle handler when window will be destroyed
|
|
||||||
"""
|
|
||||||
Gtk.main_quit()
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
############################################################
|
|
||||||
# Local methods #
|
|
||||||
############################################################
|
|
||||||
|
|
||||||
def refresh_chart(self):
|
|
||||||
""" Recomputes both time bar charts and load them to the UI
|
|
||||||
"""
|
|
||||||
# Stores the start times of the periods in minutes since midnight
|
|
||||||
time_periods_min = []
|
|
||||||
|
|
||||||
if self.prefs.period_source == PeriodSourceEnum.CUSTOMTIMEPERIODS:
|
|
||||||
for i in range(0, 10):
|
|
||||||
time_str = self.prefs.period_custom_start_time[i]
|
|
||||||
|
|
||||||
time_periods_min.append(int(time_str[0:2]) * 60 + int(time_str[3:5]))
|
|
||||||
else:
|
|
||||||
if self.prefs.period_source == PeriodSourceEnum.NETWORKLOCATION:
|
|
||||||
self.suntimes.calc_suntimes(float(self.prefs.latitude_auto), float(self.prefs.longitude_auto))
|
|
||||||
else:
|
|
||||||
self.suntimes.calc_suntimes(float(self.ui.etr_latitude.get_text()), float(self.ui.etr_longitude.get_text()))
|
|
||||||
|
|
||||||
|
|
||||||
# Get all time periods. Store the minutes to the list and print the values to the text views
|
|
||||||
for i in range(0, 10):
|
|
||||||
time_range_now = self.suntimes.day_periods[i]
|
|
||||||
|
|
||||||
if i != 9:
|
|
||||||
time_range_next = self.suntimes.day_periods[i + 1]
|
|
||||||
else:
|
|
||||||
time_range_next = time(hour=23, minute=59)
|
|
||||||
|
|
||||||
self.ui.etr_periods[i].set_text(
|
|
||||||
str(time_range_now.hour).rjust(2, '0') + ":" + str(time_range_now.minute).rjust(2, '0') + \
|
|
||||||
" - " + str(time_range_next.hour).rjust(2, '0') + ":" + str(time_range_next.minute).rjust(2, '0'))
|
|
||||||
|
|
||||||
time_periods_min.append(time_range_now.hour * 60 + time_range_now.minute)
|
|
||||||
|
|
||||||
# Create time bar
|
|
||||||
# Reduce size for small displays
|
|
||||||
if self.display.get_screen_height() < self.smaller_ui_height:
|
|
||||||
bar_width = 1150
|
|
||||||
bar_height = 110
|
|
||||||
else:
|
|
||||||
bar_width = 1300
|
|
||||||
bar_height = 150
|
|
||||||
|
|
||||||
self.time_bar_chart.create_bar_chart_with_polylines(PREFERENCES_URI, bar_width, bar_height, time_periods_min)
|
|
||||||
self.time_bar_chart.create_bar_chart(PREFERENCES_URI, bar_width, bar_height, time_periods_min)
|
|
||||||
|
|
||||||
# Load to the views
|
|
||||||
pixbuf = GdkPixbuf.Pixbuf.new_from_file(PREFERENCES_URI + "/time_bar_polylines.svg")
|
|
||||||
self.ui.img_bar_images.set_from_pixbuf(pixbuf)
|
|
||||||
|
|
||||||
pixbuf2 = GdkPixbuf.Pixbuf.new_from_file(PREFERENCES_URI + "/time_bar.svg")
|
|
||||||
self.ui.img_bar_times.set_from_pixbuf(pixbuf2)
|
|
||||||
|
|
||||||
|
|
||||||
def load_image_options_to_combo_boxes(self, options: list):
|
|
||||||
""" Add a list of Strings to all image option comboboxes
|
|
||||||
|
|
||||||
Args:
|
|
||||||
options (list): All possible options
|
|
||||||
"""
|
|
||||||
options.insert(0, "")
|
|
||||||
|
|
||||||
for combobox in self.ui.cb_periods:
|
|
||||||
self.ui.add_items_to_combo_box(combobox, options)
|
|
||||||
|
|
||||||
|
|
||||||
def load_image_to_preview(self, image_preview: Gtk.Image, image_src: str):
|
|
||||||
""" Scales the image to a lower resoultion and put them into the time bar chart
|
|
||||||
|
|
||||||
Args:
|
|
||||||
image_preview (Gtk.Image): Gtk Image where it will be displayed
|
|
||||||
image_src (str): Absolute path to the image
|
|
||||||
"""
|
|
||||||
try:
|
|
||||||
pixbuf = GdkPixbuf.Pixbuf.new_from_file(image_src)
|
|
||||||
|
|
||||||
screen_height = self.display.get_screen_height()
|
|
||||||
|
|
||||||
# Scaling the images smaller for screens
|
|
||||||
if screen_height < self.smaller_ui_height:
|
|
||||||
pixbuf = pixbuf.scale_simple(221, 128, GdkPixbuf.InterpType.BILINEAR)
|
|
||||||
else:
|
|
||||||
pixbuf = pixbuf.scale_simple(260, 150, GdkPixbuf.InterpType.BILINEAR)
|
|
||||||
|
|
||||||
image_preview.set_from_pixbuf(pixbuf)
|
|
||||||
except:
|
|
||||||
pass
|
|
||||||
|
|
||||||
|
|
||||||
############################################################
|
|
||||||
# Callbacks #
|
|
||||||
############################################################
|
|
||||||
|
|
||||||
## Image Configuration
|
|
||||||
|
|
||||||
# +-----------+-----------+---------------+
|
|
||||||
# | Image Set | HEIC file | Source Folder |
|
|
||||||
# +-----------+-----------+---------------+
|
|
||||||
|
|
||||||
def on_toggle_button_image_set_clicked(self, button: Gtk.ToggleButton):
|
|
||||||
""" Clicked on ToggleButton "Image Set"
|
|
||||||
|
|
||||||
Args:
|
|
||||||
button (Gtk.ToggleButton): Clicked ToggleButton
|
|
||||||
"""
|
|
||||||
if button.get_active():
|
|
||||||
self.prefs.image_source = ImageSourceEnum.IMAGESET
|
|
||||||
self.ui.tb_heic_file.set_active(False)
|
|
||||||
self.ui.tb_source_folder.set_active(False)
|
|
||||||
|
|
||||||
self.ui.lbr_image_set.set_visible(True)
|
|
||||||
self.ui.lbr_heic_file.set_visible(False)
|
|
||||||
self.ui.lbr_source_folder.set_visible(False)
|
|
||||||
|
|
||||||
image_set_choices = [
|
|
||||||
"aurora", "beach",
|
|
||||||
"bitday", "cliffs",
|
|
||||||
"earth", "gradient",
|
|
||||||
"lakeside", "mountains",
|
|
||||||
"sahara"
|
|
||||||
]
|
|
||||||
self.ui.add_items_to_combo_box(self.ui.cb_image_set, image_set_choices)
|
|
||||||
|
|
||||||
self.ui.set_active_combobox_item(self.ui.cb_image_set, self.prefs.selected_image_set)
|
|
||||||
|
|
||||||
for i, combobox in enumerate(self.ui.cb_periods):
|
|
||||||
selected_image_name = self.prefs.period_images[i]
|
|
||||||
self.ui.set_active_combobox_item(combobox, selected_image_name)
|
|
||||||
|
|
||||||
# Make the comboboxes invisible
|
|
||||||
for combobox in self.ui.cb_periods:
|
|
||||||
combobox.set_visible(False)
|
|
||||||
|
|
||||||
|
|
||||||
def on_toggle_button_heic_file_clicked(self, button: Gtk.ToggleButton):
|
|
||||||
""" Clicked on ToggleButton "Heic file"
|
|
||||||
|
|
||||||
Args:
|
|
||||||
button (Gtk.ToggleButton): Clicked ToggleButton
|
|
||||||
"""
|
|
||||||
if button.get_active():
|
|
||||||
self.prefs.image_source = ImageSourceEnum.HEICFILE
|
|
||||||
self.ui.tb_image_set.set_active(False)
|
|
||||||
self.ui.tb_source_folder.set_active(False)
|
|
||||||
|
|
||||||
self.ui.lbr_image_set.set_visible(False)
|
|
||||||
self.ui.lbr_heic_file.set_visible(True)
|
|
||||||
self.ui.lbr_source_folder.set_visible(False)
|
|
||||||
|
|
||||||
# Make the comboboxes visible
|
|
||||||
for combobox in self.ui.cb_periods:
|
|
||||||
combobox.set_visible(True)
|
|
||||||
|
|
||||||
# Load images from source folder
|
|
||||||
files = self.images.get_images_from_folder(self.prefs.source_folder)
|
|
||||||
|
|
||||||
if len(files) != 0:
|
|
||||||
self.load_image_options_to_combo_boxes(files)
|
|
||||||
|
|
||||||
# Load the values for the images from the preferences
|
|
||||||
for i in range(0, 10):
|
|
||||||
self.ui.set_active_combobox_item(self.ui.cb_periods[i], self.prefs.period_images[i])
|
|
||||||
else:
|
|
||||||
print("No image files!")
|
|
||||||
|
|
||||||
|
|
||||||
def on_toggle_button_source_folder_clicked(self, button: Gtk.ToggleButton):
|
|
||||||
""" Clicked on ToggleButton "Source Folder"
|
|
||||||
|
|
||||||
Args:
|
|
||||||
button (Gtk.ToggleButton): Clicked ToggleButton
|
|
||||||
"""
|
|
||||||
if button.get_active():
|
|
||||||
self.prefs.image_source = ImageSourceEnum.SOURCEFOLDER
|
|
||||||
self.ui.tb_image_set.set_active(False)
|
|
||||||
self.ui.tb_heic_file.set_active(False)
|
|
||||||
|
|
||||||
self.ui.lbr_image_set.set_visible(False)
|
|
||||||
self.ui.lbr_heic_file.set_visible(False)
|
|
||||||
self.ui.lbr_source_folder.set_visible(True)
|
|
||||||
|
|
||||||
# Make the comboboxes visible
|
|
||||||
for combobox in self.ui.cb_periods:
|
|
||||||
combobox.set_visible(True)
|
|
||||||
|
|
||||||
# Load the source folder to the view
|
|
||||||
# This will update the comboboxes in the preview to contain the right items
|
|
||||||
self.ui.lbl_source_folder.set_label(self.prefs.source_folder)
|
|
||||||
|
|
||||||
# Load files from saved source folder
|
|
||||||
files = self.images.get_images_from_folder(self.prefs.source_folder)
|
|
||||||
|
|
||||||
if len(files) != 0:
|
|
||||||
self.load_image_options_to_combo_boxes(files)
|
|
||||||
|
|
||||||
# Load the values for the images from the preferences
|
|
||||||
for i in range(0, 10):
|
|
||||||
self.ui.set_active_combobox_item(self.ui.cb_periods[i], self.prefs.period_images[i])
|
|
||||||
else:
|
|
||||||
print("No image files!")
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# +------------------------------------+
|
|
||||||
# | Select an image set | aurora ▼ |
|
|
||||||
# +------------------------------------+
|
|
||||||
|
|
||||||
def on_cb_image_set_changed(self, combobox: Gtk.ComboBox):
|
|
||||||
""" User select on of the included image sets
|
|
||||||
|
|
||||||
Args:
|
|
||||||
combobox (Gtk.ComboBox): The used ComboBox
|
|
||||||
"""
|
|
||||||
tree_iter = combobox.get_active_iter()
|
|
||||||
|
|
||||||
if tree_iter is not None and self.prefs.image_source == ImageSourceEnum.IMAGESET:
|
|
||||||
# Get the selected value
|
|
||||||
model = combobox.get_model()
|
|
||||||
selected_image_set = model[tree_iter][0]
|
|
||||||
|
|
||||||
# Store to the preferences
|
|
||||||
self.prefs.selected_image_set = selected_image_set
|
|
||||||
self.prefs.source_folder = os.path.abspath(os.path.join(PREFERENCES_URI, os.pardir)) + \
|
|
||||||
"/5.4/images/included_image_sets/" + selected_image_set + "/"
|
|
||||||
|
|
||||||
# Load all possible options to the comboboxes
|
|
||||||
image_names = self.images.get_images_from_folder(self.prefs.source_folder)
|
|
||||||
self.load_image_options_to_combo_boxes(image_names)
|
|
||||||
|
|
||||||
# Image sets have the same names for the images:
|
|
||||||
# 9.jpg = Period 0
|
|
||||||
# 1.jpg = Period 1
|
|
||||||
# 2.jpg = Period 2
|
|
||||||
# and so on....
|
|
||||||
for i in range(0, 10):
|
|
||||||
self.ui.cb_periods[i].set_active(i + 1)
|
|
||||||
|
|
||||||
|
|
||||||
# +----------------------------------------------+
|
|
||||||
# | Select a heic file to import | (None) 📄 |
|
|
||||||
# +----------------------------------------------+
|
|
||||||
|
|
||||||
def on_fc_heic_file_file_set(self, fc_button: Gtk.FileChooser):
|
|
||||||
""" User has a heic file selected with the FileChooserDialog
|
|
||||||
|
|
||||||
Args:
|
|
||||||
fc_button (Gtk.FileChooser): Parameter about the selected file
|
|
||||||
"""
|
|
||||||
# The the absolute path to the heic file
|
|
||||||
file_path: str = fc_button.get_filename()
|
|
||||||
|
|
||||||
# Extract the heic file
|
|
||||||
result = self.images.extract_heic_file(file_path)
|
|
||||||
|
|
||||||
# Update the preferences
|
|
||||||
self.prefs.selected_image_set = ""
|
|
||||||
self.prefs.source_folder = PREFERENCES_URI + "/images/extracted_images/"
|
|
||||||
|
|
||||||
# Load images only if the extraction was successfully
|
|
||||||
if result:
|
|
||||||
# Collect all extracted images and push them to the comboboxes
|
|
||||||
image_names = self.images.get_images_from_folder(self.prefs.source_folder)
|
|
||||||
self.load_image_options_to_combo_boxes(image_names)
|
|
||||||
else:
|
|
||||||
self.dialogs.message_dialog("Error during extraction")
|
|
||||||
|
|
||||||
|
|
||||||
# +------------------------------------------------------------+
|
|
||||||
# | Select a source folder | 📂 Open file selection dialog |
|
|
||||||
# | /home/developer/Downloads/
|
|
||||||
# +------------------------------------------------------------+
|
|
||||||
|
|
||||||
def on_btn_source_folder_clicked(self, button: Gtk.Button):
|
|
||||||
""" Button to choose an image source folder was clicked
|
|
||||||
|
|
||||||
Args:
|
|
||||||
button (Gtk.Button): The clicked button
|
|
||||||
"""
|
|
||||||
folder = self.dialogs.source_folder_dialog()
|
|
||||||
files = self.images.get_images_from_folder(folder)
|
|
||||||
|
|
||||||
# Update the preferences
|
|
||||||
self.prefs.selected_image_set = ""
|
|
||||||
self.prefs.source_folder = folder + "/"
|
|
||||||
|
|
||||||
# Update the label
|
|
||||||
self.ui.lbl_source_folder.set_label(folder)
|
|
||||||
|
|
||||||
# Update the image comboboxes
|
|
||||||
self.load_image_options_to_combo_boxes(files)
|
|
||||||
|
|
||||||
# Load the values for the images from the preferences
|
|
||||||
for i in range(0, 10):
|
|
||||||
self.ui.cb_periods[i].set_active(0)
|
|
||||||
|
|
||||||
if len(files) == 1:
|
|
||||||
self.dialogs.message_dialog("No image files found!")
|
|
||||||
|
|
||||||
|
|
||||||
def on_cb_period_preview_changed(self, combobox: Gtk.ComboBox):
|
|
||||||
""" User select an image from the ComboBox for the time period
|
|
||||||
|
|
||||||
Args:
|
|
||||||
combobox (Gtk.ComboBox): The used ComboBox
|
|
||||||
"""
|
|
||||||
tree_iter = combobox.get_active_iter()
|
|
||||||
|
|
||||||
combobox_name = Gtk.Buildable.get_name(combobox)
|
|
||||||
period_index = int(combobox_name[10:11])
|
|
||||||
|
|
||||||
if tree_iter is not None:
|
|
||||||
# Get the selected value
|
|
||||||
model = combobox.get_model()
|
|
||||||
image_file_name = model[tree_iter][0]
|
|
||||||
|
|
||||||
# Store selection to preferences
|
|
||||||
self.prefs.period_images[period_index] = image_file_name
|
|
||||||
|
|
||||||
# Build up image path
|
|
||||||
image_path = self.prefs.source_folder + image_file_name
|
|
||||||
|
|
||||||
self.load_image_to_preview(self.ui.img_periods[period_index], image_path)
|
|
||||||
|
|
||||||
|
|
||||||
## Location & Times
|
|
||||||
|
|
||||||
def on_toggle_button_network_location_clicked(self, button: Gtk.ToggleButton):
|
|
||||||
""" User clicks on the ToggleButton for the network location
|
|
||||||
|
|
||||||
Args:
|
|
||||||
button (Gtk.ToggleButton): Clicked ToggleButton
|
|
||||||
"""
|
|
||||||
if button.get_active():
|
|
||||||
self.prefs.period_source = PeriodSourceEnum.NETWORKLOCATION
|
|
||||||
self.ui.tb_custom_location.set_active(False)
|
|
||||||
self.ui.tb_time_periods.set_active(False)
|
|
||||||
|
|
||||||
self.ui.lbr_network_location.set_visible(True)
|
|
||||||
self.ui.lbr_current_location.set_visible(True)
|
|
||||||
self.ui.lbr_custom_location_longitude.set_visible(False)
|
|
||||||
self.ui.lbr_custom_location_latitude.set_visible(False)
|
|
||||||
self.ui.lbr_time_periods.set_visible(False)
|
|
||||||
|
|
||||||
self.ui.spb_network_location_refresh_time.set_value(self.prefs.location_refresh_intervals)
|
|
||||||
|
|
||||||
|
|
||||||
# Display the location in the UI
|
|
||||||
current_location = self.location.get_location()
|
|
||||||
self.ui.lb_current_location.set_text("Latitude: " + current_location["latitude"] + \
|
|
||||||
", Longitude: " + current_location["longitude"])
|
|
||||||
|
|
||||||
# Store the location to the preferences
|
|
||||||
self.prefs.latitude_auto = float(current_location["latitude"])
|
|
||||||
self.prefs.longitude_auto = float(current_location["longitude"])
|
|
||||||
|
|
||||||
self.refresh_chart()
|
|
||||||
|
|
||||||
|
|
||||||
def on_toggle_button_custom_location_clicked(self, button: Gtk.ToggleButton):
|
|
||||||
if button.get_active():
|
|
||||||
self.prefs.period_source = PeriodSourceEnum.CUSTOMLOCATION
|
|
||||||
self.ui.tb_network_location.set_active(False)
|
|
||||||
self.ui.tb_time_periods.set_active(False)
|
|
||||||
|
|
||||||
self.ui.lbr_network_location.set_visible(False)
|
|
||||||
self.ui.lbr_current_location.set_visible(False)
|
|
||||||
self.ui.lbr_custom_location_longitude.set_visible(True)
|
|
||||||
self.ui.lbr_custom_location_latitude.set_visible(True)
|
|
||||||
self.ui.lbr_time_periods.set_visible(False)
|
|
||||||
|
|
||||||
self.ui.etr_latitude.set_text(str(self.prefs.latitude_custom))
|
|
||||||
self.ui.etr_longitude.set_text(str(self.prefs.longitude_custom))
|
|
||||||
|
|
||||||
|
|
||||||
def on_toggle_button_time_periods_clicked(self, button: Gtk.ToggleButton):
|
|
||||||
if button.get_active():
|
|
||||||
self.prefs.period_source = PeriodSourceEnum.CUSTOMTIMEPERIODS
|
|
||||||
self.ui.tb_network_location.set_active(False)
|
|
||||||
self.ui.tb_custom_location.set_active(False)
|
|
||||||
|
|
||||||
self.ui.lbr_network_location.set_visible(False)
|
|
||||||
self.ui.lbr_current_location.set_visible(False)
|
|
||||||
self.ui.lbr_custom_location_longitude.set_visible(False)
|
|
||||||
self.ui.lbr_custom_location_latitude.set_visible(False)
|
|
||||||
self.ui.lbr_time_periods.set_visible(True)
|
|
||||||
|
|
||||||
|
|
||||||
for i in range(0, 9):
|
|
||||||
pref_value = self.prefs.period_custom_start_time[i + 1]
|
|
||||||
time_parts = [int(pref_value[0:pref_value.find(":")]), int(pref_value[pref_value.find(":") + 1:])]
|
|
||||||
|
|
||||||
self.ui.spb_periods_hour[i].set_value(time_parts[0])
|
|
||||||
self.ui.spb_periods_minute[i].set_value(time_parts[1])
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def on_spb_period_value_changed(self, spin_button: Gtk.SpinButton):
|
|
||||||
""" Callback if one of the time spinners (minute or hour) will be clicked
|
|
||||||
|
|
||||||
(1) (2) (3)
|
|
||||||
Previous period Current period Next period
|
|
||||||
12:34 - 14:40 14:41 - 16:20 16:21 - 17:30
|
|
||||||
^
|
|
||||||
Variable to change
|
|
||||||
|
|
||||||
Args:
|
|
||||||
spin_button (Gtk.SpinButton): SpinButton which was changed
|
|
||||||
"""
|
|
||||||
spin_button_name = Gtk.Buildable.get_name(spin_button)
|
|
||||||
index = int(spin_button_name[11:12]) - 1
|
|
||||||
|
|
||||||
# Determe time string and store to prefs
|
|
||||||
time_current_start = datetime(2024,1,1, int(self.ui.spb_periods_hour[index].get_value()), int(self.ui.spb_periods_minute[index].get_value()))
|
|
||||||
time_current_start_str = str(time_current_start.hour).rjust(2, '0') + ":" + str(time_current_start.minute).rjust(2, '0')
|
|
||||||
|
|
||||||
self.prefs.period_custom_start_time[index + 1] = time_current_start_str
|
|
||||||
|
|
||||||
|
|
||||||
time_previous_end = time_current_start - timedelta(minutes=1)
|
|
||||||
self.ui.lb_period_end[index].set_text(str(time_previous_end.hour).rjust(2, '0') + ":" + str(time_previous_end.minute).rjust(2, '0'))
|
|
||||||
|
|
||||||
|
|
||||||
self.refresh_chart()
|
|
||||||
|
|
||||||
|
|
||||||
def on_spb_network_location_refresh_time_changed(self, spin_button: Gtk.SpinButton):
|
|
||||||
""" User changed the refresh time of network location estimation
|
|
||||||
|
|
||||||
Args:
|
|
||||||
spin_button (Gtk.SpinButton): The used SpinButton
|
|
||||||
"""
|
|
||||||
self.prefs.location_refresh_intervals = spin_button.get_value()
|
|
||||||
|
|
||||||
|
|
||||||
def on_etr_longitude_changed(self, entry: Gtk.Entry):
|
|
||||||
""" User changes the value of the longitude Entry
|
|
||||||
|
|
||||||
Args:
|
|
||||||
entry (Gtk.Entry): The manipulated Entry object
|
|
||||||
"""
|
|
||||||
try:
|
|
||||||
self.prefs.longitude_custom = float(entry.get_text())
|
|
||||||
self.refresh_chart()
|
|
||||||
except:
|
|
||||||
pass
|
|
||||||
|
|
||||||
|
|
||||||
def on_etr_latitude_changed(self, entry: Gtk.Entry):
|
|
||||||
""" User changes the value of the latitude Entry
|
|
||||||
|
|
||||||
Args:
|
|
||||||
entry (Gtk.Entry): The manipulated Entry object
|
|
||||||
"""
|
|
||||||
try:
|
|
||||||
self.prefs.latitude_custom = float(entry.get_text())
|
|
||||||
self.refresh_chart()
|
|
||||||
except:
|
|
||||||
pass
|
|
||||||
|
|
||||||
|
|
||||||
# Behaviour
|
|
||||||
|
|
||||||
def on_cb_picture_aspect_changed(self, combobox: Gtk.ComboBox):
|
|
||||||
tree_iter = combobox.get_active_iter()
|
|
||||||
|
|
||||||
if tree_iter is not None:
|
|
||||||
model = combobox.get_model()
|
|
||||||
self.prefs.picture_aspect = model[tree_iter][0]
|
|
||||||
|
|
||||||
def on_sw_dynamic_background_color_state_set(self, switch: Gtk.Switch, state):
|
|
||||||
self.prefs.dynamic_background_color = state
|
|
||||||
|
|
||||||
|
|
||||||
# About
|
|
||||||
|
|
||||||
def on_cinnamon_spices_website_button_clicked(self, button: Gtk.Button):
|
|
||||||
""" Callback for the button to navigate to the Cinnamon Spices web page of this project
|
|
||||||
|
|
||||||
Args:
|
|
||||||
button (Gtk.Button): Button which was clicked
|
|
||||||
"""
|
|
||||||
subprocess.Popen(["xdg-open", "https://cinnamon-spices.linuxmint.com/extensions/view/97"])
|
|
||||||
|
|
||||||
|
|
||||||
def on_github_website_button_clicked(self, button: Gtk.Button):
|
|
||||||
""" Callback for the button to navigate to the GitHub web page of this project
|
|
||||||
|
|
||||||
Args:
|
|
||||||
button (Gtk.Button): Button which was clicked
|
|
||||||
"""
|
|
||||||
subprocess.Popen(["xdg-open", "https://github.com/TobiZog/cinnamon-dynamic-wallpaper"])
|
|
||||||
|
|
||||||
|
|
||||||
def on_create_issue_button_clicked(self, button):
|
|
||||||
""" Callback for the button to navigate to the Issues page on GitHub of this project
|
|
||||||
|
|
||||||
Args:
|
|
||||||
button (Gtk.Button): Button which was clicked
|
|
||||||
"""
|
|
||||||
subprocess.Popen(["xdg-open", "https://github.com/TobiZog/cinnamon-dynamic-wallpaper/issues/new"])
|
|
||||||
|
|
||||||
|
|
||||||
def on_ok(self, *args):
|
|
||||||
""" Callback for the OK button in the top bar
|
|
||||||
"""
|
|
||||||
try:
|
|
||||||
self.on_apply()
|
|
||||||
except:
|
|
||||||
pass
|
|
||||||
|
|
||||||
# Close the window
|
|
||||||
self.on_destroy()
|
|
||||||
|
|
||||||
|
|
||||||
def on_apply(self, *args):
|
|
||||||
""" Callback for the Apply button in the top bar
|
|
||||||
"""
|
|
||||||
# Store all values to the JSON file
|
|
||||||
self.prefs.store_preferences()
|
|
||||||
|
|
||||||
# Use the new settings
|
|
||||||
loop = Loop()
|
|
||||||
loop.exchange_image()
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
|
||||||
Preferences().show()
|
|
||||||
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
+45
-2
@@ -1147,7 +1147,7 @@
|
|||||||
<property name="selection-mode">none</property>
|
<property name="selection-mode">none</property>
|
||||||
<property name="activate-on-single-click">False</property>
|
<property name="activate-on-single-click">False</property>
|
||||||
<child>
|
<child>
|
||||||
<object class="GtkListBoxRow" id="lbr_network_location">
|
<object class="GtkListBoxRow" id="lbr_network_refresh_time">
|
||||||
<property name="visible">True</property>
|
<property name="visible">True</property>
|
||||||
<property name="can-focus">True</property>
|
<property name="can-focus">True</property>
|
||||||
<child>
|
<child>
|
||||||
@@ -1173,7 +1173,7 @@
|
|||||||
</packing>
|
</packing>
|
||||||
</child>
|
</child>
|
||||||
<child>
|
<child>
|
||||||
<object class="GtkSpinButton" id="spb_network_location_refresh_time">
|
<object class="GtkSpinButton" id="spb_network_refresh_time">
|
||||||
<property name="visible">True</property>
|
<property name="visible">True</property>
|
||||||
<property name="can-focus">True</property>
|
<property name="can-focus">True</property>
|
||||||
<property name="adjustment">adjustment1</property>
|
<property name="adjustment">adjustment1</property>
|
||||||
@@ -1189,6 +1189,49 @@
|
|||||||
</child>
|
</child>
|
||||||
</object>
|
</object>
|
||||||
</child>
|
</child>
|
||||||
|
<child>
|
||||||
|
<object class="GtkListBoxRow" id="lbr_network_provider">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can-focus">True</property>
|
||||||
|
<child>
|
||||||
|
<object class="GtkBox">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can-focus">False</property>
|
||||||
|
<property name="margin-left">8</property>
|
||||||
|
<property name="margin-right">8</property>
|
||||||
|
<property name="margin-start">8</property>
|
||||||
|
<property name="margin-end">8</property>
|
||||||
|
<property name="margin-top">8</property>
|
||||||
|
<property name="margin-bottom">8</property>
|
||||||
|
<property name="homogeneous">True</property>
|
||||||
|
<child>
|
||||||
|
<object class="GtkLabel">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can-focus">False</property>
|
||||||
|
<property name="halign">start</property>
|
||||||
|
<property name="label" translatable="yes">Location provider</property>
|
||||||
|
</object>
|
||||||
|
<packing>
|
||||||
|
<property name="expand">False</property>
|
||||||
|
<property name="fill">True</property>
|
||||||
|
<property name="position">0</property>
|
||||||
|
</packing>
|
||||||
|
</child>
|
||||||
|
<child>
|
||||||
|
<object class="GtkComboBox" id="cb_network_provider">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can-focus">False</property>
|
||||||
|
</object>
|
||||||
|
<packing>
|
||||||
|
<property name="expand">False</property>
|
||||||
|
<property name="fill">True</property>
|
||||||
|
<property name="position">1</property>
|
||||||
|
</packing>
|
||||||
|
</child>
|
||||||
|
</object>
|
||||||
|
</child>
|
||||||
|
</object>
|
||||||
|
</child>
|
||||||
<child>
|
<child>
|
||||||
<object class="GtkListBoxRow" id="lbr_current_location">
|
<object class="GtkListBoxRow" id="lbr_current_location">
|
||||||
<property name="visible">True</property>
|
<property name="visible">True</property>
|
||||||
@@ -1,22 +0,0 @@
|
|||||||
import urllib.request, json
|
|
||||||
|
|
||||||
class Location():
|
|
||||||
""" Class to handle location requests
|
|
||||||
"""
|
|
||||||
def __init__(self):
|
|
||||||
self.GEO_URL = "https://get.geojs.io/v1/ip/geo.json"
|
|
||||||
|
|
||||||
def get_location(self) -> dict:
|
|
||||||
""" Request the location via network
|
|
||||||
|
|
||||||
Returns:
|
|
||||||
dict: latitude and longitude
|
|
||||||
"""
|
|
||||||
request = urllib.request.urlopen(self.GEO_URL)
|
|
||||||
|
|
||||||
data = json.load(request)
|
|
||||||
|
|
||||||
return {
|
|
||||||
"latitude": data["latitude"],
|
|
||||||
"longitude": data["longitude"]
|
|
||||||
}
|
|
||||||
@@ -1,147 +0,0 @@
|
|||||||
import gi
|
|
||||||
gi.require_version("Gtk", "3.0")
|
|
||||||
from gi.repository import Gtk
|
|
||||||
|
|
||||||
class UI:
|
|
||||||
""" Class to handle UI components and actions
|
|
||||||
"""
|
|
||||||
def __init__(self, builder: Gtk.Builder) -> None:
|
|
||||||
# Page 1
|
|
||||||
self.tb_image_set: Gtk.ToggleButton = builder.get_object("tb_image_set")
|
|
||||||
self.tb_heic_file: Gtk.ToggleButton = builder.get_object("tb_heic_file")
|
|
||||||
self.tb_source_folder: Gtk.ToggleButton = builder.get_object("tb_source_folder")
|
|
||||||
self.img_tb_image_set: Gtk.Image = builder.get_object("img_tb_image_set")
|
|
||||||
self.img_tb_heic_file: Gtk.Image = builder.get_object("img_tb_heic_file")
|
|
||||||
self.img_tb_source_folder: Gtk.Image = builder.get_object("img_tb_source_folder")
|
|
||||||
|
|
||||||
# Image set
|
|
||||||
self.lbr_image_set: Gtk.ListBoxRow = builder.get_object("lbr_image_set")
|
|
||||||
self.cb_image_set: Gtk.ComboBox = builder.get_object("cb_image_set")
|
|
||||||
|
|
||||||
# HEIC file
|
|
||||||
self.lbr_heic_file: Gtk.ListBoxRow = builder.get_object("lbr_heic_file")
|
|
||||||
|
|
||||||
# Source folder
|
|
||||||
self.lbr_source_folder: Gtk.ListBoxRow = builder.get_object("lbr_source_folder")
|
|
||||||
self.btn_source_folder: Gtk.Button = builder.get_object("btn_source_folder")
|
|
||||||
self.lbl_source_folder: Gtk.Label = builder.get_object("lbl_source_folder")
|
|
||||||
|
|
||||||
# Time bar chart
|
|
||||||
self.img_bar_images: Gtk.Image = builder.get_object("img_bar_images")
|
|
||||||
self.etr_periods: list[Gtk.Entry] = [
|
|
||||||
builder.get_object("etr_period_1"), builder.get_object("etr_period_2"),
|
|
||||||
builder.get_object("etr_period_3"), builder.get_object("etr_period_4"),
|
|
||||||
builder.get_object("etr_period_5"), builder.get_object("etr_period_6"),
|
|
||||||
builder.get_object("etr_period_7"), builder.get_object("etr_period_8"),
|
|
||||||
builder.get_object("etr_period_9"), builder.get_object("etr_period_10"),
|
|
||||||
]
|
|
||||||
|
|
||||||
self.img_periods: list[Gtk.Image] = [
|
|
||||||
builder.get_object("img_period_0"), builder.get_object("img_period_1"),
|
|
||||||
builder.get_object("img_period_2"), builder.get_object("img_period_3"),
|
|
||||||
builder.get_object("img_period_4"), builder.get_object("img_period_5"),
|
|
||||||
builder.get_object("img_period_6"), builder.get_object("img_period_7"),
|
|
||||||
builder.get_object("img_period_8"), builder.get_object("img_period_9"),
|
|
||||||
]
|
|
||||||
|
|
||||||
self.cb_periods: list[Gtk.ComboBox] = [
|
|
||||||
builder.get_object("cb_period_0"), builder.get_object("cb_period_1"),
|
|
||||||
builder.get_object("cb_period_2"), builder.get_object("cb_period_3"),
|
|
||||||
builder.get_object("cb_period_4"), builder.get_object("cb_period_5"),
|
|
||||||
builder.get_object("cb_period_6"), builder.get_object("cb_period_7"),
|
|
||||||
builder.get_object("cb_period_8"), builder.get_object("cb_period_9"),
|
|
||||||
]
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#### Page 2: Location & Times
|
|
||||||
self.tb_network_location: Gtk.ToggleButton = builder.get_object("tb_network_location")
|
|
||||||
self.tb_custom_location: Gtk.ToggleButton = builder.get_object("tb_custom_location")
|
|
||||||
self.tb_time_periods: Gtk.ToggleButton = builder.get_object("tb_time_periods")
|
|
||||||
self.img_tb_network_location: Gtk.Image = builder.get_object("img_tb_network_location")
|
|
||||||
self.img_tb_custom_location: Gtk.Image = builder.get_object("img_tb_custom_location")
|
|
||||||
self.img_tb_time_periods: Gtk.Image = builder.get_object("img_tb_time_periods")
|
|
||||||
|
|
||||||
# Network Location
|
|
||||||
self.lb_current_location: Gtk.Label = builder.get_object("lb_current_location")
|
|
||||||
self.lbr_current_location: Gtk.ListBoxRow = builder.get_object("lbr_current_location")
|
|
||||||
self.lbr_network_location: Gtk.ListBoxRow = builder.get_object("lbr_network_location")
|
|
||||||
self.spb_network_location_refresh_time: Gtk.SpinButton = builder.get_object("spb_network_location_refresh_time")
|
|
||||||
|
|
||||||
# Custom location
|
|
||||||
self.lbr_custom_location_longitude: Gtk.ListBoxRow = builder.get_object("lbr_custom_location_longitude")
|
|
||||||
self.lbr_custom_location_latitude: Gtk.ListBoxRow = builder.get_object("lbr_custom_location_latitude")
|
|
||||||
self.lbr_time_periods: Gtk.ListBoxRow = builder.get_object("lbr_time_periods")
|
|
||||||
self.etr_longitude: Gtk.Entry = builder.get_object("etr_longitude")
|
|
||||||
self.etr_latitude: Gtk.Entry = builder.get_object("etr_latitude")
|
|
||||||
self.img_bar_times: Gtk.Image = builder.get_object("img_bar_times")
|
|
||||||
self.spb_periods_hour: list[Gtk.SpinButton] = [
|
|
||||||
builder.get_object("spb_period_1_hour"),
|
|
||||||
builder.get_object("spb_period_2_hour"),
|
|
||||||
builder.get_object("spb_period_3_hour"),
|
|
||||||
builder.get_object("spb_period_4_hour"),
|
|
||||||
builder.get_object("spb_period_5_hour"),
|
|
||||||
builder.get_object("spb_period_6_hour"),
|
|
||||||
builder.get_object("spb_period_7_hour"),
|
|
||||||
builder.get_object("spb_period_8_hour"),
|
|
||||||
builder.get_object("spb_period_9_hour"),
|
|
||||||
]
|
|
||||||
self.spb_periods_minute: list[Gtk.SpinButton] = [
|
|
||||||
builder.get_object("spb_period_1_minute"),
|
|
||||||
builder.get_object("spb_period_2_minute"),
|
|
||||||
builder.get_object("spb_period_3_minute"),
|
|
||||||
builder.get_object("spb_period_4_minute"),
|
|
||||||
builder.get_object("spb_period_5_minute"),
|
|
||||||
builder.get_object("spb_period_6_minute"),
|
|
||||||
builder.get_object("spb_period_7_minute"),
|
|
||||||
builder.get_object("spb_period_8_minute"),
|
|
||||||
builder.get_object("spb_period_9_minute")
|
|
||||||
]
|
|
||||||
self.lb_period_end: list[Gtk.Label] = [
|
|
||||||
builder.get_object("lb_period_0_end"), builder.get_object("lb_period_1_end"),
|
|
||||||
builder.get_object("lb_period_2_end"), builder.get_object("lb_period_3_end"),
|
|
||||||
builder.get_object("lb_period_4_end"), builder.get_object("lb_period_5_end"),
|
|
||||||
builder.get_object("lb_period_6_end"), builder.get_object("lb_period_7_end"),
|
|
||||||
builder.get_object("lb_period_8_end"), builder.get_object("lb_period_9_end"),
|
|
||||||
]
|
|
||||||
|
|
||||||
|
|
||||||
# Page 3: Behaviour
|
|
||||||
self.cb_picture_aspect: Gtk.ComboBox = builder.get_object("cb_picture_aspect")
|
|
||||||
self.sw_dynamic_background_color: Gtk.Switch = builder.get_object("sw_dynamic_background_color")
|
|
||||||
|
|
||||||
|
|
||||||
def set_active_combobox_item(self, combobox: Gtk.ComboBoxText, active_item: str):
|
|
||||||
""" Change active item in combobox by String value
|
|
||||||
|
|
||||||
Args:
|
|
||||||
combobox (Gtk.ComboBoxText): ComboBox to set active
|
|
||||||
active_item (str): String item to set active
|
|
||||||
"""
|
|
||||||
list_store = combobox.get_model()
|
|
||||||
|
|
||||||
for i in range(0, len(list_store)):
|
|
||||||
row = list_store[i]
|
|
||||||
if row[0] == active_item:
|
|
||||||
combobox.set_active(i)
|
|
||||||
|
|
||||||
|
|
||||||
def add_items_to_combo_box(self, combobox: Gtk.ComboBox, items: list):
|
|
||||||
""" Add items to a combo box
|
|
||||||
|
|
||||||
Args:
|
|
||||||
combobox (Gtk.ComboBox): ComboBox where to add the options
|
|
||||||
items (list): Possible options
|
|
||||||
"""
|
|
||||||
model = combobox.get_model()
|
|
||||||
store = Gtk.ListStore(str)
|
|
||||||
|
|
||||||
for image_set in items:
|
|
||||||
store.append([image_set])
|
|
||||||
|
|
||||||
combobox.set_model(store)
|
|
||||||
|
|
||||||
if model == None:
|
|
||||||
renderer_text = Gtk.CellRendererText()
|
|
||||||
combobox.pack_start(renderer_text, True)
|
|
||||||
combobox.add_attribute(renderer_text, "text", 0)
|
|
||||||
File renamed without changes.
@@ -0,0 +1,5 @@
|
|||||||
|
from enum import Enum
|
||||||
|
|
||||||
|
class NetworkLocationProvider(Enum):
|
||||||
|
GEOJS = "https://get.geojs.io/v1/ip/geo.json"
|
||||||
|
IPAPI = "http://ip-api.com/json/?fields=61439"
|
||||||
File renamed without changes.
Loaded 100 of 115 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user