added recordings page

This commit is contained in:
DYefremov
2021-09-02 12:20:29 +03:00
parent 9fc07308ab
commit cb8ec264cc
4 changed files with 427 additions and 93 deletions

View File

@@ -121,7 +121,6 @@ Author: Dmitriy Yefremov
<object class="GtkTreeView" id="epg_view"> <object class="GtkTreeView" id="epg_view">
<property name="visible">True</property> <property name="visible">True</property>
<property name="can_focus">True</property> <property name="can_focus">True</property>
<property name="hexpand">True</property>
<property name="model">epg_model</property> <property name="model">epg_model</property>
<property name="enable_grid_lines">both</property> <property name="enable_grid_lines">both</property>
<property name="tooltip_column">2</property> <property name="tooltip_column">2</property>
@@ -1058,100 +1057,301 @@ Author: Dmitriy Yefremov
</packing> </packing>
</child> </child>
</object> </object>
<object class="GtkBox" id="recordings_box"> <object class="GtkListStore" id="rec_paths_model">
<columns>
<!-- column-name icon -->
<column type="GdkPixbuf"/>
<!-- column-name title -->
<column type="gchararray"/>
<!-- column-name path -->
<column type="gchararray"/>
</columns>
</object>
<object class="GtkListStore" id="recordings_model">
<columns>
<!-- column-name service -->
<column type="gchararray"/>
<!-- column-name title -->
<column type="gchararray"/>
<!-- column-name time -->
<column type="gchararray"/>
<!-- column-name length -->
<column type="gchararray"/>
<!-- column-name file -->
<column type="gchararray"/>
<!-- column-name desc -->
<column type="gchararray"/>
<!-- column-name data -->
<column type="PyObject"/>
</columns>
</object>
<object class="GtkFrame" id="recordings_frame">
<property name="visible">True</property> <property name="visible">True</property>
<property name="can_focus">False</property> <property name="can_focus">False</property>
<property name="orientation">vertical</property> <property name="margin_top">2</property>
<property name="spacing">5</property> <property name="label_xalign">0.49000000953674316</property>
<property name="shadow_type">in</property>
<child> <child>
<object class="GtkScrolledWindow" id="recordings_view_scrolled_window"> <object class="GtkBox" id="recordings_box">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="shadow_type">in</property>
<child>
<object class="GtkViewport" id="recordings_view_port">
<property name="visible">True</property>
<property name="can_focus">False</property>
<child>
<object class="GtkListBox" id="recordings_list_box">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="selection_mode">multiple</property>
<property name="activate_on_single_click">False</property>
<signal name="button-press-event" handler="on_recordings_press" swapped="no"/>
</object>
</child>
</object>
</child>
</object>
<packing>
<property name="expand">True</property>
<property name="fill">True</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkComboBoxText" id="recordings_dir_box">
<property name="visible">True</property>
<property name="can_focus">False</property>
<signal name="changed" handler="on_recordings_dir_changed" swapped="no"/>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">1</property>
</packing>
</child>
<child>
<object class="GtkBox" id="recordings_action_box">
<property name="visible">True</property> <property name="visible">True</property>
<property name="can_focus">False</property> <property name="can_focus">False</property>
<property name="margin_left">5</property>
<property name="margin_right">5</property>
<property name="margin_top">5</property>
<property name="margin_bottom">5</property>
<property name="orientation">vertical</property>
<property name="spacing">5</property> <property name="spacing">5</property>
<child> <child>
<object class="GtkSearchEntry" id="recordings_filter_entry"> <object class="GtkBox" id="recordings_header_box">
<property name="visible">True</property> <property name="visible">True</property>
<property name="can_focus">True</property> <property name="can_focus">False</property>
<property name="primary_icon_name">tools-check-spelling</property> <property name="margin_left">15</property>
<property name="primary_icon_activatable">False</property> <property name="margin_right">15</property>
<property name="primary_icon_sensitive">False</property> <property name="margin_top">5</property>
<property name="placeholder_text" translatable="yes">Filter</property> <property name="margin_bottom">5</property>
<signal name="search-changed" handler="on_recording_filter_changed" swapped="no"/> <property name="spacing">5</property>
</object>
<packing>
<property name="expand">True</property>
<property name="fill">True</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkButton" id="recordings_remove_button">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
<property name="tooltip_text" translatable="yes">Remove</property>
<property name="action_name">app.on_recording_remove</property>
<property name="always_show_image">True</property>
<child> <child>
<object class="GtkImage" id="remove_recording_image"> <object class="GtkButton" id="recordings_remove_button">
<property name="visible">True</property> <property name="visible">True</property>
<property name="can_focus">False</property> <property name="can_focus">True</property>
<property name="icon_name">user-trash</property> <property name="receives_default">True</property>
<property name="tooltip_text" translatable="yes">Remove</property>
<property name="always_show_image">True</property>
<signal name="clicked" handler="on_recording_remove" swapped="no"/>
<child>
<object class="GtkImage" id="remove_recording_image">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="icon_name">user-trash-symbolic</property>
</object>
</child>
</object> </object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkSearchEntry" id="recordings_filter_entry">
<property name="sensitive">False</property>
<property name="can_focus">True</property>
<property name="primary_icon_name">edit-find-replace-symbolic</property>
<property name="primary_icon_activatable">False</property>
<property name="primary_icon_sensitive">False</property>
<property name="placeholder_text" translatable="yes">Filter</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">2</property>
</packing>
</child> </child>
</object> </object>
<packing> <packing>
<property name="expand">False</property> <property name="expand">False</property>
<property name="fill">True</property> <property name="fill">True</property>
<property name="pack_type">end</property> <property name="position">0</property>
<property name="position">2</property> </packing>
</child>
<child>
<object class="GtkPaned" id="recordings_paned">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="wide_handle">True</property>
<child>
<object class="GtkScrolledWindow" id="recordings_view_scrolled_window">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="shadow_type">in</property>
<child>
<object class="GtkTreeView" id="recordings_view">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="model">recordings_model</property>
<property name="enable_grid_lines">both</property>
<property name="tooltip_column">5</property>
<signal name="row-activated" handler="on_recordings_activated" swapped="no"/>
<child internal-child="selection">
<object class="GtkTreeSelection" id="recordings_view_selection">
<property name="mode">multiple</property>
</object>
</child>
<child>
<object class="GtkTreeViewColumn" id="rec_service_column">
<property name="min_width">100</property>
<property name="title" translatable="yes">Service</property>
<property name="alignment">0.5</property>
<child>
<object class="GtkCellRendererText" id="rec_service_renderer">
<property name="xalign">0.49000000953674316</property>
</object>
<attributes>
<attribute name="text">0</attribute>
</attributes>
</child>
</object>
</child>
<child>
<object class="GtkTreeViewColumn" id="rec_title_column">
<property name="sizing">autosize</property>
<property name="min_width">150</property>
<property name="title" translatable="yes">Title</property>
<property name="alignment">0.5</property>
<child>
<object class="GtkCellRendererText" id="rec_title_renderer">
<property name="xpad">5</property>
</object>
<attributes>
<attribute name="text">1</attribute>
</attributes>
</child>
</object>
</child>
<child>
<object class="GtkTreeViewColumn" id="rec_time_column">
<property name="min_width">100</property>
<property name="title" translatable="yes">Time</property>
<property name="alignment">0.5</property>
<child>
<object class="GtkCellRendererText" id="rec_time_renderer">
<property name="xpad">5</property>
</object>
<attributes>
<attribute name="text">2</attribute>
</attributes>
</child>
</object>
</child>
<child>
<object class="GtkTreeViewColumn" id="rec_len_column">
<property name="min_width">100</property>
<property name="title" translatable="yes">Length</property>
<property name="alignment">0.5</property>
<child>
<object class="GtkCellRendererText" id="rec_len_renderer">
<property name="xalign">0.49000000953674316</property>
</object>
<attributes>
<attribute name="text">3</attribute>
</attributes>
</child>
</object>
</child>
<child>
<object class="GtkTreeViewColumn" id="rec_file_column">
<property name="resizable">True</property>
<property name="min_width">100</property>
<property name="title" translatable="yes">File</property>
<property name="expand">True</property>
<property name="alignment">0.5</property>
<child>
<object class="GtkCellRendererText" id="rec_file_renderer">
<property name="ellipsize">end</property>
</object>
<attributes>
<attribute name="text">4</attribute>
</attributes>
</child>
</object>
</child>
<child>
<object class="GtkTreeViewColumn" id="rec_desc_column">
<property name="resizable">True</property>
<property name="title" translatable="yes">Description</property>
<property name="expand">True</property>
<property name="alignment">0.5</property>
<child>
<object class="GtkCellRendererText" id="rec_desc_renderer">
<property name="ellipsize">end</property>
</object>
<attributes>
<attribute name="text">5</attribute>
</attributes>
</child>
</object>
</child>
</object>
</child>
</object>
<packing>
<property name="resize">True</property>
<property name="shrink">False</property>
</packing>
</child>
<child>
<object class="GtkScrolledWindow" id="paths_view_scrolled_window">
<property name="width_request">250</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="shadow_type">in</property>
<property name="min_content_height">100</property>
<child>
<object class="GtkTreeView" id="recordings_paths_view">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="model">rec_paths_model</property>
<property name="search_column">1</property>
<property name="rubber_banding">True</property>
<property name="activate_on_single_click">True</property>
<signal name="button-press-event" handler="on_path_press" swapped="no"/>
<signal name="row-activated" handler="on_path_activated" swapped="no"/>
<child internal-child="selection">
<object class="GtkTreeSelection" id="rec_paths_selection">
<property name="mode">multiple</property>
</object>
</child>
<child>
<object class="GtkTreeViewColumn" id="rec_paths_column">
<property name="resizable">True</property>
<property name="min_width">100</property>
<property name="title" translatable="yes">Paths</property>
<property name="expand">True</property>
<property name="clickable">True</property>
<property name="alignment">0.5</property>
<property name="sort_column_id">1</property>
<child>
<object class="GtkCellRendererPixbuf" id="ftp_icon_column_renderer">
<property name="xalign">0.019999999552965164</property>
</object>
<attributes>
<attribute name="pixbuf">0</attribute>
</attributes>
</child>
<child>
<object class="GtkCellRendererText" id="ftp_name_column_renderer">
<property name="xalign">0.019999999552965164</property>
<property name="ellipsize">end</property>
</object>
<attributes>
<attribute name="text">1</attribute>
</attributes>
</child>
</object>
</child>
</object>
</child>
</object>
<packing>
<property name="resize">False</property>
<property name="shrink">True</property>
</packing>
</child>
</object>
<packing>
<property name="expand">True</property>
<property name="fill">True</property>
<property name="position">1</property>
</packing> </packing>
</child> </child>
</object> </object>
<packing> </child>
<property name="expand">False</property> <child type="label">
<property name="fill">False</property> <object class="GtkLabel" id="recordings_label">
<property name="position">2</property> <property name="visible">True</property>
</packing> <property name="can_focus">False</property>
<property name="label" translatable="yes">Recordings</property>
</object>
</child> </child>
</object> </object>
<object class="GtkListStore" id="timer_model"> <object class="GtkListStore" id="timer_model">
@@ -1260,7 +1460,6 @@ Author: Dmitriy Yefremov
<object class="GtkTreeView" id="timer_view"> <object class="GtkTreeView" id="timer_view">
<property name="visible">True</property> <property name="visible">True</property>
<property name="can_focus">True</property> <property name="can_focus">True</property>
<property name="hexpand">True</property>
<property name="model">timer_model</property> <property name="model">timer_model</property>
<property name="enable_grid_lines">both</property> <property name="enable_grid_lines">both</property>
<property name="tooltip_column">3</property> <property name="tooltip_column">3</property>

