basic alternate layout support

This commit is contained in:
DYefremov
2021-12-19 13:15:58 +03:00
parent 5b6900cae7
commit 1b75034317
4 changed files with 144 additions and 72 deletions

View File

@@ -133,6 +133,12 @@
<attribute name="hidden-when">action-disabled</attribute>
</item>
</section>
<section>
<item>
<attribute name="label" translatable="yes">Alternate layout</attribute>
<attribute name="action">app.set_alternate_layout</attribute>
</item>
</section>
</submenu>
<submenu id="tools_menu">
<attribute name="label" translatable="yes">Tools</attribute>
@@ -323,6 +329,12 @@
<attribute name="hidden-when">action-disabled</attribute>
</item>
</section>
<section>
<item>
<attribute name="label" translatable="yes">Alternate layout</attribute>
<attribute name="action">app.set_alternate_layout</attribute>
</item>
</section>
</submenu>
<submenu>
<attribute name="label" translatable="yes">Tools</attribute>

View File

@@ -126,7 +126,7 @@ class EpgTool(Gtk.Box):
start = int(event.get("e2eventstart", "0"))
start_time = datetime.fromtimestamp(start)
end_time = datetime.fromtimestamp(start + int(event.get("e2eventduration", "0")))
time = "{} - {}".format(start_time.strftime("%A, %H:%M"), end_time.strftime("%H:%M"))
time = f"{start_time.strftime('%A, %H:%M')} - {end_time.strftime('%H:%M')}"
return title, time, desc, event
@@ -223,7 +223,7 @@ class TimerTool(Gtk.Box):
elif self._action is TimerTool.TimerAction.EVENT:
self.set_timer_from_event_data()
else:
log("{} error: No action set for timer!".format(__class__.__name__))
log(f"{__class__.__name__} error: No action set for timer!")
@property
def request(self):
@@ -242,34 +242,34 @@ class TimerTool(Gtk.Box):
s_ref = quote(t_data.get("sRef", ""))
if self._action is TimerTool.TimerAction.EVENT:
args.append("timeraddbyeventid?sRef={}".format(s_ref))
args.append("eventid={}".format(t_data.get("eit", "0")))
args.append("justplay={}".format(t_data.get("justplay", "")))
args.append("tags={}".format(""))
args.append(f"timeraddbyeventid?sRef={s_ref}")
args.append(f"eventid={t_data.get('eit', '0')}")
args.append(f"justplay={t_data.get('justplay', '')}")
args.append(f"tags={''}")
else:
if self._action is TimerTool.TimerAction.ADD:
args.append("timeradd?sRef={}".format(s_ref))
args.append("deleteOldOnSave={}".format(0))
args.append(f"timeradd?sRef={s_ref}")
args.append(f"deleteOldOnSave={0}")
elif self._action is TimerTool.TimerAction.CHANGE:
args.append("timerchange?sRef={}".format(s_ref))
args.append("channelOld={}".format(s_ref))
args.append("beginOld={}".format(self._timer_data.get("e2timebegin", "0")))
args.append("endOld={}".format(self._timer_data.get("e2timeend", "0")))
args.append("deleteOldOnSave={}".format(1))
args.append(f"timerchange?sRef={s_ref}")
args.append(f"channelOld={s_ref}")
args.append(f"beginOld={self._timer_data.get('e2timebegin', '0')}")
args.append(f"endOld={self._timer_data.get('e2timeend', '0')}")
args.append(f"deleteOldOnSave={1}")
args.append("begin={}".format(t_data.get("begin", "")))
args.append("end={}".format(t_data.get("end", "")))
args.append("name={}".format(quote(t_data.get("name", ""))))
args.append("description={}".format(quote(t_data.get("description", ""))))
args.append("tags={}".format(""))
args.append("eit={}".format("0"))
args.append("disabled={}".format(t_data.get("disabled", "1")))
args.append("justplay={}".format(t_data.get("justplay", "1")))
args.append("afterevent={}".format(t_data.get("afterevent", "0")))
args.append("repeated={}".format(TimerTool.get_repetition_flags(self._days_buttons)))
args.append(f"begin={t_data.get('begin', '')}")
args.append(f"end={t_data.get('end', '')}")
args.append(f"name={quote(t_data.get('name', ''))}")
args.append(f"description={quote(t_data.get('description', ''))}")
args.append(f"tags={''}")
args.append(f"eit={'0'}")
args.append(f"disabled={t_data.get('disabled', '1')}")
args.append(f"justplay={t_data.get('justplay', '1')}")
args.append(f"afterevent={t_data.get('afterevent', '0')}")
args.append(f"repeated={TimerTool.get_repetition_flags(self._days_buttons)}")
if self._timer_location_switch.get_active():
args.append("dirname={}".format(self._timer_location_entry.get_text()))
args.append(f"dirname={self._timer_location_entry.get_text()}")
return "&".join(args)
@@ -292,8 +292,7 @@ class TimerTool(Gtk.Box):
self._timer_begins_min_button.set_value(minute)
self._timer_begins_calendar.select_day(date.day)
self._timer_begins_calendar.select_month(date.month - 1, date.year)
self._timer_begins_entry.set_text(
"{}-{}-{} {}:{:02d}".format(date.year, date.month, date.day, hour, minute))
self._timer_begins_entry.set_text(f"{date.year}-{date.month}-{date.day} {hour}:{minute:02d}")
def get_ends_date(self):
date = self._timer_ends_calendar.get_date()
@@ -308,7 +307,7 @@ class TimerTool(Gtk.Box):
self._timer_ends_min_button.set_value(minute)
self._timer_ends_calendar.select_day(date.day)
self._timer_ends_calendar.select_month(date.month - 1, date.year)
self._timer_ends_entry.set_text("{}-{}-{} {}:{:02d}".format(date.year, date.month, date.day, hour, minute))
self._timer_ends_entry.set_text(f"{date.year}-{date.month}-{date.day} {hour}:{minute:02d}")
def set_timer_for_add(self):
self._timer_service_entry.set_text(self._timer_data.get("e2servicename", ""))
@@ -446,7 +445,7 @@ class TimerTool(Gtk.Box):
service = timer.get("e2servicename", "") or ""
start_time = datetime.fromtimestamp(int(timer.get("e2timebegin", "0")))
end_time = datetime.fromtimestamp(int(timer.get("e2timeend", "0")))
time = "{} - {}".format(start_time.strftime("%A, %H:%M"), end_time.strftime("%H:%M"))
time = f"{start_time.strftime('%A, %H:%M')} - {end_time.strftime('%H:%M')}"
return disabled, name, service, time, description, timer
@@ -486,7 +485,7 @@ class TimerTool(Gtk.Box):
@run_idle
def timer_add_edit_callback(self, resp):
if "error_code" in resp:
msg = "Error getting timer status.\n{}".format(resp.get("error_code"))
msg = f"Error getting timer status.\n{resp.get('error_code')}"
self._app.show_error_message(msg)
log(msg)
return
@@ -628,7 +627,7 @@ class TimerTool(Gtk.Box):
service = self._app.current_services.get(fav_id, None)
if service:
if service.service_type == BqServiceType.ALT.name:
msg = "Alternative service.\n\n {}".format(get_message("Not implemented yet!"))
msg = "Alternative service.\n\n {get_message('Not implemented yet!')}"
show_dialog(DialogType.ERROR, transient=self._app._main_window, text=msg)
context.finish(False, False, time)
return
@@ -647,6 +646,7 @@ class RecordingsTool(Gtk.Box):
super().__init__(*args, **kwargs)
self._app = app
self._app.connect("layout-changed", self.on_layout_changed)
self._app.connect("profile-changed", self.init)
self._settings = settings
self._ftp = None
@@ -666,6 +666,8 @@ class RecordingsTool(Gtk.Box):
self._paths_view = builder.get_object("recordings_paths_view")
self._paned = builder.get_object("recordings_paned")
self.pack_start(builder.get_object("recordings_frame"), True, True, 0)
if settings.alternate_layout:
self.on_layout_changed(app, True)
self.init()
self.show()
@@ -674,6 +676,14 @@ class RecordingsTool(Gtk.Box):
self._rec_view.get_model().clear()
self._paths_view.get_model().clear()
def on_layout_changed(self, app, alt_layout):
ch1 = self._paned.get_child1()
ch2 = self._paned.get_child2()
self._paned.remove(ch1)
self._paned.remove(ch2)
self._paned.add1(ch2)
self._paned.add(ch1)
@run_task
def init(self, app=None, arg=None):
GLib.idle_add(self.clear_data)
@@ -801,6 +811,7 @@ class ControlTool(Gtk.Box):
self._settings = settings
self._app = app
self._app.connect("layout-changed", self.on_layout_changed)
self._pix = None
handlers = {"on_volume_changed": self.on_volume_changed,
@@ -810,7 +821,7 @@ class ControlTool(Gtk.Box):
objects=("control_box", "volume_adjustment"))
self.pack_start(builder.get_object("control_box"), True, True, 0)
self._stack = builder.get_object("stack")
self._remote_box = builder.get_object("remote_box")
self._screenshot_area = builder.get_object("screenshot_area")
self._screenshot_button_box = builder.get_object("screenshot_button_box")
self._screenshot_check_button = builder.get_object("screenshot_check_button")
@@ -823,6 +834,9 @@ class ControlTool(Gtk.Box):
self._agc_level_bar = builder.get_object("agc_level_bar")
self._volume_button = builder.get_object("volume_button")
self.init_actions(app)
if settings.alternate_layout:
self.on_layout_changed(app, True)
self.show()
def init_actions(self, app):
@@ -856,6 +870,9 @@ class ControlTool(Gtk.Box):
app.set_action("on_screenshot_video", self.on_screenshot_video)
app.set_action("on_screenshot_osd", self.on_screenshot_osd)
def on_layout_changed(self, app, alt_layout):
self._remote_box.reorder_child(self._remote_box.get_children()[0], 1)
# ***************** Remote controller ********************* #
def on_remote(self, action, state=False):
@@ -875,7 +892,7 @@ class ControlTool(Gtk.Box):
@run_with_delay(0.5)
def on_volume_changed(self, button, value):
self._app.send_http_request(HttpAPI.Request.VOL, "{:.0f}".format(value), self.on_response)
self._app.send_http_request(HttpAPI.Request.VOL, f"{value:.0f}", self.on_response)
def update_volume(self, vol):
if "error_code" in vol:

