import os import datetime import time import hashlib import shutil import subprocess import platform import locale from functools import partial import PIL from PIL import Image from PyQt5 import QtCore, QtWidgets, QtGui from PyQt5.QtCore import pyqtSlot, pyqtSignal from player_functions import write_files from thread_modules import DiscoverServer from mpv_bak import MPV from threading import Lock class QBrowserWidget(QtWidgets.QWidget): def __init__(self, uiwidget, parent): QtWidgets.QWidget.__init__(self, parent) global ui ui = uiwidget self.setMouseTracking(True) def mouseMoveEvent(self, event): self.setFocus() self.setCursor(QtGui.QCursor(QtCore.Qt.ArrowCursor)) class QPushButtonExtra(QtWidgets.QPushButton): def __init__(self, parent=None): super(QPushButtonExtra, self).__init__(parent) self.setMouseTracking(True) def clicked_connect(self, callbak): if platform.system().lower() == "darwin": super(QPushButtonExtra, self).pressed.connect(callbak) else: super(QPushButtonExtra, self).clicked.connect(callbak) def clicked_emit(self): if platform.system().lower() == "darwin": super(QPushButtonExtra, self).pressed.emit() else: super(QPushButtonExtra, self).clicked.emit() def mouseMoveEvent(self, event): self.setFocus() class SidebarWidget(QtWidgets.QListWidget): """ Options Sidebar Widget """ def __init__(self, parent, uiwidget, home_dir): super(SidebarWidget, self).__init__(parent) global ui, home ui = uiwidget home = home_dir def mouseMoveEvent(self, event): if ui.player_val != 'mplayer' or ui.mpvplayer_val.processId() == 0: self.setFocus() def keyPressEvent(self, event): if event.key() == QtCore.Qt.Key_O: ui.setPreOpt() elif event.key() == QtCore.Qt.Key_Down: nextr = self.currentRow() + 1 if nextr == self.count(): self.setCurrentRow(0) else: self.setCurrentRow(nextr) elif event.key() == QtCore.Qt.Key_Up: prev_r = self.currentRow() - 1 if self.currentRow() == 0: self.setCurrentRow(self.count()-1) else: self.setCurrentRow(prev_r) elif event.key() == QtCore.Qt.Key_Right: if not ui.list1.isHidden(): ui.list1.setFocus() elif not ui.scrollArea.isHidden(): ui.scrollArea.setFocus() elif not ui.scrollArea1.isHidden(): ui.scrollArea1.setFocus() elif not ui.list_poster.isHidden(): ui.list_poster.setFocus() ui.dockWidget_3.hide() elif event.key() == QtCore.Qt.Key_Return: ui.newoptions('clicked') self.setFocus() elif event.key() == QtCore.Qt.Key_Left: if not ui.list2.isHidden(): if ui.list2.currentItem(): index = ui.list2.currentRow() ui.list2.setCurrentRow(index) ui.list2.setFocus() elif not ui.list1.isHidden(): ui.list1.setFocus() elif not ui.scrollArea.isHidden(): ui.scrollArea.setFocus() elif not ui.scrollArea1.isHidden(): ui.scrollArea1.setFocus() elif not ui.list_poster.isHidden(): ui.list_poster.setFocus() if ui.auto_hide_dock: ui.dockWidget_3.hide() elif event.key() == QtCore.Qt.Key_H: ui.setPreOpt() elif (event.modifiers() == QtCore.Qt.ControlModifier and event.key() == QtCore.Qt.Key_D): site = ui.get_parameters_value(s='site')['site'] if site.lower() == 'myserver': if not ui.discover_thread: ui.discover_thread = DiscoverServer(ui, True) ui.discover_thread.start() elif isinstance(ui.discover_thread, DiscoverServer): if ui.discover_thread.isRunning(): ui.discover_server = False else: ui.discover_thread = DiscoverServer(ui, True) ui.discover_thread.start() elif event.key() == QtCore.Qt.Key_Delete: param_dict = ui.get_parameters_value(s='site', b='bookmark') site = param_dict['site'] bookmark = param_dict['bookmark'] if site == "PlayLists": index = self.currentRow() item_r = self.item(index) if item_r: item = str(self.currentItem().text()) if item != "Default": file_pls = os.path.join(home, 'Playlists', item) if os.path.exists(file_pls): os.remove(file_pls) self.takeItem(index) del item_r ui.list2.clear() if bookmark: index = self.currentRow() item_r = self.item(index) if item_r: item = str(self.currentItem().text()) bookmark_array = [ 'All', 'Watching', 'Completed', 'Incomplete', 'Later', 'Interesting', 'Music-Videos' ] if item not in bookmark_array: file_pls = os.path.join(home, 'Bookmark', item+'.txt') if os.path.exists(file_pls): os.remove(file_pls) self.takeItem(index) del item_r ui.list1.clear() ui.list2.clear() else: super(SidebarWidget, self).keyPressEvent(event) def contextMenuEvent(self, event): menu = QtWidgets.QMenu(self) history = menu.addAction("History") anime = menu.addAction("Animes") movie = menu.addAction("Movies") action = menu.exec_(self.mapToGlobal(event.pos())) if action == history: ui.setPreOpt() elif action == anime: category = "Animes" ui.set_parameters_value(catg=category) elif action == movie: category = "Movies" ui.set_parameters_value(catg=category) class FilterTitleList(QtWidgets.QListWidget): """ Filter Titlelist Widget """ def __init__(self, parent, uiwidget, home_dir): super(FilterTitleList, self).__init__(parent) global ui, home ui = uiwidget home = home_dir def keyPressEvent(self, event): if event.key() == QtCore.Qt.Key_Down: nextr = self.currentRow() + 1 if nextr == self.count(): ui.go_page.setFocus() else: self.setCurrentRow(nextr) elif event.key() == QtCore.Qt.Key_Up: prev_r = self.currentRow() - 1 if self.currentRow() == 0: ui.go_page.setFocus() else: self.setCurrentRow(prev_r) elif event.key() == QtCore.Qt.Key_Return: ui.search_list4_options() def contextMenuEvent(self, event): menu = QtWidgets.QMenu(self) hd = menu.addAction("Hide Search Table") sideBar = menu.addAction("Show Sidebar") history = menu.addAction("Show History") action = menu.exec_(self.mapToGlobal(event.pos())) if action == hd: self.hide() elif action == sideBar: if ui.dockWidget_3.isHidden(): ui.dockWidget_3.show() ui.btn1.setFocus() else: ui.dockWidget_3.hide() ui.list1.setFocus() elif action == history: ui.setPreOpt() class FilterPlaylist(QtWidgets.QListWidget): """ Filter Playlist Widget """ def __init__(self, parent, uiwidget, home_dir, logr): super(FilterPlaylist, self).__init__(parent) global ui, home, logger ui = uiwidget home = home_dir logger = logr def keyPressEvent(self, event): if event.key() == QtCore.Qt.Key_Down: nextr = self.currentRow() + 1 if nextr == self.count(): ui.goto_epn_filter_txt.setFocus() else: self.setCurrentRow(nextr) elif event.key() == QtCore.Qt.Key_Up: prev_r = self.currentRow() - 1 if self.currentRow() == 0: ui.goto_epn_filter_txt.setFocus() else: self.setCurrentRow(prev_r) elif event.key() == QtCore.Qt.Key_Return: ui.search_list5_options() elif event.key() == QtCore.Qt.Key_Q: site = ui.get_parameters_value(s='site')['site'] if (site == "Music" or site == "Video" or site == "Local" or site == "PlayLists" or site == "None"): file_path = os.path.join(home, 'Playlists', 'Queue') if not os.path.exists(file_path): f = open(file_path, 'w') f.close() if not ui.queue_url_list: ui.list6.clear() indx = self.currentRow() item = self.item(indx) if item: tmp = str(self.currentItem().text()) tmp1 = tmp.split(':')[0] r = int(tmp1) ui.queue_url_list.append(ui.epn_arr_list[r]) ui.list6.addItem(ui.epn_arr_list[r].split(' ')[0]) logger.info(ui.queue_url_list) write_files(file_path, ui.epn_arr_list[r], line_by_line=True) class QueueListWidget(QtWidgets.QListWidget): """ Queue Widget List """ def __init__(self, parent, uiwidget, home_dir): super(QueueListWidget, self).__init__(parent) global ui, home ui = uiwidget home = home_dir def keyPressEvent(self, event): if event.key() == QtCore.Qt.Key_Down: nextr = self.currentRow() + 1 if nextr == self.count(): self.setCurrentRow(0) else: self.setCurrentRow(nextr) elif event.key() == QtCore.Qt.Key_Up: prev_r = self.currentRow() - 1 if self.currentRow() == 0: self.setCurrentRow(self.count()-1) else: self.setCurrentRow(prev_r) elif event.key() == QtCore.Qt.Key_PageUp: r = self.currentRow() if r > 0: r1 = r - 1 if not ui.video_local_stream: ui.queue_url_list[r], ui.queue_url_list[r1] = ui.queue_url_list[r1], ui.queue_url_list[r] item = self.item(r) txt = item.text() self.takeItem(r) del item self.insertItem(r1, txt) self.setCurrentRow(r1) elif event.key() == QtCore.Qt.Key_PageDown: r = self.currentRow() if r < self.count()-1 and r >= 0: r1 = r + 1 if not ui.video_local_stream: ui.queue_url_list[r], ui.queue_url_list[r1] = ui.queue_url_list[r1], ui.queue_url_list[r] item = self.item(r) txt = item.text() self.takeItem(r) del item self.insertItem(r1, txt) self.setCurrentRow(r1) elif event.key() == QtCore.Qt.Key_Return: r = self.currentRow() if self.item(r): ui.queueList_return_pressed(r) elif event.key() == QtCore.Qt.Key_Delete: r = self.currentRow() if self.item(r): item = self.item(r) self.takeItem(r) del item if not ui.video_local_stream: del ui.queue_url_list[r] class MyToolTip(QtWidgets.QToolTip): def __init__(self, uiwidget): super(MyToolTip).__init__() global ui ui = uiwidget class ToolTipWidget(QtWidgets.QWidget): def __init__(self, uiwidget, parent): QtWidgets.QWidget.__init__(self, parent) global ui ui = uiwidget self.setWindowFlags( QtCore.Qt.Window | QtCore.Qt.FramelessWindowHint | QtCore.Qt.WindowStaysOnTopHint ) self.setMouseTracking(True) def mouseMoveEvent(self, event): self.hide() def mousePressEvent(self, event): self.hide() class QLabelPreview(QtWidgets.QLabel): def __init(self, parent=None): QLabel.__init__(self, parent) self.setMouseTracking(True) def set_globals(self, uiwidget): global ui ui = uiwidget def mouseMoveEvent(self, event): ui.slider.tooltip_widget.hide() def mousePressEvent(self, event): ui.slider.tooltip_widget.hide() ui.slider.preview_pending[:] = [] class PreviewThread(QtCore.QThread): preview_cmd = pyqtSignal(list) def __init__(self, slider, gui, func, apply_list): QtCore.QThread.__init__(self) global ui ui = gui self.slider = slider self.func = func self.preview_cmd.connect(preview_slot) self.apply_list = apply_list.copy() def __del__(self): self.wait() def run(self): if self.func: final_point = (self.apply_list[-3], self.apply_list[-2]) if self.slider.final_point == final_point: self.func() self.preview_cmd.emit(self.apply_list) @pyqtSlot(list) def preview_slot(apply_list): global ui final_point = (apply_list[-3], apply_list[-2]) if ui.slider.final_point == final_point: ui.slider.preview_generated(*apply_list) class MySlider(QtWidgets.QSlider): def __init__(self, parent, uiwidget, home_dir, mw): super(MySlider, self).__init__(parent) global home, ui, MainWindow ui = uiwidget home = home_dir MainWindow = mw self.setCursor(QtGui.QCursor(QtCore.Qt.PointingHandCursor)) version = QtCore.QT_VERSION_STR self.version = tuple([int(i) for i in version.split('.')]) if self.version >= (5, 9, 0): self.tooltip = MyToolTip(ui) else: self.tooltip = None self.parent = parent self.preview_process = QtCore.QProcess() self.counter = 0 self.preview_pending = [] self.lock = False self.preview_counter = 0 self.mousemove = False #self.tooltip_widget = ToolTipWidget(ui, parent) self.tooltip_widget = QtWidgets.QWidget(MainWindow) self.v = QtWidgets.QVBoxLayout(self.tooltip_widget) self.v.setContentsMargins(0, 0, 0, 0) self.pic = QLabelPreview(self) self.pic.set_globals(ui) self.pic.setScaledContents(True) self.v.insertWidget(0, self.pic) self.txt = QtWidgets.QLabel(self) self.v.insertWidget(1, self.txt) self.txt.setAlignment(QtCore.Qt.AlignCenter) self.tooltip_widget.setMouseTracking(True) self.tooltip_widget.hide() self.txt.setStyleSheet('color:white;background:black;') self.tooltip_timer = QtCore.QTimer() self.tooltip_timer.timeout.connect(self.update_tooltip) self.tooltip_timer.setSingleShot(True) self.final_url = None self.half_size = int(ui.label.maximumWidth()/2) self.upper_limit = self.parent.x() + self.parent.width() self.lower_limit = self.parent.x() self.file_type = 'video' self.enter = False self.empty_preview_dir = False self.check_dimension_again = False self.preview_dir = None self.time_format = lambda val: time.strftime('%H:%M:%S', time.gmtime(int(val))) self.preview_lock = Lock() #self.setTickPosition(QtWidgets.QSlider.TickPosition.TicksAbove) #self.setTickInterval(100) self.valueChanged.connect(self.set_value) locale.setlocale(locale.LC_NUMERIC, 'C') self.mpv = MPV(vo="image", ytdl="no", quiet=True, aid="no", sid="no", frames=1, idle=True) self.preview_thread_list = [] self.final_point = (0, 0) self.ui = ui def set_value(self, val): self.setSliderPosition(val) def keyPressEvent(self, event): if (event.modifiers() == QtCore.Qt.ControlModifier and event.key() == QtCore.Qt.Key_Right): pos = self.cursor().pos() self.cursor().setPos(pos.x()+5, pos.y()) elif (event.modifiers() == QtCore.Qt.ControlModifier and event.key() == QtCore.Qt.Key_Left): pos = self.cursor().pos() self.cursor().setPos(pos.x()-5, pos.y()) elif event.key() == QtCore.Qt.Key_Right: ui.mpv_execute_command('seek 5', ui.cur_row) elif event.key() == QtCore.Qt.Key_Left: ui.mpv_execute_command('seek -5', ui.cur_row) elif event.key() == QtCore.Qt.Key_Return: pos = self.cursor().pos() t = ((pos.x() - self.x())/self.width()) t = int(t*ui.mplayerLength) ui.mpv_execute_command('seek {} absolute'.format(int(t)), ui.cur_row) else: super(MySlider, self).keyPressEvent(event) def leaveEvent(self, event, source=None): if self.tooltip_timer.isActive(): self.tooltip_timer.stop() self.preview_pending[:] = [] self.tooltip_widget.hide() if self.tooltip: self.tooltip.hideText() self.enter = False self.check_dimension_again = True #self.mpv.terminate() if self.preview_dir: picn = os.path.join(self.preview_dir, '00000001.jpg') if os.path.exists(picn): os.remove(picn) def enterEvent(self, event, source=None): self.enter = True if self.final_url != ui.final_playing_url: self.check_and_set_file_type() if (self.file_type == 'video' and ui.mpvplayer_val.processId() > 0 and ui.live_preview in ['slow', 'fast'] or ui.player_val == "libmpv"): self.create_preview_dir() self.mouseMoveEvent(event, source=source) def create_preview_dir(self): file_name_bytes = bytes(ui.final_playing_url, 'utf-8') h = hashlib.sha256(file_name_bytes) file_digest = h.hexdigest() self.preview_dir = os.path.join(ui.preview_download_folder, file_digest) if not os.path.exists(self.preview_dir): os.makedirs(self.preview_dir) ui.logger.debug('\n{}::{}\n'.format(self.preview_dir, ui.final_playing_url)) def check_and_set_file_type(self): if ui.final_playing_url.startswith('abs_path=') or ui.final_playing_url.startswith('relative_path='): ui.final_playing_url = ui.if_path_is_rel(ui.final_playing_url) if ui.final_playing_url.startswith('http'): self.file_type = 'network' elif '.' in ui.final_playing_url: ext = ui.final_playing_url.rsplit('.', 1)[1] if ext in ui.music_type_arr: self.file_type = 'music' self.final_url = ui.final_playing_url elif ext in ui.video_type_arr: self.file_type = 'video' else: self.file_type = 'unknown' ui.logger.debug('{}::{}'.format(self.file_type, ui.final_playing_url)) if self.file_type in ['network', 'music', 'unknown']: self.final_url = ui.final_playing_url def mpv_preview(self, preview_dir, t, scale, newpicn, url, final_point=None, timeout=None): self.preview_lock.acquire() picn = os.path.join(preview_dir, '00000001.jpg') self.mpv.vo_image_outdir = preview_dir self.mpv.start = t if scale is not None: self.mpv.vo_image_jpeg_quality = ui.live_preview_quality self.mpv.vf = "scale={}:{}".format(scale[0], scale[1]) else: self.mpv.vo_image_jpeg_quality = 90 self.mpv.vf = "" if (not os.path.exists(newpicn) and (self.ui.live_preview == "fast" or final_point is None or self.final_point == final_point)): self.mpv.play(url) self.mpv.wait_for_property("idle-active", lambda x : x, timeout=timeout) if os.path.exists(picn) and not os.path.exists(newpicn): shutil.move(picn, newpicn) self.mpv.stop = True self.preview_lock.release() def mouseMoveEvent(self, event, source=None): if ui.player_val != 'mplayer' or ui.mpvplayer_val.processId() == 0: self.setFocus() if self.tooltip_timer.isActive(): self.tooltip_timer.stop() if self.final_url != ui.final_playing_url: self.check_and_set_file_type() if (self.file_type == 'video' and ui.mpvplayer_val.processId() > 0 and ui.live_preview in ['slow', 'fast'] or ui.player_val == "libmpv"): self.create_preview_dir() self.preview_counter += 1 t = ((event.x() - self.x())/self.width()) if ui.extra_toolbar_control == 'slave' and ui.mpvplayer_val.processId() == 0: t = int(t*self.maximum()) else: t = int(t*ui.mplayerLength) #t = self.minimum() + ((self.maximum()-self.minimum()) * event.x()) / self.width() if ui.player_val == "mplayer": l=str((datetime.timedelta(milliseconds=t))) elif ui.player_val in ["mpv", "libmpv"]: l=str((datetime.timedelta(seconds=t))) else: l = str(0) if '.' in l: l = l.split('.')[0] change_aspect = False if source is not None: source_val = source.widget_name else: source_val = "none" if not os.path.exists(ui.preview_download_folder): os.makedirs(ui.preview_download_folder) if ui.live_preview in ['fast', 'slow'] and (ui.mpvplayer_val.processId() > 0 or ui.player_val in ["libmpv", "mpv"]) and self.file_type == 'video' and ui.extra_toolbar_control == "master": if self.preview_dir is None: self.create_preview_dir() command = 'mpv --vo=image --vo-image-jpeg-quality={} --no-sub --ytdl=no --quiet -aid=no -sid=no --vo-image-outdir="{}" --start={} --frames=1 "{}"'.format(ui.live_preview_quality, self.preview_dir, int(t), ui.final_playing_url) picn = os.path.join(self.preview_dir, '00000001.jpg') newpicn = os.path.join(self.preview_dir, "{}.jpg".format(int(t))) change_aspect = True if ui.player_val in ["libmpv", "mpv"]: #if True: self.final_point = (event.x(), event.y()) func = partial(self.mpv_preview, self.preview_dir, t, (ui.label.maximumWidth(), ui.label.maximumHeight()), newpicn, ui.final_playing_url, (event.x(), event.y()), timeout=0.5) apply_list = [newpicn, l, False, t, 0, event.x(), event.y(), source_val] if ui.live_preview == "fast" and not os.path.exists(newpicn): func() ui.gui_signals.generate_preview(*apply_list.copy()) else: if not os.path.exists(newpicn): pr_thread = PreviewThread(self, ui, func, apply_list) self.preview_thread_list.append(pr_thread) self.preview_thread_list[len(self.preview_thread_list)-1].start() #self.mpv_preview(self.preview_dir, t, # (ui.label.maximumWidth(), ui.label.maximumHeight()), # newpicn, ui.final_playing_url) #self.preview_generated(newpicn, l, False, t, 0, event.x(), event.y()) if os.path.exists(newpicn): ui.gui_signals.generate_preview(newpicn, l, False, t, 0, event.x(), event.y(), source_val) else: if self.tooltip is None: self.setToolTip(l) else: if source_val and source_val == "progressbar": offset = 25 else: offset = 0 point = QtCore.QPoint(self.parent.x()+event.x(), self.parent.y()+self.parent.height() - offset) rect = QtCore.QRect(self.parent.x(), self.parent.y() - offset , self.parent.width(), self.parent.height()) self.tooltip.showText(point, l, self, rect, 1000) if ui.live_preview in ['fast', 'slow'] and ui.mpvplayer_val.processId() > 0 and self.file_type == 'video' and ui.player_val not in ["mpv", "libmpv"]: self.setToolTip('') if os.path.isfile(newpicn) and self.final_url == ui.final_playing_url: use_existing = True else: use_existing = False if self.preview_process.processId() == 0 and not use_existing: self.info_preview( command, picn, l, change_aspect, t, self.preview_counter, event.x(), event.y(), use_existing, lock=False ) else: if self.preview_process.processId() > 0 or ui.live_preview == 'slow': self.preview_pending.append( (command, picn, l, change_aspect, t, self.preview_counter, event.x(), event.y(), use_existing) ) if ui.live_preview == 'fast' and self.preview_process.processId() == 0: if os.path.isfile(newpicn): self.apply_pic(newpicn, event.x(), event.y(), l, resize=True) else: self.apply_pic(picn, event.x(), event.y(), l, resize=True) elif ui.live_preview == 'fast' and self.preview_process.processId() > 0: self.apply_pic(picn, event.x(), event.y(), l, resize=True, only_text=True) def info_preview(self, command, picn, length, change_aspect, tsec, counter, x, y, use_existing=None, lock=None): if self.preview_process.processId() != 0: self.preview_process.kill() if self.preview_process.processId() == 0 and lock is False and not use_existing: ui.logger.debug('\npreview_generating - {} - {}\n'.format(length, tsec)) self.preview_process = QtCore.QProcess() self.preview_process.finished.connect(partial(self.preview_generated, picn, length, change_aspect, tsec, counter, x, y)) QtCore.QTimer.singleShot(1, partial(self.preview_process.start, command)) elif use_existing: newpicn = os.path.join(self.preview_dir, "{}.jpg".format(int(tsec))) if ui.live_preview == 'fast': self.apply_pic(newpicn, x, y, length) ui.logger.debug('\n use existing preview image \n') else: self.preview_process = QtCore.QProcess() command = 'echo "hello"' self.preview_process.finished.connect(partial(self.preview_generated, picn, length, change_aspect, tsec, counter, x, y)) QtCore.QTimer.singleShot(1, partial(self.preview_process.start, command)) def preview_generated(self, picn, length, change_aspect, tsec, counter, x, y, source_val=None): #self.tooltip_widget.hide() self.preview_counter -= 1 self.lock = True if not self.preview_dir: self.create_preview_dir() picnew = os.path.join(self.preview_dir, "{}.jpg".format(int(tsec))) if os.path.isfile(picn): if not os.path.isfile(picnew): shutil.copy(picn, picnew) picn = picnew if change_aspect: ui.image_fit_option(picn, picn, fit_size=6, widget=ui.label) else: picn = picnew txt = '<html><img src="{}">{}<html>'.format(picn, length) ui.logger.debug('\n{}::{}\n'.format(txt, tsec)) point = None rect = None self.apply_pic(picn, x, y, length, source_val=source_val) if self.preview_pending and ui.player_val != "libmpv": while self.preview_counter >= 0: self.preview_counter -= 1 ui.logger.debug('\n{}::{}\n'.format(len(self.preview_pending), self.preview_counter)) if ui.live_preview == 'slow': args = self.preview_pending[0] del self.preview_pending[0] else: args = self.preview_pending.pop() self.preview_pending[:] = [] ui.logger.debug(args) self.lock = False self.info_preview( args[0], args[1], args[2], args[3], args[4], args[5], args[6], args[7], args[8], lock=False ) def apply_pic(self, picn, x, y, length, resize=None, only_text=None, source_val=None): if resize: txt = '<html><img src="{0}" width="{2}"><p>{1}</p><html>'.format(picn, length, 100) else: txt = '<html><img src="{}"><p>{}</p><html>'.format(picn, length) if ui.live_preview_style == 'tooltip': try: if self.final_url != ui.final_playing_url and not resize: self.final_url = ui.final_playing_url img = Image.open(picn) self.half_size = int(img.size[0]/2) self.upper_limit = self.parent.x() + self.parent.width() self.lower_limit = self.parent.x() ui.logger.debug('\n change dimensions \n') except Exception as err: ui.logger.error(err) if self.tooltip is None: self.setToolTip('') self.setToolTip(txt) else: if ui.fullscreen_video or ui.force_fs: y_cord = self.parent.y() + self.parent.maximumHeight() - 25 else: y_cord = self.parent.y() + self.parent.maximumHeight() + 25 x_cord = self.parent.x() + x if x_cord + self.half_size > self.upper_limit: x_cord = self.upper_limit elif x_cord - self.half_size < self.lower_limit: x_cord = self.parent.x() else: x_cord = x_cord - self.half_size if source_val and source_val == "progressbar": offset = 25 else: offset = 0 print(offset) point = QtCore.QPoint(x_cord, y_cord - offset) rect = QtCore.QRect(self.parent.x(), self.parent.y() - offset, self.parent.width(), self.parent.height()) #print(self.parent.x(), self.parent.y(), self.parent.width(), self.parent.height()) if (not self.preview_pending or resize or ui.live_preview == 'slow') and self.enter: self.tooltip.showText(point, txt, self, rect, 3000) elif ui.live_preview_style == 'widget': try: if self.check_dimension_again and not resize: img = Image.open(picn) self.pic.setMaximumSize(QtCore.QSize(img.size[0], img.size[1])) self.pic.setMinimumSize(QtCore.QSize(img.size[0], img.size[1])) self.tooltip_widget.setMaximumSize(QtCore.QSize(img.size[0], img.size[1]+30)) self.tooltip_widget.setMinimumSize(QtCore.QSize(img.size[0], img.size[1]+30)) self.txt.setMaximumSize(QtCore.QSize(img.size[0], 30)) self.txt.setMinimumSize(QtCore.QSize(img.size[0], 30)) self.half_size = int(self.tooltip_widget.width()/2) self.upper_limit = self.parent.x() + self.parent.width() self.lower_limit = self.parent.x() ui.logger.debug('\nchange dimensions\n') self.check_dimension_again = False if self.final_url != ui.final_playing_url: img = Image.open(picn) self.pic.setMaximumSize(QtCore.QSize(img.size[0], img.size[1])) self.pic.setMinimumSize(QtCore.QSize(img.size[0], img.size[1])) self.tooltip_widget.setMaximumSize(QtCore.QSize(img.size[0], img.size[1]+30)) self.tooltip_widget.setMinimumSize(QtCore.QSize(img.size[0], img.size[1]+30)) self.txt.setMaximumSize(QtCore.QSize(img.size[0], 30)) self.txt.setMinimumSize(QtCore.QSize(img.size[0], 30)) self.final_url = ui.final_playing_url self.half_size = int(self.tooltip_widget.width()/2) self.upper_limit = self.parent.x() + self.parent.width() self.lower_limit = self.parent.x() ui.logger.debug('\nchange dimensions\n') self.check_dimension_again = True except Exception as err: ui.logger.error(err) if os.path.isfile(picn): if not only_text: self.pic.setPixmap(QtGui.QPixmap(picn, "1")) x_cord = self.parent.x()+x if x_cord + self.half_size > self.upper_limit: x_cord = self.upper_limit - self.tooltip_widget.width() elif x_cord - self.half_size < self.lower_limit: x_cord = self.parent.x() else: x_cord = x_cord - self.half_size y_cord = self.parent.y() - self.tooltip_widget.height() + ui.player_opt.height() if (not self.preview_pending or resize or ui.live_preview == 'slow') and self.enter: self.tooltip_widget.setGeometry(x_cord, y_cord, 128, 128) self.tooltip_widget.show() self.txt.setText(length) def update_tooltip(self): self.tooltip_widget.hide() def mousePressEvent(self, event, source=None): self.preview_counter = 0 old_val = int(self.value()) t = ((event.x() - self.x())/self.width()) if ui.extra_toolbar_control == 'slave' and ui.mpvplayer_val.processId() == 0: seek_per = round((t * 100), 2) ui.client_seek_val = seek_per ui.settings_box.playerseekabs.clicked.emit() t = int(t*self.maximum()) else: t = int(t*ui.mplayerLength) new_val = t if ui.player_val == 'mplayer': print(old_val, new_val, int((new_val-old_val)/1000)) else: print(old_val, new_val, int(new_val-old_val)) if ui.mpvplayer_val.processId() > 0 or ui.player_val == "libmpv": if ui.player_val == "mpv": var = bytes('\n '+"seek "+str(new_val)+" absolute"+' \n', 'utf-8') ui.mpvplayer_val.write(var) elif ui.player_val == "libmpv": try: ui.tab_5.mpv.command("seek", new_val, "absolute") except Exception as err: print(err) elif ui.player_val =="mplayer": seek_val = int((new_val-old_val)/1000) var = bytes('\n '+"seek "+str(seek_val)+' \n', 'utf-8') ui.mpvplayer_val.write(var) class VolumeSlider(QtWidgets.QSlider): def __init__(self, parent, uiwidget, mainwidget): super(VolumeSlider, self).__init__(parent) global ui, MainWindow MainWindow = mainwidget ui = uiwidget self.parent = parent self.setOrientation(QtCore.Qt.Horizontal) self.setRange(0, 100) self.setPageStep(2) self.setSingleStep(2) self.setMouseTracking(True) self.valueChanged.connect(self.adjust_volume) self.pressed = False self.setCursor(QtGui.QCursor(QtCore.Qt.PointingHandCursor)) self.release = False """ def mouseMoveEvent(self, event): if ui.frame1.isHidden(): ui.frame1.show() pos = int((event.x()/self.width())*100) def mousePressEvent(self, event): self.pressed = True self.release = False pos = int((event.x()/self.width())*100) while not self.release: print(pos, self.value()) if pos > self.value(): self.setValue(self.value() + 1) else: self.setValue(self.value() - 1) if self.value() >= 100 or self.value() <=0: break if pos == self.value(): break def mouseReleaseEvent(self, event): self.pressed = True self.release = True def keyPressEvent(self, event): if event.key() in [QtCore.Qt.Key_Right, QtCore.Qt.Key_Left]: self.pressed = False if event.key() == QtCore.Qt.Key_Right: self.setValue(self.value() + 1) else: self.setValue(self.value() - 1) ui.seek_to_vol_val(self.value(), action='dragged') ui.player_volume = str(self.value()) """ def adjust_volume(self, val): self.parent.volume_text.setPlaceholderText('{}'.format(val)) if ui.extra_toolbar_control == 'slave' and ui.pc_to_pc_casting == 'master': data_dict = {'param':'volume', 'volume':str(val)} ui.settings_box.slave_commands(data=data_dict) else: ui.player_volume = str(val) if ui.mpvplayer_val.processId() > 0 or ui.player_val == "libmpv": ui.seek_to_vol_val(val, action='pressed') ui.logger.debug(val) class QProgressBarCustom(QtWidgets.QProgressBar): def __init__(self, parent, gui): super(QProgressBarCustom, self).__init__(parent) self.gui = gui def mouseReleaseEvent(self, ev): if ev.button() == QtCore.Qt.LeftButton: if self.gui.video_local_stream: if self.gui.torrent_frame.isHidden(): self.gui.torrent_frame.show() self.gui.label_torrent_stop.setToolTip('Stop Torrent') self.gui.label_down_speed.show() self.gui.label_up_speed.show() if self.gui.torrent_download_limit == 0: down_rate = '\u221E' + ' K' else: down_rate = str(int(self.gui.torrent_download_limit/1024))+'K' if self.gui.torrent_upload_limit == 0: up_rate = '\u221E' + ' K' else: up_rate = str(int(self.gui.torrent_upload_limit/1024))+'K' down = '\u2193 RATE: ' +down_rate up = '\u2191 RATE:' +up_rate self.gui.label_down_speed.setPlaceholderText(down) self.gui.label_up_speed.setPlaceholderText(up) else: self.gui.torrent_frame.hide() else: if self.gui.torrent_frame.isHidden(): self.gui.torrent_frame.show() self.gui.label_down_speed.hide() self.gui.label_up_speed.hide() self.gui.label_torrent_stop.setToolTip('Stop Current Download') else: self.gui.torrent_frame.hide() class QProgressBarFrame(QtWidgets.QProgressBar): def __init__(self, parent, gui): super(QProgressBarFrame, self).__init__(parent) self.gui = gui self.widget_name = "progressbar" #self.setToolTip(True) def mouseMoveEvent(self, ev): self.gui.slider.mouseMoveEvent(ev, source=self) def mousePressEvent(self, ev): self.gui.slider.mousePressEvent(ev, source=self) def leaveEvent(self, ev): self.gui.slider.leaveEvent(ev, source=self) def enterEvent(self, ev): self.gui.slider.enterEvent(ev, source=self) class QLineCustom(QtWidgets.QLineEdit): def __init__(self, parent, ui_widget): super(QLineCustom, self).__init__(parent) global ui ui = ui_widget def keyPressEvent(self, event): if self.objectName() == 'go_page': if event.key() == QtCore.Qt.Key_Down: ui.list4.show() ui.list4.setFocus() self.show() elif event.key() == QtCore.Qt.Key_Up: ui.list4.show() ui.list4.setFocus() self.show() else: super(QLineCustom, self).keyPressEvent(event) elif self.objectName() == 'label_search': if event.key() in [QtCore.Qt.Key_Down, QtCore.Qt.Key_Return]: if not ui.list_poster.isHidden(): ui.list_poster.setFocus() elif not ui.scrollArea.isHidden(): ui.scrollArea.setFocus() elif not ui.scrollArea1.isHidden(): ui.scrollArea1.setFocus() else: super(QLineCustom, self).keyPressEvent(event) class QLineCustomSearch(QtWidgets.QLineEdit): def __init__(self, parent, ui_widget): super(QLineCustomSearch, self).__init__(parent) global ui ui = ui_widget def go_to_target(self): if ui.focus_widget == ui.list1: if ui.view_mode == 'thumbnail': ui.list1.setFocus() ui.tab_6.setFocus() ui.take_to_thumbnail(mode='title', focus=True) elif ui.view_mode == 'thumbnail_light': ui.tab_6.setFocus() ui.list_poster.setFocus() elif ui.focus_widget == ui.list2: if ui.view_mode == 'thumbnail_light': ui.tab_6.setFocus() ui.list_poster.setFocus() else: ui.list2.setFocus() if not ui.tab_6.isHidden(): ui.tab_6.setFocus() ui.take_to_thumbnail(mode='epn', focus=True) def keyPressEvent(self, event): print("down") if event.key() == QtCore.Qt.Key_Down: self.go_to_target() self.hide() elif event.key() == QtCore.Qt.Key_Up: self.hide() elif event.key() == QtCore.Qt.Key_Return: self.go_to_target() self.hide() else: super(QLineCustomSearch, self).keyPressEvent(event) class QLineCustomEpn(QtWidgets.QLineEdit): def __init__(self, parent, ui_widget): super(QLineCustomEpn, self).__init__(parent) global ui ui = ui_widget def keyPressEvent(self, event): if (event.type()==QtCore.QEvent.KeyPress) and (event.key() == QtCore.Qt.Key_Down): print("Down") ui.list5.setFocus() elif event.key() == QtCore.Qt.Key_Up: ui.list5.setFocus() super(QLineCustomEpn, self).keyPressEvent(event) class QLabelFloat(QtWidgets.QLabel): def __init(self, parent=None): QLabel.__init__(self, parent) def set_globals(self, uiwidget, home_dir): global ui, home ui = uiwidget home = home_dir def mouseMoveEvent(self, event): if ui.float_timer.isActive(): ui.float_timer.stop() if ui.new_tray_widget.cover_mode.text() == ui.player_buttons['up']: wid_height = int(ui.float_window.height()/3) else: wid_height = int(ui.float_window.height()) ui.new_tray_widget.setMaximumHeight(wid_height) ui.new_tray_widget.show() ui.float_timer.start(1000) print('float') def mouseEnterEvent(self, event): print('Enter Float') class SelectButton(QtWidgets.QComboBox): def __init__(self, parent, ui_widget): super(SelectButton, self).__init__(parent) global ui ui = ui_widget def keyPressEvent(self, event): if event.key() == QtCore.Qt.Key_Right: if not ui.list1.isHidden(): ui.list1.setFocus() elif not ui.scrollArea.isHidden(): ui.scrollArea.setFocus() elif not ui.scrollArea1.isHidden(): ui.scrollArea1.setFocus() elif not ui.list_poster.isHidden(): ui.list_poster.setFocus() if ui.auto_hide_dock: ui.dockWidget_3.hide() elif event.key() == QtCore.Qt.Key_Left: if self.currentText() == 'Addons': ui.btnAddon.setFocus() else: ui.list3.setFocus() else: super(SelectButton, self).keyPressEvent(event) class SmallLabel(QtWidgets.QLabel): def __init(self, parent): super(SmallLabel, self).__init__(parent) def set_param(self, parent): self.parent = parent def mousePressEvent(self, event): label_txt = self.text().lower() widget = eval('self.parent.{}_slider'.format(label_txt)) widget.setValue(0) class GSBCSlider(QtWidgets.QSlider): def __init__(self, parent, uiwidget, name): super(GSBCSlider, self).__init__(parent) global ui self.parent = parent ui = uiwidget self.setObjectName(name) self.setOrientation(QtCore.Qt.Horizontal) if name == 'zoom': self.setRange(-2000, 2000) self.setSingleStep(10) self.setPageStep(10) elif name == 'speed': self.setRange(-100, 900) self.setSingleStep(10) self.setPageStep(10) else: self.setRange(-100, 100) self.setSingleStep(1) self.setPageStep(1) #self.setTickInterval(5) self.setValue(0) self.setMouseTracking(True) self.valueChanged.connect(self.adjust_gsbc_values) self.setCursor(QtGui.QCursor(QtCore.Qt.PointingHandCursor)) #self.setTickPosition(QtWidgets.QSlider.TicksAbove) def adjust_gsbc_values(self, val): name = self.objectName() if ui.extra_toolbar_control == 'slave' and ui.pc_to_pc_casting == 'master': data_dict = {'param':'gsbc', name:str(val)} ui.settings_box.slave_commands(data=data_dict) if name == 'zoom': label_value = eval('self.parent.{}_value'.format(name)) zoom_val = 0.001* val label_value.setPlaceholderText(str(zoom_val)) elif name == 'speed': label_value = eval('self.parent.{}_value'.format(name)) speed_val = 1 + 0.01* val label_value.setPlaceholderText(str(speed_val)) else: label_value = eval('self.parent.{}_value'.format(name)) label_value.setPlaceholderText(str(val)) else: cmd = None if name == 'zoom': label_value = eval('self.parent.{}_value'.format(name)) zoom_val = 0.001* val label_value.setPlaceholderText(str(zoom_val)) if ui.player_val.lower() in ['mpv', 'libmpv']: cmd = '\n set video-zoom {} \n'.format(zoom_val) else: cmd = '\n set_property panscan {} \n'.format(zoom_val) if ui.mpvplayer_val.processId() > 0: ui.mpvplayer_val.write(bytes(cmd, 'utf-8')) elif name == 'speed': label_value = eval('self.parent.{}_value'.format(name)) speed_val = 1 + 0.01* val label_value.setPlaceholderText(str(speed_val)) if ui.player_val.lower() in ['mpv', 'libmpv']: cmd = '\n set speed {} \n'.format(speed_val) else: cmd = '\n set_property speed {} \n'.format(speed_val) if ui.mpvplayer_val.processId() > 0: ui.mpvplayer_val.write(bytes(cmd, 'utf-8')) else: label_value = eval('self.parent.{}_value'.format(name)) label_value.setPlaceholderText(str(val)) if ui.player_val.lower() in ['mpv', 'libmpv']: cmd = '\n set {} {} \n'.format(name, val) else: cmd = '\n set_property {} {} \n'.format(name, val) if ui.mpvplayer_val.processId() > 0: ui.mpvplayer_val.write(bytes(cmd, 'utf-8')) ui.gsbc_dict.update({name:val}) if cmd and ui.player_val == "libmpv": ui.mpvplayer_val.write(bytes(cmd, 'utf-8')) class SubtitleSlider(QtWidgets.QSlider): def __init__(self, parent, uiwidget, name): super(SubtitleSlider, self).__init__(parent) global ui self.parent = parent ui = uiwidget self.setObjectName(name) self.setOrientation(QtCore.Qt.Horizontal) if name == 'text': self.setRange(0, 100) self.setSingleStep(1) self.setPageStep(1) self.setValue(55) elif name == 'border': self.setRange(0, 100) self.setSingleStep(1) self.setPageStep(1) self.setValue(30) elif name == 'shadow': self.setRange(0, 100) self.setSingleStep(1) self.setPageStep(1) self.setValue(0) elif name == 'blur': self.setRange(0, 2000) self.setSingleStep(10) self.setPageStep(10) self.setValue(0) elif name == 'subscale': self.setRange(0, 1000) self.setSingleStep(10) self.setPageStep(10) self.setValue(100) elif name == 'space': self.setRange(-1000, 1000) self.setSingleStep(10) self.setPageStep(10) self.setValue(0) elif name in ['xmargin', 'ymargin', 'xymargin']: self.setRange(0, 100) self.setSingleStep(1) self.setPageStep(1) if name == 'xmargin': self.setValue(25) elif name == 'ymargin': self.setValue(22) else: self.setValue(0) self.setMouseTracking(True) self.valueChanged.connect(self.adjust_sub_size) self.setCursor(QtGui.QCursor(QtCore.Qt.PointingHandCursor)) def adjust_sub_size(self, val): name = self.objectName() if ui.extra_toolbar_control == 'slave' and ui.pc_to_pc_casting == 'master': data_dict = {'param':'subtitle', name:str(val)} ui.settings_box.slave_commands(data=data_dict) if name == 'text': label_value = eval('self.parent.subtitle_{}_value'.format(name)) label_value.setPlaceholderText(str(val)) elif name == 'border': label_value = eval('self.parent.subtitle_{}_value'.format(name)) value = val * 0.1 value_str = str(value) label_value.setPlaceholderText(value_str[:4]) elif name == 'shadow': label_value = eval('self.parent.subtitle_{}_value'.format(name)) value = val * 0.1 value_str = str(value) label_value.setPlaceholderText(value_str[:4]) elif name == 'blur': label_value = eval('self.parent.subtitle_{}_value'.format(name)) value = val * 0.01 value_str = str(value) label_value.setPlaceholderText(value_str[:4]) elif name == 'subscale': label_value = eval('self.parent.subtitle_{}_value'.format(name)) value = val * 0.01 value_str = str(value) label_value.setPlaceholderText(value_str[:4]) elif name == 'xmargin': label_value = eval('self.parent.subtitle_{}_value'.format(name)) label_value.setPlaceholderText(str(val)) elif name == 'ymargin': label_value = eval('self.parent.subtitle_{}_value'.format(name)) label_value.setPlaceholderText(str(val)) elif name == 'xymargin': val = 100 - val label_value = eval('self.parent.subtitle_{}_value'.format(name)) label_value.setPlaceholderText(str(val)) elif name == 'space': label_value = eval('self.parent.subtitle_{}_value'.format(name)) value = val * 0.01 value_str = str(value) label_value.setPlaceholderText(value_str[:4]) else: cmd = None if name == 'text': label_value = eval('self.parent.subtitle_{}_value'.format(name)) label_value.setPlaceholderText(str(val)) cmd = '\n set sub-font-size {} \n'.format(val) ui.subtitle_dict.update({'sub-font-size':str(val)}) if ui.mpvplayer_val.processId() > 0: ui.mpvplayer_val.write(bytes(cmd, 'utf-8')) elif name == 'border': label_value = eval('self.parent.subtitle_{}_value'.format(name)) value = val * 0.1 value_str = str(value) label_value.setPlaceholderText(value_str[:4]) cmd = '\n set sub-border-size {} \n'.format(value) ui.subtitle_dict.update({'sub-border-size':str(value)}) if ui.mpvplayer_val.processId() > 0: ui.mpvplayer_val.write(bytes(cmd, 'utf-8')) elif name == 'shadow': label_value = eval('self.parent.subtitle_{}_value'.format(name)) value = val * 0.1 value_str = str(value) label_value.setPlaceholderText(value_str[:4]) cmd = '\n set sub-shadow-offset {} \n'.format(value) ui.subtitle_dict.update({'sub-shadow-offset':str(value)}) if ui.mpvplayer_val.processId() > 0: ui.mpvplayer_val.write(bytes(cmd, 'utf-8')) elif name == 'blur': label_value = eval('self.parent.subtitle_{}_value'.format(name)) value = val * 0.01 value_str = str(value) label_value.setPlaceholderText(value_str[:4]) cmd = '\n set sub-blur {} \n'.format(value) ui.subtitle_dict.update({'sub-blur':str(value)}) if ui.mpvplayer_val.processId() > 0: ui.mpvplayer_val.write(bytes(cmd, 'utf-8')) elif name == 'subscale': label_value = eval('self.parent.subtitle_{}_value'.format(name)) value = val * 0.01 value_str = str(value) label_value.setPlaceholderText(value_str[:4]) if ui.player_val.lower() in ['mpv', 'libmpv']: cmd = '\n set sub-scale {} \n'.format(value) else: cmd = '\n set_property sub_scale {} \n'.format(value) if ui.mpvplayer_val.processId() > 0: ui.mpvplayer_val.write(bytes(cmd, 'utf-8')) ui.subtitle_dict.update({'sub-scale':value}) elif name == 'xmargin': label_value = eval('self.parent.subtitle_{}_value'.format(name)) label_value.setPlaceholderText(str(val)) cmd = '\n set sub-margin-x {} \n'.format(val) ui.subtitle_dict.update({'sub-margin-x':str(val)}) if ui.mpvplayer_val.processId() > 0: ui.mpvplayer_val.write(bytes(cmd, 'utf-8')) elif name == 'ymargin': label_value = eval('self.parent.subtitle_{}_value'.format(name)) label_value.setPlaceholderText(str(val)) cmd = '\n set sub-margin-y {} \n'.format(val) ui.subtitle_dict.update({'sub-margin-y':str(val)}) if ui.mpvplayer_val.processId() > 0: ui.mpvplayer_val.write(bytes(cmd, 'utf-8')) elif name == 'xymargin': val = 100 - val label_value = eval('self.parent.subtitle_{}_value'.format(name)) label_value.setPlaceholderText(str(val)) cmd = '\n set sub-pos {} \n'.format(val) ui.subtitle_dict.update({'sub-pos':str(val)}) if ui.mpvplayer_val.processId() > 0: ui.mpvplayer_val.write(bytes(cmd, 'utf-8')) elif name == 'space': label_value = eval('self.parent.subtitle_{}_value'.format(name)) value = val * 0.01 value_str = str(value) label_value.setPlaceholderText(value_str[:4]) cmd = '\n set sub-spacing {} \n'.format(value) ui.subtitle_dict.update({'sub-spacing':str(value)}) if ui.mpvplayer_val.processId() > 0: ui.mpvplayer_val.write(bytes(cmd, 'utf-8')) if ui.player_val == "libmpv" and cmd: ui.mpvplayer_val.write(bytes(cmd, 'utf-8')) class QLineCustomFont(QtWidgets.QLineEdit): def __init__(self, parent, ui_widget): super(QLineCustomFont, self).__init__(parent) global ui ui = ui_widget self.setMouseTracking(True) def mouseMoveEvent(self, event): if ui.tab_5.arrow_timer.isActive(): ui.tab_5.arrow_timer.stop() self.setFocus() class ExtraToolBar(QtWidgets.QFrame): def __init__(self, parent, uiwidget): super(ExtraToolBar, self).__init__(parent) global ui, MainWindow ui = uiwidget MainWindow = parent self.setCursor(QtGui.QCursor(QtCore.Qt.ArrowCursor)) self.setFrameShape(QtWidgets.QFrame.NoFrame) self.setFrameShadow(QtWidgets.QFrame.Raised) self.setObjectName("frame_extra_toolbar") self.super_layout = QtWidgets.QVBoxLayout(self) self.super_layout.setContentsMargins(0, 0, 0, 0) self.super_layout.setSpacing(0) self.tab_frame = QtWidgets.QFrame(self) self.tab_frame_layout = QtWidgets.QHBoxLayout(self.tab_frame) self.tab_frame_layout.setSpacing(0) self.tab_frame_layout.setContentsMargins(5,5,5,5) self.general_tab_btn = QPushButtonExtra(self.tab_frame) self.tab_frame_layout.insertWidget(0, self.general_tab_btn, 0) self.general_tab_btn.setText('General') self.general_tab_btn.clicked_connect(self.general_tab_show) self.subtitle_tab_btn = QPushButtonExtra(self.tab_frame) self.tab_frame_layout.insertWidget(1, self.subtitle_tab_btn, 0) self.subtitle_tab_btn.setText('Subtitle') self.subtitle_tab_btn.clicked_connect(self.subtitle_tab_show) self.master_slave_tab_btn = QPushButtonExtra(self.tab_frame) self.tab_frame_layout.insertWidget(2, self.master_slave_tab_btn, 0) self.master_slave_tab_btn.setText('Master') self.master_slave_tab_btn.clicked_connect(self.toggle_master_slave) msg = ('<html>Toggle use of Extra Toolbar between Master and Slave.\ Only useful in PC-To-PC casting mode.\ Toggle it to Slave, in order to use controls available in\ Extra Toolbar to control Slave Computer from Master. </html>') self.master_slave_tab_btn.setToolTip(msg) self.child_frame = QtWidgets.QFrame(self) self.subtitle_frame = QtWidgets.QFrame(self) self.super_layout.insertWidget(0, self.tab_frame, 0) self.super_layout.insertWidget(1, self.child_frame, 0) self.super_layout.insertWidget(2, self.subtitle_frame, 0) self.subtitle_frame.hide() self.sub_layout = QtWidgets.QVBoxLayout(self.subtitle_frame) self.layout = QtWidgets.QVBoxLayout(self.child_frame) self.layout.setObjectName("extra_toolbar_layout") self.playlist_hide = False self.hide() self.gsbc_layout = QtWidgets.QGridLayout(self) self.gsbc_layout.setObjectName('gsbc_layout') self.layout.insertLayout(1, self.gsbc_layout) self.brightness_slider = GSBCSlider(self, uiwidget, 'brightness') self.contrast_slider = GSBCSlider(self, uiwidget, 'contrast') self.saturation_slider = GSBCSlider(self, uiwidget, 'saturation') self.gamma_slider = GSBCSlider(self, uiwidget, 'gamma') self.hue_slider = GSBCSlider(self, uiwidget, 'hue') self.zoom_slider = GSBCSlider(self, uiwidget, 'zoom') self.speed_slider = GSBCSlider(self, uiwidget, 'speed') self.brightness_label = SmallLabel(self) self.brightness_label.setText('Brightness') self.brightness_value = QtWidgets.QLineEdit(self) self.contrast_label = SmallLabel(self) self.contrast_label.setText('Contrast') self.contrast_value = QtWidgets.QLineEdit(self) self.saturation_label = SmallLabel(self) self.saturation_label.setText('Saturation') self.saturation_value = QtWidgets.QLineEdit(self) self.gamma_label = SmallLabel(self) self.gamma_label.setText('Gamma') self.gamma_value = QtWidgets.QLineEdit(self) self.hue_label = SmallLabel(self) self.hue_label.setText('Hue') self.hue_value = QtWidgets.QLineEdit(self) self.zoom_label = SmallLabel(self) self.zoom_label.setText('Zoom') self.zoom_value = QtWidgets.QLineEdit(self) self.speed_label = SmallLabel(self) self.speed_label.setText('Speed') self.speed_value = QtWidgets.QLineEdit(self) self.speed_value.setPlaceholderText('1.0') label_list = [ self.brightness_label, self.contrast_label, self.saturation_label, self.gamma_label, self.hue_label, self.zoom_label, self.speed_label ] for label in label_list: label.set_param(self) label.setStyleSheet(""" text-align:left;background:rgba(0,0,0,0); """) label.setToolTip('Click on Text To Reset') slider_list = [ self.contrast_slider, self.brightness_slider, self.gamma_slider, self.saturation_slider, self.hue_slider, self.zoom_slider, self.speed_slider ] for index, slider in enumerate(slider_list): label = eval("self.{}_label".format(slider.objectName())) label_value = eval("self.{}_value".format(slider.objectName())) label_value.setMaximumWidth(42) label_value.setPlaceholderText(str(slider.value())) label_value.returnPressed.connect(partial(self.gsbc_entered, label_value, slider)) self.gsbc_layout.addWidget(label, index, 0, 1, 1) self.gsbc_layout.addWidget(slider, index, 1, 1, 3) self.gsbc_layout.addWidget(label_value, index, 5, 1, 1) self.buttons_layout = QtWidgets.QGridLayout(self) self.buttons_layout.setObjectName('buttons_layout') self.layout.insertLayout(2, self.buttons_layout) self.btn_aspect_label = QtWidgets.QLabel(self) self.btn_aspect_label.setText('Aspect\nRatio') self.buttons_layout.addWidget(self.btn_aspect_label, 0, 0, 2, 1) self.btn_aspect_original = QPushButtonExtra(self) self.btn_aspect_original.setText('Original') self.btn_aspect_original.clicked_connect(partial(self.change_aspect, 'original', 'btn_aspect_original')) self.buttons_layout.addWidget(self.btn_aspect_original, 0, 1, 1, 2) self.btn_aspect_disable = QPushButtonExtra(self) self.btn_aspect_disable.setText('Disable') self.btn_aspect_disable.clicked_connect(partial(self.change_aspect, 'disable', 'btn_aspect_disable')) self.buttons_layout.addWidget(self.btn_aspect_disable, 0, 3, 1, 1) self.btn_aspect_4_3 = QPushButtonExtra(self) self.btn_aspect_4_3.setText('4:3') self.btn_aspect_4_3.clicked_connect(partial(self.change_aspect, '4:3', 'btn_aspect_4_3')) self.buttons_layout.addWidget(self.btn_aspect_4_3, 1, 1, 1, 1) self.btn_aspect_16_9 = QPushButtonExtra(self) self.btn_aspect_16_9.setText('16:9') self.btn_aspect_16_9.clicked_connect(partial(self.change_aspect, '16:9', 'btn_aspect_16_9')) self.buttons_layout.addWidget(self.btn_aspect_16_9, 1, 2, 1, 1) self.btn_aspect_235 = QPushButtonExtra(self) self.btn_aspect_235.setText('2.35:1') self.btn_aspect_235.clicked_connect(partial(self.change_aspect, '2.35:1', 'btn_aspect_235')) self.buttons_layout.addWidget(self.btn_aspect_235, 1, 3, 1, 1) self.btn_scr_label = QtWidgets.QLabel(self) self.btn_scr_label.setText('Screenshot') self.buttons_layout.addWidget(self.btn_scr_label, 2, 0, 1, 1) self.btn_scr_1 = QPushButtonExtra(self) self.btn_scr_1.setText('1') self.btn_scr_1.clicked_connect(partial(self.execute_command, 'async screenshot', 'btn_scr_1')) self.buttons_layout.addWidget(self.btn_scr_1, 2, 1, 1, 1) self.btn_scr_1.setToolTip("Take Screenshot with subtitle") self.btn_scr_2 = QPushButtonExtra(self) self.btn_scr_2.setText('2') self.btn_scr_2.clicked_connect(partial(self.execute_command, 'async screenshot video', 'btn_scr_2')) self.buttons_layout.addWidget(self.btn_scr_2, 2, 2, 1, 1) self.btn_scr_2.setToolTip("Take Screenshot without subtitle") self.btn_scr_3 = QPushButtonExtra(self) self.btn_scr_3.setText('3') self.btn_scr_3.clicked_connect(partial(self.execute_command, 'async screenshot window', 'btn_scr_3')) self.buttons_layout.addWidget(self.btn_scr_3, 2, 3, 1, 1) self.btn_scr_3.setToolTip("Take Screenshot with window") """ self.btn_speed_half = QPushButtonExtra(self) self.btn_speed_half.setText('0.5x') self.btn_speed_half.clicked_connect(partial(self.adjust_speed, '0.5')) self.buttons_layout.addWidget(self.btn_speed_half, 3, 0, 1, 1) self.btn_speed_half.setToolTip('Half Speed') self.btn_speed_reset = QPushButtonExtra(self) self.btn_speed_reset.setText('1x') self.btn_speed_reset.clicked_connect(partial(self.adjust_speed, '1.0')) self.buttons_layout.addWidget(self.btn_speed_reset, 3, 1, 1, 1) self.btn_speed_reset.setToolTip('Original Speed') self.btn_speed_did = QPushButtonExtra(self) self.btn_speed_did.setText('1.5x') self.btn_speed_did.clicked_connect(partial(self.adjust_speed, '1.5')) self.buttons_layout.addWidget(self.btn_speed_did, 3, 2, 1, 1) self.btn_speed_did.setToolTip('Multiply speed by 1.5') self.btn_speed_twice = QPushButtonExtra(self) self.btn_speed_twice.setText('2x') self.btn_speed_twice.clicked_connect(partial(self.adjust_speed, '2.0')) self.buttons_layout.addWidget(self.btn_speed_twice, 3, 3, 1, 1) self.btn_speed_twice.setToolTip('Multiply speed by 2') """ self.btn_sub_minus = QPushButtonExtra(self) self.btn_sub_minus.setText('Sub-') self.btn_sub_minus.clicked_connect(partial(self.execute_command, 'add sub-delay -0.1', 'btn_sub_minus')) self.buttons_layout.addWidget(self.btn_sub_minus, 4, 0, 1, 1) self.btn_sub_minus.setToolTip('Add Subtitle Delay of -0.1s') self.btn_sub_plus = QPushButtonExtra(self) self.btn_sub_plus.setText('Sub+') self.btn_sub_plus.clicked_connect(partial(self.execute_command, 'add sub-delay +0.1', 'btn_sub_plus')) self.buttons_layout.addWidget(self.btn_sub_plus, 4, 1, 1, 1) self.btn_sub_plus.setToolTip('Add Subtitle Delay of +0.1s') self.btn_aud_minus = QPushButtonExtra(self) self.btn_aud_minus.setText('A-') self.btn_aud_minus.clicked_connect(partial(self.execute_command, 'add audio-delay -0.1', 'btn_aud_minus')) self.buttons_layout.addWidget(self.btn_aud_minus, 4, 2, 1, 1) self.btn_aud_minus.setToolTip('Add Audio Delay of -0.1s') self.btn_aud_plus = QPushButtonExtra(self) self.btn_aud_plus.setText('A+') self.btn_aud_plus.clicked_connect(partial(self.execute_command, 'add audio-delay +0.1', 'btn_aud_plus')) self.buttons_layout.addWidget(self.btn_aud_plus, 4, 3, 1, 1) self.btn_aud_plus.setToolTip('Add Audio Delay of +0.1s') self.btn_chapter_minus = QPushButtonExtra(self) self.btn_chapter_minus.setText('Chapter-') self.btn_chapter_minus.clicked_connect(partial(self.add_chapter, '-', 'btn_chapter_minus')) self.buttons_layout.addWidget(self.btn_chapter_minus, 5, 0, 1, 2) self.btn_chapter_plus = QPushButtonExtra(self) self.btn_chapter_plus.setText('Chapter+') self.btn_chapter_plus.clicked_connect(partial(self.add_chapter, '+', 'btn_chapter_plus')) self.buttons_layout.addWidget(self.btn_chapter_plus, 5, 2, 1, 2) self.btn_show_stat = QPushButtonExtra(self) self.btn_show_stat.setText('Stats') self.btn_show_stat.setToolTip('<html>Show Some Statistics on Video. Applicable only for mpv v0.28+</html>') self.btn_show_stat.clicked_connect( partial(self.execute_command, 'script-binding stats/display-stats-toggle', 'btn_show_stat') ) self.buttons_layout.addWidget(self.btn_show_stat, 6, 0, 1, 1) self.btn_fs_window = QPushButtonExtra(self) self.btn_fs_window.setText('FS') self.btn_fs_window.setToolTip('Toggle Application Fullscreen') #self.btn_fs_window.clicked_connect(ui.fullscreenToggle) self.btn_fs_window.clicked_connect(partial(self.execute_command, 'TAFS', 'btn_fs_window')) self.buttons_layout.addWidget(self.btn_fs_window, 6, 1, 1, 1) self.btn_fs_video = QPushButtonExtra(self) self.btn_fs_video.setText('F') self.btn_fs_video.setToolTip('Toggle Video Fullscreen') #self.btn_fs_window.clicked_connect(ui.fullscreenToggle) self.btn_fs_video.clicked_connect(partial(self.execute_command, 'TVFS', 'btn_fs_video')) self.buttons_layout.addWidget(self.btn_fs_video, 6, 2, 1, 1) self.btn_external_sub = QPushButtonExtra(self) self.btn_external_sub.setText('ES') self.btn_external_sub.setToolTip('Load External Subtitle') self.btn_external_sub.clicked_connect(partial(self.execute_command, 'external-subtitle', 'btn_external_sub')) self.buttons_layout.addWidget(self.btn_external_sub, 6, 3, 1, 1) self.volume_layout = QtWidgets.QGridLayout(self) self.volume_layout.setObjectName('volume_layout') self.layout.insertLayout(3, self.volume_layout) self.scale_label = QtWidgets.QLabel(self) self.scale_label.setText('Sub Scale') self.volume_layout.addWidget(self.scale_label, 0, 0, 1, 1) self.subscale_slider = SubtitleSlider(self, uiwidget, 'subscale') self.subscale_slider.setObjectName("subscale") self.volume_layout.addWidget(self.subscale_slider, 0, 1, 1, 3) self.subtitle_subscale_value = QtWidgets.QLineEdit(self) self.subtitle_subscale_value.returnPressed.connect( partial(self.gsbc_entered, self.subtitle_subscale_value, self.subscale_slider) ) self.volume_layout.addWidget(self.subtitle_subscale_value, 0, 5, 1, 1) self.subtitle_subscale_value.setMaximumWidth(32) self.subtitle_subscale_value.setPlaceholderText('1.0') self.scale_label.setToolTip('<html>Scale factor for subtitle. Default 1.0.\ This affects ASS subtitles as well, and may lead to incorrect subtitle rendering.\ Use with care, or use Text size from Subtitle Section instead.</html>') self.volume_label = QtWidgets.QLabel(self) self.volume_label.setText('Volume') self.volume_layout.addWidget(self.volume_label, 1, 0, 1, 1) self.slider_volume = VolumeSlider(self, uiwidget, MainWindow) self.slider_volume.setObjectName("slider_volume") self.volume_layout.addWidget(self.slider_volume, 1, 1, 1, 3) self.volume_text = QtWidgets.QLineEdit(self) self.volume_text.returnPressed.connect(self.volume_entered) self.volume_layout.addWidget(self.volume_text, 1, 5, 1, 1) self.volume_text.setMaximumWidth(32) self.speed_value.setPlaceholderText('1.0') self.speed_value.setToolTip('Default Original Speed 1.0') self.generate_subtitle_frame() self.subtitle_box_opened = False def toggle_master_slave(self): txt = self.master_slave_tab_btn.text() if txt.lower() == 'master': self.master_slave_tab_btn.setText('Slave') ui.extra_toolbar_control = 'slave' if not ui.settings_box.tabs_present: ui.gui_signals.box_settings('hide') else: self.master_slave_tab_btn.setText('Master') ui.extra_toolbar_control = 'master' def generate_subtitle_frame(self): try: self.font_families = [i for i in QtGui.QFontDatabase().families()] except Exception as err: ui.logger.error(err) self.font_families = [ui.global_font] self.sub_grid = QtWidgets.QGridLayout(self) self.sub_layout.insertLayout(0, self.sub_grid) self.completer = QtWidgets.QCompleter(self.font_families) self.completer.setCaseSensitivity(QtCore.Qt.CaseInsensitive) self.font_label = QtWidgets.QLabel(self) self.font_label.setText('Font') self.font_label.setToolTip('<html>Set Subtitle Font. Start typing\ in text box to see available fonts starting with an entered letter.</html>') self.sub_grid.addWidget(self.font_label, 0, 0, 1, 1) self.font_value = QLineCustomFont(self, ui) self.font_value.setCompleter(self.completer) self.sub_grid.addWidget(self.font_value, 0, 1, 1, 3) self.font_value.setPlaceholderText(ui.global_font) self.font_value.returnPressed.connect(partial(self.change_sub_font, self.font_value, 'font_value')) self.font_value.textChanged['QString'].connect(self.font_value_changed) self.font_color_label = QtWidgets.QLabel(self) self.font_color_label.setText('Text Color') self.font_color_label.setToolTip('<html>Set Subtitle Text Color</html>') self.font_color_label.setWordWrap(True) self.sub_grid.addWidget(self.font_color_label, 1, 0, 1, 1) self.font_color_value = QPushButtonExtra(self) self.font_color_value.clicked_connect( partial(self.choose_color, self.font_color_value, 'text', 'font_color_value') ) self.sub_grid.addWidget(self.font_color_value, 1, 1, 1, 3) self.border_color_label = QtWidgets.QLabel(self) self.border_color_label.setText('Border') self.border_color_label.setToolTip('<html>Set Subtitle Border Color</html>') self.border_color_label.setWordWrap(True) self.sub_grid.addWidget(self.border_color_label, 2, 0, 1, 1) self.border_color_value = QPushButtonExtra(self) self.border_color_value.clicked_connect( partial(self.choose_color, self.border_color_value, 'border', 'border_color_value') ) self.sub_grid.addWidget(self.border_color_value, 2, 1, 1, 3) self.shadow_color_label = QtWidgets.QLabel(self) self.shadow_color_label.setText('Shadow') self.shadow_color_label.setToolTip('<html>Set Subtitle Shadow Color</html>') self.shadow_color_label.setWordWrap(True) self.sub_grid.addWidget(self.shadow_color_label, 3, 0, 1, 1) self.shadow_color_value = QPushButtonExtra(self) self.shadow_color_value.clicked_connect( partial(self.choose_color, self.shadow_color_value, 'shadow', 'shadow_color_value') ) self.sub_grid.addWidget(self.shadow_color_value, 3, 1, 1, 3) self.checkbox_bold = QtWidgets.QCheckBox("Bold") self.checkbox_bold.stateChanged.connect( partial(self.checkbox_options, self.checkbox_bold, 'checkbox_bold') ) self.sub_grid.addWidget(self.checkbox_bold, 4, 0, 1, 1) self.checkbox_italic = QtWidgets.QCheckBox("Italic") self.checkbox_italic.stateChanged.connect( partial(self.checkbox_options, self.checkbox_italic, 'checkbox_italic') ) self.sub_grid.addWidget(self.checkbox_italic, 4, 1, 1, 1) self.checkbox_gray = QtWidgets.QCheckBox("GrayScale") self.checkbox_gray.stateChanged.connect( partial(self.checkbox_options, self.checkbox_gray, 'checkbox_gray') ) self.sub_grid.addWidget(self.checkbox_gray, 4, 2, 1, 2) self.checkbox_gray.setToolTip('Useful only for yellow DVD/Vobsubs') self.subtitle_text_label = QtWidgets.QLabel(self) self.subtitle_text_label.setText('Text Size') self.subtitle_text_label.setToolTip('<html>Set Subtitle Text Size. Default, 55</html>') self.subtitle_text_label.setWordWrap(True) self.sub_grid.addWidget(self.subtitle_text_label, 5, 0, 1, 1) self.subtitle_text_slider = SubtitleSlider(self, ui, 'text') self.sub_grid.addWidget(self.subtitle_text_slider, 5, 1, 1, 2) self.subtitle_text_value = QtWidgets.QLineEdit(self) self.subtitle_text_value.setPlaceholderText('55') self.sub_grid.addWidget(self.subtitle_text_value, 5, 3, 1, 1) self.subtitle_text_value.setMaximumWidth(42) self.subtitle_text_value.setToolTip('Default, 55') self.subtitle_text_value.returnPressed.connect( partial(self.gsbc_entered, self.subtitle_text_value, self.subtitle_text_slider) ) self.subtitle_border_label = QtWidgets.QLabel(self) self.subtitle_border_label.setText('Border') self.subtitle_border_label.setToolTip('<html>Set Subtitle Border Size. Default, 3</html>') self.subtitle_border_label.setWordWrap(True) self.sub_grid.addWidget(self.subtitle_border_label, 6, 0, 1, 1) self.subtitle_border_slider = SubtitleSlider(self, ui, 'border') self.sub_grid.addWidget(self.subtitle_border_slider, 6, 1, 1, 2) self.subtitle_border_value = QtWidgets.QLineEdit(self) self.subtitle_border_value.setPlaceholderText('3') self.sub_grid.addWidget(self.subtitle_border_value, 6, 3, 1, 1) self.subtitle_border_value.setMaximumWidth(42) self.subtitle_border_value.setToolTip('Default, 3') self.subtitle_border_value.returnPressed.connect( partial(self.gsbc_entered, self.subtitle_border_value, self.subtitle_border_slider) ) self.subtitle_shadow_label = QtWidgets.QLabel(self) self.subtitle_shadow_label.setText('Shadow') self.subtitle_shadow_label.setToolTip('<html>Set Subtitle Shadow Size. Default, 0</html>') self.subtitle_shadow_label.setWordWrap(True) self.sub_grid.addWidget(self.subtitle_shadow_label, 7, 0, 1, 1) self.subtitle_shadow_slider = SubtitleSlider(self, ui, 'shadow') self.sub_grid.addWidget(self.subtitle_shadow_slider, 7, 1, 1, 2) self.subtitle_shadow_value = QtWidgets.QLineEdit(self) self.subtitle_shadow_value.setPlaceholderText('0') self.sub_grid.addWidget(self.subtitle_shadow_value, 7, 3, 1, 1) self.subtitle_shadow_value.setMaximumWidth(42) self.subtitle_shadow_value.setToolTip('Default, 0') self.subtitle_shadow_value.returnPressed.connect( partial(self.gsbc_entered, self.subtitle_shadow_value, self.subtitle_shadow_slider) ) self.subtitle_space_label = QtWidgets.QLabel(self) self.subtitle_space_label.setText('Spacing') self.subtitle_space_label.setToolTip('<html>Set Spacing</html>') self.sub_grid.addWidget(self.subtitle_space_label, 8, 0, 1, 1) self.subtitle_space_slider = SubtitleSlider(self, ui, 'space') self.sub_grid.addWidget(self.subtitle_space_slider, 8, 1, 1, 2) self.subtitle_space_value = QtWidgets.QLineEdit(self) self.subtitle_space_value.setPlaceholderText('0') self.sub_grid.addWidget(self.subtitle_space_value, 8, 3, 1, 1) self.subtitle_space_value.setMaximumWidth(42) self.subtitle_space_value.setToolTip('Default, 0') self.subtitle_space_value.returnPressed.connect( partial(self.gsbc_entered, self.subtitle_space_value, self.subtitle_space_slider) ) self.subtitle_blur_label = QtWidgets.QLabel(self) self.subtitle_blur_label.setText('Blur') self.subtitle_blur_label.setToolTip('<html>Set Gaussian Blur Factor. Default, 0</html>') self.subtitle_blur_label.setWordWrap(True) self.sub_grid.addWidget(self.subtitle_blur_label, 9, 0, 1, 1) self.subtitle_blur_slider = SubtitleSlider(self, ui, 'blur') self.sub_grid.addWidget(self.subtitle_blur_slider, 9, 1, 1, 2) self.subtitle_blur_value = QtWidgets.QLineEdit(self) self.subtitle_blur_value.setPlaceholderText('0') self.sub_grid.addWidget(self.subtitle_blur_value, 9, 3, 1, 1) self.subtitle_blur_value.setMaximumWidth(42) self.subtitle_blur_value.setToolTip('Default, 0') self.subtitle_blur_value.returnPressed.connect( partial(self.gsbc_entered, self.subtitle_blur_value, self.subtitle_blur_slider) ) self.subtitle_xmargin_label = QtWidgets.QLabel(self) self.subtitle_xmargin_label.setText('X-Margin') self.sub_grid.addWidget(self.subtitle_xmargin_label, 10, 0, 1, 1) self.subtitle_xmargin_slider = SubtitleSlider(self, ui, 'xmargin') self.sub_grid.addWidget(self.subtitle_xmargin_slider, 10, 1, 1, 2) self.subtitle_xmargin_value = QtWidgets.QLineEdit(self) self.subtitle_xmargin_value.setPlaceholderText('25') self.sub_grid.addWidget(self.subtitle_xmargin_value, 10, 3, 1, 1) self.subtitle_xmargin_value.setMaximumWidth(42) self.subtitle_xmargin_value.setToolTip('Default, 25') self.subtitle_xmargin_value.returnPressed.connect( partial(self.gsbc_entered, self.subtitle_xmargin_value, self.subtitle_xmargin_slider) ) #self.subtitle_xmargin_value.hide() self.subtitle_ymargin_label = QtWidgets.QLabel(self) self.subtitle_ymargin_label.setText('Y-Margin') self.sub_grid.addWidget(self.subtitle_ymargin_label, 11, 0, 1, 1) self.subtitle_ymargin_slider = SubtitleSlider(self, ui, 'ymargin') self.sub_grid.addWidget(self.subtitle_ymargin_slider, 11, 1, 1, 2) self.subtitle_ymargin_value = QtWidgets.QLineEdit(self) self.subtitle_ymargin_value.setPlaceholderText('22') self.sub_grid.addWidget(self.subtitle_ymargin_value, 11, 3, 1, 1) self.subtitle_ymargin_value.setMaximumWidth(42) self.subtitle_ymargin_value.setToolTip('Default, 22') self.subtitle_ymargin_value.returnPressed.connect( partial(self.gsbc_entered, self.subtitle_ymargin_value, self.subtitle_ymargin_slider) ) #self.subtitle_ymargin_value.hide() self.subtitle_xymargin_label = QtWidgets.QLabel(self) self.subtitle_xymargin_label.setText('Vertical') self.subtitle_xymargin_label.setToolTip('<html>Move Subtitle Vertically</html>') self.sub_grid.addWidget(self.subtitle_xymargin_label, 12, 0, 1, 1) self.subtitle_xymargin_slider = SubtitleSlider(self, ui, 'xymargin') self.sub_grid.addWidget(self.subtitle_xymargin_slider, 12, 1, 1, 2) self.subtitle_xymargin_value = QtWidgets.QLineEdit(self) self.subtitle_xymargin_value.setPlaceholderText('100') self.sub_grid.addWidget(self.subtitle_xymargin_value, 12, 3, 1, 1) self.subtitle_xymargin_value.setMaximumWidth(42) self.subtitle_xymargin_value.setToolTip('Default, 100') self.subtitle_xymargin_value.returnPressed.connect( partial(self.gsbc_entered, self.subtitle_xymargin_value, self.subtitle_xymargin_slider) ) self.subtitle_align_label = QtWidgets.QLabel(self) self.subtitle_align_label.setText('Alignment') self.sub_grid.addWidget(self.subtitle_align_label, 13, 0, 1, 1) self.subtitle_horiz_align = QtWidgets.QComboBox(self) self.sub_grid.addWidget(self.subtitle_horiz_align, 13, 1, 1, 1) for i in ['Center', 'Left', 'Right']: self.subtitle_horiz_align.addItem(i) self.subtitle_horiz_align.currentIndexChanged['int'].connect( partial(self.change_alignment, self.subtitle_horiz_align, 'x', 'subtitle_horiz_align') ) self.subtitle_vertical_align = QtWidgets.QComboBox(self) self.sub_grid.addWidget(self.subtitle_vertical_align, 13, 2, 1, 1) for i in ['Bottom', 'Middle', 'Top']: self.subtitle_vertical_align.addItem(i) self.subtitle_vertical_align.currentIndexChanged['int'].connect( partial(self.change_alignment, self.subtitle_vertical_align, 'y', 'subtitle_vertical_align') ) """ self.spinbox_space = QtWidgets.QDoubleSpinBox(self) self.sub_grid.addWidget(self.spinbox_space, 12, 3, 1, 1) self.spinbox_space.setRange(-50.0, 50.0) self.spinbox_space.setValue(0) self.spinbox_space.setSingleStep(0.1) self.spinbox_space.valueChanged.connect(partial(self.spinbox_changed, self.spinbox_space, 'space')) self.spinbox_space.setMaximumWidth(42) self.spinbox_space.setDecimals(1) self.spinbox_scale_label = QtWidgets.QLabel(self) self.spinbox_scale_label.setText('Scale') self.sub_grid.addWidget(self.spinbox_scale_label, 13, 0, 1, 1) self.spinbox_scale = QtWidgets.QDoubleSpinBox(self) self.sub_grid.addWidget(self.spinbox_scale, 13, 1, 1, 1) self.spinbox_scale.setRange(0.00, 10.00) self.spinbox_scale.setValue(1.00) self.spinbox_scale.setSingleStep(0.1) self.spinbox_scale.setToolTip('<html>Scale factor for subtitle. Default 1.0.\ This affects ASS subtitles as well, and may lead to incorrect subtitle rendering.\ Use with care, or use Text size from above instead.</html>') self.spinbox_scale.valueChanged.connect(partial(self.spinbox_changed, self.spinbox_scale, 'scale')) self.spinbox_scale.hide() self.spinbox_scale_label.hide() """ self.ass_override_label = QtWidgets.QLabel(self) self.ass_override_label.setText('Sub ASS Override') self.ass_override_label.setWordWrap(True) self.sub_grid.addWidget(self.ass_override_label, 14, 0, 1, 2) self.ass_override_label.setToolTip('Apply Above Style to ASS files.') self.ass_override_value = QtWidgets.QComboBox(self) for i in ['Yes', 'No', 'Force', 'Scale', 'Strip']: self.ass_override_value.addItem(i) self.ass_override_value.currentIndexChanged['int'].connect(self.ass_override_function) self.ass_override_value.setCurrentIndex(0) self.sub_grid.addWidget(self.ass_override_value, 14, 2, 1, 1) self.ass_override_value.setToolTip('Default, Yes') self.checkbox_dont = QtWidgets.QCheckBox("Don't Apply Above Settings") self.checkbox_dont.stateChanged.connect( partial(self.checkbox_options, self.checkbox_dont, 'checkbox_dont') ) self.sub_grid.addWidget(self.checkbox_dont, 15, 0, 1, 3) self.checkbox_dont.setToolTip('<html>Do not apply above custom settings</html>') self.subtitle_widgets = { 'sub-ass-override': self.ass_override_value, 'sub-font': self.font_value, 'sub-color': self.font_color_value, 'sub-border-color': self.border_color_value, 'sub-shadow-color': self.shadow_color_value, 'sub-bold': self.checkbox_bold, 'sub-italic': self.checkbox_italic, 'sub-gray': self.checkbox_gray, 'sub-font-size': self.subtitle_text_slider, 'sub-border-size': self.subtitle_border_slider, 'sub-shadow-offset': self.subtitle_shadow_slider, 'sub-blur': self.subtitle_blur_slider, 'sub-margin-x': self.subtitle_xmargin_slider, 'sub-margin-y': self.subtitle_ymargin_slider, 'sub-pos': self.subtitle_xymargin_slider, 'sub-align-x': self.subtitle_horiz_align, 'sub-align-y': self.subtitle_vertical_align, 'sub-spacing': self.subtitle_space_slider } def change_alignment(self, widget, val, widget_name=None): txt = widget.currentText().lower() if txt == 'middle': txt = 'center' if ui.extra_toolbar_control == 'slave' and ui.pc_to_pc_casting == 'master': self.execute_command('change_align', {widget_name:txt}) else: cmd = None if val == 'x': cmd = 'set sub-align-x "{}"'.format(txt) ui.subtitle_dict.update({'sub-align-x':txt}) elif val == 'y': cmd = 'set sub-align-y "{}"'.format(txt) ui.subtitle_dict.update({'sub-align-y':txt}) if cmd: self.execute_command(cmd) def spinbox_changed(self, widget, val): flval = widget.value() if val == 'scale': self.execute_command('set sub-scale {}'.format(flval)) ui.subtitle_dict.update({'sub-scale':flval}) elif val == 'space': self.execute_command('set sub-spacing {}'.format(flval)) def font_value_changed(self): self.font_value.setFocus() def ass_override_function(self): txt = self.ass_override_value.currentText().lower() if ui.extra_toolbar_control == 'slave' and ui.pc_to_pc_casting == 'master': self.execute_command('ass_override', {'ass_override_value':txt}) else: ui.subtitle_dict.update({'sub-ass-override':txt}) self.execute_command('set sub-ass-override {}'.format(txt)) def change_sub_font(self, widget, widget_name): txt = widget.text() widget.clear() widget.setPlaceholderText(txt) if ui.extra_toolbar_control == 'slave' and ui.pc_to_pc_casting == 'master': self.execute_command('change_font', {widget_name:txt}) else: ui.subtitle_dict.update({'sub-font':txt}) self.execute_command('set sub-font "{}"'.format(txt)) def checkbox_options(self, widget, widget_name): if ui.extra_toolbar_control == 'slave' and ui.pc_to_pc_casting == 'master': self.execute_command('checkbox', {widget_name:str(widget.isChecked())}) else: cmd = None if widget_name == 'checkbox_bold': if widget.isChecked(): ui.subtitle_dict.update({'sub-bold':'yes'}) cmd = 'set sub-bold yes' else: ui.subtitle_dict.update({'sub-bold':'no'}) cmd = 'set sub-bold no' elif widget_name == 'checkbox_italic': if widget.isChecked(): ui.subtitle_dict.update({'sub-italic':'yes'}) cmd = 'set sub-italic yes' else: ui.subtitle_dict.update({'sub-italic':'no'}) cmd = 'set sub-italic no' elif widget_name == 'checkbox_gray': if widget.isChecked(): ui.subtitle_dict.update({'sub-gray':'yes'}) cmd = 'set sub-gray yes' else: ui.subtitle_dict.update({'sub-gray':'no'}) cmd = 'set sub-gray no' elif widget_name == 'checkbox_dont': if widget.isChecked(): ui.apply_subtitle_settings = False else: ui.apply_subtitle_settings = True ui.playerStop(msg='remember quit', restart=True) if cmd: self.execute_command(cmd) def general_tab_show(self): self.subtitle_frame.hide() self.child_frame.show() def get_default_color(self, widget, name): color_name = None if name == 'text': color_name = ui.subtitle_dict.get('sub-color') if not color_name: color_name = '#FFFFFF' elif name == 'border': color_name = ui.subtitle_dict.get('sub-border-color') if not color_name: color_name = '#000000' elif name == 'shadow': color_name = ui.subtitle_dict.get('sub-shadow-color') if not color_name: color_name = '#FFFFFF' return color_name def choose_color(self, widget, name, widget_name): default_color = self.get_default_color(widget, name) color = QtWidgets.QColorDialog.getColor(QtGui.QColor(default_color)) if color.isValid(): color_name = color.name().upper() widget.setStyleSheet('background:{};'.format(color_name)) if ui.extra_toolbar_control == 'slave' and ui.pc_to_pc_casting == 'master': self.execute_command('choose_color', {widget_name:color_name}) else: cmd = None if name == 'text': ui.subtitle_dict.update({'sub-color':color_name}) cmd = 'set sub-color "{}"'.format(color_name) elif name == 'border': ui.subtitle_dict.update({'sub-border-color':color_name}) cmd = 'set sub-border-color "{}"'.format(color_name) elif name == 'shadow': ui.subtitle_dict.update({'sub-shadow-color':color_name}) cmd = 'set sub-shadow-color "{}"'.format(color_name) if cmd: self.execute_command(cmd) def apply_slave_subtitile_effects(self, widget_name, color_name): widget = eval('ui.frame_extra_toolbar.{}'.format(widget_name)) widget.setStyleSheet('background:{};'.format(color_name)) cmd = None if widget_name == 'font_color_value': ui.subtitle_dict.update({'sub-color':color_name}) cmd = 'set sub-color "{}"'.format(color_name) elif widget_name == 'border_color_value': ui.subtitle_dict.update({'sub-border-color':color_name}) cmd = 'set sub-border-color "{}"'.format(color_name) elif widget_name == 'shadow_color_value': ui.subtitle_dict.update({'sub-shadow-color':color_name}) cmd = 'set sub-shadow-color "{}"'.format(color_name) if cmd: self.execute_command(cmd) def subtitle_tab_show(self): self.subtitle_frame.setMinimumHeight(self.child_frame.height()) #self.subtitle_frame.setMaximumHeight(self.child_frame.height()) self.child_frame.hide() self.subtitle_frame.show() if not self.subtitle_box_opened: self.subtitle_box_opened = True self.apply_initial_sub_settings() print(self.subtitle_frame.height(), self.child_frame.height()) if self.subtitle_frame.height() > self.child_frame.height(): self.child_frame.setMinimumHeight(self.subtitle_frame.height()) def apply_initial_sub_settings(self): for property_name in ui.subtitle_dict: property_value = ui.subtitle_dict.get(property_name) widget = self.subtitle_widgets.get(property_name) if widget and property_value: if property_name == 'sub-font': widget.clear() widget.setPlaceholderText(property_value) elif property_name in ['sub-color', 'sub-border-color', 'sub-shadow-color']: widget.setStyleSheet("background:{};".format(property_value)) elif property_name in ['sub-bold', 'sub-italic', 'sub-gray']: if property_value == 'yes': widget.setChecked(True) else: widget.setChecked(False) elif property_name in ['sub-font-size', 'sub-margin-x', 'sub-margin-y']: if isinstance(property_value, int): widget.setValue(property_value) elif isinstance(property_value, str): if property_value.isnumeric(): widget.setValue(int(property_value)) elif property_name == 'sub-pos': if property_value.isnumeric(): widget.setValue(100 - int(property_value)) elif property_name in ['sub-border-size', 'sub-shadow-offset']: new_val = float(property_value) * 10 widget.setValue(new_val) elif property_name in ['sub-blur', 'sub-spacing']: new_val = float(property_value) * 100 widget.setValue(new_val) elif property_name == 'sub-scale': new_val = float(property_value) widget.setValue(new_val) elif property_name in ['sub-ass-override', 'sub-align-x', 'sub-align-y']: if property_name == 'sub-align-y' and property_value == 'center': property_value = 'Middle' property_value = property_value.title() index = widget.findText(property_value) widget.setCurrentIndex(index) def mouseMoveEvent(self, event): self.setFocus() if not self.subtitle_frame.isHidden(): self.subtitle_frame.setFocus() elif not self.child_frame.isHidden(): self.child_frame.setFocus() def change_aspect(self, val, widget=None): if val == '2.35:1': key = '3' elif val == 'disable': key = '4' elif val == '16:9': key = '1' elif val == '4:3': key = '2' else: key = '0' if ui.extra_toolbar_control == 'slave' and ui.pc_to_pc_casting == 'master': data_dict = {'param':'click', 'widget':widget} ui.settings_box.slave_commands(data=data_dict) else: ui.tab_5.change_aspect_ratio(key=key) def execute_command(self, msg, widget=None): if ui.extra_toolbar_control == 'slave' and ui.pc_to_pc_casting == 'master': if msg == 'external-subtitle': ui.list2.send_subtitle_method() elif isinstance(widget, dict): data_dict = {'param':'click'} for key, val in widget.items(): data_dict.update({key:val}) ui.settings_box.slave_commands(data=data_dict) else: data_dict = {'param':'click', 'widget':widget} ui.settings_box.slave_commands(data=data_dict) else: if msg == 'external-subtitle': ui.tab_5.load_external_sub() elif msg == 'TAFS': ui.fullscreenToggle() elif msg == 'TVFS': if ui.mpvplayer_val.processId() > 0 or ui.player_val == "libmpv": if ui.player_val == "libmpv": if platform.system().lower() == "darwin": ui.tab_5.mpv.command("set", "pause", "yes") MainWindow.showMaximized() ui.force_fs = False if platform.system().lower() == "darwin": ui.tab_5.fs_timer.start(2000) else: ui.tab_5.fs_timer.start(500) else: ui.tab_5.toggle_fullscreen_mode() if ui.tab_5.arrow_timer.isActive(): ui.tab_5.arrow_timer.stop() ui.tab_5.arrow_timer.start(5000) elif ui.mpvplayer_val.processId() > 0 or ui.player_val == "libmpv": if ui.player_val.lower() == 'mplayer': if 'sub-delay' in msg or 'audio-delay' in msg: msg = msg.replace('add ', '') msg = msg.strip() if 'sub-delay' in msg: msg = msg.replace('sub-delay', 'sub_delay') elif 'audio-delay' in msg: msg = msg.replace('audio-delay', 'audio_delay') elif 'screenshot' in msg: msg = 'screenshot 0' bmsg = bytes('\n {} \n'.format(msg), 'utf-8') print(bmsg) ui.mpvplayer_val.write(bmsg) pmsg = None if 'sub-delay' in msg: if ui.player_val.lower() in ['mpv', 'libmpv']: pmsg = '\n show-text "Sub delay: ${sub-delay}" \n' else: pmsg = '\n osd_show_property_text "Sub delay: ${sub_delay}" \n' elif 'audio-delay' in msg: if ui.player_val.lower() in ['mpv', 'libmpv']: pmsg = '\n show-text "A-V delay: ${audio-delay}" \n' else: pmsg = '\n osd_show_property_text "A-V delay: ${audio_delay}" \n' if pmsg: pmsg = bytes(pmsg, 'utf-8') ui.mpvplayer_val.write(pmsg) def add_chapter(self, val, widget=None): if ui.extra_toolbar_control == 'slave' and ui.pc_to_pc_casting == 'master': data_dict = {'param':'click', 'widget':widget} ui.settings_box.slave_commands(data=data_dict) else: if val == '-': if ui.player_val.lower() in ['mpv', 'libmpv']: msg = bytes('\n add chapter -1 \n', 'utf-8') else: msg = bytes('\n seek_chapter -1 0 \n', 'utf-8') else: if ui.player_val.lower() in ['mpv', 'libmpv']: msg = bytes('\n add chapter 1 \n', 'utf-8') else: msg = bytes('\n seek_chapter +1 0 \n', 'utf-8') ui.mpvplayer_val.write(msg) if ui.player_val.lower() in ['mpv', 'libmpv']: pmsg = bytes('\n show-text "Chapter: ${chapter}" \n', 'utf-8') else: pmsg = bytes('\n osd_show_property_text "Chapter: ${chapter}" \n', 'utf-8') ui.mpvplayer_val.write(pmsg) def adjust_speed(self, val): msg = None if val == '1.0': msg = bytes('\n set speed 1.0 \n', 'utf-8') else: msg = bytes('\n multiply speed {} \n'.format(val), 'utf-8') if msg: ui.mpvplayer_val.write(msg) def volume_entered(self): txt = self.volume_text.text() self.volume_text.clear() if txt.isnumeric(): self.slider_volume.setValue(int(txt)) def gsbc_entered(self, label, slider): value = label.text() label.clear() try: if slider.objectName() == 'zoom': label.setPlaceholderText(value) value = float(value)*100 slider.setValue(int(value)) elif slider.objectName() == 'speed': label.setPlaceholderText(value) value = float(value)*100 - 100 slider.setValue(int(value)) elif slider.objectName() in ['border', 'shadow']: label.setPlaceholderText(value) value = float(value)*10 slider.setValue(int(value)) elif slider.objectName() in ['blur', 'space']: label.setPlaceholderText(value) value = float(value)*100 slider.setValue(int(value)) elif slider.objectName() == 'subscale': label.setPlaceholderText(value) value = float(value)*100 slider.setValue(int(value)) elif slider.objectName() == 'xymargin': label.setPlaceholderText(value) value = 100 - int(value) slider.setValue(value) else: slider.setValue(int(value)) label.setPlaceholderText(value) except Exception as err: ui.logger.error(err) slider.setValue(0) label.setPlaceholderText('0')