View File

@@ -29,14 +29,15 @@
""" Receiver control module via HTTP API. """ """ Receiver control module via HTTP API. """
import os import os
from datetime import datetime from datetime import datetime
from ftplib import all_errors
from urllib.parse import quote from urllib.parse import quote
from gi.repository import GLib from gi.repository import GLib
from .dialogs import get_builder from .dialogs import get_builder, show_dialog, DialogType
from .uicommons import Gtk, Gdk, UI_RESOURCES_PATH, Page from .uicommons import Gtk, Gdk, UI_RESOURCES_PATH, Page
from ..commons import run_task, run_with_delay, log, run_idle from ..commons import run_task, run_with_delay, log, run_idle
from ..connections import HttpAPI from ..connections import HttpAPI, UtfFTP
class EpgBox(Gtk.Box): class EpgBox(Gtk.Box):
@@ -51,7 +52,7 @@ class EpgBox(Gtk.Box):
builder = get_builder(UI_RESOURCES_PATH + "control.glade", handlers, objects=("epg_frame", "epg_model")) builder = get_builder(UI_RESOURCES_PATH + "control.glade", handlers, objects=("epg_frame", "epg_model"))
self._view = builder.get_object("epg_view") self._view = builder.get_object("epg_view")
self.add(builder.get_object("epg_frame")) self.pack_start(builder.get_object("epg_frame"), True, True, 0)
self.show() self.show()
def on_epg_press(self, list_box, event): def on_epg_press(self, list_box, event):
@@ -96,7 +97,7 @@ class TimersBox(Gtk.Box):
builder = get_builder(UI_RESOURCES_PATH + "control.glade", handlers, objects=("timers_frame", "timer_model")) builder = get_builder(UI_RESOURCES_PATH + "control.glade", handlers, objects=("timers_frame", "timer_model"))
self._view = builder.get_object("timer_view") self._view = builder.get_object("timer_view")
self._remove_button = builder.get_object("timer_remove_button") self._remove_button = builder.get_object("timer_remove_button")
self.add(builder.get_object("timers_frame")) self.pack_start(builder.get_object("timers_frame"), True, True, 0)
self.show() self.show()
def update_timer_list(self, app, page): def update_timer_list(self, app, page):
@@ -123,7 +124,143 @@ class TimersBox(Gtk.Box):
return name, service, time, description, timer return name, service, time, description, timer
class ControlBox(Gtk.HBox): class RecordingsBox(Gtk.Box):
ROOT = ".."
DEFAULT_PATH = "/hdd"
def __init__(self, app, http_api, settings, *args, **kwargs):
super().__init__(*args, **kwargs)
self._http_api = http_api
self._app = app
self._app.connect("profile-changed", self.init)
self._settings = settings
self._ftp = None
# Icon.
theme = Gtk.IconTheme.get_default()
icon = "folder-symbolic"
self._icon = theme.load_icon(icon, 32, 0) if theme.lookup_icon(icon, 32, 0) else None
handlers = {"on_path_press": self.on_path_press,
"on_path_activated": self.on_path_activated,
"on_recordings_activated": self.on_recordings_activated,
"on_recording_remove": self.on_recording_remove}
builder = get_builder(UI_RESOURCES_PATH + "control.glade", handlers,
objects=("recordings_frame", "recordings_model", "rec_paths_model"))
self._rec_view = builder.get_object("recordings_view")
self._paths_view = builder.get_object("recordings_paths_view")
self.pack_start(builder.get_object("recordings_frame"), True, True, 0)
self.init()
self.show()
def clear_data(self):
self._rec_view.get_model().clear()
self._paths_view.get_model().clear()
@run_task
def init(self, app=None, arg=None):
GLib.idle_add(self.clear_data)
try:
if self._ftp:
self._ftp.close()
self._ftp = UtfFTP(host=self._settings.host, user=self._settings.user, passwd=self._settings.password)
self._ftp.encoding = "utf-8"
except all_errors:
pass # NOP
else:
self.init_paths(self.DEFAULT_PATH)
@run_idle
def init_paths(self, path=None):
self.clear_data()
if not self._ftp:
return
if path:
try:
self._ftp.cwd(path)
except all_errors as e:
pass
files = []
try:
self._ftp.dir(files.append)
except all_errors as e:
log(e)
else:
self.append_paths(files)
@run_idle
def append_paths(self, files):
model = self._paths_view.get_model()
model.clear()
model.append((None, self.ROOT, self._ftp.pwd()))
for f in files:
f_data = f.split()
f_type = f_data[0][0]
if f_type == "d":
model.append((self._icon, f_data[-1], self._ftp.pwd()))
def on_path_activated(self, view, path, column):
row = view.get_model()[path][:]
path = "{}/{}".format(row[-1], row[1])
self._http_api.send(HttpAPI.Request.RECORDINGS, quote(path), self.update_recordings_data)
def on_path_press(self, view, event):
target = view.get_path_at_pos(event.x, event.y)
if not target or event.button != Gdk.BUTTON_PRIMARY:
return
if event.get_event_type() == Gdk.EventType.DOUBLE_BUTTON_PRESS:
self.init_paths(self._paths_view.get_model()[target[0]][1])
@run_idle
def update_recordings_data(self, recordings):
model = self._rec_view.get_model()
model.clear()
list(map(model.append, (self.get_recordings_row(r) for r in recordings.get("recordings", []))))
def get_recordings_row(self, rec):
service = rec.get("e2servicename")
title = rec.get("e2title", "")
time = datetime.fromtimestamp(int(rec.get("e2time", "0"))).strftime("%A, %H:%M")
length = rec.get("e2length", "0")
file = rec.get("e2filename", "")
desc = rec.get("e2description", "")
return service, title, time, length, file, desc, rec
def on_recordings_activated(self, view, path, column):
rec = view.get_model()[path][-1]
self._http_api.send(HttpAPI.Request.STREAM_TS, rec.get("e2filename", ""), self.on_play_recording)
def on_play_recording(self, m3u):
url = self._app.get_url_from_m3u(m3u)
if url:
self._app.play(url)
def on_recording_remove(self, action, value=None):
""" Removes recordings via FTP. """
if show_dialog(DialogType.QUESTION, self._app.app_window) != Gtk.ResponseType.OK:
return
model, paths = self._rec_view.get_selection().get_selected_rows()
if paths and self._ftp:
for file, itr in ((model[p][-1].get("e2filename", ""), model.get_iter(p)) for p in paths):
resp = self._ftp.delete_file(file)
if resp.startswith("2"):
GLib.idle_add(model.remove, itr)
else:
self._app.show_error_message(resp)
break
class ControlBox(Gtk.Box):
def __init__(self, app, http_api, settings, *args, **kwargs): def __init__(self, app, http_api, settings, *args, **kwargs):
super().__init__(*args, **kwargs) super().__init__(*args, **kwargs)
@@ -137,7 +274,7 @@ class ControlBox(Gtk.HBox):
builder = get_builder(UI_RESOURCES_PATH + "control.glade", handlers, builder = get_builder(UI_RESOURCES_PATH + "control.glade", handlers,
objects=("control_box", "volume_adjustment")) objects=("control_box", "volume_adjustment"))
self.add(builder.get_object("control_box")) self.pack_start(builder.get_object("control_box"), True, True, 0)
self._stack = builder.get_object("stack") self._stack = builder.get_object("stack")
self._screenshot_image = builder.get_object("screenshot_image") self._screenshot_image = builder.get_object("screenshot_image")
self._screenshot_button_box = builder.get_object("screenshot_button_box") self._screenshot_button_box = builder.get_object("screenshot_button_box")