View File

@@ -1311,6 +1311,8 @@ Author: Dmitriy Yefremov
<object class="GtkPaned" id="data_paned">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="margin_left">5</property>
<property name="margin_right">5</property>
<property name="position_set">True</property>
<property name="wide_handle">True</property>
<signal name="realize" handler="on_data_paned_realize" swapped="no"/>
@@ -1382,7 +1384,6 @@ Author: Dmitriy Yefremov
<object class="GtkFrame" id="services_frame">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="margin_left">5</property>
<property name="label_xalign">0.49000000953674316</property>
<property name="shadow_type">in</property>
<child>
@@ -2262,8 +2263,6 @@ Author: Dmitriy Yefremov
<object class="GtkBox" id="satellite_box">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="margin_left">5</property>
<property name="margin_right">5</property>
<property name="margin_top">2</property>
<property name="orientation">vertical</property>
<signal name="realize" handler="on_satellites_realize" swapped="no"/>
@@ -2281,7 +2280,6 @@ Author: Dmitriy Yefremov
<object class="GtkBox" id="picon_box">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="margin_left">5</property>
<property name="margin_top">2</property>
<property name="orientation">vertical</property>
<signal name="realize" handler="on_picons_realize" swapped="no"/>
@@ -2299,7 +2297,6 @@ Author: Dmitriy Yefremov
<object class="GtkBox" id="epg_box">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="margin_left">5</property>
<property name="margin_top">2</property>
<property name="orientation">vertical</property>
<signal name="realize" handler="on_epg_realize" swapped="no"/>
@@ -2317,7 +2314,6 @@ Author: Dmitriy Yefremov
<object class="GtkBox" id="timers_box">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="margin_left">5</property>
<property name="margin_top">2</property>
<property name="orientation">vertical</property>
<signal name="realize" handler="on_timers_realize" swapped="no"/>
@@ -2335,8 +2331,6 @@ Author: Dmitriy Yefremov
<object class="GtkBox" id="recordings_box">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="margin_left">5</property>
<property name="margin_right">5</property>
<property name="margin_top">2</property>
<property name="orientation">vertical</property>
<signal name="realize" handler="on_recordings_realize" swapped="no"/>
@@ -2354,8 +2348,6 @@ Author: Dmitriy Yefremov
<object class="GtkBox" id="ftp_box">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="margin_left">5</property>
<property name="margin_right">5</property>
<property name="margin_top">2</property>
<property name="orientation">vertical</property>
<signal name="realize" handler="on_ftp_realize" swapped="no"/>
@@ -2373,9 +2365,6 @@ Author: Dmitriy Yefremov
<object class="GtkBox" id="control_box">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="margin_left">5</property>
<property name="margin_right">5</property>
<property name="margin_top">2</property>
<signal name="realize" handler="on_control_realize" swapped="no"/>
<child>
<placeholder/>
@@ -2397,7 +2386,6 @@ Author: Dmitriy Yefremov
<object class="GtkPaned" id="fav_paned">
<property name="width_request">350</property>
<property name="can_focus">False</property>
<property name="margin_right">5</property>
<property name="position_set">True</property>
<property name="wide_handle">True</property>
<child>

