You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

1463 lines
50 KiB

10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
  1. #!/usr/bin/env python2
  2. # -*- coding: utf-8 -*-
  3. """Youtubedlg module responsible for the options window. """
  4. from __future__ import unicode_literals
  5. import os
  6. import gettext
  7. import wx
  8. from .version import __version__
  9. from .info import (
  10. __descriptionfull__,
  11. __licensefull__,
  12. __projecturl__,
  13. __appname__,
  14. __author__
  15. )
  16. from .utils import TwoWayOrderedDict as twodict
  17. class OptionsFrame(wx.Frame):
  18. """Youtubedlg options frame class.
  19. Attributes:
  20. FRAME_TITLE (string): Options window title.
  21. *_TAB (string): Constant string with the name of each tab.
  22. Args:
  23. parent (mainframe.MainFrame): Parent class.
  24. """
  25. FRAME_TITLE = _("Options")
  26. GENERAL_TAB = _("General")
  27. VIDEO_TAB = _("Video")
  28. AUDIO_TAB = _("Audio")
  29. PLAYLIST_TAB = _("Playlist")
  30. OUTPUT_TAB = _("Output")
  31. SUBTITLES_TAB = _("Subtitles")
  32. FILESYS_TAB = _("Filesystem")
  33. SHUTDOWN_TAB = _("Shutdown")
  34. AUTH_TAB = _("Authentication")
  35. CONNECTION_TAB = _("Connection")
  36. LOG_TAB = _("Log")
  37. CMD_TAB = _("Commands")
  38. LOCALIZATION_TAB = _("Localization")
  39. def __init__(self, parent):
  40. wx.Frame.__init__(self, parent, title=self.FRAME_TITLE, size=parent.opt_manager.options['opts_win_size'])
  41. self.opt_manager = parent.opt_manager
  42. self.log_manager = parent.log_manager
  43. self.app_icon = parent.app_icon
  44. if self.app_icon is not None:
  45. self.SetIcon(self.app_icon)
  46. # Create GUI
  47. panel = wx.Panel(self)
  48. notebook = wx.Notebook(panel)
  49. # Create Tabs
  50. tab_args = (self, notebook)
  51. self.tabs = (
  52. (GeneralTab(*tab_args), self.GENERAL_TAB),
  53. (VideoTab(*tab_args), self.VIDEO_TAB),
  54. (AudioTab(*tab_args), self.AUDIO_TAB),
  55. (PlaylistTab(*tab_args), self.PLAYLIST_TAB),
  56. (OutputTab(*tab_args), self.OUTPUT_TAB),
  57. (SubtitlesTab(*tab_args), self.SUBTITLES_TAB),
  58. (FilesystemTab(*tab_args), self.FILESYS_TAB),
  59. (ShutdownTab(*tab_args), self.SHUTDOWN_TAB),
  60. (AuthenticationTab(*tab_args), self.AUTH_TAB),
  61. (ConnectionTab(*tab_args), self.CONNECTION_TAB),
  62. (LogTab(*tab_args), self.LOG_TAB),
  63. (CMDTab(*tab_args), self.CMD_TAB),
  64. (LocalizationTab(*tab_args), self.LOCALIZATION_TAB)
  65. )
  66. # Add tabs on notebook
  67. for tab, label in self.tabs:
  68. notebook.AddPage(tab, label)
  69. sizer = wx.BoxSizer()
  70. sizer.Add(notebook, 1, wx.EXPAND)
  71. panel.SetSizer(sizer)
  72. self.Bind(wx.EVT_CLOSE, self._on_close)
  73. self.load_all_options()
  74. def _on_close(self, event):
  75. """Event handler for wx.EVT_CLOSE event.
  76. This method is used to save the options and hide the options window.
  77. """
  78. self.save_all_options()
  79. self.Hide()
  80. def reset(self):
  81. """Resets the default options. """
  82. self.opt_manager.load_default()
  83. self.load_all_options()
  84. def load_all_options(self):
  85. """Load options from optionsmanager.OptionsManager
  86. on each tab. """
  87. for tab, _ in self.tabs:
  88. tab.load_options()
  89. def save_all_options(self):
  90. """Save options back to optionsmanager.OptionsManager
  91. from each tab. """
  92. for tab, _ in self.tabs:
  93. tab.save_options()
  94. class TabPanel(wx.Panel):
  95. """Main tab class from which each tab inherits.
  96. Contains methods to create widgets, load options etc..
  97. Attributes:
  98. Each of this attributes is the Default one. In order to use a
  99. different size you must overwrite the corresponding attribute
  100. on the child object.
  101. CHECKBOX_SIZE (tuple): wx.Checkbox size (width, height). On Windows
  102. we change the height value in order to look the same with Linux.
  103. BUTTONS_SIZE (tuple): wx.Button size (width, height)
  104. TEXTCTRL_SIZE (tuple): wx.TextCtrl size (width, height)
  105. SPINCTRL_SIZE (tuple): wx.SpinCtrl size (width, height)
  106. SIZE_* (int): Constant size number.
  107. Args:
  108. parent (OptionsFrame): The parent of all tabs.
  109. notebook (wx.Notebook): The container for each tab.
  110. """
  111. CHECKBOX_SIZE = (-1, -1)
  112. if os.name == 'nt':
  113. CHECKBOX_SIZE = (-1, 25)
  114. BUTTONS_SIZE = (-1, -1)
  115. TEXTCTRL_SIZE = (-1, -1)
  116. SPINCTRL_SIZE = (70, 20)
  117. SIZE_80 = 80
  118. SIZE_50 = 50
  119. SIZE_40 = 40
  120. SIZE_30 = 30
  121. SIZE_20 = 20
  122. SIZE_15 = 15
  123. SIZE_10 = 10
  124. SIZE_5 = 5
  125. def __init__(self, parent, notebook):
  126. wx.Panel.__init__(self, notebook)
  127. self.opt_manager = parent.opt_manager
  128. self.log_manager = parent.log_manager
  129. self.app_icon = parent.app_icon
  130. self.reset_handler = parent.reset
  131. def create_button(self, label, event_handler=None):
  132. """Creates and returns an wx.Button.
  133. Args:
  134. label (string): wx.Button label.
  135. event_handler (function): Can be any function with one parameter
  136. the event item.
  137. Note:
  138. In order to change the button size you need to overwrite the
  139. BUTTONS_SIZE attribute on the child class.
  140. """
  141. button = wx.Button(self, label=label, size=self.BUTTONS_SIZE)
  142. if event_handler is not None:
  143. button.Bind(wx.EVT_BUTTON, event_handler)
  144. return button
  145. def create_checkbox(self, label, event_handler=None):
  146. """Creates and returns an wx.CheckBox.
  147. Args:
  148. label (string): wx.CheckBox label.
  149. event_handler (function): Can be any function with one parameter
  150. the event item.
  151. Note:
  152. In order to change the checkbox size you need to overwrite the
  153. CHECKBOX_SIZE attribute on the child class.
  154. """
  155. checkbox = wx.CheckBox(self, label=label, size=self.CHECKBOX_SIZE)
  156. if event_handler is not None:
  157. checkbox.Bind(wx.EVT_CHECKBOX, event_handler)
  158. return checkbox
  159. def create_textctrl(self, style=None):
  160. """Creates and returns an wx.TextCtrl.
  161. Args:
  162. style (long): Can be any valid wx.TextCtrl style.
  163. Note:
  164. In order to change the textctrl size you need to overwrite the
  165. TEXTCTRL_SIZE attribute on the child class.
  166. """
  167. if style is None:
  168. textctrl = wx.TextCtrl(self, size=self.TEXTCTRL_SIZE)
  169. else:
  170. textctrl = wx.TextCtrl(self, size=self.TEXTCTRL_SIZE, style=style)
  171. return textctrl
  172. def create_combobox(self, choices, size=(-1, -1), event_handler=None):
  173. """Creates and returns an wx.ComboBox.
  174. Args:
  175. choices (list): List of strings that contains the choices for the
  176. wx.ComboBox widget.
  177. size (tuple): wx.ComboBox size (width, height).
  178. event_handler (function): Can be any function with one parameter
  179. the event item.
  180. """
  181. combobox = wx.ComboBox(self, choices=choices, size=size)
  182. if event_handler is not None:
  183. combobox.Bind(wx.EVT_COMBOBOX, event_handler)
  184. return combobox
  185. def create_dirdialog(self, label):
  186. """Creates and returns an wx.DirDialog.
  187. Args:
  188. label (string): wx.DirDialog widget title.
  189. """
  190. dlg = wx.DirDialog(self, label)
  191. return dlg
  192. def create_radiobutton(self, label, event_handler=None, style=None):
  193. """Creates and returns an wx.RadioButton.
  194. Args:
  195. label (string): wx.RadioButton label.
  196. event_handler (function): Can be any function with one parameter
  197. the event item.
  198. style (long): Can be any valid wx.RadioButton style.
  199. """
  200. if style is None:
  201. radiobutton = wx.RadioButton(self, label=label)
  202. else:
  203. radiobutton = wx.RadioButton(self, label=label, style=style)
  204. if event_handler is not None:
  205. radiobutton.Bind(wx.EVT_RADIOBUTTON, event_handler)
  206. return radiobutton
  207. def create_spinctrl(self, spin_range=(0, 999)):
  208. """Creates and returns an wx.SpinCtrl.
  209. Args:
  210. spin_range (tuple): wx.SpinCtrl range (min, max).
  211. Note:
  212. In order to change the size of the spinctrl widget you need
  213. to overwrite the SPINCTRL_SIZE attribute on the child class.
  214. """
  215. spinctrl = wx.SpinCtrl(self, size=self.SPINCTRL_SIZE)
  216. spinctrl.SetRange(*spin_range)
  217. return spinctrl
  218. def create_statictext(self, label):
  219. """Creates and returns an wx.StaticText.
  220. Args:
  221. label (string): wx.StaticText label.
  222. """
  223. statictext = wx.StaticText(self, label=label)
  224. return statictext
  225. def create_popup(self, text, title, style):
  226. """Creates an wx.MessageBox.
  227. Args:
  228. text (string): wx.MessageBox message.
  229. title (string): wx.MessageBox title.
  230. style (long): Can be any valid wx.MessageBox style.
  231. """
  232. wx.MessageBox(text, title, style)
  233. def _set_sizer(self):
  234. """Sets the sizer for the current panel.
  235. You need to overwrite this method on the child class in order
  236. to set the panels sizers.
  237. """
  238. pass
  239. def _disable_items(self):
  240. """Disables widgets.
  241. If you want any widgets to be disabled by default you specify
  242. them in this method.
  243. Example:
  244. mybutton.Disable()
  245. """
  246. pass
  247. def load_options(self):
  248. """Load options from the optionsmanager.OptionsManager object
  249. to the current tab. """
  250. pass
  251. def save_options(self):
  252. """Save options of the current tab back to
  253. optionsmanager.OptionsManager object. """
  254. pass
  255. class LogTab(TabPanel):
  256. """Options frame log tab.
  257. Attributes:
  258. Constant strings for the widgets.
  259. """
  260. ENABLE_LABEL = _("Enable Log")
  261. WRITE_LABEL = _("Write Time")
  262. CLEAR_LABEL = _("Clear Log")
  263. VIEW_LABEL = _("View Log")
  264. PATH_LABEL = _("Path: {0}")
  265. LOGSIZE_LABEL = _("Log Size: {0} Bytes")
  266. RESTART_LABEL = _("Restart")
  267. RESTART_MSG = _("Please restart {0}")
  268. def __init__(self, *args, **kwargs):
  269. super(LogTab, self).__init__(*args, **kwargs)
  270. self.enable_checkbox = self.create_checkbox(self.ENABLE_LABEL, self._on_enable)
  271. self.time_checkbox = self.create_checkbox(self.WRITE_LABEL, self._on_time)
  272. self.clear_button = self.create_button(self.CLEAR_LABEL, self._on_clear)
  273. self.view_button = self.create_button(self.VIEW_LABEL, self._on_view)
  274. self.log_path = self.create_statictext(self.PATH_LABEL.format(self._get_logpath()))
  275. self.log_size = self.create_statictext(self.LOGSIZE_LABEL.format(self._get_logsize()))
  276. self._set_sizer()
  277. self._disable_items()
  278. def _set_sizer(self):
  279. main_sizer = wx.BoxSizer(wx.VERTICAL)
  280. main_sizer.AddSpacer(self.SIZE_20)
  281. main_sizer.Add(self.enable_checkbox, flag=wx.ALIGN_CENTER_HORIZONTAL)
  282. main_sizer.AddSpacer(self.SIZE_5)
  283. main_sizer.Add(self.time_checkbox, flag=wx.ALIGN_CENTER_HORIZONTAL)
  284. main_sizer.AddSpacer(self.SIZE_15)
  285. buttons_sizer = wx.BoxSizer(wx.HORIZONTAL)
  286. buttons_sizer.Add(self.clear_button)
  287. buttons_sizer.AddSpacer(self.SIZE_20)
  288. buttons_sizer.Add(self.view_button)
  289. main_sizer.Add(buttons_sizer, flag=wx.ALIGN_CENTER_HORIZONTAL)
  290. main_sizer.AddSpacer(self.SIZE_20)
  291. main_sizer.Add(self.log_path, flag=wx.ALIGN_CENTER_HORIZONTAL)
  292. main_sizer.AddSpacer(self.SIZE_10)
  293. main_sizer.Add(self.log_size, flag=wx.ALIGN_CENTER_HORIZONTAL)
  294. self.SetSizer(main_sizer)
  295. def _disable_items(self):
  296. if self.log_manager is None:
  297. self.time_checkbox.Disable()
  298. self.clear_button.Disable()
  299. self.view_button.Disable()
  300. self.log_path.Hide()
  301. self.log_size.Hide()
  302. def _get_logpath(self):
  303. """Returns the path to the log file. """
  304. if self.log_manager is None:
  305. return ''
  306. return self.log_manager.log_file
  307. def _get_logsize(self):
  308. """Returns the size(Bytes) of the log file. """
  309. if self.log_manager is None:
  310. return 0
  311. return self.log_manager.log_size()
  312. def _set_logsize(self):
  313. """Updates the self.log_size widget with the current log file size ."""
  314. self.log_size.SetLabel(self.LOGSIZE_LABEL.format(self._get_logsize()))
  315. def _on_time(self, event):
  316. """Event handler for self.time_checkbox. """
  317. self.log_manager.add_time = self.time_checkbox.GetValue()
  318. def _on_enable(self, event):
  319. """Event handler for self.enable_checkbox. """
  320. self.create_popup(self.RESTART_MSG.format(__appname__),
  321. self.RESTART_LABEL,
  322. wx.OK | wx.ICON_INFORMATION)
  323. def _on_clear(self, event):
  324. """Event handler for self.clear_button. """
  325. self.log_manager.clear()
  326. self.log_size.SetLabel(self.LOGSIZE_LABEL.format(self._get_logsize()))
  327. def _on_view(self, event):
  328. """Event handler for self.view_button. """
  329. logger_gui = LogGUI(self)
  330. logger_gui.Show()
  331. logger_gui.load(self.log_manager.log_file)
  332. def load_options(self):
  333. self.enable_checkbox.SetValue(self.opt_manager.options['enable_log'])
  334. self.time_checkbox.SetValue(self.opt_manager.options['log_time'])
  335. self._set_logsize()
  336. def save_options(self):
  337. self.opt_manager.options['enable_log'] = self.enable_checkbox.GetValue()
  338. self.opt_manager.options['log_time'] = self.time_checkbox.GetValue()
  339. class ShutdownTab(TabPanel):
  340. """Options frame shutdown tab.
  341. Attributes:
  342. TEXTCTRL_SIZE (tuple): Overwrites the TEXTCTRL_SIZE attribute of
  343. the TabPanel class.
  344. *_LABEL (string): Constant string label for the widgets.
  345. """
  346. TEXTCTRL_SIZE = (250, 25)
  347. SHUTDOWN_LABEL = _("Shutdown when finished")
  348. SUDO_LABEL = _("SUDO password")
  349. def __init__(self, *args, **kwargs):
  350. super(ShutdownTab, self).__init__(*args, **kwargs)
  351. self.shutdown_checkbox = self.create_checkbox(self.SHUTDOWN_LABEL, self._on_shutdown_check)
  352. self.sudo_text = self.create_statictext(self.SUDO_LABEL)
  353. self.sudo_box = self.create_textctrl(wx.TE_PASSWORD)
  354. self._set_sizer()
  355. self._disable_items()
  356. def _disable_items(self):
  357. if os.name == 'nt':
  358. self.sudo_text.Hide()
  359. self.sudo_box.Hide()
  360. def _set_sizer(self):
  361. main_sizer = wx.BoxSizer(wx.VERTICAL)
  362. main_sizer.AddSpacer(self.SIZE_40)
  363. main_sizer.Add(self.shutdown_checkbox, flag=wx.ALIGN_CENTER_HORIZONTAL)
  364. main_sizer.AddSpacer(self.SIZE_20)
  365. main_sizer.Add(self.sudo_text, flag=wx.ALIGN_CENTER_HORIZONTAL)
  366. main_sizer.AddSpacer(self.SIZE_5)
  367. main_sizer.Add(self.sudo_box, flag=wx.ALIGN_CENTER_HORIZONTAL)
  368. self.SetSizer(main_sizer)
  369. def _on_shutdown_check(self, event):
  370. """Event handler for self.shutdown_checkbox. """
  371. self.sudo_box.Enable(self.shutdown_checkbox.GetValue())
  372. def load_options(self):
  373. self.shutdown_checkbox.SetValue(self.opt_manager.options['shutdown'])
  374. self.sudo_box.SetValue(self.opt_manager.options['sudo_password'])
  375. self._on_shutdown_check(None)
  376. def save_options(self):
  377. self.opt_manager.options['shutdown'] = self.shutdown_checkbox.GetValue()
  378. self.opt_manager.options['sudo_password'] = self.sudo_box.GetValue()
  379. class PlaylistTab(TabPanel):
  380. """Options frame playlist tab.
  381. Attributes:
  382. *_LABEL (string): Constant string label for the widgets.
  383. """
  384. START_LABEL = _("Playlist Start")
  385. STOP_LABEL = _("Playlist Stop")
  386. MAX_LABEL = _("Max Downloads")
  387. def __init__(self, *args, **kwargs):
  388. super(PlaylistTab, self).__init__(*args, **kwargs)
  389. self.start_spinctrl = self.create_spinctrl((1, 999))
  390. self.stop_spinctrl = self.create_spinctrl()
  391. self.max_spinctrl = self.create_spinctrl()
  392. self.start_text = self.create_statictext(self.START_LABEL)
  393. self.stop_text = self.create_statictext(self.STOP_LABEL)
  394. self.max_text = self.create_statictext(self.MAX_LABEL)
  395. self._set_sizer()
  396. def _set_sizer(self):
  397. main_sizer = wx.BoxSizer(wx.VERTICAL)
  398. main_sizer.AddSpacer(self.SIZE_20)
  399. main_sizer.Add(self.start_text, flag=wx.ALIGN_CENTER_HORIZONTAL)
  400. main_sizer.AddSpacer(self.SIZE_5)
  401. main_sizer.Add(self.start_spinctrl, flag=wx.ALIGN_CENTER_HORIZONTAL)
  402. main_sizer.AddSpacer(self.SIZE_15)
  403. main_sizer.Add(self.stop_text, flag=wx.ALIGN_CENTER_HORIZONTAL)
  404. main_sizer.AddSpacer(self.SIZE_5)
  405. main_sizer.Add(self.stop_spinctrl, flag=wx.ALIGN_CENTER_HORIZONTAL)
  406. main_sizer.AddSpacer(self.SIZE_15)
  407. main_sizer.Add(self.max_text, flag=wx.ALIGN_CENTER_HORIZONTAL)
  408. main_sizer.AddSpacer(self.SIZE_5)
  409. main_sizer.Add(self.max_spinctrl, flag=wx.ALIGN_CENTER_HORIZONTAL)
  410. self.SetSizer(main_sizer)
  411. def load_options(self):
  412. self.start_spinctrl.SetValue(self.opt_manager.options['playlist_start'])
  413. self.stop_spinctrl.SetValue(self.opt_manager.options['playlist_end'])
  414. self.max_spinctrl.SetValue(self.opt_manager.options['max_downloads'])
  415. def save_options(self):
  416. self.opt_manager.options['playlist_start'] = self.start_spinctrl.GetValue()
  417. self.opt_manager.options['playlist_end'] = self.stop_spinctrl.GetValue()
  418. self.opt_manager.options['max_downloads'] = self.max_spinctrl.GetValue()
  419. class ConnectionTab(TabPanel):
  420. """Options frame connection tab.
  421. Attributes:
  422. SPINCTRL_SIZE (tuple): Overwrites the SPINCTRL_SIZE attribute of
  423. the TabPanel class.
  424. *_LABEL (string): Constant string label for widgets.
  425. """
  426. SPINCTRL_SIZE = (60, -1)
  427. RETRIES_LABEL = _("Retries")
  428. USERAGENT_LABEL = _("User Agent")
  429. REF_LABEL = _("Referer")
  430. PROXY_LABEL = _("Proxy")
  431. def __init__(self, *args, **kwargs):
  432. super(ConnectionTab, self).__init__(*args, **kwargs)
  433. self.retries_spinctrl = self.create_spinctrl((1, 999))
  434. self.useragent_box = self.create_textctrl()
  435. self.referer_box = self.create_textctrl()
  436. self.proxy_box = self.create_textctrl()
  437. self.retries_text = self.create_statictext(self.RETRIES_LABEL)
  438. self.useragent_text = self.create_statictext(self.USERAGENT_LABEL)
  439. self.referer_text = self.create_statictext(self.REF_LABEL)
  440. self.proxy_text = self.create_statictext(self.PROXY_LABEL)
  441. self._set_sizer()
  442. def _set_sizer(self):
  443. main_sizer = wx.BoxSizer(wx.HORIZONTAL)
  444. vertical_sizer = wx.BoxSizer(wx.VERTICAL)
  445. vertical_sizer.AddSpacer(self.SIZE_10)
  446. retries_sizer = wx.BoxSizer(wx.HORIZONTAL)
  447. retries_sizer.Add(self.retries_text)
  448. retries_sizer.AddSpacer(self.SIZE_5)
  449. retries_sizer.Add(self.retries_spinctrl)
  450. vertical_sizer.Add(retries_sizer)
  451. vertical_sizer.AddSpacer(self.SIZE_10)
  452. vertical_sizer.Add(self.useragent_text)
  453. vertical_sizer.AddSpacer(self.SIZE_5)
  454. vertical_sizer.Add(self.useragent_box, flag=wx.EXPAND)
  455. vertical_sizer.AddSpacer(self.SIZE_10)
  456. vertical_sizer.Add(self.referer_text)
  457. vertical_sizer.AddSpacer(self.SIZE_5)
  458. vertical_sizer.Add(self.referer_box, flag=wx.EXPAND)
  459. vertical_sizer.AddSpacer(self.SIZE_10)
  460. vertical_sizer.Add(self.proxy_text)
  461. vertical_sizer.AddSpacer(self.SIZE_5)
  462. vertical_sizer.Add(self.proxy_box, flag=wx.EXPAND)
  463. main_sizer.AddSpacer(self.SIZE_10)
  464. main_sizer.Add(vertical_sizer, 1, flag=wx.RIGHT, border=self.SIZE_40)
  465. self.SetSizer(main_sizer)
  466. def load_options(self):
  467. self.proxy_box.SetValue(self.opt_manager.options['proxy'])
  468. self.referer_box.SetValue(self.opt_manager.options['referer'])
  469. self.retries_spinctrl.SetValue(self.opt_manager.options['retries'])
  470. self.useragent_box.SetValue(self.opt_manager.options['user_agent'])
  471. def save_options(self):
  472. self.opt_manager.options['proxy'] = self.proxy_box.GetValue()
  473. self.opt_manager.options['referer'] = self.referer_box.GetValue()
  474. self.opt_manager.options['retries'] = self.retries_spinctrl.GetValue()
  475. self.opt_manager.options['user_agent'] = self.useragent_box.GetValue()
  476. class AuthenticationTab(TabPanel):
  477. """Options frame authentication tab.
  478. Attributes:
  479. TEXTCTRL_SIZE (tuple): Overwrites the TEXTCTRL_SIZE attribute of the
  480. TabPanel class.
  481. *_LABEL (string): Constant string label for the widgets.
  482. """
  483. TEXTCTRL_SIZE = (250, 25)
  484. USERNAME_LABEL = _("Username")
  485. PASSWORD_LABEL = _("Password")
  486. VIDEOPASS_LABEL = _("Video Password (vimeo, smotri)")
  487. def __init__(self, *args, **kwargs):
  488. super(AuthenticationTab, self).__init__(*args, **kwargs)
  489. self.username_box = self.create_textctrl()
  490. self.password_box = self.create_textctrl(wx.TE_PASSWORD)
  491. self.videopass_box = self.create_textctrl(wx.TE_PASSWORD)
  492. self.username_text = self.create_statictext(self.USERNAME_LABEL)
  493. self.password_text = self.create_statictext(self.PASSWORD_LABEL)
  494. self.videopass_text = self.create_statictext(self.VIDEOPASS_LABEL)
  495. self._set_sizer()
  496. def _set_sizer(self):
  497. main_sizer = wx.BoxSizer(wx.VERTICAL)
  498. main_sizer.AddSpacer(self.SIZE_15)
  499. main_sizer.Add(self.username_text, flag=wx.ALIGN_CENTER_HORIZONTAL)
  500. main_sizer.AddSpacer(self.SIZE_5)
  501. main_sizer.Add(self.username_box, flag=wx.ALIGN_CENTER_HORIZONTAL)
  502. main_sizer.AddSpacer(self.SIZE_15)
  503. main_sizer.Add(self.password_text, flag=wx.ALIGN_CENTER_HORIZONTAL)
  504. main_sizer.AddSpacer(self.SIZE_5)
  505. main_sizer.Add(self.password_box, flag=wx.ALIGN_CENTER_HORIZONTAL)
  506. main_sizer.AddSpacer(self.SIZE_15)
  507. main_sizer.Add(self.videopass_text, flag=wx.ALIGN_CENTER_HORIZONTAL)
  508. main_sizer.AddSpacer(self.SIZE_5)
  509. main_sizer.Add(self.videopass_box, flag=wx.ALIGN_CENTER_HORIZONTAL)
  510. self.SetSizer(main_sizer)
  511. def load_options(self):
  512. self.username_box.SetValue(self.opt_manager.options['username'])
  513. self.password_box.SetValue(self.opt_manager.options['password'])
  514. self.videopass_box.SetValue(self.opt_manager.options['video_password'])
  515. def save_options(self):
  516. self.opt_manager.options['username'] = self.username_box.GetValue()
  517. self.opt_manager.options['password'] = self.password_box.GetValue()
  518. self.opt_manager.options['video_password'] = self.videopass_box.GetValue()
  519. class AudioTab(TabPanel):
  520. """Options frame audio tab.
  521. Attributes:
  522. AUDIO_QUALITY (TwoWayOrderedDict): Contains audio qualities.
  523. AUDIO_FORMATS (list): Contains audio formats.
  524. See optionsmanager.OptionsManager 'audio_format' option
  525. for available values.
  526. *_LABEL (string): Constant string label for the widgets.
  527. """
  528. AUDIO_QUALITY = twodict([("0", _("high")), ("5", _("mid")), ("9", _("low"))])
  529. AUDIO_FORMATS = ["mp3", "wav", "aac", "m4a", "vorbis"]
  530. TO_AUDIO_LABEL = _("Convert to Audio")
  531. KEEP_VIDEO_LABEL = _("Keep Video")
  532. AUDIO_FORMAT_LABEL = _("Audio Format")
  533. AUDIO_QUALITY_LABEL = _("Audio Quality")
  534. def __init__(self, *args, **kwargs):
  535. super(AudioTab, self).__init__(*args, **kwargs)
  536. self.to_audio_checkbox = self.create_checkbox(self.TO_AUDIO_LABEL, self._on_audio_check)
  537. self.keep_video_checkbox = self.create_checkbox(self.KEEP_VIDEO_LABEL)
  538. self.audioformat_combo = self.create_combobox(self.AUDIO_FORMATS, (160, 30))
  539. self.audioquality_combo = self.create_combobox(self.AUDIO_QUALITY.values(), (80, 25))
  540. self.audioformat_text = self.create_statictext(self.AUDIO_FORMAT_LABEL)
  541. self.audioquality_text = self.create_statictext(self.AUDIO_QUALITY_LABEL)
  542. self._set_sizer()
  543. def _set_sizer(self):
  544. main_sizer = wx.BoxSizer(wx.VERTICAL)
  545. main_sizer.AddSpacer(self.SIZE_15)
  546. main_sizer.Add(self.to_audio_checkbox, flag=wx.ALIGN_CENTER_HORIZONTAL)
  547. main_sizer.AddSpacer(self.SIZE_5)
  548. main_sizer.Add(self.keep_video_checkbox, flag=wx.ALIGN_CENTER_HORIZONTAL)
  549. main_sizer.AddSpacer(self.SIZE_10)
  550. main_sizer.Add(self.audioformat_text, flag=wx.ALIGN_CENTER_HORIZONTAL)
  551. main_sizer.AddSpacer(self.SIZE_5)
  552. main_sizer.Add(self.audioformat_combo, flag=wx.ALIGN_CENTER_HORIZONTAL)
  553. main_sizer.AddSpacer(self.SIZE_10)
  554. main_sizer.Add(self.audioquality_text, flag=wx.ALIGN_CENTER_HORIZONTAL)
  555. main_sizer.AddSpacer(self.SIZE_5)
  556. main_sizer.Add(self.audioquality_combo, flag=wx.ALIGN_CENTER_HORIZONTAL)
  557. self.SetSizer(main_sizer)
  558. def _on_audio_check(self, event):
  559. """Event handler for self.to_audio_checkbox. """
  560. self.audioformat_combo.Enable(self.to_audio_checkbox.GetValue())
  561. self.audioquality_combo.Enable(self.to_audio_checkbox.GetValue())
  562. def load_options(self):
  563. self.to_audio_checkbox.SetValue(self.opt_manager.options['to_audio'])
  564. self.keep_video_checkbox.SetValue(self.opt_manager.options['keep_video'])
  565. self.audioformat_combo.SetValue(self.opt_manager.options['audio_format'])
  566. self.audioquality_combo.SetValue(self.AUDIO_QUALITY[self.opt_manager.options['audio_quality']])
  567. self._on_audio_check(None)
  568. def save_options(self):
  569. self.opt_manager.options['to_audio'] = self.to_audio_checkbox.GetValue()
  570. self.opt_manager.options['keep_video'] = self.keep_video_checkbox.GetValue()
  571. self.opt_manager.options['audio_format'] = self.audioformat_combo.GetValue()
  572. self.opt_manager.options['audio_quality'] = self.AUDIO_QUALITY[self.audioquality_combo.GetValue()]
  573. class VideoTab(TabPanel):
  574. """Options frame video tab.
  575. Attributes:
  576. FORMATS (TwoWayOrderedDict): Contains video formats. This list
  577. contains all the available video formats without the 'default'
  578. and 'none' options.
  579. VIDEO_FORMATS (list): List that contains all the video formats
  580. plus the 'default' one.
  581. SECOND_VIDEO_FORMATS (list): List that contains all the video formats
  582. plus the 'none' one.
  583. COMBOBOX_SIZE (tuple): Overwrites the COMBOBOX_SIZE attribute of the
  584. TabPanel class.
  585. *_LABEL (string): Constant string label for the widgets.
  586. """
  587. FORMATS = twodict([
  588. ("17", "3gp [176x144]"),
  589. ("36", "3gp [320x240]"),
  590. ("5", "flv [400x240]"),
  591. ("34", "flv [640x360]"),
  592. ("35", "flv [854x480]"),
  593. ("43", "webm [640x360]"),
  594. ("44", "webm [854x480]"),
  595. ("45", "webm [1280x720]"),
  596. ("46", "webm [1920x1080]"),
  597. ("18", "mp4 [640x360]"),
  598. ("22", "mp4 [1280x720]"),
  599. ("37", "mp4 [1920x1080]"),
  600. ("38", "mp4 [4096x3072]"),
  601. ("160", "mp4 144p (DASH)"),
  602. ("133", "mp4 240p (DASH)"),
  603. ("134", "mp4 360p (DASH)"),
  604. ("135", "mp4 480p (DASH)"),
  605. ("136", "mp4 720p (DASH)"),
  606. ("137", "mp4 1080p (DASH)"),
  607. ("264", "mp4 1440p (DASH)"),
  608. ("138", "mp4 2160p (DASH)"),
  609. ("242", "webm 240p (DASH)"),
  610. ("243", "webm 360p (DASH)"),
  611. ("244", "webm 480p (DASH)"),
  612. ("247", "webm 720p (DASH)"),
  613. ("248", "webm 1080p (DASH)"),
  614. ("271", "webm 1440p (DASH)"),
  615. ("272", "webm 2160p (DASH)"),
  616. ("82", "mp4 360p (3D)"),
  617. ("83", "mp4 480p (3D)"),
  618. ("84", "mp4 720p (3D)"),
  619. ("85", "mp4 1080p (3D)"),
  620. ("100", "webm 360p (3D)"),
  621. ("101", "webm 480p (3D)"),
  622. ("102", "webm 720p (3D)"),
  623. ("139", "m4a 48k (DASH AUDIO)"),
  624. ("140", "m4a 128k (DASH AUDIO)"),
  625. ("141", "m4a 256k (DASH AUDIO)"),
  626. ("171", "webm 48k (DASH AUDIO)"),
  627. ("172", "webm 256k (DASH AUDIO)")
  628. ])
  629. VIDEO_FORMATS = [_("default")] + FORMATS.values()
  630. SECOND_VIDEO_FORMATS = [_("none")] + FORMATS.values()
  631. COMBOBOX_SIZE = (200, 30)
  632. VIDEO_FORMAT_LABEL = _("Video Format")
  633. SEC_VIDEOFORMAT_LABEL = _("Mix Format")
  634. def __init__(self, *args, **kwargs):
  635. super(VideoTab, self).__init__(*args, **kwargs)
  636. self.videoformat_combo = self.create_combobox(self.VIDEO_FORMATS,
  637. self.COMBOBOX_SIZE,
  638. self._on_videoformat)
  639. self.sec_videoformat_combo = self.create_combobox(self.SECOND_VIDEO_FORMATS,
  640. self.COMBOBOX_SIZE)
  641. self.videoformat_text = self.create_statictext(self.VIDEO_FORMAT_LABEL)
  642. self.sec_videoformat_text = self.create_statictext(self.SEC_VIDEOFORMAT_LABEL)
  643. self._set_sizer()
  644. def _set_sizer(self):
  645. main_sizer = wx.BoxSizer(wx.VERTICAL)
  646. main_sizer.AddSpacer(self.SIZE_30)
  647. main_sizer.Add(self.videoformat_text, flag=wx.ALIGN_CENTER_HORIZONTAL)
  648. main_sizer.AddSpacer(self.SIZE_5)
  649. main_sizer.Add(self.videoformat_combo, flag=wx.ALIGN_CENTER_HORIZONTAL)
  650. main_sizer.AddSpacer(self.SIZE_10)
  651. main_sizer.Add(self.sec_videoformat_text, flag=wx.ALIGN_CENTER_HORIZONTAL)
  652. main_sizer.AddSpacer(self.SIZE_5)
  653. main_sizer.Add(self.sec_videoformat_combo, flag=wx.ALIGN_CENTER_HORIZONTAL)
  654. self.SetSizer(main_sizer)
  655. def _on_videoformat(self, event):
  656. """Event handler for self.videoformat_combo. """
  657. condition = (self.videoformat_combo.GetValue() != self.VIDEO_FORMATS[0])
  658. self.sec_videoformat_combo.Enable(condition)
  659. def load_options(self):
  660. self.videoformat_combo.SetValue(self.FORMATS.get(self.opt_manager.options['video_format'], self.VIDEO_FORMATS[0]))
  661. self.sec_videoformat_combo.SetValue(self.FORMATS.get(self.opt_manager.options['second_video_format'], self.SECOND_VIDEO_FORMATS[0]))
  662. self._on_videoformat(None)
  663. def save_options(self):
  664. self.opt_manager.options['video_format'] = self.FORMATS.get(self.videoformat_combo.GetValue(), '0')
  665. self.opt_manager.options['second_video_format'] = self.FORMATS.get(self.sec_videoformat_combo.GetValue(), '0')
  666. class OutputTab(TabPanel):
  667. """Options frame output tab.
  668. Attributes:
  669. TEXTCTRL_SIZE (tuple): Overwrites the TEXTCTRL_SIZE attribute of
  670. the TabPanel class.
  671. * (string): Constant string label for the widgets.
  672. """
  673. TEXTCTRL_SIZE = (300, 20)
  674. RESTRICT_LABEL = _("Restrict filenames (ASCII)")
  675. ID_AS_NAME = _("ID as Name")
  676. TITLE_AS_NAME = _("Title as Name")
  677. CUST_TITLE = _("Custom Template (youtube-dl)")
  678. def __init__(self, *args, **kwargs):
  679. super(OutputTab, self).__init__(*args, **kwargs)
  680. self.res_names_checkbox = self.create_checkbox(self.RESTRICT_LABEL)
  681. self.id_rbtn = self.create_radiobutton(self.ID_AS_NAME, self._on_pick, wx.RB_GROUP)
  682. self.title_rbtn = self.create_radiobutton(self.TITLE_AS_NAME, self._on_pick)
  683. self.custom_rbtn = self.create_radiobutton(self.CUST_TITLE, self._on_pick)
  684. self.title_template = self.create_textctrl()
  685. self._set_sizer()
  686. def _set_sizer(self):
  687. main_sizer = wx.BoxSizer(wx.HORIZONTAL)
  688. vertical_sizer = wx.BoxSizer(wx.VERTICAL)
  689. vertical_sizer.AddSpacer(self.SIZE_15)
  690. vertical_sizer.Add(self.res_names_checkbox)
  691. vertical_sizer.AddSpacer(self.SIZE_5)
  692. vertical_sizer.Add(self.id_rbtn)
  693. vertical_sizer.AddSpacer(self.SIZE_5)
  694. vertical_sizer.Add(self.title_rbtn)
  695. vertical_sizer.AddSpacer(self.SIZE_5)
  696. vertical_sizer.Add(self.custom_rbtn)
  697. vertical_sizer.AddSpacer(self.SIZE_10)
  698. vertical_sizer.Add(self.title_template)
  699. main_sizer.Add(vertical_sizer, flag=wx.LEFT, border=self.SIZE_5)
  700. self.SetSizer(main_sizer)
  701. def _on_pick(self, event):
  702. """Event handler for the radiobuttons. """
  703. self.title_template.Enable(self.custom_rbtn.GetValue())
  704. def _get_output_format(self):
  705. """Returns output_format string type base on the radiobuttons.
  706. See optionsmanager.OptionsManager 'output_format' option for more
  707. informations.
  708. """
  709. if self.id_rbtn.GetValue():
  710. return 'id'
  711. elif self.title_rbtn.GetValue():
  712. return 'title'
  713. elif self.custom_rbtn.GetValue():
  714. return 'custom'
  715. def _set_output_format(self, output_format):
  716. """Enables the corresponding radiobutton base on the output_format. """
  717. if output_format == 'id':
  718. self.id_rbtn.SetValue(True)
  719. elif output_format == 'title':
  720. self.title_rbtn.SetValue(True)
  721. elif output_format == 'custom':
  722. self.custom_rbtn.SetValue(True)
  723. def load_options(self):
  724. self._set_output_format(self.opt_manager.options['output_format'])
  725. self.title_template.SetValue(self.opt_manager.options['output_template'])
  726. self.res_names_checkbox.SetValue(self.opt_manager.options['restrict_filenames'])
  727. self._on_pick(None)
  728. def save_options(self):
  729. self.opt_manager.options['output_format'] = self._get_output_format()
  730. self.opt_manager.options['output_template'] = self.title_template.GetValue()
  731. self.opt_manager.options['restrict_filenames'] = self.res_names_checkbox.GetValue()
  732. class FilesystemTab(TabPanel):
  733. """Options frame filesystem tab.
  734. Attributes:
  735. FILESIZES (TwoWayOrderedDict): Contains filesize units.
  736. *_LABEL (string): Constant string label for the widgets.
  737. """
  738. FILESIZES = twodict([
  739. ("", "Bytes"),
  740. ("k", "Kilobytes"),
  741. ("m", "Megabytes"),
  742. ("g", "Gigabytes"),
  743. ("t", "Terabytes"),
  744. ("p", "Petabytes"),
  745. ("e", "Exabytes"),
  746. ("z", "Zettabytes"),
  747. ("y", "Yottabytes")
  748. ])
  749. IGN_ERR_LABEL = _("Ignore Errors")
  750. OPEN_DIR_LABEL = _("Open destination folder")
  751. WRT_INFO_LABEL = _("Write info to (.json) file")
  752. WRT_DESC_LABEL = _("Write description to file")
  753. WRT_THMB_LABEL = _("Write thumbnail to disk")
  754. FILESIZE_LABEL = _("Filesize")
  755. MIN_LABEL = _("Min")
  756. MAX_LABEL = _("Max")
  757. def __init__(self, *args, **kwargs):
  758. super(FilesystemTab, self).__init__(*args, **kwargs)
  759. self.ign_err_checkbox = self.create_checkbox(self.IGN_ERR_LABEL)
  760. self.open_dir_checkbox = self.create_checkbox(self.OPEN_DIR_LABEL)
  761. self.write_info_checkbox = self.create_checkbox(self.WRT_INFO_LABEL)
  762. self.write_desc_checkbox = self.create_checkbox(self.WRT_DESC_LABEL)
  763. self.write_thumbnail_checkbox = self.create_checkbox(self.WRT_THMB_LABEL)
  764. self.min_filesize_spinner = self.create_spinctrl((0, 1024))
  765. self.max_filesize_spinner = self.create_spinctrl((0, 1024))
  766. self.min_filesize_combo = self.create_combobox(self.FILESIZES.values())
  767. self.max_filesize_combo = self.create_combobox(self.FILESIZES.values())
  768. self.min_text = self.create_statictext(self.MIN_LABEL)
  769. self.max_text = self.create_statictext(self.MAX_LABEL)
  770. self._set_sizer()
  771. def _set_sizer(self):
  772. main_sizer = wx.BoxSizer(wx.HORIZONTAL)
  773. main_sizer.Add(self._set_left_sizer(), 1, wx.LEFT, border=self.SIZE_5)
  774. main_sizer.Add(self._set_right_sizer(), 1, wx.EXPAND)
  775. self.SetSizer(main_sizer)
  776. def _set_left_sizer(self):
  777. """Sets and returns the left BoxSizer. """
  778. sizer = wx.BoxSizer(wx.VERTICAL)
  779. sizer.AddSpacer(self.SIZE_15)
  780. sizer.Add(self.ign_err_checkbox)
  781. sizer.AddSpacer(self.SIZE_5)
  782. sizer.Add(self.open_dir_checkbox)
  783. sizer.AddSpacer(self.SIZE_5)
  784. sizer.Add(self.write_desc_checkbox)
  785. sizer.AddSpacer(self.SIZE_5)
  786. sizer.Add(self.write_thumbnail_checkbox)
  787. sizer.AddSpacer(self.SIZE_5)
  788. sizer.Add(self.write_info_checkbox)
  789. return sizer
  790. def _set_right_sizer(self):
  791. """Sets and returns the right BoxSizer. """
  792. static_box = wx.StaticBox(self, label=self.FILESIZE_LABEL)
  793. sizer = wx.StaticBoxSizer(static_box, wx.VERTICAL)
  794. sizer.AddSpacer(self.SIZE_20)
  795. sizer.Add(self.min_text, flag=wx.ALIGN_CENTER_HORIZONTAL)
  796. sizer.AddSpacer(self.SIZE_5)
  797. hor_sizer = wx.BoxSizer(wx.HORIZONTAL)
  798. hor_sizer.Add(self.min_filesize_spinner)
  799. hor_sizer.AddSpacer(self.SIZE_10)
  800. hor_sizer.Add(self.min_filesize_combo)
  801. sizer.Add(hor_sizer, flag=wx.ALIGN_CENTER_HORIZONTAL)
  802. sizer.AddSpacer(self.SIZE_10)
  803. sizer.Add(self.max_text, flag=wx.ALIGN_CENTER_HORIZONTAL)
  804. sizer.AddSpacer(self.SIZE_5)
  805. hor_sizer = wx.BoxSizer(wx.HORIZONTAL)
  806. hor_sizer.Add(self.max_filesize_spinner)
  807. hor_sizer.AddSpacer(self.SIZE_10)
  808. hor_sizer.Add(self.max_filesize_combo)
  809. sizer.Add(hor_sizer, flag=wx.ALIGN_CENTER_HORIZONTAL)
  810. return sizer
  811. def load_options(self):
  812. self.open_dir_checkbox.SetValue(self.opt_manager.options['open_dl_dir'])
  813. self.write_info_checkbox.SetValue(self.opt_manager.options['write_info'])
  814. self.ign_err_checkbox.SetValue(self.opt_manager.options['ignore_errors'])
  815. self.write_desc_checkbox.SetValue(self.opt_manager.options['write_description'])
  816. self.write_thumbnail_checkbox.SetValue(self.opt_manager.options['write_thumbnail'])
  817. self.min_filesize_spinner.SetValue(self.opt_manager.options['min_filesize'])
  818. self.max_filesize_spinner.SetValue(self.opt_manager.options['max_filesize'])
  819. self.min_filesize_combo.SetValue(self.FILESIZES[self.opt_manager.options['min_filesize_unit']])
  820. self.max_filesize_combo.SetValue(self.FILESIZES[self.opt_manager.options['max_filesize_unit']])
  821. def save_options(self):
  822. self.opt_manager.options['write_thumbnail'] = self.write_thumbnail_checkbox.GetValue()
  823. self.opt_manager.options['write_description'] = self.write_desc_checkbox.GetValue()
  824. self.opt_manager.options['ignore_errors'] = self.ign_err_checkbox.GetValue()
  825. self.opt_manager.options['write_info'] = self.write_info_checkbox.GetValue()
  826. self.opt_manager.options['open_dl_dir'] = self.open_dir_checkbox.GetValue()
  827. self.opt_manager.options['min_filesize'] = self.min_filesize_spinner.GetValue()
  828. self.opt_manager.options['max_filesize'] = self.max_filesize_spinner.GetValue()
  829. self.opt_manager.options['min_filesize_unit'] = self.FILESIZES[self.min_filesize_combo.GetValue()]
  830. self.opt_manager.options['max_filesize_unit'] = self.FILESIZES[self.max_filesize_combo.GetValue()]
  831. class SubtitlesTab(TabPanel):
  832. """Options frame subtitles tab.
  833. Attributes:
  834. SUBS_LANG (TwoWayOrderedDict): Contains subtitles languages.
  835. *_LABEL (string): Constant string label for the widgets.
  836. """
  837. SUBS_LANG = twodict([
  838. ("en", _("English")),
  839. ("gr", _("Greek")),
  840. ("pt", _("Portuguese")),
  841. ("fr", _("French")),
  842. ("it", _("Italian")),
  843. ("ru", _("Russian")),
  844. ("es", _("Spanish")),
  845. ("de", _("German"))
  846. ])
  847. DL_SUBS_LABEL = _("Download subtitle file by language")
  848. DL_ALL_SUBS_LABEL = _("Download all available subtitles")
  849. DL_AUTO_SUBS_LABEL = _("Download automatic subtitle file (YOUTUBE ONLY)")
  850. EMBED_SUBS_LABEL = _("Embed subtitles in the video (only for mp4 videos)")
  851. SUBS_LANG_LABEL = _("Subtitles Language")
  852. def __init__(self, *args, **kwargs):
  853. super(SubtitlesTab, self).__init__(*args, **kwargs)
  854. self.write_subs_checkbox = self.create_checkbox(self.DL_SUBS_LABEL, self._on_subs_pick)
  855. self.write_all_subs_checkbox = self.create_checkbox(self.DL_ALL_SUBS_LABEL, self._on_subs_pick)
  856. self.write_auto_subs_checkbox = self.create_checkbox(self.DL_AUTO_SUBS_LABEL, self._on_subs_pick)
  857. self.embed_subs_checkbox = self.create_checkbox(self.EMBED_SUBS_LABEL)
  858. self.subs_lang_combo = self.create_combobox(self.SUBS_LANG.values(), (140, 30))
  859. self.subs_lang_text = self.create_statictext(self.SUBS_LANG_LABEL)
  860. self._set_sizer()
  861. self._disable_items()
  862. def _disable_items(self):
  863. self.embed_subs_checkbox.Disable()
  864. self.subs_lang_combo.Disable()
  865. def _set_sizer(self):
  866. main_sizer = wx.BoxSizer(wx.HORIZONTAL)
  867. vertical_sizer = wx.BoxSizer(wx.VERTICAL)
  868. vertical_sizer.AddSpacer(self.SIZE_15)
  869. vertical_sizer.Add(self.write_subs_checkbox)
  870. vertical_sizer.AddSpacer(self.SIZE_5)
  871. vertical_sizer.Add(self.write_all_subs_checkbox)
  872. vertical_sizer.AddSpacer(self.SIZE_5)
  873. vertical_sizer.Add(self.write_auto_subs_checkbox)
  874. vertical_sizer.AddSpacer(self.SIZE_5)
  875. vertical_sizer.Add(self.embed_subs_checkbox)
  876. vertical_sizer.AddSpacer(self.SIZE_10)
  877. vertical_sizer.Add(self.subs_lang_text, flag=wx.LEFT, border=self.SIZE_5)
  878. vertical_sizer.AddSpacer(self.SIZE_5)
  879. vertical_sizer.Add(self.subs_lang_combo, flag=wx.LEFT, border=self.SIZE_10)
  880. main_sizer.Add(vertical_sizer, flag=wx.LEFT, border=self.SIZE_5)
  881. self.SetSizer(main_sizer)
  882. def _on_subs_pick(self, event):
  883. """Event handler for the write_subs checkboxes. """
  884. if self.write_subs_checkbox.GetValue():
  885. self.write_all_subs_checkbox.Disable()
  886. self.write_auto_subs_checkbox.Disable()
  887. self.embed_subs_checkbox.Enable()
  888. self.subs_lang_combo.Enable()
  889. elif self.write_all_subs_checkbox.GetValue():
  890. self.write_subs_checkbox.Disable()
  891. self.write_auto_subs_checkbox.Disable()
  892. elif self.write_auto_subs_checkbox.GetValue():
  893. self.write_subs_checkbox.Disable()
  894. self.write_all_subs_checkbox.Disable()
  895. self.embed_subs_checkbox.Enable()
  896. else:
  897. self.embed_subs_checkbox.Disable()
  898. self.embed_subs_checkbox.SetValue(False)
  899. self.subs_lang_combo.Disable()
  900. self.write_subs_checkbox.Enable()
  901. self.write_all_subs_checkbox.Enable()
  902. self.write_auto_subs_checkbox.Enable()
  903. def load_options(self):
  904. self.subs_lang_combo.SetValue(self.SUBS_LANG[self.opt_manager.options['subs_lang']])
  905. self.write_subs_checkbox.SetValue(self.opt_manager.options['write_subs'])
  906. self.embed_subs_checkbox.SetValue(self.opt_manager.options['embed_subs'])
  907. self.write_all_subs_checkbox.SetValue(self.opt_manager.options['write_all_subs'])
  908. self.write_auto_subs_checkbox.SetValue(self.opt_manager.options['write_auto_subs'])
  909. self._on_subs_pick(None)
  910. def save_options(self):
  911. self.opt_manager.options['subs_lang'] = self.SUBS_LANG[self.subs_lang_combo.GetValue()]
  912. self.opt_manager.options['write_subs'] = self.write_subs_checkbox.GetValue()
  913. self.opt_manager.options['embed_subs'] = self.embed_subs_checkbox.GetValue()
  914. self.opt_manager.options['write_all_subs'] = self.write_all_subs_checkbox.GetValue()
  915. self.opt_manager.options['write_auto_subs'] = self.write_auto_subs_checkbox.GetValue()
  916. class GeneralTab(TabPanel):
  917. """Options frame general tab.
  918. Attributes:
  919. BUTTONS_SIZE (tuple): Overwrites the BUTTONS_SIZE attribute of the
  920. TabPanel class.
  921. *_LABEL (string): Constant string label for the widgets.
  922. """
  923. BUTTONS_SIZE = (110, 40)
  924. ABOUT_LABEL = _("About")
  925. OPEN_LABEL = _("Open")
  926. RESET_LABEL = _("Reset Options")
  927. SAVEPATH_LABEL = _("Save Path")
  928. SETTINGS_DIR_LABEL = _("Settings File: {0}")
  929. PICK_DIR_LABEL = _("Choose Directory")
  930. def __init__(self, *args, **kwargs):
  931. super(GeneralTab, self).__init__(*args, **kwargs)
  932. self.savepath_box = self.create_textctrl()
  933. self.about_button = self.create_button(self.ABOUT_LABEL, self._on_about)
  934. self.open_button = self.create_button(self.OPEN_LABEL, self._on_open)
  935. self.reset_button = self.create_button(self.RESET_LABEL, self._on_reset)
  936. self.savepath_text = self.create_statictext(self.SAVEPATH_LABEL)
  937. cfg_file = self.SETTINGS_DIR_LABEL.format(self.opt_manager.settings_file)
  938. self.cfg_file_dir = self.create_statictext(cfg_file)
  939. self._set_sizer()
  940. def _set_sizer(self):
  941. main_sizer = wx.BoxSizer(wx.VERTICAL)
  942. main_sizer.AddSpacer(self.SIZE_20)
  943. main_sizer.Add(self.savepath_text, flag=wx.ALIGN_CENTER_HORIZONTAL)
  944. main_sizer.AddSpacer(self.SIZE_10)
  945. savepath_sizer = wx.BoxSizer(wx.HORIZONTAL)
  946. savepath_sizer.Add(self.savepath_box, 1, wx.LEFT | wx.RIGHT, self.SIZE_80)
  947. main_sizer.Add(savepath_sizer, flag=wx.ALIGN_CENTER_HORIZONTAL | wx.EXPAND)
  948. main_sizer.AddSpacer(self.SIZE_20)
  949. buttons_sizer = wx.BoxSizer(wx.HORIZONTAL)
  950. buttons_sizer.Add(self.about_button)
  951. buttons_sizer.Add(self.open_button, flag=wx.LEFT | wx.RIGHT, border=self.SIZE_50)
  952. buttons_sizer.Add(self.reset_button)
  953. main_sizer.Add(buttons_sizer, flag=wx.ALIGN_CENTER_HORIZONTAL)
  954. main_sizer.AddSpacer(self.SIZE_30)
  955. main_sizer.Add(self.cfg_file_dir, flag=wx.ALIGN_CENTER_HORIZONTAL)
  956. self.SetSizer(main_sizer)
  957. def _on_reset(self, event):
  958. """Event handler of the self.reset_button. """
  959. self.reset_handler()
  960. def _on_open(self, event):
  961. """Event handler of the self.open_button. """
  962. dlg = self.create_dirdialog(self.PICK_DIR_LABEL)
  963. if dlg.ShowModal() == wx.ID_OK:
  964. self.savepath_box.SetValue(dlg.GetPath())
  965. dlg.Destroy()
  966. def _on_about(self, event):
  967. """Event handler of the self.about_button. """
  968. info = wx.AboutDialogInfo()
  969. if self.app_icon is not None:
  970. info.SetIcon(self.app_icon)
  971. info.SetName(__appname__)
  972. info.SetVersion(__version__)
  973. info.SetDescription(__descriptionfull__)
  974. info.SetWebSite(__projecturl__)
  975. info.SetLicense(__licensefull__)
  976. info.AddDeveloper(__author__)
  977. wx.AboutBox(info)
  978. def load_options(self):
  979. self.savepath_box.SetValue(self.opt_manager.options['save_path'])
  980. def save_options(self):
  981. self.opt_manager.options['save_path'] = self.savepath_box.GetValue()
  982. class CMDTab(TabPanel):
  983. """Options frame command tab.
  984. Attributes:
  985. CMD_LABEL (string): Constant string label for the widgets.
  986. """
  987. CMD_LABEL = _("Command line arguments (e.g. --help)")
  988. def __init__(self, *args, **kwargs):
  989. super(CMDTab, self).__init__(*args, **kwargs)
  990. self.cmd_args_box = self.create_textctrl()
  991. self.cmd_args_text = self.create_statictext(self.CMD_LABEL)
  992. self._set_sizer()
  993. def _set_sizer(self):
  994. main_sizer = wx.BoxSizer(wx.VERTICAL)
  995. main_sizer.AddSpacer(self.SIZE_50)
  996. main_sizer.Add(self.cmd_args_text, flag=wx.ALIGN_CENTER_HORIZONTAL)
  997. main_sizer.AddSpacer(self.SIZE_10)
  998. cmdbox_sizer = wx.BoxSizer(wx.HORIZONTAL)
  999. cmdbox_sizer.Add(self.cmd_args_box, 1, wx.LEFT | wx.RIGHT, border=self.SIZE_80)
  1000. main_sizer.Add(cmdbox_sizer, flag=wx.ALIGN_CENTER_HORIZONTAL | wx.EXPAND)
  1001. self.SetSizer(main_sizer)
  1002. def load_options(self):
  1003. self.cmd_args_box.SetValue(self.opt_manager.options['cmd_args'])
  1004. def save_options(self):
  1005. self.opt_manager.options['cmd_args'] = self.cmd_args_box.GetValue()
  1006. class LocalizationTab(TabPanel):
  1007. """Options frame localization tab.
  1008. Attributes:
  1009. COMBOBOX_SIZE (tuple): Tuple that contains the size(width, height)
  1010. of the combobox widget.
  1011. LOCALE_NAMES (TwoWayOrderedDict): Stores the locale names.
  1012. *_LABEL (string): Constant string label for the widgets.
  1013. """
  1014. COMBOBOX_SIZE = (150, 30)
  1015. LOCALE_NAMES = twodict([
  1016. ('en_US', 'English'),
  1017. ('fr_FR', 'French'),
  1018. ('de_DE', 'German'),
  1019. ('ar_AR', 'Arabic')
  1020. ])
  1021. RESTART_LABEL = _("Restart")
  1022. LOCALE_LABEL = _("Localization Language")
  1023. RESTART_MSG = _("In order for the changes to take effect please restart {0}")
  1024. def __init__(self, *args, **kwargs):
  1025. super(LocalizationTab, self).__init__(*args, **kwargs)
  1026. self.locale_text = self.create_statictext(self.LOCALE_LABEL)
  1027. self.locale_box = self.create_combobox(self.LOCALE_NAMES.values(), self.COMBOBOX_SIZE, self._on_locale)
  1028. self._set_sizer()
  1029. def _set_sizer(self):
  1030. main_sizer = wx.BoxSizer(wx.VERTICAL)
  1031. main_sizer.AddSpacer(self.SIZE_50)
  1032. main_sizer.Add(self.locale_text, flag=wx.ALIGN_CENTER_HORIZONTAL)
  1033. main_sizer.AddSpacer(self.SIZE_10)
  1034. main_sizer.Add(self.locale_box, flag=wx.ALIGN_CENTER_HORIZONTAL)
  1035. self.SetSizer(main_sizer)
  1036. def _on_locale(self, event):
  1037. """Event handler for the self.locale_box widget. """
  1038. self.create_popup(self.RESTART_MSG.format(__appname__),
  1039. self.RESTART_LABEL,
  1040. wx.OK | wx.ICON_INFORMATION)
  1041. def load_options(self):
  1042. self.locale_box.SetValue(self.LOCALE_NAMES[self.opt_manager.options['locale_name']])
  1043. def save_options(self):
  1044. self.opt_manager.options['locale_name'] = self.LOCALE_NAMES[self.locale_box.GetValue()]
  1045. class LogGUI(wx.Frame):
  1046. """Simple window for reading the STDERR.
  1047. Attributes:
  1048. TITLE (string): Frame title.
  1049. FRAME_SIZE (tuple): Tuple that holds the frame size (width, height).
  1050. Args:
  1051. parent (wx.Window): Frame parent.
  1052. """
  1053. TITLE = _("Log Viewer")
  1054. FRAME_SIZE = (650, 200)
  1055. def __init__(self, parent=None):
  1056. wx.Frame.__init__(self, parent, title=self.TITLE, size=self.FRAME_SIZE)
  1057. panel = wx.Panel(self)
  1058. self._text_area = wx.TextCtrl(
  1059. panel,
  1060. style=wx.TE_MULTILINE | wx.TE_READONLY | wx.HSCROLL
  1061. )
  1062. sizer = wx.BoxSizer()
  1063. sizer.Add(self._text_area, 1, wx.EXPAND)
  1064. panel.SetSizerAndFit(sizer)
  1065. def load(self, filename):
  1066. """Load file content on the text area. """
  1067. if os.path.exists(filename):
  1068. self._text_area.LoadFile(filename)