mirror of
https://github.com/DYefremov/DemonEditor.git
synced 2026-07-14 07:13:28 +02:00
reworking of built-in player [GStreamer support]
This commit is contained in:
@@ -6,103 +6,102 @@ from app.commons import run_task, log, _DATE_FORMAT
|
||||
|
||||
|
||||
class Player:
|
||||
""" Simple wrapper for VLC media player. """
|
||||
__VLC_INSTANCE = None
|
||||
""" Simple wrapper for GStreamer playbin. """
|
||||
__INSTANCE = None
|
||||
|
||||
def __init__(self, mode, rewind_cb, position_cb, error_cb, playing_cb):
|
||||
try:
|
||||
from app.tools import vlc
|
||||
from app.tools.vlc import EventType
|
||||
import gi
|
||||
|
||||
gi.require_version("Gst", "1.0")
|
||||
gi.require_version("GstVideo", "1.0")
|
||||
from gi.repository import Gst, GstVideo
|
||||
except OSError as e:
|
||||
log("{}: Load library error: {}".format(__class__.__name__, e))
|
||||
raise ImportError
|
||||
else:
|
||||
# initialize GStreamer
|
||||
Gst.init(sys.argv)
|
||||
self.STATE = Gst.State
|
||||
self.STAT_RETURN = Gst.StateChangeReturn
|
||||
|
||||
self._mode = mode
|
||||
self._is_playing = False
|
||||
args = "--quiet {}".format("" if sys.platform == "darwin" else "--no-xlib")
|
||||
self._player = vlc.Instance(args).media_player_new()
|
||||
ev_mgr = self._player.event_manager()
|
||||
self._player = Gst.ElementFactory.make("playbin", "player")
|
||||
|
||||
if rewind_cb:
|
||||
# TODO look other EventType options
|
||||
ev_mgr.event_attach(EventType.MediaPlayerBuffering,
|
||||
lambda et, p: rewind_cb(p.get_media().get_duration()),
|
||||
self._player)
|
||||
if position_cb:
|
||||
ev_mgr.event_attach(EventType.MediaPlayerTimeChanged,
|
||||
lambda et, p: position_cb(p.get_time()),
|
||||
self._player)
|
||||
|
||||
if error_cb:
|
||||
ev_mgr.event_attach(EventType.MediaPlayerEncounteredError,
|
||||
lambda et, p: error_cb(),
|
||||
self._player)
|
||||
if playing_cb:
|
||||
ev_mgr.event_attach(EventType.MediaPlayerPlaying,
|
||||
lambda et, p: playing_cb(),
|
||||
self._player)
|
||||
bus = self._player.get_bus()
|
||||
bus.add_signal_watch()
|
||||
bus.connect("message::error", error_cb)
|
||||
bus.connect("message::state-changed", playing_cb)
|
||||
|
||||
@classmethod
|
||||
def get_instance(cls, mode, rewind_cb=None, position_cb=None, error_cb=None, playing_cb=None):
|
||||
if not cls.__VLC_INSTANCE:
|
||||
cls.__VLC_INSTANCE = Player(mode, rewind_cb, position_cb, error_cb, playing_cb)
|
||||
return cls.__VLC_INSTANCE
|
||||
if not cls.__INSTANCE:
|
||||
cls.__INSTANCE = Player(mode, rewind_cb, position_cb, error_cb, playing_cb)
|
||||
return cls.__INSTANCE
|
||||
|
||||
def get_play_mode(self):
|
||||
return self._mode
|
||||
|
||||
@run_task
|
||||
def play(self, mrl=None):
|
||||
if mrl:
|
||||
self._player.set_mrl(mrl)
|
||||
self._player.play()
|
||||
self._is_playing = True
|
||||
self.stop()
|
||||
|
||||
if mrl:
|
||||
self._player.set_property("uri", mrl)
|
||||
|
||||
ret = self._player.set_state(self.STATE.PLAYING)
|
||||
|
||||
if ret == self.STAT_RETURN.FAILURE:
|
||||
log("ERROR: Unable to set the 'PLAYING' state for '{}'.".format(mrl))
|
||||
else:
|
||||
self._is_playing = True
|
||||
|
||||
@run_task
|
||||
def stop(self):
|
||||
if self._is_playing:
|
||||
self._player.stop()
|
||||
self._player.set_state(self.STATE.READY)
|
||||
self._is_playing = False
|
||||
|
||||
def pause(self):
|
||||
self._player.pause()
|
||||
self._player.set_state(self.STATE.PAUSED)
|
||||
|
||||
def set_time(self, time):
|
||||
self._player.set_time(time)
|
||||
pass
|
||||
|
||||
@run_task
|
||||
def release(self):
|
||||
if self._player:
|
||||
self._is_playing = False
|
||||
self._player.stop()
|
||||
self._player.release()
|
||||
self.__VLC_INSTANCE = None
|
||||
self.stop()
|
||||
self._player.set_state(self.STATE.NULL)
|
||||
self.__INSTANCE = None
|
||||
|
||||
def set_xwindow(self, xid):
|
||||
self._player.set_xwindow(xid)
|
||||
|
||||
def set_nso(self, widget):
|
||||
""" Used on MacOS to set NSObject.
|
||||
def set_handle(self, widget):
|
||||
""" Used on Windows to set window pointer.
|
||||
|
||||
Based on gtkvlc.py[get_window_pointer] example from here:
|
||||
https://github.com/oaubert/python-vlc/tree/master/examples
|
||||
"""
|
||||
try:
|
||||
import ctypes
|
||||
g_dll = ctypes.CDLL("libgdk-3.0.dylib")
|
||||
|
||||
libgdk = ctypes.CDLL("libgdk-3-0.dll")
|
||||
except OSError as e:
|
||||
log("{}: Load library error: {}".format(__class__.__name__, e))
|
||||
else:
|
||||
get_nsview = g_dll.gdk_quartz_window_get_nsview
|
||||
get_nsview.restype, get_nsview.argtypes = ctypes.c_void_p, [ctypes.c_void_p]
|
||||
# https://gitlab.gnome.org/GNOME/pygobject/-/issues/112
|
||||
ctypes.pythonapi.PyCapsule_GetPointer.restype = ctypes.c_void_p
|
||||
ctypes.pythonapi.PyCapsule_GetPointer.argtypes = [ctypes.py_object]
|
||||
# Get the C void* pointer to the window
|
||||
pointer = ctypes.pythonapi.PyCapsule_GetPointer(widget.get_window().__gpointer__, None)
|
||||
self._player.set_nsobject(get_nsview(pointer))
|
||||
gpointer = ctypes.pythonapi.PyCapsule_GetPointer(widget.get_window().__gpointer__, None)
|
||||
libgdk.gdk_win32_window_get_handle.restype = ctypes.c_void_p
|
||||
libgdk.gdk_win32_window_get_handle.argtypes = [ctypes.c_void_p]
|
||||
handle = libgdk.gdk_win32_window_get_handle(gpointer)
|
||||
|
||||
self._player.set_window_handle(handle)
|
||||
|
||||
def set_mrl(self, mrl):
|
||||
self._player.set_mrl(mrl)
|
||||
self._player.set_property("uri", mrl)
|
||||
|
||||
def is_playing(self):
|
||||
return self._is_playing
|
||||
|
||||
@@ -11,6 +11,7 @@ from urllib.parse import unquote
|
||||
from urllib.request import Request, urlopen, urlretrieve
|
||||
|
||||
from app.commons import log
|
||||
from app.settings import SEP
|
||||
from app.ui.uicommons import show_notification
|
||||
|
||||
_YT_PATTERN = re.compile(r"https://www.youtube.com/.+(?:v=)([\w-]{11}).*")
|
||||
@@ -169,7 +170,7 @@ class PlayListParser(HTMLParser):
|
||||
|
||||
try:
|
||||
resp = json.loads(data)
|
||||
except JSONDecodeError as e:
|
||||
except YouTubeException as e:
|
||||
log("{}: Parsing data error: {}".format(__class__.__name__, e))
|
||||
else:
|
||||
sb = resp.get("sidebar", None)
|
||||
@@ -229,7 +230,7 @@ class YouTubeDL:
|
||||
"cookiefile": "cookies.txt"} # File name where cookies should be read from and dumped to.
|
||||
|
||||
def __init__(self, settings, callback):
|
||||
self._path = settings.default_data_path + "tools/"
|
||||
self._path = settings.default_data_path + "tools{}".format(SEP)
|
||||
self._update = settings.enable_yt_dl_update
|
||||
self._supported = {"22", "18"}
|
||||
self._dl = None
|
||||
@@ -246,7 +247,7 @@ class YouTubeDL:
|
||||
return cls._DL_INSTANCE
|
||||
|
||||
def init(self):
|
||||
if not os.path.isfile(self._path + "youtube_dl/version.py"):
|
||||
if not os.path.isfile(self._path + "youtube_dl{}version.py".format(SEP)):
|
||||
self.get_latest_release()
|
||||
|
||||
if self._path not in sys.path:
|
||||
@@ -313,7 +314,7 @@ class YouTubeDL:
|
||||
os.makedirs(os.path.dirname(self._path), exist_ok=True)
|
||||
|
||||
for info in arch.infolist():
|
||||
pref, sep, f = info.filename.partition("/youtube_dl/")
|
||||
pref, sep, f = info.filename.partition("{}youtube_dl{}".format(SEP, SEP))
|
||||
if sep:
|
||||
arch.extract(info.filename)
|
||||
shutil.move(info.filename, "{}{}{}".format(self._path, sep, f))
|
||||
|
||||
@@ -17,7 +17,7 @@ from app.eparser.ecommons import CAS, Flag, BouquetService
|
||||
from app.eparser.enigma.bouquets import BqServiceType
|
||||
from app.eparser.iptv import export_to_m3u
|
||||
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_WIN
|
||||
from app.tools.media import Player, Recorder
|
||||
from app.ui.epg_dialog import EpgDialog
|
||||
from app.ui.transmitter import LinksTransmitter
|
||||
@@ -304,12 +304,11 @@ class Application(Gtk.Application):
|
||||
self._player_tool_bar = builder.get_object("player_tool_bar")
|
||||
self._player_prev_button = builder.get_object("player_prev_button")
|
||||
self._player_next_button = builder.get_object("player_next_button")
|
||||
self._player_box.bind_property("visible", tool_bar, "visible", 4)
|
||||
self._player_box.bind_property("visible", self._services_main_box, "visible", 4)
|
||||
self._player_box.bind_property("visible", self._bouquets_main_box, "visible", 4)
|
||||
self._player_box.bind_property("visible", builder.get_object("fav_pos_column"), "visible", 4)
|
||||
self._player_box.bind_property("visible", builder.get_object("fav_pos_column"), "visible", 4)
|
||||
self._player_box.bind_property("visible", self._profile_combo_box, "sensitive", 4)
|
||||
self._player_box.bind_property("visible", tool_bar, "sensitive", 4)
|
||||
self._fav_view.bind_property("sensitive", self._player_prev_button, "sensitive")
|
||||
self._fav_view.bind_property("sensitive", self._player_next_button, "sensitive")
|
||||
# Record
|
||||
@@ -333,21 +332,23 @@ class Application(Gtk.Application):
|
||||
self._status_bar_box.get_style_context().add_provider_for_screen(Gdk.Screen.get_default(), style_provider,
|
||||
Gtk.STYLE_PROVIDER_PRIORITY_USER)
|
||||
|
||||
# Menu bar
|
||||
main_box = builder.get_object("main_window_box")
|
||||
builder.add_from_file(UI_RESOURCES_PATH + "app_menu_bar.ui")
|
||||
menu_bar = Gtk.MenuBar.new_from_model(builder.get_object("menu_bar"))
|
||||
menu_bar.set_visible(True)
|
||||
main_box.pack_start(menu_bar, False, False, 0)
|
||||
main_box.reorder_child(menu_bar, 0)
|
||||
self._main_data_box.bind_property("visible", menu_bar, "visible")
|
||||
self._player_box.bind_property("visible", menu_bar, "sensitive", 4)
|
||||
if self._settings.get("telnet"):
|
||||
self.init_telnet(builder)
|
||||
|
||||
def do_startup(self):
|
||||
Gtk.Application.do_startup(self)
|
||||
|
||||
self.init_keys()
|
||||
self.set_accels()
|
||||
|
||||
builder = Gtk.Builder()
|
||||
builder.set_translation_domain("demon-editor")
|
||||
builder.add_from_file(UI_RESOURCES_PATH + "app_menu_bar.ui")
|
||||
self.set_menubar(builder.get_object("menu_bar"))
|
||||
self.set_app_menu(builder.get_object("app-menu"))
|
||||
|
||||
if self._settings.get("telnet"):
|
||||
self.init_telnet(builder)
|
||||
|
||||
self.update_profile_label()
|
||||
self.init_drag_and_drop()
|
||||
self.init_colors()
|
||||
@@ -2445,7 +2446,7 @@ class Application(Gtk.Application):
|
||||
|
||||
def on_player_stop(self, item=None):
|
||||
if self._player:
|
||||
self._player.stop()
|
||||
GLib.idle_add(self._player.stop)
|
||||
|
||||
def on_player_previous(self, item):
|
||||
if self._fav_view.do_move_cursor(self._fav_view, Gtk.MovementStep.DISPLAY_LINES, -1):
|
||||
@@ -2498,12 +2499,12 @@ class Application(Gtk.Application):
|
||||
if not self._full_screen and self._player_rewind_box.get_visible():
|
||||
GLib.idle_add(self._player_current_time_label.set_text, self.get_time_str(t), priority=GLib.PRIORITY_LOW)
|
||||
|
||||
def on_player_error(self):
|
||||
def on_player_error(self, bus=None, msg=None):
|
||||
self.set_playback_elms_active()
|
||||
self.show_error_dialog("Can't Playback!")
|
||||
|
||||
@run_idle
|
||||
def set_playback_elms_active(self):
|
||||
def set_playback_elms_active(self, bus=None, msg=None):
|
||||
self._fav_view.set_sensitive(True)
|
||||
self._fav_view.do_grab_focus(self._fav_view)
|
||||
|
||||
@@ -2525,8 +2526,8 @@ class Application(Gtk.Application):
|
||||
self.show_error_dialog("No VLC is found. Check that it is installed!")
|
||||
return True
|
||||
else:
|
||||
if self._settings.is_darwin:
|
||||
self._player.set_nso(widget)
|
||||
if IS_WIN:
|
||||
self._player.set_handle(widget)
|
||||
else:
|
||||
self._player.set_xwindow(widget.get_window().get_xid())
|
||||
self._player.play(self._current_mrl)
|
||||
@@ -2541,20 +2542,15 @@ class Application(Gtk.Application):
|
||||
widget.set_size_request(w * 0.6, -1)
|
||||
|
||||
def on_player_drawing_area_draw(self, widget, cr):
|
||||
""" Used for black background drawing in the player drawing area.
|
||||
""" Used for black background drawing in the player drawing area. """
|
||||
if not self._player.is_playing:
|
||||
allocation = widget.get_allocation()
|
||||
|
||||
Required for Gtk >= 3.20.
|
||||
More info: https://developer.gnome.org/gtk3/stable/ch32s10.html,
|
||||
https://developer.gnome.org/gtk3/stable/GtkStyleContext.html#gtk-render-background
|
||||
"""
|
||||
context = widget.get_style_context()
|
||||
width = widget.get_allocated_width()
|
||||
height = widget.get_allocated_height()
|
||||
Gtk.render_background(context, cr, 0, 0, width, height)
|
||||
r, g, b, a = 0, 0, 0, 1 # black color
|
||||
cr.set_source_rgba(r, g, b, a)
|
||||
cr.rectangle(0, 0, width, height)
|
||||
cr.fill()
|
||||
cr.set_source_rgb(0, 0, 0)
|
||||
cr.rectangle(0, 0, allocation.width, allocation.height)
|
||||
cr.fill()
|
||||
|
||||
return False
|
||||
|
||||
def on_player_press(self, area, event):
|
||||
if event.button == Gdk.BUTTON_PRIMARY:
|
||||
|
||||
@@ -1005,305 +1005,22 @@ Author: Dmitriy Yefremov
|
||||
<property name="can_focus">False</property>
|
||||
<property name="orientation">vertical</property>
|
||||
<child>
|
||||
<object class="GtkBox" id="top_box">
|
||||
<object class="GtkBox" id="top_toolbar">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="valign">center</property>
|
||||
<property name="margin_left">10</property>
|
||||
<property name="margin_top">10</property>
|
||||
<property name="margin_bottom">10</property>
|
||||
<property name="spacing">10</property>
|
||||
<child>
|
||||
<object class="GtkBox" id="top_toolbar">
|
||||
<object class="GtkComboBoxText" id="profile_combo_box">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="halign">center</property>
|
||||
<property name="valign">center</property>
|
||||
<property name="margin_left">10</property>
|
||||
<property name="margin_top">10</property>
|
||||
<property name="margin_bottom">10</property>
|
||||
<property name="spacing">10</property>
|
||||
<child>
|
||||
<object class="GtkComboBoxText" id="profile_combo_box">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="tooltip_text" translatable="yes">Profile</property>
|
||||
<property name="active">0</property>
|
||||
<property name="focus_on_click">False</property>
|
||||
<signal name="changed" handler="on_profile_changed" swapped="no"/>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkButtonBox" id="toolbar_main_box">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="layout_style">expand</property>
|
||||
<child>
|
||||
<object class="GtkButton" id="open_tool_button">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="receives_default">True</property>
|
||||
<property name="tooltip_text" translatable="yes">Open</property>
|
||||
<property name="action_name">app.on_data_open</property>
|
||||
<property name="image">open_image</property>
|
||||
<property name="always_show_image">True</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="download_tool_button">
|
||||
<property name="label" translatable="yes"> </property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="receives_default">True</property>
|
||||
<property name="tooltip_text" translatable="yes">FTP-transfer</property>
|
||||
<property name="action_name">app.on_download</property>
|
||||
<property name="image">ftp_image</property>
|
||||
<property name="always_show_image">True</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">True</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkButton" id="telnet_tool_button">
|
||||
<property name="label" translatable="yes"> </property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="receives_default">True</property>
|
||||
<property name="tooltip_text" translatable="yes">Telnet</property>
|
||||
<property name="action_name">app.on_telnet_client_show</property>
|
||||
<property name="image">telnet_image</property>
|
||||
<property name="always_show_image">True</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">True</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">2</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkButton" id="save_tool_button">
|
||||
<property name="label" translatable="yes"> </property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="receives_default">True</property>
|
||||
<property name="tooltip_text" translatable="yes">Save</property>
|
||||
<property name="action_name">app.on_data_save</property>
|
||||
<property name="image">save_image</property>
|
||||
<property name="always_show_image">True</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">True</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">3</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkButton" id="backup_tool_button">
|
||||
<property name="label" translatable="yes"> </property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="receives_default">True</property>
|
||||
<property name="tooltip_text" translatable="yes">Backups</property>
|
||||
<property name="action_name">app.on_backup_tool_show</property>
|
||||
<property name="image">backups_image</property>
|
||||
<property name="always_show_image">True</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">True</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">4</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkButtonBox" id="toolbar_extra_box">
|
||||
<property name="can_focus">False</property>
|
||||
<property name="opacity">0.99000000022351742</property>
|
||||
<property name="resize_mode">immediate</property>
|
||||
<property name="layout_style">expand</property>
|
||||
<child>
|
||||
<object class="GtkToggleButton" id="search_tool_button">
|
||||
<property name="label" translatable="yes">Search</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="receives_default">True</property>
|
||||
<property name="tooltip_text" translatable="yes">Search</property>
|
||||
<property name="action_name">win.search</property>
|
||||
<property name="image">find_image</property>
|
||||
<property name="always_show_image">True</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">True</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkToggleButton" id="filter_tool_button">
|
||||
<property name="label" translatable="yes">Filter</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="receives_default">True</property>
|
||||
<property name="tooltip_text" translatable="yes">Filter</property>
|
||||
<property name="action_name">win.filter</property>
|
||||
<property name="image">filter_image</property>
|
||||
<property name="always_show_image">True</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">True</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">4</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkButton" id="lock_tool_button">
|
||||
<property name="label" translatable="yes">Lock</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="receives_default">True</property>
|
||||
<property name="tooltip_text" translatable="yes">Parent lock</property>
|
||||
<property name="action_name">app.on_locked</property>
|
||||
<property name="image">lock_image</property>
|
||||
<property name="always_show_image">True</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">True</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">5</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkButton" id="hide_tool_button">
|
||||
<property name="label" translatable="yes">Hide</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="receives_default">True</property>
|
||||
<property name="tooltip_text" translatable="yes">Hide/Skip</property>
|
||||
<property name="action_name">app.on_hide</property>
|
||||
<property name="image">hide_image</property>
|
||||
<property name="always_show_image">True</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">True</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">5</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">2</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkButtonBox" id="toolbar_tools_box">
|
||||
<property name="can_focus">False</property>
|
||||
<property name="halign">center</property>
|
||||
<property name="layout_style">expand</property>
|
||||
<child>
|
||||
<object class="GtkButton" id="sat_editor_tool_button">
|
||||
<property name="label" translatable="yes">Satellites</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="receives_default">True</property>
|
||||
<property name="tooltip_text" translatable="yes">Satellites editor</property>
|
||||
<property name="action_name">app.on_satellite_editor_show</property>
|
||||
<property name="image">sat_editor_image</property>
|
||||
<property name="always_show_image">True</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="picons_manager_tool_button">
|
||||
<property name="label" translatable="yes">Picons</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="receives_default">True</property>
|
||||
<property name="tooltip_text" translatable="yes">Picons manager</property>
|
||||
<property name="action_name">app.on_picons_manager_show</property>
|
||||
<property name="image">picons_image</property>
|
||||
<property name="always_show_image">True</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">True</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkMenuButton" id="iptv_tools_menu_button">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="receives_default">True</property>
|
||||
<property name="tooltip_text" translatable="yes">IPTV tools</property>
|
||||
<property name="popup">toolbar_iptv_menu</property>
|
||||
<child>
|
||||
<object class="GtkBox" id="iptv_tools_menu_button_box">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="halign">center</property>
|
||||
<property name="spacing">2</property>
|
||||
<child>
|
||||
<object class="GtkImage" id="iptv_tools_menu_button_image">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="halign">center</property>
|
||||
<property name="valign">center</property>
|
||||
<property name="icon_name">network-wired-symbolic</property>
|
||||
<property name="icon_size">1</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel" id="iptv_tools_menu_button_label">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="label" translatable="yes">IPTV</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">True</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">5</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">3</property>
|
||||
</packing>
|
||||
</child>
|
||||
<property name="tooltip_text" translatable="yes">Profile</property>
|
||||
<property name="active">0</property>
|
||||
<property name="focus_on_click">False</property>
|
||||
<signal name="changed" handler="on_profile_changed" swapped="no"/>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
@@ -1311,11 +1028,279 @@ Author: Dmitriy Yefremov
|
||||
<property name="position">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkButtonBox" id="toolbar_main_box">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="layout_style">expand</property>
|
||||
<child>
|
||||
<object class="GtkButton" id="open_tool_button">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="receives_default">True</property>
|
||||
<property name="tooltip_text" translatable="yes">Open</property>
|
||||
<property name="action_name">app.on_data_open</property>
|
||||
<property name="image">open_image</property>
|
||||
<property name="always_show_image">True</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="download_tool_button">
|
||||
<property name="label" translatable="yes"> </property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="receives_default">True</property>
|
||||
<property name="tooltip_text" translatable="yes">FTP-transfer</property>
|
||||
<property name="action_name">app.on_download</property>
|
||||
<property name="image">ftp_image</property>
|
||||
<property name="always_show_image">True</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">True</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkButton" id="telnet_tool_button">
|
||||
<property name="label" translatable="yes"> </property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="receives_default">True</property>
|
||||
<property name="tooltip_text" translatable="yes">Telnet</property>
|
||||
<property name="action_name">app.on_telnet_client_show</property>
|
||||
<property name="image">telnet_image</property>
|
||||
<property name="always_show_image">True</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">True</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">2</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkButton" id="save_tool_button">
|
||||
<property name="label" translatable="yes"> </property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="receives_default">True</property>
|
||||
<property name="tooltip_text" translatable="yes">Save</property>
|
||||
<property name="action_name">app.on_data_save</property>
|
||||
<property name="image">save_image</property>
|
||||
<property name="always_show_image">True</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">True</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">3</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkButton" id="backup_tool_button">
|
||||
<property name="label" translatable="yes"> </property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="receives_default">True</property>
|
||||
<property name="tooltip_text" translatable="yes">Backups</property>
|
||||
<property name="action_name">app.on_backup_tool_show</property>
|
||||
<property name="image">backups_image</property>
|
||||
<property name="always_show_image">True</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">True</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">4</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkButtonBox" id="toolbar_extra_box">
|
||||
<property name="can_focus">False</property>
|
||||
<property name="opacity">0.99000000022351742</property>
|
||||
<property name="resize_mode">immediate</property>
|
||||
<property name="layout_style">expand</property>
|
||||
<child>
|
||||
<object class="GtkToggleButton" id="search_tool_button">
|
||||
<property name="label" translatable="yes">Search</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="receives_default">True</property>
|
||||
<property name="tooltip_text" translatable="yes">Search</property>
|
||||
<property name="action_name">win.search</property>
|
||||
<property name="image">find_image</property>
|
||||
<property name="always_show_image">True</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">True</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkToggleButton" id="filter_tool_button">
|
||||
<property name="label" translatable="yes">Filter</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="receives_default">True</property>
|
||||
<property name="tooltip_text" translatable="yes">Filter</property>
|
||||
<property name="action_name">win.filter</property>
|
||||
<property name="image">filter_image</property>
|
||||
<property name="always_show_image">True</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">True</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">4</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkButton" id="lock_tool_button">
|
||||
<property name="label" translatable="yes">Lock</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="receives_default">True</property>
|
||||
<property name="tooltip_text" translatable="yes">Parent lock</property>
|
||||
<property name="action_name">app.on_locked</property>
|
||||
<property name="image">lock_image</property>
|
||||
<property name="always_show_image">True</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">True</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">5</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkButton" id="hide_tool_button">
|
||||
<property name="label" translatable="yes">Hide</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="receives_default">True</property>
|
||||
<property name="tooltip_text" translatable="yes">Hide/Skip</property>
|
||||
<property name="action_name">app.on_hide</property>
|
||||
<property name="image">hide_image</property>
|
||||
<property name="always_show_image">True</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">True</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">5</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">2</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkButtonBox" id="toolbar_tools_box">
|
||||
<property name="can_focus">False</property>
|
||||
<property name="layout_style">expand</property>
|
||||
<child>
|
||||
<object class="GtkButton" id="sat_editor_tool_button">
|
||||
<property name="label" translatable="yes">Satellites</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="receives_default">True</property>
|
||||
<property name="tooltip_text" translatable="yes">Satellites editor</property>
|
||||
<property name="action_name">app.on_satellite_editor_show</property>
|
||||
<property name="image">sat_editor_image</property>
|
||||
<property name="always_show_image">True</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="picons_manager_tool_button">
|
||||
<property name="label" translatable="yes">Picons</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="receives_default">True</property>
|
||||
<property name="tooltip_text" translatable="yes">Picons manager</property>
|
||||
<property name="action_name">app.on_picons_manager_show</property>
|
||||
<property name="image">picons_image</property>
|
||||
<property name="always_show_image">True</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">True</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkMenuButton" id="iptv_tools_menu_button">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="receives_default">True</property>
|
||||
<property name="tooltip_text" translatable="yes">IPTV tools</property>
|
||||
<property name="popup">toolbar_iptv_menu</property>
|
||||
<child>
|
||||
<object class="GtkBox" id="iptv_tools_menu_button_box">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="halign">center</property>
|
||||
<property name="spacing">2</property>
|
||||
<child>
|
||||
<object class="GtkImage" id="iptv_tools_menu_button_image">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="halign">center</property>
|
||||
<property name="valign">center</property>
|
||||
<property name="icon_name">network-wired-symbolic</property>
|
||||
<property name="icon_size">1</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel" id="iptv_tools_menu_button_label">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="label" translatable="yes">IPTV</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">True</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">5</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">3</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkButtonBox" id="toolbar_extra_tools_box">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="valign">center</property>
|
||||
<property name="margin_right">10</property>
|
||||
<property name="resize_mode">immediate</property>
|
||||
<property name="homogeneous">True</property>
|
||||
@@ -1323,7 +1308,7 @@ Author: Dmitriy Yefremov
|
||||
<child>
|
||||
<object class="GtkButton" id="add_bouquet_tool_button">
|
||||
<property name="sensitive">False</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="receives_default">True</property>
|
||||
<property name="tooltip_text" translatable="yes">Create bouquet</property>
|
||||
<property name="always_show_image">True</property>
|
||||
@@ -1390,13 +1375,13 @@ Author: Dmitriy Yefremov
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="pack_type">end</property>
|
||||
<property name="position">1</property>
|
||||
<property name="position">4</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">False</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
|
||||
Reference in New Issue
Block a user