View File

@@ -1480,7 +1480,6 @@ Author: Dmitriy Yefremov
<property name="visible">True</property> <property name="visible">True</property>
<property name="can_focus">False</property> <property name="can_focus">False</property>
<property name="margin_left">5</property> <property name="margin_left">5</property>
<property name="margin_top">5</property>
<property name="margin_bottom">5</property> <property name="margin_bottom">5</property>
<property name="label_xalign">0.49000000953674316</property> <property name="label_xalign">0.49000000953674316</property>
<property name="shadow_type">in</property> <property name="shadow_type">in</property>
@@ -2160,7 +2159,6 @@ Author: Dmitriy Yefremov
<property name="can_focus">False</property> <property name="can_focus">False</property>
<property name="margin_left">5</property> <property name="margin_left">5</property>
<property name="margin_right">5</property> <property name="margin_right">5</property>
<property name="margin_top">5</property>
<property name="margin_bottom">5</property> <property name="margin_bottom">5</property>
<property name="orientation">vertical</property> <property name="orientation">vertical</property>
<signal name="realize" handler="on_satellites_realize" swapped="no"/> <signal name="realize" handler="on_satellites_realize" swapped="no"/>
@@ -2179,7 +2177,6 @@ Author: Dmitriy Yefremov
<property name="visible">True</property> <property name="visible">True</property>
<property name="can_focus">False</property> <property name="can_focus">False</property>
<property name="margin_left">5</property> <property name="margin_left">5</property>
<property name="margin_top">5</property>
<property name="margin_bottom">5</property> <property name="margin_bottom">5</property>
<property name="orientation">vertical</property> <property name="orientation">vertical</property>
<signal name="realize" handler="on_picons_realize" swapped="no"/> <signal name="realize" handler="on_picons_realize" swapped="no"/>
@@ -2385,7 +2382,6 @@ Author: Dmitriy Yefremov
<property name="visible">True</property> <property name="visible">True</property>
<property name="can_focus">False</property> <property name="can_focus">False</property>
<property name="margin_left">5</property> <property name="margin_left">5</property>
<property name="margin_top">5</property>
<property name="margin_bottom">5</property> <property name="margin_bottom">5</property>
<property name="orientation">vertical</property> <property name="orientation">vertical</property>
<signal name="realize" handler="on_epg_realize" swapped="no"/> <signal name="realize" handler="on_epg_realize" swapped="no"/>
@@ -2404,7 +2400,6 @@ Author: Dmitriy Yefremov
<property name="visible">True</property> <property name="visible">True</property>
<property name="can_focus">False</property> <property name="can_focus">False</property>
<property name="margin_left">5</property> <property name="margin_left">5</property>
<property name="margin_top">5</property>
<property name="margin_bottom">5</property> <property name="margin_bottom">5</property>
<property name="orientation">vertical</property> <property name="orientation">vertical</property>
<signal name="realize" handler="on_timers_realize" swapped="no"/> <signal name="realize" handler="on_timers_realize" swapped="no"/>
@@ -2424,9 +2419,9 @@ Author: Dmitriy Yefremov
<property name="can_focus">False</property> <property name="can_focus">False</property>
<property name="margin_left">5</property> <property name="margin_left">5</property>
<property name="margin_right">5</property> <property name="margin_right">5</property>
<property name="margin_top">5</property>
<property name="margin_bottom">5</property> <property name="margin_bottom">5</property>
<property name="orientation">vertical</property> <property name="orientation">vertical</property>
<signal name="realize" handler="on_recordings_realize" swapped="no"/>
<child> <child>
<placeholder/> <placeholder/>
</child> </child>
@@ -2443,7 +2438,6 @@ Author: Dmitriy Yefremov
<property name="can_focus">False</property> <property name="can_focus">False</property>
<property name="margin_left">5</property> <property name="margin_left">5</property>
<property name="margin_right">5</property> <property name="margin_right">5</property>
<property name="margin_top">5</property>
<property name="margin_bottom">5</property> <property name="margin_bottom">5</property>
<property name="orientation">vertical</property> <property name="orientation">vertical</property>
<signal name="realize" handler="on_ftp_realize" swapped="no"/> <signal name="realize" handler="on_ftp_realize" swapped="no"/>
@@ -2463,7 +2457,6 @@ Author: Dmitriy Yefremov
<property name="can_focus">False</property> <property name="can_focus">False</property>
<property name="margin_left">5</property> <property name="margin_left">5</property>
<property name="margin_right">5</property> <property name="margin_right">5</property>
<property name="margin_top">5</property>
<property name="margin_bottom">5</property> <property name="margin_bottom">5</property>
<signal name="realize" handler="on_control_realize" swapped="no"/> <signal name="realize" handler="on_control_realize" swapped="no"/>
<child> <child>
@@ -2486,7 +2479,6 @@ Author: Dmitriy Yefremov
<object class="GtkPaned" id="fav_paned"> <object class="GtkPaned" id="fav_paned">
<property name="can_focus">False</property> <property name="can_focus">False</property>
<property name="margin_right">5</property> <property name="margin_right">5</property>
<property name="margin_top">5</property>
<property name="margin_bottom">5</property> <property name="margin_bottom">5</property>
<property name="wide_handle">True</property> <property name="wide_handle">True</property>
<child> <child>

