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_handset_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
.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_play_one
= QtGui
.QAction(QtGui
.QIcon(''), _("Play One").decode("utf-8"), self
.main_window
, shortcut
="Ctrl+O",
83 statusTip
="Play one file", triggered
=self
.play_one_callback
)
84 self
.action_save_playlist
= QtGui
.QAction(QtGui
.QIcon(':/images/save.png'), _("Save Playlist").decode("utf-8"), self
.main_window
, shortcut
="Ctrl+W",
85 statusTip
="Save current playlist as m3u", triggered
=self
.save_playlist_callback
)
86 self
.action_clear_playlist
= QtGui
.QAction(QtGui
.QIcon(':/images/trashcan.png'), _("Clear Playlist").decode("utf-8"), self
.main_window
, shortcut
="Ctrl+H",
87 statusTip
="Clear current playlist", triggered
=self
.clear_playlist_callback
)
88 self
.action_delete_bookmarks
= QtGui
.QAction(QtGui
.QIcon(':/images/trashcan.png'), _("Delete All Bookmarks").decode("utf-8"), self
.main_window
, shortcut
="Ctrl+K",
89 statusTip
="Delete all bookmarks", triggered
=self
.delete_bookmarks_callback
)
90 self
.action_quit
= QtGui
.QAction(QtGui
.QIcon('/usr/share/icons/gnome/16x16/actions/exit.png'), "Quit", self
.main_window
, shortcut
="Ctrl+Q",
91 statusTip
="Exit the application", triggered
=self
.quit_panucci
)
93 self
.action_playlist
= QtGui
.QAction(_("Playlist"), self
.main_window
, shortcut
="Ctrl+P",
94 statusTip
=_("Open playlist"), triggered
=self
.playlist_callback
)
95 self
.action_settings
= QtGui
.QAction(_("Settings"), self
.main_window
, shortcut
="Ctrl+C",
96 statusTip
=_("Open settings dialog"), triggered
=self
.settings_callback
)
97 self
.action_timer
= QtGui
.QAction(_("Sleep Timer"), self
.main_window
, shortcut
="Ctrl+T",
98 statusTip
=_("Start a timed shutdown"), triggered
=self
.create_timer_dialog
)
100 self
.action_lock_progress
= QtGui
.QAction(_("Lock Progress Bar").decode("utf-8"), self
.main_window
, shortcut
="Ctrl+L",
101 statusTip
="Lock progress bar", triggered
=self
.lock_progress_callback
)
102 self
.action_lock_progress
.setCheckable(True)
103 self
.action_lock_progress
.setChecked(self
.config
.getboolean("options", "lock_progress"))
104 self
.action_dual_action
= QtGui
.QAction(_("Dual Action Button").decode("utf-8"), self
.main_window
, shortcut
="Ctrl+B",
105 statusTip
="Set dual action button", triggered
=self
.dual_action_callback
)
106 self
.action_dual_action
.setCheckable(True)
107 self
.action_dual_action
.setChecked(self
.config
.getboolean("options", "dual_action_button"))
108 self
.action_stay_at_end
= QtGui
.QAction(_("Stay at End").decode("utf-8"), self
.main_window
, shortcut
="Ctrl+E",
109 statusTip
="Stay at file end", triggered
=self
.stay_at_end_callback
)
110 self
.action_stay_at_end
.setCheckable(True)
111 self
.action_stay_at_end
.setChecked(self
.config
.getboolean("options", "stay_at_end"))
112 self
.action_seek_back
= QtGui
.QAction(_("Seek Back").decode("utf-8"), self
.main_window
, shortcut
="Ctrl+S",
113 statusTip
="Seek back to previous file", triggered
=self
.seek_back_callback
)
114 self
.action_seek_back
.setCheckable(True)
115 self
.action_seek_back
.setChecked(self
.config
.getboolean("options", "seek_back"))
116 self
.action_scrolling_labels
= QtGui
.QAction(_("Scrolling Labels").decode("utf-8"), self
.main_window
, shortcut
="Ctrl+V",
117 statusTip
="Scroll title labels when too long", triggered
=self
.scrolling_labels_callback
)
118 self
.action_scrolling_labels
.setCheckable(True)
119 self
.action_scrolling_labels
.setChecked(self
.config
.getboolean("options", "scrolling_labels"))
120 self
.action_play_mode_all
= QtGui
.QAction(_("All").decode("utf-8"), self
.main_window
, statusTip
="Set play mode",
121 triggered
=self
.play_mode_all_callback
)
122 self
.action_play_mode_all
.setCheckable(True)
123 self
.action_play_mode_single
= QtGui
.QAction(_("Single").decode("utf-8"), self
.main_window
, statusTip
="Set play mode",
124 triggered
=self
.play_mode_single_callback
)
125 self
.action_play_mode_single
.setCheckable(True)
126 self
.action_play_mode_random
= QtGui
.QAction(_("Random").decode("utf-8"), self
.main_window
, statusTip
="Set play mode",
127 triggered
=self
.play_mode_random_callback
)
128 self
.action_play_mode_random
.setCheckable(True)
129 self
.action_play_mode_repeat
= QtGui
.QAction(_("Repeat").decode("utf-8"), self
.main_window
, statusTip
="Set play mode",
130 triggered
=self
.play_mode_repeat_callback
)
131 self
.action_play_mode_repeat
.setCheckable(True)
132 actiongroup
= QtGui
.QActionGroup(self
.main_window
)
133 actiongroup
.setExclusive(True)
134 self
.action_play_mode_all
.setActionGroup(actiongroup
)
135 self
.action_play_mode_single
.setActionGroup(actiongroup
)
136 self
.action_play_mode_random
.setActionGroup(actiongroup
)
137 self
.action_play_mode_repeat
.setActionGroup(actiongroup
)
138 if self
.config
.get("options", "play_mode") == "single":
139 self
.action_play_mode_single
.setChecked(True)
140 elif self
.config
.get("options", "play_mode") == "random":
141 self
.action_play_mode_random
.setChecked(True)
142 elif self
.config
.get("options", "play_mode") == "repeat":
143 self
.action_play_mode_repeat
.setChecked(True)
145 self
.action_play_mode_all
.setChecked(True)
147 self
.action_about
= QtGui
.QAction(QtGui
.QIcon('about.png'), _("About").decode("utf-8"), self
.main_window
,
148 statusTip
="Show about dialog", triggered
=self
.about_callback
)
150 def create_menus(self
):
152 self
.menu_file
= self
.main_window
.menuBar().addMenu(_("File").decode("utf-8"))
153 self
.menu_file
.addAction(self
.action_add_file
)
154 self
.menu_file
.addAction(self
.action_add_folder
)
155 self
.menu_file
.addAction(self
.action_play_one
)
156 self
.menu_file
.addAction(self
.action_save_playlist
)
157 self
.menu_file
.addAction(self
.action_clear_playlist
)
158 self
.menu_file
.addAction(self
.action_delete_bookmarks
)
159 self
.menu_file
.addSeparator()
160 self
.menu_file
.addAction(self
.action_quit
)
162 self
.menu_tools
= self
.main_window
.menuBar().addMenu(_("Tools").decode("utf-8"))
163 self
.menu_tools
.addAction(self
.action_playlist
)
164 self
.menu_tools
.addAction(self
.action_timer
)
165 #self.menu_tools.addAction(self.action_settings)
167 self
.menu_settings
= self
.main_window
.menuBar().addMenu(_("Settings").decode("utf-8"))
168 self
.menu_settings
.addAction(self
.action_lock_progress
)
169 self
.menu_settings
.addAction(self
.action_dual_action
)
170 self
.menu_settings
.addAction(self
.action_stay_at_end
)
171 self
.menu_settings
.addAction(self
.action_seek_back
)
172 self
.menu_settings
.addAction(self
.action_scrolling_labels
)
173 self
.menu_play_mode
= self
.menu_settings
.addMenu(_("Play Mode").decode("utf-8"))
174 self
.menu_play_mode
.addAction(self
.action_play_mode_all
)
175 self
.menu_play_mode
.addAction(self
.action_play_mode_single
)
176 self
.menu_play_mode
.addAction(self
.action_play_mode_random
)
177 self
.menu_play_mode
.addAction(self
.action_play_mode_repeat
)
179 self
.menu_help
= self
.main_window
.menuBar().addMenu(_("Help").decode("utf-8"))
180 self
.menu_help
.addAction(self
.action_about
)
182 def create_handset_menus(self
):
184 self
.menu_player
= self
.main_window
.menuBar().addMenu("Player")
185 self
.menu_player
.addAction(self
.action_settings
)
186 self
.menu_player
.addAction(self
.action_playlist
)
187 self
.menu_player
.addAction(self
.action_add_file
)
188 self
.menu_player
.addAction(self
.action_add_folder
)
189 self
.menu_player
.addAction(self
.action_play_one
)
190 self
.menu_player
.addAction(self
.action_clear_playlist
)
191 self
.menu_player
.addAction(self
.action_timer
)
192 self
.menu_player
.addAction(self
.action_about
)
194 self
.menu_playlist
= self
.__playlist
_tab
.main_window
.menuBar().addMenu("Playlist")
195 self
.menu_playlist
.addAction(self
.action_save_playlist
)
196 self
.menu_playlist
.addAction(self
.action_delete_bookmarks
)
198 def create_timer_dialog(self
):
199 response
= QtGui
.QInputDialog
.getInteger(self
.main_window
, _("Sleep Timer"), _("Shutdown time in minutes"),
202 QtCore
.QTimer
.singleShot(60000*response
[0], self
.quit_panucci
)
204 def quit_panucci(self
):
205 self
.main_window
.hide()
207 util
.write_config(self
.config
)
210 def close_main_window_callback(self
, event
):
213 def show_main_window(self
):
214 self
.main_window
.activateWindow()
216 def add_file_callback(self
):
217 filenames
= qtutil
.get_file_from_filechooser(self
)
219 self
._play
_file
(filenames
[0].encode('utf-8'))
221 def add_folder_callback(self
):
222 filenames
= qtutil
.get_file_from_filechooser(self
, folder
=True)
224 self
._play
_file
(filenames
[0].encode('utf-8'))
226 def play_one_callback(self
):
227 filenames
= qtutil
.get_file_from_filechooser(self
)
229 self
.clear_playlist_callback()
230 self
._play
_file
(filenames
[0].encode('utf-8'))
232 def save_playlist_callback(self
):
233 filenames
= qtutil
.get_file_from_filechooser(self
, save_file
=True, save_to
=True)
237 filename
= filenames
[0]
238 if os
.path
.isfile(filename
):
239 response
= qtutil
.dialog(self
.main_window
, _('File already exists!'),
240 _('The file %s already exists. You can choose another name or '
241 'overwrite the existing file.') % os
.path
.basename(filename
), False, True, True, True)
243 if response
== QtGui
.QMessageBox
.Cancel
:
245 elif response
== QtGui
.QMessageBox
.Discard
:
246 return self
.save_playlist_callback()
248 ext
= util
.detect_filetype(filename
)
249 if not self
.playlist
.save_to_new_playlist(filename
, ext
):
250 self
.notify(_('Error saving playlist...'))
255 def clear_playlist_callback(self
):
256 self
.playlist
.reset_playlist()
257 self
.__playlist
_tab
.clear_model()
259 def delete_bookmarks_callback(self
):
260 response
= qtutil
.dialog(self
.main_window
, _('Delete all bookmarks?'),
261 _('By accepting all bookmarks in the database will be deleted.'), True, False, True, False)
262 if response
== QtGui
.QMessageBox
.Ok
:
263 self
.playlist
.delete_all_bookmarks()
264 self
.__playlist
_tab
.update_model()
266 def playlist_callback(self
):
267 self
.__playlist
_tab
.main_window
.show()
269 def settings_callback(self
):
270 from panucci
.qtui
.qtsettingsdialog
import SettingsDialog
273 def lock_progress_callback(self
):
274 self
.set_config_option("lock_progress", str(self
.action_lock_progress
.isChecked()).lower())
276 def dual_action_callback(self
):
277 self
.set_config_option("dual_action_button", str(self
.action_dual_action
.isChecked()).lower())
279 def stay_at_end_callback(self
):
280 self
.set_config_option("stay_at_end", str(self
.action_stay_at_end
.isChecked()).lower())
282 def seek_back_callback(self
):
283 self
.set_config_option("seek_back", str(self
.action_seek_back
.isChecked()).lower())
285 def scrolling_labels_callback(self
):
286 self
.set_config_option("scrolling_labels", str(self
.action_scrolling_labels
.isChecked()).lower())
287 self
.__player
_tab
.label_title
.set_scrolling(self
.config
.getboolean("options", "scrolling_labels"))
289 def play_mode_all_callback(self
):
290 self
.set_config_option("play_mode", "all")
292 def play_mode_single_callback(self
):
293 self
.set_config_option("play_mode", "single")
295 def play_mode_random_callback(self
):
296 self
.set_config_option("play_mode", "random")
298 def play_mode_repeat_callback(self
):
299 self
.set_config_option("play_mode", "repeat")
301 def about_callback(self
):
302 from panucci
.qtui
import qtaboutdialog
303 qtaboutdialog
.AboutDialog(self
.main_window
, panucci
.__version
__)
305 def set_config_option(self
, option
, value
):
306 self
.config
.set("options", option
, value
)
308 def _play_file(self
, filename
, pause_on_load
=False):
309 self
.playlist
.load( os
.path
.abspath(filename
) )
311 if self
.playlist
.is_empty
:
314 ##################################################
316 ##################################################
317 class PlayerTab(ObservableService
):
318 """ The tab that holds the player elements """
320 signals
= [ 'select-current-item-request', ]
322 def __init__(self
, gui_root
):
323 self
.__log
= logging
.getLogger('panucci.panucci.PlayerTab')
324 self
.__gui
_root
= gui_root
325 self
.config
= gui_root
.config
326 self
.playlist
= gui_root
.playlist
327 ObservableService
.__init
__(self
, self
.signals
, self
.__log
)
329 self
.playlist
.player
.register( 'stopped', self
.on_player_stopped
)
330 self
.playlist
.player
.register( 'playing', self
.on_player_playing
)
331 self
.playlist
.player
.register( 'paused', self
.on_player_paused
)
332 #self.playlist.player.register( 'eof', self.on_player_eof )
333 self
.playlist
.register( 'end-of-playlist', self
.on_player_end_of_playlist
)
334 self
.playlist
.register( 'new-track-loaded', self
.on_player_new_track
)
335 self
.playlist
.register( 'new-metadata-available', self
.on_player_new_metadata
)
336 self
.playlist
.register( 'reset-playlist', self
.on_player_reset_playlist
)
338 self
.mainbox
= QtGui
.QVBoxLayout()
339 self
.mainbox
.setContentsMargins(0, 0, 0, 0)
340 self
.mainbox
.setSpacing(0)
342 layout
= QtGui
.QHBoxLayout()
343 layout
.setContentsMargins(0, 0, 0, 0)
345 self
.label_cover
= QtGui
.QLabel()
346 self
.label_cover
.setContentsMargins(0, 5, 2, 5)
347 layout
.addWidget(self
.label_cover
)
348 vlayout
= QtGui
.QVBoxLayout()
349 vlayout
.setContentsMargins(0, 0, 0, 0)
350 vlayout
.setSpacing(0)
351 vlayout
.addStretch(5)
352 self
.label_artist
= QtGui
.QLabel()
353 self
.label_album
= QtGui
.QLabel()
354 self
.label_artist
.setContentsMargins(3, 0, 5, 10)
355 self
.label_album
.setContentsMargins(3, 0, 5, 10)
356 self
.label_title
= qtwidgets
.ScrollingLabel(self
.config
)
357 self
.label_title
.setContentsMargins(0, 0, 0, 0)
358 vlayout
.addWidget(self
.label_artist
)
359 vlayout
.addWidget(self
.label_album
)
360 vlayout
.addWidget(self
.label_title
)
361 vlayout
.addStretch(5)
362 layout
.addLayout(vlayout
, 2)
363 self
.mainbox
.addLayout(layout
, 8)
365 self
.progress
= QtGui
.QProgressBar()
366 self
.progress
.setContentsMargins(0, 0, 0, 0)
367 self
.mainbox
.addWidget(self
.progress
)
368 self
.progress
.setTextVisible(True)
369 self
.progress
.setFormat("00:00 / 00:00")
370 self
.progress
.setValue(0)
371 self
.progress
.mousePressEvent
= self
.on_progress_clicked
372 progress_height
= self
.config
.getint("options", "progress_height")
373 if progress_height
!= -1:
374 self
.progress
.setFixedHeight(progress_height
)
376 self
.icon_play
= QtGui
.QIcon(util
.find_data_file('media-playback-start.png'))
377 self
.icon_pause
= QtGui
.QIcon(util
.find_data_file('media-playback-pause.png'))
379 self
.button_rrewind
= qtwidgets
.DualActionButton(self
.config
,
380 QtGui
.QIcon(util
.find_data_file('media-skip-backward.png')),
381 self
.button_rrewind_callback
,
382 QtGui
.QIcon(util
.find_data_file("gtk-goto-first-ltr.png")),
384 self
.button_rewind
= QtGui
.QPushButton(QtGui
.QIcon(util
.find_data_file('media-seek-backward.png')), "")
385 self
.button_rewind
.clicked
.connect(self
.button_rewind_callback
)
386 self
.button_play
= QtGui
.QPushButton(self
.icon_play
, "")
387 self
.button_play
.clicked
.connect(self
.button_play_callback
)
388 self
.button_forward
= QtGui
.QPushButton(QtGui
.QIcon(util
.find_data_file('media-seek-forward.png')), "")
389 self
.button_forward
.clicked
.connect(self
.button_forward_callback
)
390 self
.button_fforward
= qtwidgets
.DualActionButton(self
.config
,
391 QtGui
.QIcon(util
.find_data_file('media-skip-forward.png')),
392 self
.button_fforward_callback
,
393 QtGui
.QIcon(util
.find_data_file("gtk-goto-last-ltr.png")),
395 self
.button_bookmark
= QtGui
.QPushButton(QtGui
.QIcon(util
.find_data_file('bookmark-new.png')), "")
396 self
.button_bookmark
.clicked
.connect(self
.button_bookmark_callback
)
398 button_height
= self
.config
.getint("options", "button_height")
399 if button_height
!= -1:
400 self
.button_rrewind
.setFixedHeight(button_height
)
401 self
.button_rewind
.setFixedHeight(button_height
)
402 self
.button_play
.setFixedHeight(button_height
)
403 self
.button_forward
.setFixedHeight(button_height
)
404 self
.button_fforward
.setFixedHeight(button_height
)
405 self
.button_bookmark
.setFixedHeight(button_height
)
407 layout
= QtGui
.QHBoxLayout()
408 layout
.setContentsMargins(0, 4, 0, 0)
410 layout
.addWidget(self
.button_rrewind
)
411 layout
.addWidget(self
.button_rewind
)
412 layout
.addWidget(self
.button_play
)
413 layout
.addWidget(self
.button_forward
)
414 layout
.addWidget(self
.button_fforward
)
415 layout
.addWidget(self
.button_bookmark
)
416 self
.mainbox
.addLayout(layout
)
418 self
.timer
= QtCore
.QTimer()
419 self
.timer
.setInterval(1000);
420 self
.timer
.timeout
.connect(self
.timer_callback
)
422 def on_player_stopped(self
):
423 self
.stop_progress_timer()
424 #self.set_controls_sensitivity(False)
425 self
.button_play
.setIcon(self
.icon_play
)
427 def on_player_playing(self
):
428 self
.start_progress_timer()
429 self
.button_play
.setIcon(self
.icon_pause
)
430 #self.set_controls_sensitivity(True)
432 def on_player_paused( self
, position
, duration
):
433 self
.stop_progress_timer()
434 #self.set_progress_callback( position, duration )
435 self
.button_play
.setIcon(self
.icon_play
)
437 def on_player_new_track(self
):
438 for widget
in [self
.label_title
, self
.label_artist
, self
.label_album
, self
.label_cover
]:
440 self
.label_cover
.hide()
441 self
.has_coverart
= False
443 def on_player_new_metadata(self
):
444 self
.metadata
= self
.playlist
.get_file_metadata()
445 self
.set_metadata(self
.metadata
)
447 if not self
.playlist
.player
.playing
:
448 position
= self
.playlist
.get_current_position()
449 estimated_length
= self
.metadata
.get('length', 0)
450 self
.set_progress_callback( position
, estimated_length
)
451 self
.playlist
.player
.set_position_duration(position
, 0)
453 def on_player_end_of_playlist(self
, loop
):
455 self
.playlist
.player
.stop_end_of_playlist()
456 estimated_length
= self
.metadata
.get('length', 0)
457 self
.set_progress_callback( 0, estimated_length
)
458 self
.playlist
.player
.set_position_duration(0, 0)
460 def on_player_reset_playlist(self
):
461 self
.on_player_stopped()
462 self
.on_player_new_track()
463 self
.reset_progress()
464 self
.__gui
_root
.main_window
.setWindowTitle("Panucci")
466 def reset_progress(self
):
467 self
.set_progress_callback(0,0)
469 def button_rrewind_callback(self
):
470 self
.do_seek(-1*self
.config
.getint("options", "seek_long"))
472 def button_rewind_callback(self
):
473 self
.do_seek(-1*self
.config
.getint("options", "seek_short"))
475 def button_play_callback(self
):
476 self
.playlist
.player
.play_pause_toggle()
478 def button_forward_callback(self
):
479 self
.do_seek(self
.config
.getint("options", "seek_short"))
481 def button_fforward_callback(self
):
482 self
.do_seek(self
.config
.getint("options", "seek_long"))
484 def button_bookmark_callback(self
):
485 self
.playlist
.player
.add_bookmark_at_current_position()
487 def set_progress_callback(self
, time_elapsed
, total_time
):
488 """ times must be in nanoseconds """
489 time_string
= "%s / %s" % ( util
.convert_ns(time_elapsed
),
490 util
.convert_ns(total_time
) )
491 self
.progress
.setFormat( time_string
)
492 fraction
= float(time_elapsed
) / float(total_time
) if total_time
else 0
493 self
.progress
.setValue( int(fraction
*100) )
495 def on_progress_clicked(self
, event
):
496 if ( not self
.config
.getboolean("options", "lock_progress") and
497 event
.button() == QtCore
.Qt
.MouseButton
.LeftButton
):
498 new_fraction
= float(event
.x())/float(self
.progress
.width())
499 resp
= self
.playlist
.player
.do_seek(percent
=new_fraction
)
501 # Preemptively update the progressbar to make seeking smoother
502 self
.set_progress_callback( *resp
)
504 def timer_callback( self
):
505 if self
.playlist
.player
.playing
and not self
.playlist
.player
.seeking
:
506 pos_int
, dur_int
= self
.playlist
.player
.get_position_duration()
507 # This prevents bogus values from being set while seeking
508 if ( pos_int
> 10**9 ) and ( dur_int
> 10**9 ):
509 self
.set_progress_callback( pos_int
, dur_int
)
512 def start_progress_timer( self
):
515 def stop_progress_timer( self
):
518 def get_cover_size(self
):
519 if self
.__gui
_root
.main_window
.isFullScreen():
520 size
= self
.config
.getint("options", "cover_full_height")
522 size
= self
.config
.getint("options", "cover_height")
525 def set_cover_size(self
):
526 if self
.has_coverart
:
527 size
= self
.get_cover_size()
528 pixmap
= self
.label_cover
.pixmap().scaled(size
, size
, mode
=QtCore
.Qt
.SmoothTransformation
)
529 self
.label_cover
.setPixmap(pixmap
)
531 def set_metadata( self
, tag_message
):
532 tags
= { 'title': self
.label_title
, 'artist': self
.label_artist
,
533 'album': self
.label_album
}
536 if tag_message
.has_key('image') and tag_message
['image'] is not None:
537 value
= tag_message
['image']
540 pixmap
= QtGui
.QPixmap()
541 pixmap
.loadFromData(value
)
542 size
= self
.get_cover_size()
543 pixmap
= pixmap
.scaled(size
, size
, mode
=QtCore
.Qt
.SmoothTransformation
)
544 self
.label_cover
.setPixmap(pixmap
)
545 self
.label_cover
.show()
546 self
.has_coverart
= True
548 self
.__log
.exception('Error setting coverart...')
550 # set the text metadata
551 for tag
,value
in tag_message
.iteritems():
552 if tags
.has_key(tag
) and value
is not None and value
.strip():
553 value
= value
.decode('utf-8')
555 _str
= '<big>' + cgi
.escape(value
) + '</big>'
557 _str
= cgi
.escape(value
)
559 _str
= '<b><big>' + cgi
.escape(value
) + '</big></b>'
560 if not platform
.MAEMO
:
561 value
+= ' - Panucci'
562 if platform
.FREMANTLE
and len(value
) > 25:
563 value
= value
[:24] + '...'
564 self
.__gui
_root
.main_window
.setWindowTitle(value
)
566 if not self
.has_coverart
:
567 tags
[tag
].setAlignment(QtCore
.Qt
.AlignHCenter
)
569 tags
[tag
].setAlignment(QtCore
.Qt
.AlignLeft
)
571 tags
[tag
].setText(_str
)
573 self
.__log
.exception(str(e
))
577 def do_seek(self
, seek_amount
):
578 resp
= self
.playlist
.do_seek(seek_amount
*10**9)
580 # Preemptively update the progressbar to make seeking smoother
581 self
.set_progress_callback( *resp
)