1 # -*- coding: utf-8 -*-
3 # This file is part of Panucci.
4 # Copyright (c) 2008-2011 The Panucci Project
6 # Panucci is free software: you can redistribute it and/or modify
7 # it under the terms of the GNU General Public License as published by
8 # the Free Software Foundation, either version 3 of the License, or
9 # (at your option) any later version.
11 # Panucci is distributed in the hope that it will be useful,
12 # but WITHOUT ANY WARRANTY; without even the implied warranty of
13 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 # GNU General Public License for more details.
16 # You should have received a copy of the GNU General Public License
17 # along with Panucci. If not, see <http://www.gnu.org/licenses/>.
19 from __future__
import absolute_import
24 from PySide
import QtCore
25 from PySide
import QtGui
29 pynotify
.init('Panucci')
35 from panucci
import util
36 from panucci
import platform
37 from panucci
import playlist
38 from panucci
.dbusinterface
import interface
39 from panucci
.services
import ObservableService
40 from panucci
.qtui
import qtutil
41 from panucci
.qtui
import qtplaylist
42 from panucci
.qtui
import qtwidgets
44 ##################################################
46 ##################################################
47 class PanucciGUI(object):
48 """ The object that holds the entire panucci gui """
50 def __init__(self
, settings
, filename
=None):
51 self
.__log
= logging
.getLogger('panucci.panucci.PanucciGUI')
52 interface
.register_gui(self
)
53 self
.config
= settings
.config
54 self
.playlist
= playlist
.Playlist(self
.config
)
56 self
.app
= QtGui
.QApplication(["Panucci"])
57 self
.app
.setWindowIcon(QtGui
.QIcon(util
.find_data_file('panucci.png')))
58 self
.main_window
= QtGui
.QMainWindow(None)
59 if platform
.FREMANTLE
:
60 self
.main_window
.setAttribute(QtCore
.Qt
.WA_Maemo5StackedWindow
)
61 self
.main_window
.closeEvent
= self
.close_main_window_callback
63 self
.__player
_tab
= PlayerTab(self
)
64 self
.__playlist
_tab
= qtplaylist
.PlaylistTab(self
, self
.playlist
)
66 self
.create_maemo_menus()
69 widget
= QtGui
.QWidget()
70 widget
.setLayout(self
.__player
_tab
.mainbox
)
71 self
.main_window
.setCentralWidget(widget
)
72 self
.main_window
.show()
73 self
.playlist
.player
.init(filepath
=filename
)
76 def create_actions(self
):
78 self
.action_add_file
= QtGui
.QAction(QtGui
.QIcon(':/actions/add.png'), _("Add File").decode("utf-8"), self
.main_window
, shortcut
="Ctrl+A",
79 statusTip
="Add file to playlist", triggered
=self
.add_file_callback
)
80 self
.action_add_folder
= QtGui
.QAction(QtGui
.QIcon(':/images/open.png'), _("Add Folder").decode("utf-8"), self
.main_window
, shortcut
="Ctrl+D",
81 statusTip
="Add folder to playlist", triggered
=self
.add_folder_callback
)
82 self
.action_save_playlist
= QtGui
.QAction(QtGui
.QIcon(':/images/save.png'), _("Save Playlist").decode("utf-8"), self
.main_window
, shortcut
="Ctrl+W",
83 statusTip
="Save current playlist as m3u", triggered
=self
.save_playlist_callback
)
84 self
.action_clear_playlist
= QtGui
.QAction(QtGui
.QIcon(':/images/trashcan.png'), _("Clear Playlist").decode("utf-8"), self
.main_window
, shortcut
="Ctrl+H",
85 statusTip
="Clear current playlist", triggered
=self
.clear_playlist_callback
)
86 self
.action_delete_bookmarks
= QtGui
.QAction(QtGui
.QIcon(':/images/trashcan.png'), _("Delete All Bookmarks").decode("utf-8"), self
.main_window
, shortcut
="Ctrl+K",
87 statusTip
="Delete all bookmarks", triggered
=self
.delete_bookmarks_callback
)
88 self
.action_quit
= QtGui
.QAction(QtGui
.QIcon('/usr/share/icons/gnome/16x16/actions/exit.png'), "Quit", self
.main_window
, shortcut
="Ctrl+Q",
89 statusTip
="Exit the application", triggered
=self
.quit_panucci
)
91 self
.action_playlist
= QtGui
.QAction("Playlist", self
.main_window
, shortcut
="Ctrl+P",
92 statusTip
="Open playlist", triggered
=self
.playlist_callback
)
93 self
.action_settings
= QtGui
.QAction("Settings", self
.main_window
, shortcut
="Ctrl+C",
94 statusTip
="Open settings dialog", triggered
=self
.settings_callback
)
96 self
.action_lock_progress
= QtGui
.QAction(_("Lock Progress Bar").decode("utf-8"), self
.main_window
, shortcut
="Ctrl+L",
97 statusTip
="Lock progress bar", triggered
=self
.lock_progress_callback
)
98 self
.action_lock_progress
.setCheckable(True)
99 self
.action_lock_progress
.setChecked(self
.config
.getboolean("options", "lock_progress"))
100 self
.action_dual_action
= QtGui
.QAction(_("Dual Action Button").decode("utf-8"), self
.main_window
, shortcut
="Ctrl+B",
101 statusTip
="Set dual action button", triggered
=self
.dual_action_callback
)
102 self
.action_dual_action
.setCheckable(True)
103 self
.action_dual_action
.setChecked(self
.config
.getboolean("options", "dual_action_button"))
104 self
.action_stay_at_end
= QtGui
.QAction(_("Stay at End").decode("utf-8"), self
.main_window
, shortcut
="Ctrl+E",
105 statusTip
="Stay at file end", triggered
=self
.stay_at_end_callback
)
106 self
.action_stay_at_end
.setCheckable(True)
107 self
.action_stay_at_end
.setChecked(self
.config
.getboolean("options", "stay_at_end"))
108 self
.action_seek_back
= QtGui
.QAction(_("Seek Back").decode("utf-8"), self
.main_window
, shortcut
="Ctrl+S",
109 statusTip
="Seek back to previous file", triggered
=self
.seek_back_callback
)
110 self
.action_seek_back
.setCheckable(True)
111 self
.action_seek_back
.setChecked(self
.config
.getboolean("options", "seek_back"))
112 self
.action_scrolling_labels
= QtGui
.QAction(_("Scrolling Labels").decode("utf-8"), self
.main_window
, shortcut
="Ctrl+V",
113 statusTip
="Scroll title labels when too long", triggered
=self
.scrolling_labels_callback
)
114 self
.action_scrolling_labels
.setCheckable(True)
115 self
.action_scrolling_labels
.setChecked(self
.config
.getboolean("options", "scrolling_labels"))
116 self
.action_play_mode_all
= QtGui
.QAction(_("All").decode("utf-8"), self
.main_window
, statusTip
="Set play mode",
117 triggered
=self
.play_mode_all_callback
)
118 self
.action_play_mode_all
.setCheckable(True)
119 self
.action_play_mode_single
= QtGui
.QAction(_("Single").decode("utf-8"), self
.main_window
, statusTip
="Set play mode",
120 triggered
=self
.play_mode_single_callback
)
121 self
.action_play_mode_single
.setCheckable(True)
122 self
.action_play_mode_random
= QtGui
.QAction(_("Random").decode("utf-8"), self
.main_window
, statusTip
="Set play mode",
123 triggered
=self
.play_mode_random_callback
)
124 self
.action_play_mode_random
.setCheckable(True)
125 self
.action_play_mode_repeat
= QtGui
.QAction(_("Repeat").decode("utf-8"), self
.main_window
, statusTip
="Set play mode",
126 triggered
=self
.play_mode_repeat_callback
)
127 self
.action_play_mode_repeat
.setCheckable(True)
128 actiongroup
= QtGui
.QActionGroup(self
.main_window
)
129 actiongroup
.setExclusive(True)
130 self
.action_play_mode_all
.setActionGroup(actiongroup
)
131 self
.action_play_mode_single
.setActionGroup(actiongroup
)
132 self
.action_play_mode_random
.setActionGroup(actiongroup
)
133 self
.action_play_mode_repeat
.setActionGroup(actiongroup
)
134 if self
.config
.get("options", "play_mode") == "single":
135 self
.action_play_mode_single
.setChecked(True)
136 elif self
.config
.get("options", "play_mode") == "random":
137 self
.action_play_mode_random
.setChecked(True)
138 elif self
.config
.get("options", "play_mode") == "repeat":
139 self
.action_play_mode_repeat
.setChecked(True)
141 self
.action_play_mode_all
.setChecked(True)
143 self
.action_about
= QtGui
.QAction(QtGui
.QIcon('about.png'), _("About").decode("utf-8"), self
.main_window
,
144 statusTip
="Show about dialog", triggered
=self
.about_callback
)
146 def create_menus(self
):
148 self
.menu_file
= self
.main_window
.menuBar().addMenu(_("File").decode("utf-8"))
149 self
.menu_file
.addAction(self
.action_add_file
)
150 self
.menu_file
.addAction(self
.action_add_folder
)
151 self
.menu_file
.addAction(self
.action_save_playlist
)
152 self
.menu_file
.addAction(self
.action_clear_playlist
)
153 self
.menu_file
.addAction(self
.action_delete_bookmarks
)
154 self
.menu_file
.addSeparator()
155 self
.menu_file
.addAction(self
.action_quit
)
157 self
.menu_tools
= self
.main_window
.menuBar().addMenu(_("Tools").decode("utf-8"))
158 self
.menu_tools
.addAction(self
.action_playlist
)
159 self
.menu_tools
.addAction(self
.action_settings
)
161 self
.menu_settings
= self
.main_window
.menuBar().addMenu(_("Settings").decode("utf-8"))
162 self
.menu_settings
.addAction(self
.action_lock_progress
)
163 self
.menu_settings
.addAction(self
.action_dual_action
)
164 self
.menu_settings
.addAction(self
.action_stay_at_end
)
165 self
.menu_settings
.addAction(self
.action_seek_back
)
166 self
.menu_settings
.addAction(self
.action_scrolling_labels
)
167 self
.menu_play_mode
= self
.menu_settings
.addMenu(_("Play Mode").decode("utf-8"))
168 self
.menu_play_mode
.addAction(self
.action_play_mode_all
)
169 self
.menu_play_mode
.addAction(self
.action_play_mode_single
)
170 self
.menu_play_mode
.addAction(self
.action_play_mode_random
)
171 self
.menu_play_mode
.addAction(self
.action_play_mode_repeat
)
173 self
.menu_help
= self
.main_window
.menuBar().addMenu(_("Help").decode("utf-8"))
174 self
.menu_help
.addAction(self
.action_about
)
176 def create_maemo_menus(self
):
178 self
.menu_player
= self
.main_window
.menuBar().addMenu("Player")
179 self
.menu_player
.addAction(self
.action_settings
)
180 self
.menu_player
.addAction(self
.action_playlist
)
181 self
.menu_player
.addAction(self
.action_add_file
)
182 self
.menu_player
.addAction(self
.action_add_folder
)
183 self
.menu_player
.addAction(self
.action_clear_playlist
)
184 self
.menu_player
.addAction(self
.action_about
)
186 self
.menu_playlist
= self
.__playlist
_tab
.main_window
.menuBar().addMenu("Playlist")
187 self
.menu_playlist
.addAction(self
.action_save_playlist
)
188 self
.menu_playlist
.addAction(self
.action_delete_bookmarks
)
190 def quit_panucci(self
):
191 self
.main_window
.hide()
192 self
.playlist
.player
.quit()
193 util
.write_config(self
.config
)
196 def close_main_window_callback(self
, event
):
199 def show_main_window(self
):
200 self
.main_window
.activateWindow()
202 def add_file_callback(self
):
203 filenames
= qtutil
.get_file_from_filechooser(self
)
205 self
._play
_file
(filenames
[0].encode('utf-8'))
207 def add_folder_callback(self
):
208 filenames
= qtutil
.get_file_from_filechooser(self
, folder
=True)
210 self
._play
_file
(filenames
[0].encode('utf-8'))
212 def save_playlist_callback(self
):
213 filenames
= qtutil
.get_file_from_filechooser(self
, save_file
=True, save_to
=True)
217 filename
= filenames
[0]
218 if os
.path
.isfile(filename
):
219 response
= qtutil
.dialog(self
.main_window
, _('File already exists!'),
220 _('The file %s already exists. You can choose another name or '
221 'overwrite the existing file.') % os
.path
.basename(filename
), False, True, True, True)
223 if response
== QtGui
.QMessageBox
.Cancel
:
225 elif response
== QtGui
.QMessageBox
.Discard
:
226 return self
.save_playlist_callback()
228 ext
= util
.detect_filetype(filename
)
229 if not self
.playlist
.save_to_new_playlist(filename
, ext
):
230 self
.notify(_('Error saving playlist...'))
235 def clear_playlist_callback(self
):
236 self
.playlist
.reset_playlist()
237 self
.__playlist
_tab
.clear_model()
239 def delete_bookmarks_callback(self
):
240 response
= qtutil
.dialog(self
.main_window
, _('Delete all bookmarks?'),
241 _('By accepting all bookmarks in the database will be deleted.'), True, False, True, False)
242 if response
== QtGui
.QMessageBox
.Ok
:
243 self
.playlist
.delete_all_bookmarks()
245 def playlist_callback(self
):
246 self
.__playlist
_tab
.main_window
.show()
248 def settings_callback(self
):
249 from panucci
.qtui
.qtsettingsdialog
import SettingsDialog
252 def lock_progress_callback(self
):
253 self
.set_config_option("lock_progress", str(self
.action_lock_progress
.isChecked()).lower())
255 def dual_action_callback(self
):
256 self
.set_config_option("dual_action_button", str(self
.action_dual_action
.isChecked()).lower())
258 def stay_at_end_callback(self
):
259 self
.set_config_option("stay_at_end", str(self
.action_stay_at_end
.isChecked()).lower())
261 def seek_back_callback(self
):
262 self
.set_config_option("seek_back", str(self
.action_seek_back
.isChecked()).lower())
264 def scrolling_labels_callback(self
):
265 self
.set_config_option("scrolling_labels", str(self
.action_scrolling_labels
.isChecked()).lower())
266 self
.__player
_tab
.label_title
.set_scrolling(self
.config
.getboolean("options", "scrolling_labels"))
268 def play_mode_all_callback(self
):
269 self
.set_config_option("play_mode", "all")
271 def play_mode_single_callback(self
):
272 self
.set_config_option("play_mode", "single")
274 def play_mode_random_callback(self
):
275 self
.set_config_option("play_mode", "random")
277 def play_mode_repeat_callback(self
):
278 self
.set_config_option("play_mode", "repeat")
280 def about_callback(self
):
281 from panucci
.qtui
import qtaboutdialog
282 qtaboutdialog
.AboutDialog(self
.main_window
, panucci
.__version
__)
284 def set_config_option(self
, option
, value
):
285 self
.config
.set("options", option
, value
)
287 def _play_file(self
, filename
, pause_on_load
=False):
288 self
.playlist
.load( os
.path
.abspath(filename
) )
290 if self
.playlist
.is_empty
:
293 ##################################################
295 ##################################################
296 class PlayerTab(ObservableService
):
297 """ The tab that holds the player elements """
299 signals
= [ 'select-current-item-request', ]
301 def __init__(self
, gui_root
):
302 self
.__log
= logging
.getLogger('panucci.panucci.PlayerTab')
303 self
.__gui
_root
= gui_root
304 self
.config
= gui_root
.config
305 self
.playlist
= gui_root
.playlist
306 ObservableService
.__init
__(self
, self
.signals
, self
.__log
)
308 self
.playlist
.player
.register( 'stopped', self
.on_player_stopped
)
309 self
.playlist
.player
.register( 'playing', self
.on_player_playing
)
310 self
.playlist
.player
.register( 'paused', self
.on_player_paused
)
311 self
.playlist
.player
.register( 'eof', self
.on_player_eof
)
312 self
.playlist
.register( 'end-of-playlist', self
.on_player_end_of_playlist
)
313 self
.playlist
.register( 'new-track-loaded', self
.on_player_new_track
)
314 self
.playlist
.register( 'new-metadata-available', self
.on_player_new_metadata
)
315 self
.playlist
.register( 'reset-playlist', self
.on_player_reset_playlist
)
317 self
.mainbox
= QtGui
.QVBoxLayout()
318 self
.mainbox
.setContentsMargins(0, 0, 0, 0)
319 self
.mainbox
.setSpacing(0)
321 layout
= QtGui
.QHBoxLayout()
322 layout
.setContentsMargins(0, 0, 0, 0)
324 self
.label_cover
= QtGui
.QLabel()
325 self
.label_cover
.setContentsMargins(0, 5, 2, 5)
326 layout
.addWidget(self
.label_cover
)
327 vlayout
= QtGui
.QVBoxLayout()
328 vlayout
.setContentsMargins(0, 0, 0, 0)
329 vlayout
.setSpacing(0)
330 vlayout
.addStretch(5)
331 self
.label_artist
= QtGui
.QLabel()
332 self
.label_album
= QtGui
.QLabel()
333 self
.label_artist
.setContentsMargins(3, 0, 5, 10)
334 self
.label_album
.setContentsMargins(3, 0, 5, 10)
335 self
.label_title
= qtwidgets
.ScrollingLabel(self
.config
)
336 self
.label_title
.setContentsMargins(0, 0, 0, 0)
337 vlayout
.addWidget(self
.label_artist
)
338 vlayout
.addWidget(self
.label_album
)
339 vlayout
.addWidget(self
.label_title
)
340 vlayout
.addStretch(5)
341 layout
.addLayout(vlayout
, 2)
342 self
.mainbox
.addLayout(layout
, 8)
344 self
.progress
= QtGui
.QProgressBar()
345 self
.progress
.setContentsMargins(0, 0, 0, 0)
346 self
.mainbox
.addWidget(self
.progress
)
347 self
.progress
.setTextVisible(True)
348 self
.progress
.setFormat("00:00 / 00:00")
349 self
.progress
.setValue(0)
350 self
.progress
.mousePressEvent
= self
.on_progress_clicked
351 self
.progress
.setFixedHeight(self
.config
.getint("options", "progress_height"))
353 self
.icon_play
= QtGui
.QIcon(util
.find_data_file('media-playback-start.png'))
354 self
.icon_pause
= QtGui
.QIcon(util
.find_data_file('media-playback-pause.png'))
355 self
.button_rrewind
= qtwidgets
.DualActionButton(self
.config
,
356 QtGui
.QIcon(util
.find_data_file('media-skip-backward.png')),
357 self
.button_rrewind_callback
,
358 QtGui
.QIcon("/usr/share/icons/gnome/24x24/actions/gtk-goto-first-ltr.png"),
360 self
.button_rrewind
.setFixedHeight(self
.config
.getint("options", "button_height"))
361 self
.button_rewind
= QtGui
.QPushButton(QtGui
.QIcon(util
.find_data_file('media-seek-backward.png')), "")
362 self
.button_rewind
.clicked
.connect(self
.button_rewind_callback
)
363 self
.button_rewind
.setFixedHeight(self
.config
.getint("options", "button_height"))
364 self
.button_play
= QtGui
.QPushButton(self
.icon_play
, "")
365 self
.button_play
.clicked
.connect(self
.button_play_callback
)
366 self
.button_play
.setFixedHeight(self
.config
.getint("options", "button_height"))
367 self
.button_forward
= QtGui
.QPushButton(QtGui
.QIcon(util
.find_data_file('media-seek-forward.png')), "")
368 self
.button_forward
.clicked
.connect(self
.button_forward_callback
)
369 self
.button_forward
.setFixedHeight(self
.config
.getint("options", "button_height"))
370 self
.button_fforward
= qtwidgets
.DualActionButton(self
.config
,
371 QtGui
.QIcon(util
.find_data_file('media-skip-forward.png')),
372 self
.button_fforward_callback
,
373 QtGui
.QIcon("/usr/share/icons/gnome/24x24/actions/gtk-goto-last-ltr.png"),
375 self
.button_fforward
.setFixedHeight(self
.config
.getint("options", "button_height"))
376 self
.button_bookmark
= QtGui
.QPushButton(QtGui
.QIcon(util
.find_data_file('bookmark-new.png')), "")
377 self
.button_bookmark
.clicked
.connect(self
.button_bookmark_callback
)
378 self
.button_bookmark
.setFixedHeight(self
.config
.getint("options", "button_height"))
380 layout
= QtGui
.QHBoxLayout()
381 layout
.setContentsMargins(0, 4, 0, 0)
383 layout
.addWidget(self
.button_rrewind
)
384 layout
.addWidget(self
.button_rewind
)
385 layout
.addWidget(self
.button_play
)
386 layout
.addWidget(self
.button_forward
)
387 layout
.addWidget(self
.button_fforward
)
388 layout
.addWidget(self
.button_bookmark
)
389 self
.mainbox
.addLayout(layout
)
391 self
.timer
= QtCore
.QTimer()
392 self
.timer
.setInterval(1000);
393 self
.timer
.timeout
.connect(self
.timer_callback
)
395 def on_player_stopped(self
):
396 self
.stop_progress_timer()
397 #self.set_controls_sensitivity(False)
398 self
.button_play
.setIcon(self
.icon_play
)
400 def on_player_playing(self
):
401 self
.start_progress_timer()
402 self
.button_play
.setIcon(self
.icon_pause
)
403 #self.set_controls_sensitivity(True)
405 def on_player_paused( self
, position
, duration
):
406 self
.stop_progress_timer()
407 #self.set_progress_callback( position, duration )
408 self
.button_play
.setIcon(self
.icon_play
)
410 def on_player_eof(self
):
411 play_mode
= self
.config
.get("options", "play_mode")
412 if play_mode
== "single":
413 if not self
.config
.getboolean("options", "stay_at_end"):
414 self
.on_player_end_of_playlist(False)
415 elif play_mode
== "random":
416 self
.playlist
.random()
417 elif play_mode
== "repeat":
418 self
.playlist
.next(True)
420 if self
.playlist
.end_of_playlist():
421 if not self
.config
.getboolean("options", "stay_at_end"):
422 self
.playlist
.next(False)
424 self
.playlist
.next(False)
426 def on_player_new_track(self
):
427 for widget
in [self
.label_title
, self
.label_artist
, self
.label_album
, self
.label_cover
]:
429 self
.label_cover
.hide()
430 self
.has_coverart
= False
432 def on_player_new_metadata(self
):
433 self
.metadata
= self
.playlist
.get_file_metadata()
434 self
.set_metadata(self
.metadata
)
436 if not self
.playlist
.player
.playing
:
437 position
= self
.playlist
.get_current_position()
438 estimated_length
= self
.metadata
.get('length', 0)
439 self
.set_progress_callback( position
, estimated_length
)
440 self
.playlist
.player
.set_position_duration(position
, 0)
442 def on_player_end_of_playlist(self
, loop
):
444 self
.playlist
.player
.stop_end_of_playlist()
445 estimated_length
= self
.metadata
.get('length', 0)
446 self
.set_progress_callback( 0, estimated_length
)
447 self
.playlist
.player
.set_position_duration(0, 0)
449 def on_player_reset_playlist(self
):
450 self
.on_player_stopped()
451 self
.on_player_new_track()
452 self
.reset_progress()
453 self
.__gui
_root
.main_window
.setWindowTitle("Panucci")
455 def reset_progress(self
):
456 self
.set_progress_callback(0,0)
458 def button_rrewind_callback(self
):
459 self
.do_seek(-1*self
.config
.getint("options", "seek_long"))
461 def button_rewind_callback(self
):
462 self
.do_seek(-1*self
.config
.getint("options", "seek_short"))
464 def button_play_callback(self
):
465 self
.playlist
.player
.play_pause_toggle()
467 def button_forward_callback(self
):
468 self
.do_seek(self
.config
.getint("options", "seek_short"))
470 def button_fforward_callback(self
):
471 self
.do_seek(self
.config
.getint("options", "seek_long"))
473 def button_bookmark_callback(self
):
474 self
.playlist
.player
.add_bookmark_at_current_position()
476 def set_progress_callback(self
, time_elapsed
, total_time
):
477 """ times must be in nanoseconds """
478 time_string
= "%s / %s" % ( util
.convert_ns(time_elapsed
),
479 util
.convert_ns(total_time
) )
480 self
.progress
.setFormat( time_string
)
481 fraction
= float(time_elapsed
) / float(total_time
) if total_time
else 0
482 self
.progress
.setValue( int(fraction
*100) )
484 def on_progress_clicked(self
, event
):
485 if ( not self
.config
.getboolean("options", "lock_progress") and
486 event
.button() == QtCore
.Qt
.MouseButton
.LeftButton
):
487 new_fraction
= float(event
.x())/float(self
.progress
.width())
488 resp
= self
.playlist
.player
.do_seek(percent
=new_fraction
)
490 # Preemptively update the progressbar to make seeking smoother
491 self
.set_progress_callback( *resp
)
493 def timer_callback( self
):
494 if self
.playlist
.player
.playing
and not self
.playlist
.player
.seeking
:
495 pos_int
, dur_int
= self
.playlist
.player
.get_position_duration()
496 # This prevents bogus values from being set while seeking
497 if ( pos_int
> 10**9 ) and ( dur_int
> 10**9 ):
498 self
.set_progress_callback( pos_int
, dur_int
)
501 def start_progress_timer( self
):
504 def stop_progress_timer( self
):
507 def get_cover_size(self
):
508 if self
.__gui
_root
.main_window
.isFullScreen():
509 size
= self
.config
.getint("options", "cover_full_height")
511 size
= self
.config
.getint("options", "cover_height")
514 def set_cover_size(self
):
515 if self
.has_coverart
:
516 size
= self
.get_cover_size()
517 pixmap
= self
.label_cover
.pixmap().scaled(size
, size
, mode
=QtCore
.Qt
.SmoothTransformation
)
518 self
.label_cover
.setPixmap(pixmap
)
520 def set_metadata( self
, tag_message
):
521 tags
= { 'title': self
.label_title
, 'artist': self
.label_artist
,
522 'album': self
.label_album
}
525 if tag_message
.has_key('image') and tag_message
['image'] is not None:
526 value
= tag_message
['image']
529 pixmap
= QtGui
.QPixmap()
530 pixmap
.loadFromData(value
)
531 size
= self
.get_cover_size()
532 pixmap
= pixmap
.scaled(size
, size
, mode
=QtCore
.Qt
.SmoothTransformation
)
533 self
.label_cover
.setPixmap(pixmap
)
534 self
.label_cover
.show()
535 self
.has_coverart
= True
537 self
.__log
.exception('Error setting coverart...')
539 # set the text metadata
540 for tag
,value
in tag_message
.iteritems():
541 if tags
.has_key(tag
) and value
is not None and value
.strip():
542 value
= value
.decode('utf-8')
544 _str
= '<big>' + cgi
.escape(value
) + '</big>'
546 _str
= cgi
.escape(value
)
548 _str
= '<b><big>' + cgi
.escape(value
) + '</big></b>'
549 if not platform
.MAEMO
:
550 value
+= ' - Panucci'
551 if platform
.FREMANTLE
and len(value
) > 25:
552 value
= value
[:24] + '...'
553 self
.__gui
_root
.main_window
.setWindowTitle(value
)
555 if not self
.has_coverart
:
556 tags
[tag
].setAlignment(QtCore
.Qt
.AlignHCenter
)
558 tags
[tag
].setAlignment(QtCore
.Qt
.AlignLeft
)
560 tags
[tag
].setText(_str
)
562 self
.__log
.exception(str(e
))
566 def do_seek(self
, seek_amount
):
567 seek_amount
= seek_amount
*10**9
569 if not self
.config
.getboolean("options", "seek_back") or self
.playlist
.start_of_playlist() or seek_amount
> 0:
570 resp
= self
.playlist
.player
.do_seek(from_current
=seek_amount
)
572 pos_int
, dur_int
= self
.playlist
.player
.get_position_duration()
573 if pos_int
+ seek_amount
>= 0:
574 resp
= self
.playlist
.player
.do_seek(from_current
=seek_amount
)
577 pos_int
, dur_int
= self
.playlist
.player
.get_position_duration()
578 resp
= self
.playlist
.player
.do_seek(from_beginning
=dur_int
+seek_amount
)
580 # Preemptively update the progressbar to make seeking smoother
581 self
.set_progress_callback( *resp
)