View File

@@ -48,7 +48,7 @@ from app.eparser.neutrino.bouquets import BqType
from app.settings import (SettingsType, Settings, SettingsException, PlayStreamsMode, SettingsReadException, from app.settings import (SettingsType, Settings, SettingsException, PlayStreamsMode, SettingsReadException,
IS_DARWIN) IS_DARWIN)
from app.tools.media import Player, Recorder from app.tools.media import Player, Recorder
from app.ui.control import ControlBox, EpgBox, TimersBox from app.ui.control import ControlBox, EpgBox, TimersBox, RecordingsBox
from app.ui.epg_dialog import EpgDialog from app.ui.epg_dialog import EpgDialog
from app.ui.ftp import FtpClientBox from app.ui.ftp import FtpClientBox
from app.ui.transmitter import LinksTransmitter from app.ui.transmitter import LinksTransmitter
@@ -201,6 +201,7 @@ class Application(Gtk.Application):
"on_picons_realize": self.on_picons_realize, "on_picons_realize": self.on_picons_realize,
"on_epg_realize": self.on_epg_realize, "on_epg_realize": self.on_epg_realize,
"on_timers_realize": self.on_timers_realize, "on_timers_realize": self.on_timers_realize,
"on_recordings_realize": self.on_recordings_realize,
"on_control_realize": self.on_control_realize, "on_control_realize": self.on_control_realize,
"on_ftp_realize": self.on_ftp_realize, "on_ftp_realize": self.on_ftp_realize,
"on_visible_page": self.on_visible_page} "on_visible_page": self.on_visible_page}
@@ -236,6 +237,7 @@ class Application(Gtk.Application):
self._picon_manager = None self._picon_manager = None
self._epg_box = None self._epg_box = None
self._timers_box = None self._timers_box = None
self._recordings_box = None
self._control_box = None self._control_box = None
self._ftp_client = None self._ftp_client = None
# Player # Player
@@ -743,6 +745,10 @@ class Application(Gtk.Application):
self._epg_box = TimersBox(self, self._http_api) self._epg_box = TimersBox(self, self._http_api)
box.pack_start(self._epg_box, True, True, 0) box.pack_start(self._epg_box, True, True, 0)
def on_recordings_realize(self, box):
self._recordings_box = RecordingsBox(self, self._http_api, self._settings)
box.pack_start(self._recordings_box, True, True, 0)
def on_ftp_realize(self, box): def on_ftp_realize(self, box):
self._ftp_client = FtpClientBox(self, self._settings) self._ftp_client = FtpClientBox(self, self._settings)
box.pack_start(self._ftp_client, True, True, 0) box.pack_start(self._ftp_client, True, True, 0)