clWindow.py

00001 #!/usr/bin/env python
00002 # -*- coding: utf-8 -*-
00003 
00004 # ----------------------------------------------------------------------------
00005 # pyjama - python jamendo audioplayer
00006 # Copyright (c) 2008 Daniel Nögel
00007 #
00008 # This program is free software: you can redistribute it and/or modify
00009 # it under the terms of the GNU General Public License as published by
00010 # the Free Software Foundation, either version 3 of the License, or
00011 # (at your option) any later version.
00012 #
00013 # This program is distributed in the hope that it will be useful,
00014 # but WITHOUT ANY WARRANTY; without even the implied warranty of
00015 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00016 # GNU General Public License for more details.
00017 # You should have received a copy of the GNU General Public License
00018 # along with this program.  If not, see <http://www.gnu.org/licenses/>.
00019 # ----------------------------------------------------------------------------
00020 
00021 # GUI
00022 import pygtk
00023 pygtk.require('2.0')
00024 import gtk
00025 import gobject
00026 
00027 # Glade
00028 import gtk.glade
00029 
00030 import os
00031 import sys
00032 #sys.path.insert(0, "/home/barabbas/.pyjama/user_modules/")
00033 if os.name == "posix" or os.name == "mac":
00034     sys.path.append("/usr/share/apps/pyjama") # linux
00035 else:
00036     sys.path.append(os.path.join(os.getenv('PROGRAMFILES'), "pyjama")) # windows
00037 
00038 # Time formatting
00039 from time import strftime, gmtime, time, sleep
00040 
00041 #RegEx
00042 import re
00043 import hashlib
00044 
00045 # Needed for my special functions
00046 # like imagepack creation
00047 import shutil
00048 import tarfile
00049 
00050 # Object Serialisation for Drag'n'Drop
00051 import pickle
00052 
00053 import clMain
00054 from clWidgets import *
00055 import clEntry
00056 import clMenu, clToolbar
00057 import functions
00058 import clLayouts
00059 from clLayouts.default_layouts import clAlbumBrowser, clAlbumLayout, clArtistLayout
00060 
00061 #~ from threading import Thread
00062 #~ def threaded(f):
00063     #~ def wrapper(*args, **kwargs):
00064         #~ t = Thread(target=f, args=args, kwargs=kwargs)
00065         #~ t.start()
00066     #~ return wrapper
00067     #~ 
00068 #~ @threaded
00069 class winGTK(gtk.Window):
00070     def __init__(self, options, parent=None):
00071         self.__alldone = False
00072         self.options = options
00073         
00074         self.main = clMain.main(self, options)
00075         self.main.settings.set_value("PYJAMA", "crashed", True)
00076 
00077         self.layout = {}
00078 
00079         ### Standard- Hintergrundfarbe:
00080         self.bgcolor = "#4785C2" #"#75A3D1"#"#4785C2"
00081 
00082         ### Standardfarben- Playlist
00083         self.CellBGColor = "STANDARD"
00084         self.CellSize = 8
00085         self.markupCurPlaying = '<span foreground="blue"><i><b>__ARTIST__</b></i>\n   __NUM__) __TITLE__</span>'
00086         self.markupNormalEntry ='<span>__ARTIST__\n   __NUM__) __TITLE__</span>'# '__ARTIST__\n\t__TITLE__' 
00087         
00088         gtk.Window.__init__(self)
00089 #        try:
00090 #            self.set_screen(parent.get_screen())
00091 #        except AttributeError:
00092 #            self.connect('delete', self.quit)
00093 
00094         self.event_delete = self.connect('delete_event', self.quit)
00095         self.set_title("Pyjama - Python Jamendo Audiocenter")#(self.__class__.__name__)
00096         self.set_default_size(850, 600)
00097         self.set_position(gtk.WIN_POS_CENTER)
00098         self.set_icon_from_file(os.path.join(functions.install_dir(), "images", "pyjama.png"))
00099         self.set_skip_taskbar_hint(not self.main.settings.get_value("PYJAMA", "show_window_in_taskbar", False))
00100 
00101         self.set_border_width(0)
00102         self.event_window_state = self.connect('window-state-event', self.window_state_event)
00103         
00104         self.vbox = gtk.VBox(False, 0)
00105         self.add(self.vbox)
00106         self.vbox.set_border_width(5)
00107 
00108         ## Tooltip delay for the tvPlaylist
00109         # needed 'cause somehow the query-tooltip
00110         # event is fired on mousemove all the time
00111         self.tooltip_delay = self.main.settings.get_value("PERFORMANCE", "TOOLTIP_DELAY", 70)
00112 
00113         #
00114         # Buttonbox -------------
00115         #
00116         ##### PLACE FOR MENU
00117         ###################
00118         
00119         # CREATE SIDEBAR
00120         # Place for Menu and Toobar
00121         self.vbTop = gtk.VBox()
00122         self.vbox.pack_start(self.vbTop, False, False)
00123         # Paned Playlist / Media
00124         self.hpaned = gtk.HPaned()
00125         self.vbox.pack_start(self.hpaned, True, True, 0)
00126         
00127         # CREATE MAIN VIEW
00128         # Place for Media / Table
00129         self.vbMain = gtk.VBox()
00130         self.vpaned = gtk.VPaned()
00131 
00132 
00133         self.hpaned.pack1(self.vbMain, True, False)
00134         self.vbMedia = gtk.VBox()
00135         self.vbMain.pack_end(self.vbMedia, True, True)
00136         self.vbMedia.pack_end(self.vpaned, True, True)
00137 
00138         #################################################################
00139         # Menu
00140 #        NEW_TOOLBAR_POSITION = self.main.settings.get_value("PYJAMA", "NEW_TOOLBAR_POSITION", False)
00141         self.menubar = clMenu.Menu(self)
00142  #       if NEW_TOOLBAR_POSITION is True:
00143         self.vbTop.pack_start(self.menubar, False, False)
00144 #        else:
00145 #            self.vbMain.pack_start(self.menubar, False, False)
00146 
00147         #################################################################
00148 
00149 
00150         #################################################################
00151         # TOP NAVBAR
00152         # NAV BUTTONBOX
00153 
00154         self.toolbar = clToolbar.Toolbar(self)
00155 #        if NEW_TOOLBAR_POSITION is True:
00156         self.vbTop.pack_start(self.toolbar, False, False)
00157 #        else:
00158 #            self.vbMain.pack_start(self.toolbar, False, False)
00159         #################################################################
00160 
00161 
00162 
00163         #################################################################
00164         # CREATE MEDIA VIEW
00165 #        self.vpaned.pack1(self.vbTop, False, True)
00166         self.scrolledwindow = gtk.ScrolledWindow()
00167         self.scrolledwindow.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
00168         self.scrolledwindow.set_size_request(550, 150) #zwangsgröße
00169         self.event_scrolled_window_resize = self.scrolledwindow.connect("size-allocate", self.scrolled_window_resize)        
00170 
00171         # This VBox contains all items to be shown in the top vpaned
00172         self.vbMainLayout = gtk.VBox()
00173         self.vbMainLayout.pack_end(self.scrolledwindow, True, True)
00174 
00175         # this frame holds vbMainLayout
00176         self.f = gtk.Frame()
00177         self.f.set_shadow_type(gtk.SHADOW_IN)
00178         self.LayoutInfo = InfoLabel(self.main)
00179         self.f.set_label_widget(self.LayoutInfo)
00180         self.f.add(self.vbMainLayout)
00181 
00182 
00183 
00184 
00185         self.vpaned.pack1(self.f, True, True)
00186         
00187 
00188 ##        self.vbTop.pack_end(self.scrolledwindow, True, True, 0)
00189 
00190         
00191         #################################################################
00192       
00193         ##################################################################
00194         ## Top- VIEW, Result p Page etc.
00195         ##
00196         ## this vbox devides next hbox from infolabel following
00197 #        self.vbTop = gtk.VBox()
00198 #        self.vbMedia.pack_end(self.vbTop, False, True)
00199 
00200 
00201         #MUST STAY
00202         # Info- Widget
00203         # contains title for currently shown Layout
00204 #        self.lbCaption = gtk.Label("")
00205 #        self.vbMain.pack_end(self.lbCaption, False, True , 10)
00206 
00207 #        self.LayoutInfo = InfoLabel(self.main)
00208 #        self.vbMain.pack_end(self.LayoutInfo, False, True , 10)
00209         #################################################################
00210         
00211 
00212         #################################################################
00213         # PLAYLIST
00214         # CREATE TREEVIEW 
00215 
00216         self.vbSideBar = gtk.VBox(False)
00217         self.swTreeView = gtk.ScrolledWindow()
00218         self.swTreeView.set_policy(gtk.POLICY_NEVER, gtk.POLICY_AUTOMATIC)
00219         # create a liststore with one string column to use as the model
00220         self.liststore = gtk.ListStore(gobject.TYPE_STRING) # gobject.TYPE_INT
00221         # create the TreeView using liststore
00222         self.tvPlaylist = gtk.TreeView(self.liststore)
00223         self.tvPlaylist.props.has_tooltip = True
00224         self.tooltip_timestamp = 0 # needed since this signial fired all the time the mouse moves. This var will implement a delay of some ms
00225         self.tvPlaylist.connect('query-tooltip', self.cb_query_tooltip)
00226 
00227 #        # After an update to python2.6 the old-school set_custom() method
00228 #        # for tooltips didn't work any more for me.
00229 #        # For this reason, I use the set_tooltip_window method
00230 #        ttwin = gtk.Window(gtk.WINDOW_POPUP)
00231 #        hbox = gtk.HBox()
00232 #        ttwin.add(hbox)
00233 #        self.tvPlaylist.set_tooltip_window(ttwin)
00234 
00235         self.tvPlaylist.connect("row_activated", self.on_tvPlaylist_row_activated)
00236         self.tvPlaylist.connect("cursor-changed", self.on_tvPlaylist_cursor_changed)
00237         self.tvPlaylist.connect("motion-notify-event", self.on_tvPlaylist_motion_notify)
00238         self.tvPlaylist.connect("enter-notify-event", self.on_tvPlaylist_enter_notify)
00239         self.tvPlaylist.connect("leave-notify-event", self.on_tvPlaylist_leave_notify)
00240         self.tvPlaylist.connect("button-press-event", self.on_tvPlaylist_button_press)
00241         self.tvPlaylist.connect("key-press-event",self.on_tvPlaylist_key_press)
00242         #self.tvPlaylist.set_hover_selection(True)
00243         # TreeSelection:
00244         self.tvPlaylistSelection = self.tvPlaylist.get_selection()
00245         self.tvPlaylistSelection.set_mode(gtk.SELECTION_SINGLE)
00246         # CELLRENDERER FOR TEXT
00247         self.cell = gtk.CellRendererText()
00248         # CREATE COLUMN 
00249         # create the TreeViewColumns to display the data
00250         self.tvColumn = gtk.TreeViewColumn('Playlist', self.cell, markup=0)#text=0)
00251         # ADD COLUMN TO TV
00252         self.tvPlaylist.append_column(self.tvColumn)
00253         # DRAG&DROP
00254         self.tvPlaylist.enable_model_drag_source(gtk.gdk.BUTTON1_MASK, [('text/plain', gtk.TARGET_SAME_APP, 0)], gtk.gdk.ACTION_MOVE)
00255         self.tvPlaylist.connect("drag-data-get", self.on_tvPlaylist_DragDataGet)
00256 
00257         self.tvPlaylist.enable_model_drag_dest([('text/plain', 0, 0)], gtk.gdk.ACTION_MOVE)
00258         self.tvPlaylist.connect("drag-data-received", self.on_tvPlaylist_DragDataReceived)
00259 
00260         self.tvPlaylist.connect("drag_data_delete", self.on_tvPlaylist_DragDataEnd)
00261 
00262 #        self.tvPlaylist.connect("drag_data_get", self.drag_data_get_data)
00263 #        self.tvPlaylist.connect("drag_data_received",self.drag_data_received_data)
00264         # Pack TV INTO SCROLLED WINDOW
00265         self.swTreeView.add(self.tvPlaylist)
00266         self.swTreeView.set_size_request(150, 100)
00267 
00268         # PROGRESSBAR
00269         self.pbSong = gtk.ProgressBar()
00270         self.pbSong.set_orientation(gtk.PROGRESS_LEFT_TO_RIGHT)
00271         self.pbSong.set_pulse_step(0.05)   
00272         self.pbSong.set_tooltip_text("Left click: Seek the stream\nRight click: Switch time display")     
00273         self.ebProgressbar = gtk.EventBox()
00274         self.ebProgressbar.add(self.pbSong)
00275         self.ebProgressbar.set_above_child(False)
00276         self.ebProgressbar.add_events (gtk.gdk.BUTTON_RELEASE)
00277         self.ebProgressbar.connect("button_release_event", self.on_pbSong_clicked)
00278         self.pbSong.ShowRemainingTime = False
00279         self.pbSong.counter = 0
00280         
00281         # HSCALE AS VOLUME CONTROL
00282         hsAdjustment = gtk.Adjustment(value=self.main.settings.get_value("SOUND", "default_vol"), lower=0, upper=self.main.settings.get_value("SOUND", "vol_max"), step_incr=10, page_incr=2, page_size=10)
00283         self.hsVolume = gtk.VolumeButton()#gtk.HScale(hsAdjustment)
00284         self.hsVolume.set_value(self.main.settings.get_value("SOUND", "default_vol"))
00285         self.hsVolume.set_adjustment(hsAdjustment)
00286         self.hsVolume.connect("value-changed", self.on_sbVolume_Change)
00287         #self.hsVolume.set_draw_value(False)      
00288             #self.hsVolume.set_digits(0)
00289         #################################################################        
00290 
00291         #################################################################
00292         #
00293         # TABLE FOR PLAYER- CONTROL
00294         #
00295         #self.bbControls = gtk.HButtonBox()
00296         #self.bbControls.set_spacing(gtk.BUTTONBOX_SPREAD)
00297         self.tbControls = gtk.Table(1, 4, True)
00298         
00299         # POSSIBLE SIZES FOR STOCKBUTTON
00300         # gtk.ICON_SIZE_INVALID gtk.ICON_SIZE_MENU gtk.ICON_SIZE_SMALL_TOOLBAR gtk.ICON_SIZE_LARGE_TOOLBAR   
00301         # gtk.ICON_SIZE_BUTTON gtk.ICON_SIZE_DND gtk.ICON_SIZE_DIALOG
00302         # DEFAULT IS gtk.ICON_SIZE_MENU
00303         # PREV- Button
00304         self.bPrev = StockButton(gtk.STOCK_MEDIA_PREVIOUS)
00305         #self.bbControls.add(self.bPrev False, True, 0)
00306         self.bPrev.connect("clicked", self.on_bPrev_clicked)
00307         self.bPrev.set_tooltip_text(_("Play previous"))
00308         self.tbControls.attach(self.bPrev, 0, 1, 0, 1)
00309         # Play- Button       
00310         self.bPlay = StockButton(gtk.STOCK_MEDIA_PLAY)
00311         #self.bbControls.pack_start(self.bPlay, False, True, 0)
00312         self.bPlay.connect("clicked", self.on_bPlay_clicked)
00313         self.bPlay.connect("button_press_event", self.on_bPlay_pressed)
00314 
00315 
00316 
00317 
00318 #        self.__accel_group = gtk.AccelGroup()
00319 #        self.bPlay.add_accelerator("clicked", self.__accel_group, gtk.keysyms.space, 0, gtk.ACCEL_VISIBLE)
00320 #        self.add_accel_group(self.__accel_group)
00321 
00322 
00323         
00324         self.bPlay.set_tooltip_text("%s\n%s" % (_("Play/pause"), _("Right click for stop")))
00325 
00326         self.tbControls.attach(self.bPlay, 1, 2, 0, 1)
00327 #        # Stop- Button
00328 #        self.bStop = StockButton(gtk.STOCK_MEDIA_STOP)
00329 #        #self.bbControls.pack_start(self.bStop, False, True, 0)
00330 #        self.bStop.connect("clicked", self.on_bStop_clicked)
00331 #        self.bStop.set_tooltip_text(_("Stop"))
00332 #        self.tbControls.attach(self.bStop, 2, 3, 0, 1)
00333         # Next- Button
00334         self.bNext = StockButton(gtk.STOCK_MEDIA_NEXT)
00335         #self.bbControls.pack_start(self.bNext, False, True, 0)
00336         self.bNext.connect("clicked", self.on_bNext_clicked)
00337         self.bNext.set_tooltip_text(_("Play next"))
00338         self.tbControls.attach(self.bNext, 2, 3, 0, 1)
00339 
00340         self.tbControls.attach(self.hsVolume, 3, 4, 0, 1)
00341         #################################################################
00342         
00343         #################################################################
00344         #
00345         # TABLE FOR PLAYLIST- CONTROL
00346         #
00347         self.tbPlaylist = gtk.Table(1, 4, True)
00348         # DELETE- Button
00349         self.bDelete = StockButton(gtk.STOCK_REMOVE)#STOCK_DELETE
00350         self.bDelete.connect("clicked", self.on_bDelete_clicked)
00351         self.bDelete.set_tooltip_text(_("Remove selected song from playlist"))
00352         self.tbPlaylist.attach(self.bDelete, 0, 1, 0, 1)
00353         # CLEAR- Button
00354         self.bClear = StockButton(gtk.STOCK_CLEAR)#CLEAR
00355         self.bClear.connect("clicked", self.on_bClear_clicked)
00356         self.bClear.set_tooltip_text(_("Clear playlist"))
00357         self.tbPlaylist.attach(self.bClear, 1, 2, 0, 1)
00358         # SAVE- Button
00359         self.bSave = StockButton(gtk.STOCK_SAVE)
00360         self.bSave.connect("clicked", self.on_bSave_clicked)
00361         self.bSave.set_tooltip_text(_("Save Playlist"))
00362         self.tbPlaylist.attach(self.bSave, 2, 3, 0, 1)
00363         # LOAD- Button
00364         self.bLoad = StockButton(gtk.STOCK_OPEN)
00365         self.bLoad.connect("clicked", self.on_bLoad_clicked)
00366         self.bLoad.set_tooltip_text(_("Load Playlist"))
00367         self.tbPlaylist.attach(self.bLoad, 3, 4, 0, 1)
00368         #################################################################
00369 
00370         #################################################################
00371         #
00372         # ADD TO SIDEBAR
00373         #
00374         # ADD VPaned TO HPANED
00375         SideBarFrame = gtk.Frame(_("Playlist"))
00376         SideBarFrame.set_shadow_type(gtk.SHADOW_IN)
00377         SideBarFrame.add(self.vbSideBar)
00378         self.hpaned.pack2(SideBarFrame, False, True) #swTreeView
00379         self.hpaned.set_position(700)
00380         
00381         # COVER VIEW
00382         self.vbCover = gtk.VBox()
00383         self.vbSideBar.pack_start(self.vbCover, False, True, 5)
00384         self.lbCoverArtist = gtk.Label("")
00385         self.lbCoverAlbum = gtk.Label("")
00386         self.imgCover = gtk.Image()
00387         self.imgCover.set_size_request(100,100)
00388         sep = gtk.HSeparator()
00389         self.vbCover.pack_start(self.imgCover, False, True)
00390         self.vbCover.pack_start(self.lbCoverArtist, False, True)
00391         self.vbCover.pack_start(self.lbCoverAlbum, False, True)
00392         self.vbCover.pack_end(sep, False, False, 5)
00393 
00394         if True:
00395             self.imgCover.set_from_file(os.path.join(functions.install_dir(), "images", "pyjama.png"))
00396         else:
00397             animation = gtk.gdk.PixbufAnimation(os.path.join(functions.install_dir(), "images", "pyjama_anim.gif"))
00398             self.imgCover.set_from_animation(animation)
00399         self.lbCoverArtist.set_text('Pyjama')
00400         self.lbCoverAlbum.set_text('Python Jamendo Audio')
00401         
00402         # ADD SCROLLBAR TO VBOX
00403         #self.vbSideBar.pack_start(self.hsVolume, False, True)
00404         # ADD PROGRESSBAR's EVENTBOX TO VBOX
00405 #        self.hbox_scroll_volume = gtk.HBox()
00406 #        self.hbox_scroll_volume.pack_end(self.ebProgressbar, True, True)
00407 #        self.hbox_scroll_volume.show_all()
00408 #        self.hbox_scroll_volume.set_size_request(-1, 28)
00409 #        self.vbSideBar.pack_start(self.hbox_scroll_volume, False, True)
00410 
00411 
00412 
00413         # ADD TV TO VPANED
00414         # ADD BUTTONBOX CONTROLS TO VBOX
00415         # ADD BUTTONBOX CONTROLS PLAYLIST TO VBOX
00416 
00417         self.vbSideBar.pack_start(self.tbControls, False, True)
00418         self.vbSideBar.pack_start(self.ebProgressbar, False, True)
00419 
00420         self.vbSideBar.pack_start(self.swTreeView, True, True)
00421 
00422         self.vbSideBar.pack_start(self.tbPlaylist, False, True)
00423 
00424 
00425 
00426         self.tvSelection = self.tvPlaylist.get_selection()
00427         #################################################################        
00428 
00429         #################################################################
00430         # USER WIDGET STATUSBAR
00431         self.sbStatus = StatusBar("Counter", "Info", "VarInfo", "Player")
00432         self.sbStatus.statusbars["Player"]['statusbar'].set_size_request(100,-1)
00433         self.sbStatus.set_text("Counter", _("Artists: %i, Albums: %i, Tracks: %i") % (self.main.db.artists, self.main.db.albums, self.main.db.tracks))
00434 
00435         self.sbStatus.show()
00436         self.vbox.pack_start(self.sbStatus, False, True, 0)
00437         
00438         self.pbWait = gtk.ProgressBar()
00439         self.vbox.pack_start(self.pbWait, False, True, 0)
00440         self.pbWait.set_pulse_step(0.02)        
00441         self.pbWait.show()
00442         #################################################################
00443         
00444 #       model, iter = treeselection.get_selected()
00445 
00446 #        REMOVE SELECTED
00447 #        selection = self.tvPlaylist.get_selection()
00448 #        model, iter = selection.get_selected()
00449 
00450 #        if iter:
00451 #            path = self.liststore.get_path(iter)[0]
00452 #            self.liststore.remove(iter)
00453 #            print path
00454 #            del articles[ path ]
00455 
00456         #################################################################
00457         ### BACKGROUND COLORS
00458         if self.CellBGColor != "STANDARD":
00459             self.cell.set_property('cell-background', self.CellBGColor)
00460         self.cell.set_property('size-points', self.CellSize)
00461         #################################################################
00462         
00463         #################################################################
00464         # BOTTOM LIST SHOWING TRACKS
00465         # TreeView
00466         # CREATE TREEVIEW 
00467         self.swTVList = gtk.ScrolledWindow()
00468         self.swTVList.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
00469         self.tvList = TreeViewList()
00470         self.tvList.connect("row_activated", self.on_tvList_row_activated)
00471         self.tvList.connect("button-press-event", self.on_tvList_button_press)
00472         self.swTVList.add(self.tvList)
00473 
00474 #        self.tvList.enable_model_drag_source(gtk.gdk.BUTTON1_MASK, [('text/plain', gtk.TARGET_SAME_APP, 0)], gtk.gdk.ACTION_MOVE)
00475 #        self.tvList.connect("drag-data-get", self.on_tvList_DragDataGet)
00476 
00477 #        self.vpaned.pack2(self.swTVList, True, True)
00478         self.vpaned2 = gtk.VPaned()  # containing tracklist and mozilla?
00479         self.vpaned.pack2(self.vpaned2, True, True) # containing media view and vpaned2        
00480 
00481         ## Frame vor swTVList
00482         self.TVListFrame = gtk.Frame(_("Tracklist"))
00483         self.TVListFrame.add(self.swTVList)
00484 
00485         self.vpaned2.pack1(self.TVListFrame, True, True)
00486         #################################################################
00487 
00488         #self.connect("configure-event", self.test2)
00489 
00490         self.show_all()
00491 
00492         # Insert a Menu item for showing / hiding vbCover
00493         chkCover = gtk.CheckMenuItem(_("Show Cover Image"))
00494         chkCover.set_active(self.main.settings.get_value("PYJAMA", "SHOW_COVER", True))
00495         view = self.menubar.get_rootmenu("View").get_submenu()
00496         view.insert(chkCover, 0)
00497         chkCover.connect("activate", self.switch_show_cover)
00498         chkCover.show()
00499         self.switch_show_cover(chkCover)
00500         sep = gtk.SeparatorMenuItem()
00501         view.insert(sep, 1)
00502         sep.show()
00503 
00504 #        chkToolbarPos = gtk.CheckMenuItem(_("new toolbar position"))
00505 #        chkToolbarPos.set_active(NEW_TOOLBAR_POSITION)
00506 #        view.insert(chkToolbarPos, 1)
00507 #        sep = sep = gtk.SeparatorMenuItem()
00508 #        view.insert(sep, 2)
00509 #        chkToolbarPos.connect("activate", self.switch_new_toolbar_position)
00510 #        chkToolbarPos.show()
00511 #        sep.show()
00512 
00513         self.pbWait.hide()     
00514 
00515 #        import gtkmozembed as gtkmoz #gtkmoz
00516 #        self.mozillaWidget = gtkmoz.MozEmbed()
00517 #        self.mozillaWidget.set_size_request(400,300)
00518 #        self.vpaned2.pack2(self.mozillaWidget, True, True)
00519 #        self.vpaned2.show()
00520 #        self.mozillaWidget.show()
00521 
00522         # Register Layouts:
00523         self.main.layouts.register_layout("top", clAlbumBrowser.AlbumBrowser(self.main))
00524         self.main.layouts.register_layout("album", clAlbumLayout.AlbumLayout(self.main))
00525         self.main.layouts.register_layout("artist", clArtistLayout.ArtistLayout(self.main))
00526 
00527         # Menu Entry
00528         menu = self.menubar
00529         entry = menu.append_entry(menu.get_rootmenu("Browse"), _("Albums"), "top")
00530         entry.connect("activate", self.cb_show_album_browser)
00531         menu.set_item_image(entry, os.path.join(functions.install_dir(), "images", "star.png"))
00532         menu.show()
00533 
00534         # Show starting- window
00535 #        self.main.layouts.show_layout("top", 10, "ratingweek", 1, "all", who_called = "window.__init__") 
00536         #self.main.draw_topoftheweek()
00537 
00538         #
00539         # Check Database
00540         #
00541 #        if options.update or not os.path.exists(os.path.join(self.main.home, "pyjama.db")):
00542         if options.update or not self.main.db.database_ok:
00543             self.main.download_database()
00544         if options.update_jamendo:
00545             self.main.download_database(force_jamendo=True)
00546 
00547         # Raise "alldone" event --this is now called in pyjama.py
00548         self.__alldone = True
00549         ev = self.main.Events
00550         ev.raise_event("alldone")
00551 
00552         # Add preferences menu to the menubar
00553         # add menu entry
00554         menu = self.menubar
00555         root = menu.get_rootmenu("Extras")
00556         if root:
00557             menu.append_entry(root, "---", "prefsep")
00558             mnu = menu.append_entry(root, _("Preferences"), "preferences")
00559             menu.set_item_image(mnu, gtk.STOCK_PREFERENCES)
00560             mnu.connect("activate", self.main.show_preferences)
00561 
00562         self.main.jamendo.last_query_hack()
00563         self.main.go_home()
00564 
00565         # for startup time checks:
00566         if "check-time" in sys.argv:
00567             sys.exit()
00568 
00569         self.__special_checks()
00570 
00571         if self.main.plugins.blacklisted_browser:
00572             self.main.need_attention = True
00573             self.main.info("Blacklisted browser", "Pyjama probably crashed last time.\nIn most cases <b>mozplug</b> or <b>webkit-plugin</b> a responsible for that.\n\nThe browser-pluins where disabled for this reason")
00574             self.main.need_attention = False
00575 
00576         self.main.need_attention = True
00577         self.main.info("Experimental!", "You are using an <b>experimental version</b> of pyjama. It was released to let you review some new features of my program.\nPlease: Report any bugs via \n\n<u>bugs.launchpad.net/pyjama</u>.\n\nThanks!")
00578         self.main.need_attention = False
00579 
00580         #~ if "hang-up" in sys.argv:
00581             #~ while 1:
00582                 #~ pass
00583 
00584         #~ if self.main.xmlrpc.role == "client":
00585             #~ self.main.xmlrpc.server.check()
00586 
00587 
00588 #        while gtk.events_pending(): gtk.main_iteration()
00589 
00590     ## This event is raised when a tooltip
00591     # in the playlist is going to be shown.
00592     # Please connect to pyjama's event
00593     # 'playlist_tooltip'. It will pass:
00594     # - the x coords of the mouse pointer
00595     # - the y coords of the mouse pointer
00596     # - a tuple holding two vboxes
00597     # Add the description of the info you want
00598     # to add to the first vbox and the info
00599     # itself to the second vbox.
00600     # /todo: Make this whole event more intuitiv
00601     def cb_query_tooltip(self, widget, x, y, keyboard_tip, tooltip):
00602 #        tooltip.set_markup("test")
00603 #        print 99*99**9
00604 #        return True
00605 #        CONTAINER="BOX"
00606 #        lbl = gtk.Label("Bin ich krass wunderschönes Tooltip")
00607 #        lbl.show()
00608 #        b = gtk.Button("tst2")
00609 #        b.show()
00610 
00611 #        if CONTAINER == "BOX":
00612 #            hbox = gtk.VBox()
00613 #            hbox.show()
00614 #            hbox.pack_start(lbl)
00615 #            hbox.pack_start(b)
00616 
00617 #            try:
00618 #                tooltip.set_custom(hbox)
00619 #            except Exception, inst:
00620 #                inst
00621 #        return True
00622 
00623 
00624 
00625 #        return True
00626 
00627 #        widget.props.has_tooltip = True
00628 #        print tooltip
00629 
00630 #        hbox = gtk.HBox()
00631 #        l = gtk.Label("asd")
00632 #        l.show()
00633 #        hbox.pack_start(l)
00634 #        hbox.show()
00635 
00636 #        tooltip.set_custom(hbox)
00637 
00638 #        return True
00639 
00640 #        settings = gtk.settings_get_default() 
00641 #        print settings.props.gtk_tooltip_timeout
00642 
00643         if self.tooltip_timestamp + self.tooltip_delay > time()*1000:
00644             return False
00645         self.tooltip_timestamp = time()*1000
00646 
00647         y = y - 27
00648         # One can add widgets to this vbox in order
00649         # to show them in the tooltip
00650         hbox = gtk.HBox()
00651         vbox1 = gtk.VBox(True)
00652         vbox2 = gtk.VBox(True)
00653         hbox.pack_start(vbox1, False, True)
00654         hbox.pack_start(vbox2, False, True)
00655 
00656         hbox.set_spacing (10)
00657         vbox1.set_spacing (10)
00658         vbox2.set_spacing (10)
00659 
00660     
00661 
00662         l = gtk.Label()
00663         path = self.tvPlaylist.get_path_at_pos(int(x), int(y))
00664         if path:
00665             # Some basic infos
00666             track = self.main.player.playlist[path[0][0]]
00667             img_uri = self.main.get_album_image(track.album_id)
00668             if img_uri:
00669                 img = gtk.Image()
00670                 try:
00671                     pix = gtk.gdk.pixbuf_new_from_file_at_size(img_uri, 50, 50)
00672                     img.set_from_pixbuf(pix)
00673                 except:
00674                     img.set_from_stock(gtk.STOCK_MISSING_IMAGE, gtk.ICON_SIZE_BUTTON)
00675                 img.show()
00676                 vbox1.pack_start(img, False, True)
00677 
00678             l.set_markup("<b>%s</b>\n%s\n%s" % (track.artist_name[:30], track.album_name[:30], track.name[:30]))
00679             l.show()
00680             vbox2.pack_start(l, False, True)
00681 
00682 #            vbox.pack_start(hbox, False, True)
00683         else:
00684             return False
00685 
00686 
00687         hbox.show_all()
00688         
00689         # Call other functions that might
00690         # add widgets to the hbox
00691         self.main.Events.raise_event("playlist_tooltip", x, y, (vbox1, vbox2))
00692 
00693 
00694         
00695 
00696 #        win = widget.get_tooltip_window()
00697 #        win.show()
00698 #        try:
00699 #            win.remove(win.get_child())
00700 #        except:
00701 #            pass
00702 #        win.move(x, y)
00703 #        win.add(hbox)
00704 
00705         # set the vbox as tooltip custom widget
00706         tooltip.set_custom(hbox)
00707         return True
00708 
00709     def cb_show_album_browser(self, widget):
00710         self.main.layouts.show_layout("top", 10, "ratingweek", 1, "all", who_called = "window.__init__")
00711 
00712 #    def switch_new_toolbar_position(self, widget):
00713 #        new = widget.get_active()
00714 #        if new is True:
00715 #            container =  self.toolbar.get_parent()
00716 #            container.remove(self.toolbar)
00717 #            container.remove(self.menubar)
00718 #            self.vbTop.pack_start(self.menubar, False, False)
00719 #            self.vbTop.reorder_child(self.menubar, 0)
00720 #            self.vbTop.pack_start(self.toolbar, False, False)
00721 #            self.vbTop.reorder_child(self.toolbar, 1)
00722 #            self.main.settings.set_value("PYJAMA", "NEW_TOOLBAR_POSITION", "True")
00723 #        else:
00724 #            container =  self.toolbar.get_parent()
00725 #            container.remove(self.toolbar)
00726 #            container.remove(self.menubar)
00727 #            self.vbMain.pack_start(self.menubar, False, False)
00728 #            self.vbMain.reorder_child(self.menubar, 0)
00729 #            self.vbMain.pack_start(self.toolbar, False, False)
00730 #            self.vbMain.reorder_child(self.toolbar, 1)
00731 #            self.main.settings.set_value("PYJAMA", "NEW_TOOLBAR_POSITION", "False")
00732 
00733     def switch_show_cover(self, widget):
00734         show = widget.get_active()
00735         if show is True:
00736             self.vbCover.show()
00737             self.main.settings.set_value("PYJAMA", "SHOW_COVER", "True")
00738         else:
00739             self.main.settings.set_value("PYJAMA", "SHOW_COVER", "False")
00740             self.vbCover.hide()
00741 
00742     def window_state_event(self, widget, event):
00743         if event.new_window_state & gtk.gdk.WINDOW_STATE_ICONIFIED:
00744             self.window.visible = False
00745 
00746     def show_window(self,ev):
00747         self.present()
00748         #~ self.window.set_skip_taskbar_hint(False)
00749         
00750     def on_tvPlaylist_key_press(self, widget, event):
00751         if event.keyval == 32:
00752             self.on_bPlay_clicked(None)
00753             return True
00754 
00755     def on_tvPlaylist_row_activated(self, treeview, path, view_column):
00756         if path:
00757             self.on_bStop_clicked(None)
00758             self.on_bPlay_clicked(path[0])
00759 
00760     def on_tvPlaylist_enter_notify(self, treeview, event):
00761         pass
00762 #        if not self.menubar.bolFullScreen:
00763 #            self.popup.show_all()
00764 #            self.popup.move(-500,-500)
00765 
00766     def on_tvPlaylist_leave_notify(self, treeview, event):
00767 #        self.popup.hide()
00768         self.main.showInfo()
00769 
00770     def on_tvPlaylist_motion_notify(self, treeview, event):
00771         ret = treeview.get_path_at_pos(int(event.x), int(event.y))
00772 
00773         if ret != None:
00774             current_path, current_column = ret[:2]
00775             self.main.showInfo(current_path[0])
00776 
00777 #            self.popup.move(int(event.x_root-100), int(event.y_root+20))
00778 #            track = self.main.player.playlist[current_path[0]]
00779 
00780 #            self.popup.lbl_artist.set_markup("<b>%s</b>" % track.artist_name)
00781 #            self.popup.lbl_album.set_markup( track.album_name )
00782 #            self.popup.lbl_track.set_markup( track.name)
00783 
00784 #            self.main.Events.raise_event("playlist_tooltip_move", event, current_path)
00785 
00786 #            #print current_column.get_title()
00787 #            renderer = current_column.get_cell_renderers()
00788 #            if renderer != None:
00789 #                renderer = renderer[0]
00790 #                current_position = current_column.cell_get_position(renderer)
00791 #                if current_position:
00792 #                    current_position = current_position[0]
00793 #                    print current_position
00794 #            else:
00795 #                return None
00796     def on_tvPlaylist_cursor_changed(self, treeview):
00797             self.main.showInfo()
00798 
00799     def on_pbSong_clicked(self, widget, event):
00800         if event.button == 3:
00801             self.pbSong.ShowRemainingTime = not self.pbSong.ShowRemainingTime
00802             self.main.timer_event()
00803         elif event.button == 1 and self.main.player.status == "Playing" or self.main.player.status == "paused":
00804             # get width of this widget
00805             allocation = widget.get_allocation()
00806             width = allocation[2]
00807             # pointer
00808             pointer = widget.get_pointer()
00809             x = pointer[0]
00810 
00811             # Calculate Position in percent
00812             percentage = x * 100 / width
00813 
00814             # seek
00815             real = long(percentage * self.main.player.duration* (10**7)) # in ns
00816             self.main.player.seek(real)
00817 
00818 
00819     def on_tvList_DragDataGet(self, widget, drag_context, selection, info, timestamp):
00820         tvListSelection = widget.get_selection()
00821         model, iter = tvListSelection.get_selected()
00822         data = model.get_value(iter, 0)
00823         path =  model.get_path(iter)
00824 
00825         # Will have to replace this with a
00826         # TYPE_PYOBJECT !!
00827 
00828         data= pickle.dumps({'source':'list','data':data,'path':path})
00829         print {'source':'list','data':data,'path':path}
00830         selection.set(selection.target, 8, data)
00831         return
00832 
00833     def on_tvPlaylist_DragDataGet(self, widget, drag_context, selection, info, timestamp):
00834         tvPlaylistSelection = self.tvPlaylist.get_selection()
00835         model, iter = tvPlaylistSelection.get_selected()
00836         data = model.get_value(iter, 0)
00837         path =  model.get_path(iter)
00838 
00839         data= pickle.dumps({'source':'playlist','data':data,'path':path})
00840 
00841         selection.set(selection.target, 8, data)
00842         return
00843 
00844 
00845     def on_tvPlaylist_DragDataReceived(self, widget, context, x, y, selection, info, timestamp):
00846         model = widget.get_model()
00847         data = selection.data
00848         data = pickle.loads(data)
00849         source = data['source']
00850         if source == "playlist":
00851             data = [data]
00852         drop_info = widget.get_dest_row_at_pos(x, y)
00853         for datum in data:
00854             if drop_info:
00855                 destpath, position = drop_info
00856                 iter = model.get_iter(destpath)
00857 
00858                 destpath = destpath[0]
00859                 sourcepath = datum['path'][0]
00860 
00861                 datum = datum['data']
00862                 if self.main.debug_extreme:
00863                     print "!", sourcepath, destpath, "!"
00864                 if (position == gtk.TREE_VIEW_DROP_BEFORE or position == gtk.TREE_VIEW_DROP_INTO_OR_BEFORE):
00865                     if self.main.debug_extreme:
00866                         print "into intoorbefore"
00867                     model.insert_before(iter, [datum])  
00868                     self.main.move_playlist_item(sourcepath, destpath, before=True)
00869                 else:
00870                     if self.main.debug_extreme:
00871                         print "else"
00872                     self.main.move_playlist_item(sourcepath, destpath, before=False)
00873                     model.insert_after(iter, [datum])
00874             else:
00875                 return
00876         if context.action == gtk.gdk.ACTION_MOVE:
00877             context.finish(True, True, timestamp)
00878         return
00879 
00880     def on_tvPlaylist_DragDataEnd(widget, context, data):
00881         pass
00882 
00883     def on_tvPlaylist_button_press(self, widget, event):
00884         if event.button == 3:
00885 #            ret = self.tvPlaylist.get_path_at_pos(int(event.x), int(event.y))
00886 #            selection = self.tvPlaylist.get_selection()
00887 #            model, retIter = selection.get_selected()
00888 #            if retIter is None: retIter = model.get_iter(ret[0])
00889 #            selection.select_iter(retIter)
00890 
00891             mnu = PlaylistMenu(self.main)
00892             mnu.popup(None, None, None, event.button, event.time)
00893             if mnu.get_children() == []:
00894                 mnu.destroy()
00895 
00896     def on_tvList_row_activated(self, treeview, path, view_column):
00897         # ==> view_column ==> geklickte Spalte!
00898         ret = self.tvList.get_item(path)
00899         tracknum = ret[self.tvList.COLUMN_TRACKNUM]
00900         trackid = ret[self.tvList.COLUMN_TRACKID]
00901         albumid = ret[self.tvList.COLUMN_ALBUMID]
00902         artistid = ret[self.tvList.COLUMN_ARTISTID]
00903         if trackid > -1:
00904             track = self.main.db.get_trackinfos2(trackid)
00905         #    track.uid = "%f%s" % (time(), trackid)
00906             self.main.add2playlist(track)
00907         elif albumid > -1:
00908             print albumid
00909             albumdetails = self.main.jamendo.albuminfos(albumid)
00910             if albumdetails == None:
00911                 tofast(self.window)
00912                 return None
00913             elif albumdetails == -1:
00914                 return None    
00915             self.main.layouts.show_layout("album", albumdetails, who_called = "on_tvList_row_activated")
00916         elif artistid > -1:
00917             artist = self.main.db.artistinfos(artistid)
00918             self.main.layouts.show_layout("artist", artist, who_called = "on_tvList_row_activated")
00919 
00920     def on_tvList_button_press(self, widget, event):
00921         if event.button == 3:
00922 #            ret = self.tvList.get_path_at_pos(int(event.x), int(event.y))
00923 #            selection = self.tvList.get_selection()
00924 #            model, retIter = selection.get_selected()
00925 #            if retIter is None: retIter = model.get_iter(ret[0])
00926 #            selection.select_iter(retIter)
00927 
00928 #            ret = self.tvList.get_item(ret[0])
00929 #            print ret
00930 
00931             mnu = ListMenu(self.main)
00932             mnu.popup(None, None, None, event.button, event.time)
00933             if mnu.get_children() == []:
00934                 mnu.destroy()
00935 
00936     def on_bDelete_clicked(self, ev):
00937         liststore, markedIter = self.tvPlaylistSelection.get_selected()
00938         if markedIter:
00939             model = self.tvPlaylist.get_model()
00940             self.main.remove_item_from_playlist(model.get_path(markedIter))
00941             liststore.remove(markedIter)
00942 
00943     def on_bClear_clicked(self, ev):
00944         self.main.player.clearplaylist()
00945         model = self.tvPlaylist.get_model()
00946         model.clear()
00947 
00948     def on_bNext_clicked(self, ev):
00949         self.on_bStop_clicked(None)
00950         self.main.player.next()
00951         self.main.icon.menu.switch_play_button("pause")
00952         
00953     def on_bPrev_clicked(self, ev):
00954         self.on_bStop_clicked(None)    
00955         self.main.player.prev()
00956         self.main.icon.menu.switch_play_button("pause")
00957 
00958     def on_bLoad_clicked(self, ev):
00959         # Append menu entrys
00960         mnu = gtk.Menu()
00961         counter = 0
00962         #~ if self.main.settings.section_exists("Playlists"):
00963             #~ for name, ids in self.main.settings.config.items("Playlists"):
00964         sql = "SELECT option, value FROM settings WHERE section='playlists'"
00965         playlists = self.main.settingsdb.query(sql)
00966         if playlists:
00967             for name, ids in playlists:
00968                 counter += 1
00969                 playlist = gtk.ImageMenuItem(name.replace("_", "__"), False)
00970                 playlist.show()
00971                 mnu.append(playlist)
00972                 playlist.connect("activate", self.main.playlists.cb_load_playlist, name)
00973         if counter == 0:
00974             tmp = gtk.ImageMenuItem("No playlists saved, yet.")
00975             tmp.show()
00976             tmp.set_sensitive(False)
00977             mnu.append(tmp)
00978 
00979         mnu.show()
00980         mnu.popup(None, None, None, 1,0)
00981         #self.main.playlists.cb_load_playlist(None)
00982 
00983 
00984     def on_bSave_clicked(self, ev):
00985         self.main.playlists.cb_save_playlist(None)
00986         return
00987 
00988     def cb_export_playlist(self, widget):
00989         m3u = ""
00990         xspf = '''<?xml version="1.0" encoding="UTF-8"?>
00991 <playlist version="1" xmlns="http://xspf.org/ns/0/">
00992     <tracklist>
00993 '''
00994         playlist = self.main.player.playlist
00995         for track in playlist:
00996             m3u += track.stream+"\n"
00997             xspf += "    <track>\n      <title>%s</title>\n       <creator>%s</creator>\n       <location>%s</location>\n    </track>\n" % (track.name, track.artist_name, track.stream)
00998         m3u = m3u[0:-1]
00999         xspf += '''\n    <tracklist>
01000 </playlist>'''
01001 
01002         buttons = (gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL, gtk.STOCK_SAVE,   gtk.RESPONSE_OK)
01003         dialog = gtk.FileChooserDialog(_("Save Playlist"), None, action=gtk.FILE_CHOOSER_ACTION_SAVE, buttons=buttons, backend=None)
01004         filter1 = gtk.FileFilter()
01005         filter1.set_name("M3U Playlist Format")
01006         filter1.add_pattern("*.m3u")
01007         dialog.add_filter(filter1)
01008         filter2 = gtk.FileFilter()
01009         filter2.set_name("XSPF Playlist Format")
01010         filter2.add_pattern("*.xspf")
01011         dialog.add_filter(filter2)
01012 
01013         dialog.set_default_response(gtk.RESPONSE_OK)
01014         dialog.set_current_folder(os.getenv("HOME"))
01015         dialog.set_current_name("pyjama-playlist")
01016 
01017         response = dialog.run()
01018         dialog.hide()
01019         if response == gtk.RESPONSE_OK:
01020             filename = dialog.get_filename()
01021             if dialog.get_filter() == filter1: #IF M3U
01022                 content = m3u
01023                 if filename[-4:] != ".m3u":
01024                     filename += ".m3u"
01025             else: #XSPF
01026                 content = xspf
01027                 if filename[-5:] != ".xspf":
01028                     filename += ".xspf"
01029             if self.main.debug:
01030                 print "Writing to %s" % filename
01031             fh = open(filename, "w")
01032             if fh:
01033                 fh.write(content)
01034                 fh.close()
01035             else:
01036                 print ("Error writing %s") % filename
01037 
01038     def set_play(self):
01039         status = self.bPlay.tag
01040         if status == "play" or not status:
01041             status = "play"
01042         
01043         if status == "pause" and self.main.player.is_playing:
01044             self.main.player.pause()
01045             self.bPlay.setimage(gtk.STOCK_MEDIA_PLAY)
01046             self.main.icon.menu.switch_play_button("play")
01047             self.bPlay.tag = "play"
01048             return "paused"
01049         elif status == "play" and self.main.player.status == "paused":
01050             self.main.player.play()
01051             self.bPlay.setimage(gtk.STOCK_MEDIA_PAUSE)
01052             self.main.icon.menu.switch_play_button("pause")
01053             self.bPlay.tag = "pause"
01054             return "continued"
01055         elif status == "play":
01056             self.bPlay.setimage(gtk.STOCK_MEDIA_PAUSE)
01057             self.main.icon.menu.switch_play_button("pause")
01058             self.bPlay.tag = "pause"            
01059             return "play"
01060             
01061 
01062     def on_bPlay_pressed(self, widget, event):
01063         if event.button == 3:
01064             self.on_bStop_clicked(None)
01065         
01066     def on_bPlay_clicked(self, ev):
01067 
01068         stat =  self.set_play()
01069         if stat == "paused":
01070             return
01071         elif stat == "continued":
01072             return
01073         model, tmpIter = self.tvSelection.get_selected()
01074         if tmpIter != None:
01075             path = self.liststore.get_path(tmpIter)[0]
01076             self.main.player.play(self.main.player.playlist[path], path)
01077             self.main.timer_event()
01078 #            if not self.main.timer:
01079 #                self.main.start_timer()
01080         else:
01081             model = self.tvPlaylist.get_model()
01082             # improve this
01083             try:
01084                 tmpIter = model.get_iter(0)
01085             except ValueError:
01086                 return None
01087             path = self.liststore.get_path(tmpIter)[0]
01088             self.main.player.play(self.main.player.playlist[path], path)
01089             self.main.timer_event()
01090 #            if not self.main.timer:
01091 #                self.main.start_timer()
01092 
01093                 
01094     def on_bStop_clicked(self, ev):
01095         self.main.icon.menu.switch_play_button("play")
01096         self.bPlay.setimage(gtk.STOCK_MEDIA_PLAY)
01097         self.bPlay.tag = "play"
01098         listview, markedIter = self.tvPlaylistSelection.get_selected()
01099         
01100         # Unmark last played Item
01101         if markedIter != None and self.main.player.cur_playing != None:
01102             track = self.main.player.cur_playing
01103             artist_name = track.artist_name
01104             track_name = track.name
01105             track_numalbum = track.numalbum
01106             markup = self.markupNormalEntry.replace("__ARTIST__", artist_name).replace("__TITLE__", track_name).replace("__NUM__", str(track_numalbum))
01107             self.liststore.set(markedIter, 0, markup)
01108 
01109         self.main.player.stop()
01110 
01111     def scrolled_window_resize(self, obj, gdkrect):
01112         self.scrolledwindow_width = gdkrect[2]
01113         self.scrolledwindow_height = gdkrect[3]
01114         if self.main.allow_rearrange:
01115             self.main.allow_rearrange = False
01116             self.main.Events.raise_event("scrolled_window_resized")
01117             gobject.timeout_add(200, self.main.set_allow_rearrange)
01118 
01119         
01120         #if self.main.allow_rearrange and self.main.layout_mode=="top":
01121             #self.main.allow_rearrange = False
01122             #self.main.arrange_topoftheweek()
01123             #gobject.timeout_add(200, self.main.set_allow_rearrange)
01124         #elif self.main.allow_rearrange and self.main.layout_mode=="artist":
01125             #self.main.allow_rearrange = False
01126             #self.main.arrange_artistdetail()
01127             #gobject.timeout_add(200, self.main.set_allow_rearrange)
01128 
01129     def show_about(self, widget=None):
01130         xml = gtk.glade.XML(os.path.join(functions.install_dir(), "about.glade"))
01131         about = xml.get_widget('About')
01132 
01133         img = None
01134 
01135         for child in about.vbox.get_children():
01136             if isinstance(child, gtk.VBox):
01137                 for sub_child in child.get_children():
01138                     if isinstance(sub_child, gtk.Image):
01139                         img = sub_child
01140                         break
01141         if img is not None:
01142             animation = gtk.gdk.PixbufAnimation(os.path.join(functions.install_dir(), "images", "pyjama_anim.gif"))
01143 #            img = gtk.Image()
01144             img.set_from_animation(animation)
01145 #            img.show()
01146 #            while gtk.events_pending():
01147 #                 gtk.main_iteration()
01148 #            about.vbox.pack_start(img, False, True)
01149         else:
01150             pixbuf = gtk.gdk.pixbuf_new_from_file(os.path.join(functions.install_dir(), "images", "pyjama.png"))
01151             about.set_logo(pixbuf)
01152         about.run()
01153         about.destroy()
01154 
01155     def get_active_text(self, combobox):
01156         model = combobox.get_model()
01157         active = combobox.get_active()
01158         if active < 0:
01159             return None
01160         return model[active][0]
01161         ## => active = combobox.get_active()
01162 
01163     def setStatus(self, text=""):
01164         self.message_id = self.sbStatus.push(self.context_id, text)
01165 
01166     def quit(self, widget, event ):
01167         #~ self.set_skip_taskbar_hint(True)
01168         self.do_events()
01169         self.iconify()
01170         return True
01171 #        return None
01172 
01173     def really_quit(self, ev=None):
01174         if self.main.verbose:
01175             print "##########################################################"
01176             print ("Query Session Statistics:")
01177             print ("Cached Queries: %i") % self.main.jamendo.cache_counter
01178             print ("Jamendo Queries: %i") % self.main.jamendo.jamendo_counter
01179             print ("Database Queries: %i") % self.main.db.query_counter
01180             print ("Settings Database Queries: %i") % self.main.settingsdb.query_counter
01181             print "##########################################################"
01182             print ("Total Cache Statistics:")
01183             os.system("du -h %s" % os.path.join(functions.preparedirs(), "cache")) 
01184             print "##########################################################"
01185             print ("Cached Queries Total:")
01186             os.system("du -a %s|wc -l" % os.path.join(functions.preparedirs(), "cache")) 
01187             print "##########################################################"
01188             print ("Stored Images:")
01189             os.system("du -a %s|wc -l" % os.path.join(functions.preparedirs(), "images")) 
01190             print "##########################################################"
01191             print ("Stored Images Size:")
01192             os.system("du -h %s|cut -f 1" % os.path.join(functions.preparedirs(), "images")) 
01193             print "##########################################################"
01194 
01195         self.main.quit()
01196         self.do_events()
01197         
01198 
01199         gtk.main_quit()
01200 
01201 
01202     #def on_sbVolume_Change(self, range, scroll, value):
01203     def on_sbVolume_Change(self, widget, value):
01204         value = int(value)
01205         if value > self.main.settings.get_value("SOUND", "vol_max"): value = self.main.settings.get_value("SOUND", "vol_max")
01206         if value < 0: value = 0
01207         self.main.player.set_volume(value)
01208 
01209     def show_error_message(self, desc, tb):
01210         dia = gtk.Dialog()
01211         dia.set_size_request(400,-1)
01212         dia.set_icon_from_file(os.path.join(functions.install_dir(), "images", "pyjama.png"))
01213 
01214         lbl = gtk.Label()
01215         lbl.show()
01216         lbl.set_markup(str(desc))
01217         lbl.set_line_wrap(True)
01218         lbl.set_single_line_mode(False)
01219         dia.vbox.pack_start(lbl, True, True, 10)
01220 
01221         if tb.strip() != "None":
01222             expander = gtk.Expander("Show/hide details")
01223             expander.show()
01224             sw = gtk.ScrolledWindow()
01225             sw.show()
01226             expander.add(sw)
01227             dia.vbox.pack_start(expander, True, True, 10)
01228 
01229             textview = gtk.TextView()
01230             textview.show()
01231             sw.add(textview)
01232             textbuffer = gtk.TextBuffer()
01233             textview.set_buffer(textbuffer)
01234             textbuffer.set_text(tb)
01235 
01236 
01237         dia.set_title("An Error occured")
01238         dia.add_button(gtk.STOCK_OK, -1)
01239         dia.run()
01240         dia.destroy()
01241 
01242     def check_alldone(self):
01243         return self.__alldone
01244 
01245     def do_events(self):
01246         i = 0
01247         try:
01248             max = self.main.settings.get_value("PERFORMANCE", "max_iterations_while_events_pending", 50)
01249         except:
01250             max = 50
01251 
01252         while gtk.events_pending():
01253             if i > max:
01254                 print ("To much interations, breaking events_pending() loop")
01255                 break
01256             gtk.main_iteration()
01257 #            i += 1
01258 
01259     def setcolor(self, widget):
01260         if self.main.nocolor:
01261             return None 
01262         style = widget.get_style()
01263         color = widget.get_colormap()
01264         bg = color.alloc_color(self.bgcolor)#(20000,20000,65000,0)
01265         fg = color.alloc_color(0, 0, 0, 0)
01266         style.bg[gtk.STATE_NORMAL] = bg
01267         style.fg[gtk.STATE_NORMAL] = fg
01268         widget.set_style(style)
01269 
01270 
01271 
01272 ###########################################################
01273 #                                                         #
01274 #                                                         #
01275 #         Special functions for creating imagepacks       #
01276 #                                                         #
01277 #                                                         #
01278 ###########################################################
01279     ## I use this functions to create imagepacks. You can 
01280     # download them using the imagepack-plugin. You should
01281     # not actually run this code.
01282     def __special_checks(self):
01283         # The following lines download all album-covers
01284         # from jamendo which aren't on disc, yet.
01285         # It was only used once to generate an image-pack.
01286         # Notice: The md5 hash is generated from the get2
01287         # query ('image_name'). The image itself is downloaded
01288         # directly from jamendo's server in order not to 
01289         # overun the get2-interface.
01290         if "create-imagepack" in sys.argv:
01291             ID = 0
01292             LICENSE = 1
01293             ARTIST = 2
01294             ALBUM = 3
01295             ARTIST_URL = 4
01296             sql = "SELECT albums.id, albums.license_artwork, artists.name, albums.name, artists.url FROM albums, artists WHERE albums.artist_id=artists.id"
01297             print ("Now querying the database - this will take a while")
01298             ret = self.main.db.query(sql)
01299             print ("Done - will now create the imagepack")
01300 
01301             images = ""
01302             last_percentage = 0.0
01303             total = len(ret)*1.0
01304             counter = 1
01305 
01306             txt = "<html><body>\nPyjama's imagepacks contains cover-images of albums that are free available @ jamendo.com<br />\n"
01307             txt += "Each image is property of it's author and comes with a own license.<br />\n"
01308             txt += "In the following table you look up informations for each image by its name in the imagepack.<br /></br>\n"
01309             txt += "<table><tr><td>MD5 Hash</td><td>Artist</td><td>Album</td><td>License</td></tr>\n"
01310 
01311 
01312             download_counter = 0
01313             for item in ret:
01314                 album_id = item[ID]
01315                 image_name = "http://api.jamendo.com/get2/image/album/redirect/?id=%s&imagesize=100" % album_id
01316                 image_url = "http://imgjam.com/albums/%i/covers/1.100.jpg" % album_id
01317 #                images += "%s\n" % image
01318                 md5hash = hashlib.md5(image_name).hexdigest()
01319 
01320                 album_name = item[ALBUM]
01321                 if len(item[ALBUM]) > 20:
01322                     album_name = "%s[...]%s" % (item[ALBUM][:17], item[ALBUM][-3:])
01323                 artist_name = item[ARTIST]
01324                 if len(item[ARTIST]) > 20:
01325                     artist_name = "%s[...]%s" % (item[ARTIST][:17], item[ARTIST][-3:])
01326 
01327                 txt += "<tr><td><a href = 'http://imgjam.com/albums/%i/covers/1.100.jpg'>%s</a></td><td><a href = '%s'>%s</a></td><td><a href='http://www.jamendo.com/album/%i'>%s</a></td><td><a href = '%s'>LICENSE</a></td></tr>\n" % (item[ID], md5hash, item[ARTIST_URL], artist_name, item[ID], album_name, item[LICENSE])
01328 
01329                 fh = os.path.join(self.main.home, "images", md5hash)
01330                 perc = float(counter/total*100.0)
01331                 if not os.path.exists(fh):
01332                     try:
01333                         download_counter += 1
01334                         print ("Dowload #%i, Album %i - %f%%" %  (download_counter, album_id, perc))
01335                         urllib.urlretrieve(image_url, fh)
01336                         sleep(4)
01337                     except IOError:
01338                         print ("Could not load image")
01339                         return None
01340                 else:
01341                     if perc >= last_percentage + 0.3:
01342                         print ("Album %i already downloaded - (%f%%)" % (album_id, perc))
01343                         last_percentage = perc
01344                 counter += 1
01345             print ("%i images downloaded" % download_counter)
01346             print ("Creating archive")
01347             tf = tarfile.open("imagepack.tar.gz", "w:gz")
01348             tf.add(os.path.join(self.main.home, "images"), arcname="images", recursive=True)
01349             filename = self.__info_file("create")
01350             if filename is not None:
01351                 tf.add(filename, arcname="README.TXT")
01352                 self.__info_file("delete")
01353             tf.close()
01354 
01355             print ("Now writing license informations")
01356             txt += "</table></body></html>"
01357             fh = open("imagepack-license-infos.htm", "w")
01358             if fh:
01359                 fh.write(txt)
01360                 fh.close()
01361 
01362             print ("Done")
01363             sys.exit(0)
01364 
01365             #fh = open("imagelist", "w")
01366             #if fh:
01367                 #fh.write(images)
01368                 #fh.close()
01369 
01370         # These lines create an "smart" image pack
01371         # with covers of popular albums
01372         if "create-smart-imagepack" in sys.argv:
01373             path = os.path.join(self.main.home, "smart_image_pack")
01374             if not os.path.exists(path):
01375                 os.mkdir(path)
01376             query1 = "id/album/json/?n=100&order=ratingmonth_desc"
01377             query2 = "id/album/json/?n=100&order=rating_desc"
01378             query3 = "id/album/json/?n=100&order=ratingweek_desc"
01379             query4 = "id/album/json/?n=100&order=downloaded_desc"
01380             query5 = "id/album/json/?n=100&order=listened_desc"
01381             query6 = "id/album/json/?n=100&order=stared_desc"
01382             for query in [query1, query2, query3, query4, query5, query6]:
01383                 ret = self.main.jamendo.query(query)
01384                 images = ""
01385                 total = len(ret)*1.0
01386                 counter = 1
01387                 for item in ret:
01388                     album_id = item
01389                     image_name = "http://api.jamendo.com/get2/image/album/redirect/?id=%s&imagesize=100" % album_id
01390                     image_url = "http://imgjam.com/albums/%i/covers/1.100.jpg" % album_id
01391     #                images += "%s\n" % image
01392                     md5hash = hashlib.md5(image_name).hexdigest()
01393                     fh = os.path.join(self.main.home, "smart_image_pack", md5hash)
01394                     test_image = os.path.join(self.main.home, "images", md5hash)
01395                     perc = float(counter/total*100.0)
01396                     if os.path.exists(fh):
01397                         print ("%s alrady exists" % fh)
01398                     elif os.path.exists(test_image):
01399                         print ("copied %s from %s" % (fh, test_image))
01400                         shutil.copy(test_image, fh)
01401                     else:
01402                         try:
01403                             print ("Downloading", album_id, " (%f)" % perc)
01404                             urllib.urlretrieve(image_url, fh)
01405                             sleep(1)
01406                         except IOError:
01407                             print ("Could not load image")
01408                             return None
01409     #                else:
01410     #                    print (album_id, " already downloaded", " (%f)" % perc)
01411                     counter += 1
01412                 sleep(1)
01413             print ("Creating archive")
01414             tf = tarfile.open("smart-imagepack.tar.gz", "w:gz")
01415             tf.add(path, arcname="images", recursive=True)
01416             filename = self.__info_file("create")
01417             if filename is not None:
01418                 tf.add(filename, arcname="README.TXT")
01419                 self.__info_file("delete")
01420             tf.close()
01421             print ("Done")
01422             sys.exit(0)
01423 
01424         #
01425         # Find images which were downloaded from the
01426         # url http://imgjam.com/albums/%i/covers/1.100.jpg
01427         #
01428         if "find-wrong-image-uris" in sys.argv:
01429             sql = "SELECT id FROM albums WHERE 1"
01430             ret = self.main.db.query(sql)
01431             filelist = os.listdir(os.path.join(self.main.home, "images"))
01432 
01433             delete_counter = 0
01434             total = len(ret) * len(filelist)
01435             counter = 1.0
01436             for fl in filelist:
01437                 print float(counter/total*100.0)
01438                 for item in ret:
01439                     counter += 1.0
01440                     album_id = item[0]
01441                     image_name = "http://imgjam.com/albums/%i/covers/1.100.jpg" % album_id
01442                     md5hash = hashlib.md5(image_name).hexdigest()
01443                     if fl == md5hash:
01444                         if "delete-those" in sys.argv:
01445                             f = os.path.join(self.main.home, "images", fl)
01446                             try:
01447                                 os.remove(f)
01448                                 delete_counter +=1
01449                                 print("%i: Deleted %s" % (delete_counter, f))
01450                             except:
01451                                 print("Error deleting %s" % f)
01452                         else:
01453                             print fl, image_name
01454 
01455         #
01456         # Print every image that is not a regular album image
01457         # Warning: This prints also album images and album covers
01458         # with a size > 100px
01459         #
01460         if "print-none-album-covers" in sys.argv:
01461             sql = "SELECT id FROM albums WHERE 1"
01462             ret = self.main.db.query(sql)
01463             filelist = os.listdir(os.path.join(self.main.home, "images"))
01464             for fl in filelist:
01465                 ok = False
01466                 for item in ret:
01467                     counter +=1
01468                     album_id = item[0]
01469                     image_name = "http://api.jamendo.com/get2/image/album/redirect/?id=%s&imagesize=100" % album_id
01470                     md5hash = hashlib.md5(image_name).hexdigest()
01471                     if fl == md5hash:
01472                         ok = True
01473                 if not ok:
01474                     print ("Not ok: %s" % fl)
01475 
01476         if "country-check" in sys.argv:
01477             sql = "SELECT country FROM artists WHERE 1"
01478             ret = self.main.db.query(sql)
01479             cts = {}
01480             for item in ret:
01481                 country = item[0]
01482                 try:
01483                     cts[country] +=1
01484                 except:
01485                     cts[country] = 1
01486             for x in cts:
01487                 if cts[x] > 0:
01488                     print x, cts[x]
01489             print ("Total num of countries: %s" % len(cts))
01490             sys.exit(1)
01491 
01492     def __info_file(self, mode="delete"):
01493         filename = "5987635.txt"
01494         if mode != "delete":
01495             fh = open(filename, "w")
01496             if fh:
01497                 fh.write("The covers in this archive belong to albums which are available for free at www.jamendo.com.\nThey are property of their artist who released them under certain licenses.\nYou can find out which cover is released under which license by calling\n\n http://xn--ngel-5qa.de/pyjama/release/imagepack-license-infos.htm\n\n On this page every cover of the imagepack is listed.")
01498                 fh.close()
01499                 return filename
01500         else:
01501             if os.path.exists(filename):
01502                 os.remove(filename)

Generated on Thu Jun 4 19:08:24 2009 for Pyjama by  doxygen 1.5.8