View File

@@ -265,6 +265,8 @@ class Application(Gtk.Application):
GObject.TYPE_PYOBJECT, (GObject.TYPE_PYOBJECT,))
GObject.signal_new("change-page", self, GObject.SIGNAL_RUN_LAST,
GObject.TYPE_PYOBJECT, (GObject.TYPE_PYOBJECT,))
GObject.signal_new("layout-changed", self, GObject.SIGNAL_RUN_LAST,
GObject.TYPE_PYOBJECT, (GObject.TYPE_PYOBJECT,))
GObject.signal_new("play-recording", self, GObject.SIGNAL_RUN_LAST,
GObject.TYPE_PYOBJECT, (GObject.TYPE_PYOBJECT,))
GObject.signal_new("play-current", self, GObject.SIGNAL_RUN_LAST,
@@ -280,6 +282,8 @@ class Application(Gtk.Application):
self._main_window = builder.get_object("main_window")
self._stack = builder.get_object("stack")
self._fav_paned = builder.get_object("fav_paned")
self._bq_frame = builder.get_object("bq_frame")
self._fav_frame = builder.get_object("fav_frame")
self._services_view = builder.get_object("services_tree_view")
self._fav_view = builder.get_object("fav_tree_view")
self._bouquets_view = builder.get_object("bouquets_tree_view")
@@ -363,17 +367,13 @@ class Application(Gtk.Application):
self._fav_search_button.connect("toggled", fav_search_provider.on_search_toggled)
# Playback.
self._player_box = PlayerBox(self)
paned = builder.get_object("main_paned")
data_paned = paned.get_child1()
paned.remove(data_paned)
self._player_box.bind_property("visible", self._profile_combo_box, "visible", 4)
paned.pack1(self._player_box, True, False)
paned.pack2(data_paned, True, False)
self._player_box.connect("show", self.on_playback_show)
self._player_box.connect("playback-close", self.on_playback_close)
self._player_box.connect("playback-full-screen", self.on_playback_full_screen)
self._data_paned = builder.get_object("data_paned")
self._data_paned.bind_property("visible", self._status_bar_box, "visible")
self._main_paned = builder.get_object("main_paned")
# Record.
self._record_image = builder.get_object("record_button_image")
# Dynamically active elements depending on the selected view.
@@ -469,6 +469,7 @@ class Application(Gtk.Application):
self.init_actions()
self.set_accels()
self.init_layout()
self.init_drag_and_drop()
self.init_appearance()
@@ -530,6 +531,9 @@ class Application(Gtk.Application):
sa = self.set_state_action("show_control", self.on_page_show, self._settings.get("show_control", True))
sa.connect("change-state", lambda a, v: self._stack_control_box.set_visible(v))
self.bind_property("is-enigma", sa, "enabled")
# Alternate layout.
sa = self.set_state_action("set_alternate_layout", self.set_use_alt_layout, self._settings.alternate_layout)
sa.connect("change-state", self.on_layout_change)
# Menu bar and playback.
self.set_action("on_playback_close", self._player_box.on_close)
if not IS_GNOME_SESSION:
@@ -701,6 +705,27 @@ class Application(Gtk.Application):
self._NEW_COLOR = new_rgb
self._EXTRA_COLOR = extra_rgb
def init_layout(self):
""" Initializes an alternate layout, if enabled. """
if self._settings.alternate_layout:
self._main_paned.pack2(self._player_box, True, False)
self.reverse_main_elements(True)
else:
self._main_paned.remove(self._data_paned)
self._main_paned.pack1(self._player_box, True, False)
self._main_paned.pack2(self._data_paned, True, False)
def init_bq_position(self):
self._fav_paned.remove(self._fav_frame)
self._fav_paned.remove(self._bq_frame)
if self._settings.alternate_layout:
self._fav_paned.pack1(self._bq_frame, True, False)
self._fav_paned.pack2(self._fav_frame, True, False)
else:
self._fav_paned.pack1(self._fav_frame, True, False)
self._fav_paned.pack2(self._bq_frame, True, False)
def init_main_paned_position(self, paned):
""" Initializes starting positions of main paned widgets. """
width = paned.get_allocated_width()
@@ -791,40 +816,47 @@ class Application(Gtk.Application):
# ************** Pages initialization *************** #
def on_satellites_realize(self, box):
self._satellite_tool = SatellitesTool(self, self._settings)
box.pack_start(self._satellite_tool, True, True, 0)
if not self._satellite_tool:
self._satellite_tool = SatellitesTool(self, self._settings)
box.pack_start(self._satellite_tool, True, True, 0)
def on_picons_realize(self, box):
ids = {}
if self._s_type is SettingsType.ENIGMA_2:
for r in self._services_model:
data = r[Column.SRV_PICON_ID].split("_")
ids[f"{data[3]}:{data[5]}:{data[6]}"] = r[Column.SRV_PICON_ID]
if not self._picon_manager:
ids = {}
if self._s_type is SettingsType.ENIGMA_2:
for r in self._services_model:
data = r[Column.SRV_PICON_ID].split("_")
ids[f"{data[3]}:{data[5]}:{data[6]}"] = r[Column.SRV_PICON_ID]
self._picon_manager = PiconManager(self, self._settings, ids, self._sat_positions)
box.pack_start(self._picon_manager, True, True, 0)
self._picon_manager = PiconManager(self, self._settings, ids, self._sat_positions)
box.pack_start(self._picon_manager, True, True, 0)
def on_epg_realize(self, box):
self._epg_tool = EpgTool(self)
box.pack_start(self._epg_tool, True, True, 0)
if not self._epg_tool:
self._epg_tool = EpgTool(self)
box.pack_start(self._epg_tool, True, True, 0)
def on_timers_realize(self, box):
self._timers_tool = TimerTool(self, self._http_api)
box.pack_start(self._timers_tool, True, True, 0)
if not self._timers_tool:
self._timers_tool = TimerTool(self, self._http_api)
box.pack_start(self._timers_tool, True, True, 0)
def on_recordings_realize(self, box):
self._recordings_tool = RecordingsTool(self, self._settings)
box.pack_start(self._recordings_tool, True, True, 0)
self._player_box.connect("play", self._recordings_tool.on_playback)
self._player_box.connect("playback-close", self._recordings_tool.on_playback_close)
if not self._recordings_tool:
self._recordings_tool = RecordingsTool(self, self._settings)
box.pack_start(self._recordings_tool, True, True, 0)
self._player_box.connect("play", self._recordings_tool.on_playback)
self._player_box.connect("playback-close", self._recordings_tool.on_playback_close)
def on_ftp_realize(self, box):
self._ftp_client = FtpClientBox(self, self._settings)
box.pack_start(self._ftp_client, True, True, 0)
if not self._ftp_client:
self._ftp_client = FtpClientBox(self, self._settings)
box.pack_start(self._ftp_client, True, True, 0)
def on_control_realize(self, box):
self._control_tool = ControlTool(self, self._http_api, self._settings)
box.pack_start(self._control_tool, True, True, 0)
if not self._control_tool:
self._control_tool = ControlTool(self, self._settings)
box.pack_start(self._control_tool, True, True, 0)
def on_telnet_realize(self, box):
box.pack_start(TelnetClient(self), True, True, 0)
@@ -845,6 +877,29 @@ class Application(Gtk.Application):
def on_page_change(self, app, page_name):
self._stack.set_visible_child_name(page_name)
def set_use_alt_layout(self, action, value):
action.set_state(value)
self._settings.alternate_layout = bool(value)
@run_idle
def on_layout_change(self, action, value):
is_alt = bool(value)
self.reverse_main_elements(is_alt)
if self._settings.play_streams_mode is PlayStreamsMode.BUILT_IN:
msg = get_message("Layout of elements has been changed!")
msg = f"{msg} {get_message('Restart the program to apply all changes.')}"
self.show_info_message(msg, Gtk.MessageType.WARNING)
self.emit("layout-changed", is_alt)
def reverse_main_elements(self, alt_layout):
self._data_paned.remove(self._stack)
self._data_paned.remove(self._fav_paned)
self._data_paned.pack1(self._fav_paned if alt_layout else self._stack, True, False)
self._data_paned.pack2(self._stack if alt_layout else self._fav_paned, True, False)
self.init_bq_position()
# ***************** Copy - Cut - Paste ********************* #
def on_services_copy(self, view):