Exemplo n.º 1
0
    def rebuild_database(self):
        from time import time as systime
        systime1 = systime()

        #Tempory Database connection for thread
        conn = sqlite3.connect(self.dblocation)
        cursor = conn.cursor()
        trackparser = TrackMetaData()

        #clear out current database
        cursor.execute("DELETE FROM Songs")

        for libraryfolder in self.libraryfolders:
            libraryfolder = libraryfolder.replace('file://', '').replace(
                '%20', ' ')  #simple but is a bit slow
            if os.path.isdir(libraryfolder):
                for root, dirs, files in scandir.walk(libraryfolder):
                    for name in files:
                        metadata = trackparser.getTrackType(
                            os.path.join(root, name))
                        if metadata != False:
                            #escape single quotes for sql query
                            metadata[2] = metadata[2].replace("'",
                                                              "''")  #Title
                            metadata[3] = metadata[3].replace("'",
                                                              "''")  #Artist
                            metadata[4] = metadata[4].replace("'",
                                                              "''")  #Album
                            metadata[6] = metadata[6].replace("'",
                                                              "''")  #Genre
                            metadata[7] = metadata[7].replace("'", "''")  #Url

                            #build query and encode to ascii for python 2
                            #query = "INSERT INTO Songs(TrackNum,Title,Artist,Album,Length,Genre,Url) VALUES ({},'{}','{}','{}','{}','{}','{}');".format(metadata[1],metadata[2].encode('ascii','ignore'),metadata[3].encode('ascii','ignore'),metadata[4].encode('ascii','ignore'),metadata[5].encode('ascii','ignore'),metadata[6].encode('ascii','ignore'),metadata[7])

                            #since we truncate anyway, checking for existing entrys is redundant for now
                            """cursor.execute("SELECT * FROM Songs WHERE Url='{}'".format(metadata[7]))
							if cursor.fetchone() == None:
								query = "INSERT INTO Songs(TrackNum,Title,Artist,Album,Length,Genre,Url) VALUES ({},'{}','{}','{}','{}','{}','{}');".format(metadata[1],metadata[2],metadata[3],metadata[4],metadata[5],metadata[6],metadata[7])
								cursor.execute(query)	
							else:
								query = "UPDATE Songs SET TrackNum='{}',Title='{}',Artist='{}',Album='{}',Length='{}',Genre='{}' WHERE Url='{}';".format(metadata[1],metadata[2],metadata[3],metadata[4],metadata[5],metadata[6],metadata[7])
								cursor.execute(query)"""
                            query = "INSERT INTO Songs(TrackNum,Title,Artist,Album,Length,Genre,Url) VALUES ({},'{}','{}','{}','{}','{}','{}');".format(
                                metadata[1], metadata[2], metadata[3],
                                metadata[4], metadata[5], metadata[6],
                                metadata[7])
                            cursor.execute(query)
                conn.commit()
        print("%s%f" % ("Operation took ", systime() - systime1))
Exemplo n.º 2
0
    def __init__(self):
        self.sw = Gtk.ScrolledWindow()
        self.trackparser = TrackMetaData()

        builder = Gtk.Builder()
        filename = os.path.join('data', 'treeview.ui')
        builder.add_from_file(filename)
        self.abox = builder.get_object('treeview1')
        self.abox.set_fixed_height_mode(False)

        self.abox.set_search_column(1)
        self.abox.get_selection().set_mode(Gtk.SelectionMode.MULTIPLE)
        trackCol = builder.get_object('trackCol')
        titleCol = builder.get_object('titleCol')
        artistCol = builder.get_object('artistCol')
        albumCol = builder.get_object('albumCol')
        lengthCol = builder.get_object('lengthCol')
        genreCol = builder.get_object('genreCol')
        pathCol = builder.get_object('pathCol')

        #need to figure a working sorting function
        #self.abox.get_model().set_sort_func(1, self.tracknumsortfunc, None)

        trackCol.set_sort_column_id(1)
        titleCol.set_sort_column_id(2)
        artistCol.set_sort_column_id(3)
        albumCol.set_sort_column_id(4)
        lengthCol.set_sort_column_id(5)
        genreCol.set_sort_column_id(6)

        #anEntry = Gtk.TargetEntry.new("abox",Gtk.TargetFlags.SAME_WIDGET, 10)
        self.abox.enable_model_drag_source(
            Gdk.ModifierType.BUTTON1_MASK, [
                ('TREE_MODEL_ROW', Gtk.TargetFlags.SAME_WIDGET, 0),
            ], Gdk.DragAction.COPY | Gdk.DragAction.MOVE)
        #self.abox.drag_source_set(Gdk.ModifierType.BUTTON1_MASK, [anEntry], 0)
        self.abox.enable_model_drag_dest([], Gdk.DragAction.COPY
                                         | Gdk.DragAction.DEFAULT)
        #self.abox.drag_dest_set(0, [], 0)
        self.abox.connect('drag_motion', self.drag_motion_cb)
        self.abox.connect('drag_drop', self.drop_cb)
        self.abox.connect('drag_data_received', self.got_data_cb)

        self.abox.connect("drag_data_get", self.drag_data_get_data)

        self.abox.connect('button_press_event', self.on_button_press)
        self.abox.connect('button_release_event', self.on_button_release)
        self.defer_select = False
        self.sw.add(self.abox)
Exemplo n.º 3
0
	def rebuild_database(self):
		from time import time as systime
		systime1 = systime()

		#Tempory Database connection for thread
		conn = sqlite3.connect(self.dblocation)
		cursor = conn.cursor()
		trackparser = TrackMetaData()

		#clear out current database
		cursor.execute("DELETE FROM Songs")

		for libraryfolder in self.libraryfolders:
			libraryfolder = libraryfolder.replace('file://','').replace('%20',' ') #simple but is a bit slow
			if os.path.isdir(libraryfolder):
				for root, dirs, files in scandir.walk(libraryfolder):
					for name in files:
						metadata = trackparser.getTrackType(os.path.join(root, name))
						if metadata != False:
							#escape single quotes for sql query
							metadata[2] = metadata[2].replace("'","''")#Title
							metadata[3] = metadata[3].replace("'","''")#Artist
							metadata[4] = metadata[4].replace("'","''")#Album
							metadata[6] = metadata[6].replace("'","''")#Genre
							metadata[7] = metadata[7].replace("'","''")#Url

							#build query and encode to ascii for python 2
							#query = "INSERT INTO Songs(TrackNum,Title,Artist,Album,Length,Genre,Url) VALUES ({},'{}','{}','{}','{}','{}','{}');".format(metadata[1],metadata[2].encode('ascii','ignore'),metadata[3].encode('ascii','ignore'),metadata[4].encode('ascii','ignore'),metadata[5].encode('ascii','ignore'),metadata[6].encode('ascii','ignore'),metadata[7])
							
							#since we truncate anyway, checking for existing entrys is redundant for now
							"""cursor.execute("SELECT * FROM Songs WHERE Url='{}'".format(metadata[7]))
							if cursor.fetchone() == None:
								query = "INSERT INTO Songs(TrackNum,Title,Artist,Album,Length,Genre,Url) VALUES ({},'{}','{}','{}','{}','{}','{}');".format(metadata[1],metadata[2],metadata[3],metadata[4],metadata[5],metadata[6],metadata[7])
								cursor.execute(query)	
							else:
								query = "UPDATE Songs SET TrackNum='{}',Title='{}',Artist='{}',Album='{}',Length='{}',Genre='{}' WHERE Url='{}';".format(metadata[1],metadata[2],metadata[3],metadata[4],metadata[5],metadata[6],metadata[7])
								cursor.execute(query)"""
							query = "INSERT INTO Songs(TrackNum,Title,Artist,Album,Length,Genre,Url) VALUES ({},'{}','{}','{}','{}','{}','{}');".format(metadata[1],metadata[2],metadata[3],metadata[4],metadata[5],metadata[6],metadata[7])
							cursor.execute(query)	
				conn.commit()
		print("%s%f" % ("Operation took ",systime() - systime1))
Exemplo n.º 4
0
	def __init__(self):
		self.sw = Gtk.ScrolledWindow()
		self.trackparser = TrackMetaData()

		builder = Gtk.Builder()
		filename = os.path.join('data', 'treeview.ui')
		builder.add_from_file(filename)
		self.abox = builder.get_object('treeview1')
		self.abox.set_fixed_height_mode(False)

		self.abox.set_search_column(1)
		self.abox.get_selection().set_mode(Gtk.SelectionMode.MULTIPLE)
		trackCol = builder.get_object('trackCol')
		titleCol = builder.get_object('titleCol')
		artistCol = builder.get_object('artistCol')
		albumCol = builder.get_object('albumCol')
		lengthCol = builder.get_object('lengthCol')
		genreCol = builder.get_object('genreCol')
		pathCol = builder.get_object('pathCol')

		#need to figure a working sorting function
		#self.abox.get_model().set_sort_func(1, self.tracknumsortfunc, None)

		trackCol.set_sort_column_id(1)
		titleCol.set_sort_column_id(2)
		artistCol.set_sort_column_id(3)
		albumCol.set_sort_column_id(4)
		lengthCol.set_sort_column_id(5)
		genreCol.set_sort_column_id(6)

		#anEntry = Gtk.TargetEntry.new("abox",Gtk.TargetFlags.SAME_WIDGET, 10)
		self.abox.enable_model_drag_source(Gdk.ModifierType.BUTTON1_MASK, [('TREE_MODEL_ROW', Gtk.TargetFlags.SAME_WIDGET, 0),], Gdk.DragAction.COPY|Gdk.DragAction.MOVE)
		#self.abox.drag_source_set(Gdk.ModifierType.BUTTON1_MASK, [anEntry], 0)
		self.abox.enable_model_drag_dest([], Gdk.DragAction.COPY|Gdk.DragAction.DEFAULT)
		#self.abox.drag_dest_set(0, [], 0)
		self.abox.connect('drag_motion', self.drag_motion_cb)
		self.abox.connect('drag_drop', self.drop_cb)
		self.abox.connect('drag_data_received', self.got_data_cb)

		self.abox.connect("drag_data_get", self.drag_data_get_data)

		self.abox.connect('button_press_event', self.on_button_press)
		self.abox.connect('button_release_event', self.on_button_release)
		self.defer_select=False
		self.sw.add(self.abox)
Exemplo n.º 5
0
	def __init__(self):
		#Global Variables (keep to a minimum)
		self.settings = settings.IconoSettings(sopranoGlobals.SETTINGS_DATA)
		self.taglookup = TrackMetaData()
		self.seekingnow = False	
		#load settings
		self.currentview, self.winwidth, self.winheight, self.defaultexplorer, self.shuffle, self.repeat, self.showtrayicon, self.closetotray = self.settings.get_settings()

		libraryFolderlist = settings.IconoPrefs(sopranoGlobals.LIBRARY_DATA)
		self.SopranoDB = MusicDB(os.path.join(sopranoGlobals.CONFIGDIR, 'sopranoDB.db'))
		libraryFolderlist.add_radio(('/media/Media/Music','/media/Media/Music'))
		for key,value in libraryFolderlist.get_radioStations().items():
			self.SopranoDB.add_folder(value)

		#turn on the dbus mainloop for sound menu
		from dbus.mainloop.glib import DBusGMainLoop
		DBusGMainLoop(set_as_default=True)
		#Start Sound Menu Support
		self.sopranompris = SoundMenuControls("soprano-player")
		self.sopranompris.signal_next = self.play_next
		self.sopranompris.signal_prev = self.play_prev
		self.sopranompris.signal_play_pause = self.play_pause
		self.sopranompris.signal_raise = self.toggle_window

		#Enable Notifications
		Notify.init ("Soprano")
		self.notification = Notify.Notification.new("","","")

		#Window Creation
		self.builder = Gtk.Builder()
		filename = os.path.join('data', 'MainWindow.glade')
		self.builder.add_from_file(filename)
		self.builder.connect_signals(self)

		self.window = self.builder.get_object('win-main')
		self.window.set_default_size(self.winwidth,self.winheight)
		self.window.connect('delete-event', self.pre_exit)
		
		#radiowindow
		self.aRadio = IconoRadio()

		#Gstreamer sink
		self.player = MusicPlayer()
		self.player.on_eos(self.on_message)
		#media keys setup
		self.mediakeys = mediakeys(self.play_prev, self.play_pause, self.play_next)

		timer = GObject.timeout_add(500, self.update_time_items)

		#trayicon
		self.tray = IconoTray("soprano-player-tray") 
		self.trayshowhide = self.tray.add_menu_item(self.toggle_window, "Hide/Show")
		self.tray.add_seperator()
		self.trayplaypause = self.tray.add_menu_item(self.play_pause, "Play/Pause")
		self.tray.add_menu_item(self.play_next, "Next")
		self.tray.add_menu_item(self.play_prev, "Previous")
		self.tray.add_seperator()
		self.tray.add_menu_item(self.on_exit, "Quit")
		self.update_tray_icon(self.showtrayicon)


		#View Menu#
		menuvfull = self.builder.get_object('menu-mode-full')
		menuvfull.connect('activate', self.to_full_mode)
		menuvmini = self.builder.get_object('menu-mode-mini')
		menuvmini.connect('activate', self.to_mini_mode)
		menuvplist = self.builder.get_object('menu-mode-playlist')
		menuvplist.connect('activate', self.to_playlist_mode)

		#Quit, About Menus
		menuaqt = self.builder.get_object('menu-quit')
		menuaqt.connect('activate',self.on_exit)
		menuabt = self.builder.get_object('menu-about')
		menuabt.connect('activate', aboutBoxShow, self.window)

		#Edit Menu#
		menuaddfolder = self.builder.get_object('menu-folderadd')
		#menuaddfolder.connect('activate', lambda x: self.addFolderExplorer(('Video','/media/Media/Videos')))
		menuaddfolder.connect('activate', self.show_pref_win)

		menuaddradio = self.builder.get_object('menu-radioadd')
		#menuaddradio.connect('activate', lambda x: self.delFolderExplorer(('Video','/media/Media/Videos')))
		menuaddradio.connect('activate', self.aRadio.addStationDialog)

		self.menuautopop = self.builder.get_object('menu-autopop')

		#playing Toolbar
		self.toolnext = self.builder.get_object('btn-next')
		self.toolnext.connect('clicked', self.play_next)

		self.toolprev = self.builder.get_object('btn-previous')
		self.toolprev.connect('clicked', self.play_prev)

		self.toolstop = self.builder.get_object('btn-stop')
		self.toolstop.connect('clicked', self.stop_play)

		self.toolplay = self.builder.get_object('btn-play')
		self.toolplay.connect('clicked', self.play_pause)

		self.toolSeekBar = self.builder.get_object('scl-position')
		self.toolSeekBar.connect('button-release-event', self.seek)
		self.toolSeekBar.connect('button-press-event', self.seekevent)

		self.toolVolume = self.builder.get_object('btn-volume')
		self.toolVolume.connect('value-changed', self.change_volume)

		#Text Displays
		self.titleText = self.builder.get_object('lbl-trkTitle')
		self.infoText = self.builder.get_object('lbl-trkMisc')
		self.lengthLabel = self.builder.get_object('lbl-length')
		self.elapsedLabel = self.builder.get_object('lbl-elapsed')

		#bottom toolbar
		barclr = self.builder.get_object('btn-tracklistClear')
		barclr.connect('clicked', self.clear_liststore)

		barshfl = self.builder.get_object('btn-tracklistShuffle')
		if self.shuffle == True:
			barshfl.set_active(True)
		barshfl.connect('clicked', self.shuffleliststore)

		barrpt = self.builder.get_object('btn-tracklistRepeat')
		if self.repeat == True:
			barrpt.set_active(True)
		barrpt.connect('toggled', self.setrepeat)

		#listview
		self.iconoListView = IconoListView()
		self.iconoListView.get_sw().get_child().connect('row-activated', self.on_activated)
		#self.iconoListView.get_sw().get_child().connect('button-press-event', self.on_right_click)
		vbox2 = self.builder.get_object('vbox2')
		vbox2.add(self.iconoListView.get_sw())
		vbox2.reorder_child(self.iconoListView.get_sw(), 1)
		if os.path.exists(sopranoGlobals.TREE_DATA):
			GObject.idle_add(self.iconoListView.load_shelf, sopranoGlobals.TREE_DATA)

		#combobox
		self.hCombo = HeaderedComboBox()
		self.hCombo.connect("changed", self.on_name_combo_changed)

		self.builder.get_object('box-combo-explorer').add(self.hCombo)
		
		GObject.idle_add(self.setup_explorer)
		GObject.idle_add(self.cover_update)
		self.window.show_all()
		if self.currentview == 'playlist':
			menuvplist.set_active(True)
			self.to_playlist_mode()
		elif self.currentview == 'mini':
			menuvmini.set_active(True)
			self.to_mini_mode()
		#Notebook
		self.notebook = self.builder.get_object('notebook-explorer')
Exemplo n.º 6
0
class SopranoApp:
	def __init__(self):
		#Global Variables (keep to a minimum)
		self.settings = settings.IconoSettings(sopranoGlobals.SETTINGS_DATA)
		self.taglookup = TrackMetaData()
		self.seekingnow = False	
		#load settings
		self.currentview, self.winwidth, self.winheight, self.defaultexplorer, self.shuffle, self.repeat, self.showtrayicon, self.closetotray = self.settings.get_settings()

		libraryFolderlist = settings.IconoPrefs(sopranoGlobals.LIBRARY_DATA)
		self.SopranoDB = MusicDB(os.path.join(sopranoGlobals.CONFIGDIR, 'sopranoDB.db'))
		libraryFolderlist.add_radio(('/media/Media/Music','/media/Media/Music'))
		for key,value in libraryFolderlist.get_radioStations().items():
			self.SopranoDB.add_folder(value)

		#turn on the dbus mainloop for sound menu
		from dbus.mainloop.glib import DBusGMainLoop
		DBusGMainLoop(set_as_default=True)
		#Start Sound Menu Support
		self.sopranompris = SoundMenuControls("soprano-player")
		self.sopranompris.signal_next = self.play_next
		self.sopranompris.signal_prev = self.play_prev
		self.sopranompris.signal_play_pause = self.play_pause
		self.sopranompris.signal_raise = self.toggle_window

		#Enable Notifications
		Notify.init ("Soprano")
		self.notification = Notify.Notification.new("","","")

		#Window Creation
		self.builder = Gtk.Builder()
		filename = os.path.join('data', 'MainWindow.glade')
		self.builder.add_from_file(filename)
		self.builder.connect_signals(self)

		self.window = self.builder.get_object('win-main')
		self.window.set_default_size(self.winwidth,self.winheight)
		self.window.connect('delete-event', self.pre_exit)
		
		#radiowindow
		self.aRadio = IconoRadio()

		#Gstreamer sink
		self.player = MusicPlayer()
		self.player.on_eos(self.on_message)
		#media keys setup
		self.mediakeys = mediakeys(self.play_prev, self.play_pause, self.play_next)

		timer = GObject.timeout_add(500, self.update_time_items)

		#trayicon
		self.tray = IconoTray("soprano-player-tray") 
		self.trayshowhide = self.tray.add_menu_item(self.toggle_window, "Hide/Show")
		self.tray.add_seperator()
		self.trayplaypause = self.tray.add_menu_item(self.play_pause, "Play/Pause")
		self.tray.add_menu_item(self.play_next, "Next")
		self.tray.add_menu_item(self.play_prev, "Previous")
		self.tray.add_seperator()
		self.tray.add_menu_item(self.on_exit, "Quit")
		self.update_tray_icon(self.showtrayicon)


		#View Menu#
		menuvfull = self.builder.get_object('menu-mode-full')
		menuvfull.connect('activate', self.to_full_mode)
		menuvmini = self.builder.get_object('menu-mode-mini')
		menuvmini.connect('activate', self.to_mini_mode)
		menuvplist = self.builder.get_object('menu-mode-playlist')
		menuvplist.connect('activate', self.to_playlist_mode)

		#Quit, About Menus
		menuaqt = self.builder.get_object('menu-quit')
		menuaqt.connect('activate',self.on_exit)
		menuabt = self.builder.get_object('menu-about')
		menuabt.connect('activate', aboutBoxShow, self.window)

		#Edit Menu#
		menuaddfolder = self.builder.get_object('menu-folderadd')
		#menuaddfolder.connect('activate', lambda x: self.addFolderExplorer(('Video','/media/Media/Videos')))
		menuaddfolder.connect('activate', self.show_pref_win)

		menuaddradio = self.builder.get_object('menu-radioadd')
		#menuaddradio.connect('activate', lambda x: self.delFolderExplorer(('Video','/media/Media/Videos')))
		menuaddradio.connect('activate', self.aRadio.addStationDialog)

		self.menuautopop = self.builder.get_object('menu-autopop')

		#playing Toolbar
		self.toolnext = self.builder.get_object('btn-next')
		self.toolnext.connect('clicked', self.play_next)

		self.toolprev = self.builder.get_object('btn-previous')
		self.toolprev.connect('clicked', self.play_prev)

		self.toolstop = self.builder.get_object('btn-stop')
		self.toolstop.connect('clicked', self.stop_play)

		self.toolplay = self.builder.get_object('btn-play')
		self.toolplay.connect('clicked', self.play_pause)

		self.toolSeekBar = self.builder.get_object('scl-position')
		self.toolSeekBar.connect('button-release-event', self.seek)
		self.toolSeekBar.connect('button-press-event', self.seekevent)

		self.toolVolume = self.builder.get_object('btn-volume')
		self.toolVolume.connect('value-changed', self.change_volume)

		#Text Displays
		self.titleText = self.builder.get_object('lbl-trkTitle')
		self.infoText = self.builder.get_object('lbl-trkMisc')
		self.lengthLabel = self.builder.get_object('lbl-length')
		self.elapsedLabel = self.builder.get_object('lbl-elapsed')

		#bottom toolbar
		barclr = self.builder.get_object('btn-tracklistClear')
		barclr.connect('clicked', self.clear_liststore)

		barshfl = self.builder.get_object('btn-tracklistShuffle')
		if self.shuffle == True:
			barshfl.set_active(True)
		barshfl.connect('clicked', self.shuffleliststore)

		barrpt = self.builder.get_object('btn-tracklistRepeat')
		if self.repeat == True:
			barrpt.set_active(True)
		barrpt.connect('toggled', self.setrepeat)

		#listview
		self.iconoListView = IconoListView()
		self.iconoListView.get_sw().get_child().connect('row-activated', self.on_activated)
		#self.iconoListView.get_sw().get_child().connect('button-press-event', self.on_right_click)
		vbox2 = self.builder.get_object('vbox2')
		vbox2.add(self.iconoListView.get_sw())
		vbox2.reorder_child(self.iconoListView.get_sw(), 1)
		if os.path.exists(sopranoGlobals.TREE_DATA):
			GObject.idle_add(self.iconoListView.load_shelf, sopranoGlobals.TREE_DATA)

		#combobox
		self.hCombo = HeaderedComboBox()
		self.hCombo.connect("changed", self.on_name_combo_changed)

		self.builder.get_object('box-combo-explorer').add(self.hCombo)
		
		GObject.idle_add(self.setup_explorer)
		GObject.idle_add(self.cover_update)
		self.window.show_all()
		if self.currentview == 'playlist':
			menuvplist.set_active(True)
			self.to_playlist_mode()
		elif self.currentview == 'mini':
			menuvmini.set_active(True)
			self.to_mini_mode()
		#Notebook
		self.notebook = self.builder.get_object('notebook-explorer')

	def update_tray_icon(self, enabled=True):
		if enabled:
			try:	self.tray.myStatusIcon.set_visible(True)
			except: self.tray.ind.set_status(AppIndicator3.IndicatorStatus.ACTIVE)
		elif not enabled:
			try:	self.tray.myStatusIcon.set_visible(False)
			except: self.tray.ind.set_status(AppIndicator3.IndicatorStatus.PASSIVE)
			

	def show_pref_win(self, widget=None):
		newWin = SopranoPrefWin(self.showtrayicon, self.closetotray, self.window)
		newWin.win.set_transient_for(self.window)
		newWin.win.show_all()
		newWin.win.connect("destroy", self.pref_win_closed)


	def pref_win_closed(self, widget):
		currentpage = self.notebook.get_current_page()
		currentactive = self.hCombo.get_active()
		self.clear_notebook()
		self.setup_explorer()
		self.notebook.set_current_page(currentpage + widget.change)
		self.hCombo.set_active(currentactive + widget.change)
		self.showtrayicon = widget.traycheckbox.get_active()
		if self.showtrayicon:
			self.closetotray = widget.closecheckbox.get_active()
		else:
			self.closetotray = False
		self.update_tray_icon(self.showtrayicon)

	def toggle_window(self, justShow=True):
		if self.window.get_property("visible") and not justShow == True:
			self.window.hide()
			#self.trayshowhide.set_label("Show")
		else:
			self.window.show()
			#self.trayshowhide.set_label("Hide")

	def pre_exit(self, widget, var):
		if widget == self.window and self.closetotray:
			self.window.hide()
			return True
		else:
			self.on_exit(widget)

	def on_exit(self, widget):
		#hide window and tray icon first to give appearence of instant close
		self.window.hide()
		self.tray = None
		if self.currentview != 'mini':
			size = self.window.get_size()
			winheight = size[1]#.height
			winwidth = size[0]#.width
		else:
			winheight = self.winheight
			winwidth = self.winwidth
		self.settings.write_settings([self.currentview, winwidth, winheight ,self.notebook.get_current_page()+1, self.shuffle, self.repeat, self.showtrayicon, self.closetotray])
		self.iconoListView.save_shelf(sopranoGlobals.TREE_DATA)
		Gtk.main_quit()

	def addFolderExplorer(self, station):
		explorer = IconoTreeFile(station[1], sopranoGlobals.FILE_FORMATS)
		audioFolderlist = settings.IconoPrefs(sopranoGlobals.EXPLORER_DATA)
		audioFolderlist.add_radio(station)
		self.setup_explorer_page(self.notebook, explorer.get_sw(), self.hCombo, [len(audioFolderlist.get_radioStations()), 0, station[0], sopranoGlobals.FOLDERPB], self.notebook.get_n_pages()-2)
		#Update the audioCD and Radio Indexes
		model = self.hCombo.get_model()
		length = len(model)
		for i in range(1,3):
			iter = model.get_iter(length-i)
			model.set_value(iter, 0, length-(1+i))

	def clear_notebook(self, widget=None):
		for i in range(self.notebook.get_n_pages(), 0, -1):
			self.notebook.remove_page(i-1)
		self.hCombo.get_model().clear()

	def delFolderExplorer(self, station):
		self.clear_notebook()
		audioFolderlist = settings.IconoPrefs(sopranoGlobals.EXPLORER_DATA)
		audioFolderlist.delete_radio(station)
		self.setup_explorer()
		

	#explorer and combobox Handlers
	def setup_explorer(self, widget=None):
		self.hCombo.add_entry(None, 1, "<b>Folders</b>", None, -1)

		explorer = IconoTreeFile('/', sopranoGlobals.FILE_FORMATS)
		self.setup_explorer_page(self.notebook, explorer.get_sw(), self.hCombo, [self.notebook.get_n_pages(), 0, "Root", sopranoGlobals.FOLDERPB])

		audioFolderlist = settings.IconoPrefs(sopranoGlobals.EXPLORER_DATA)
		for key, value in audioFolderlist.get_radioStations().items():
			explorer = IconoTreeFile(value, sopranoGlobals.FILE_FORMATS)	
			self.setup_explorer_page(self.notebook, explorer.get_sw(), self.hCombo, [self.notebook.get_n_pages(), 0, key, sopranoGlobals.FOLDERPB])
		#aCdTree = IconoAudioCD()
		#self.setup_explorer_page(self.notebook, aCdTree.get_sw(), self.hCombo, [self.notebook.get_n_pages(), 0, "<b>Audio CD</b>", sopranoGlobals.TRACKPB])		
		self.setup_explorer_page(self.notebook, self.aRadio.get_sw(), self.hCombo, [self.notebook.get_n_pages(), 0, "<b>Radio</b>", sopranoGlobals.RADIOPB])

		self.medialib = IconoMediaLibrary(self.SopranoDB)
		self.setup_explorer_page(self.notebook, self.medialib.get_sw(), self.hCombo, [self.notebook.get_n_pages(), 0, "<b>Library</b>", sopranoGlobals.USERSPB])

		self.notebook.set_current_page(self.defaultexplorer)
		self.hCombo.set_active(self.defaultexplorer)

	def setup_explorer_page(self, notebook, widget, combo, arglist, insertHere=-1):
		combo.add_entry(arglist[0], arglist[1], arglist[2], arglist[3], insertHere)
		label = Gtk.Label(arglist[2])
		notebook.insert_page(widget, label, insertHere)
		notebook.show_all()

	def on_name_combo_changed(self, combo):
		tree_iter = combo.get_active_iter()
		if tree_iter != None:
			model = combo.get_model()
			index, row_id, name = model[tree_iter][:3]
			if row_id == 1:
				combo.set_active_iter(model.iter_next(tree_iter)) # if they try and select a header move to the real entry below instead
			else:
				self.notebook.set_current_page(index)

	#ListStore Handlers
	def on_activated(self, widget, row, col):
		model = widget.get_model()
		text = model[row][7]
		GObject.idle_add(self.playitem, text)
		self.iconoListView.set_playmark(row)

	#View Menu Handlers
	def to_full_mode(self, unused=None):
		self.window.resize(self.winwidth,self.winheight)
		self.builder.get_object('pan-main').get_child1().show()
		self.builder.get_object('statusbar').show()
		self.builder.get_object('box-btn-tracklist').show()
		self.iconoListView.get_sw().show()
		self.currentview = 'full'

	def to_mini_mode(self, unused=None):
		self.builder.get_object('pan-main').get_child1().hide()
		self.builder.get_object('statusbar').hide()
		self.builder.get_object('box-btn-tracklist').hide()
		self.iconoListView.get_sw().hide()
		self.window.resize(600, 150)
		self.currentview = 'mini'

	def to_playlist_mode(self, unused=None):
		self.to_full_mode(None)	
		self.window.resize(self.winwidth, self.winheight)
		self.builder.get_object('pan-main').get_child1().hide()
		self.currentview = 'playlist'

	#Bottom Toolbar Handlers#
	def clear_liststore(self, action):
		GObject.idle_add(self.stop_play)
		self.iconoListView.return_model().clear()

	def shuffleliststore(self, button):
		self.shuffle = not(self.shuffle)

	def setrepeat(self, arg1):
		self.repeat = not(self.repeat)

	#Data Display Handlers
	def update_time_items(self):
		if (self.player.get_state() == Gst.State.PLAYING):
			if not(self.seekingnow):
				self.toolSeekBar.set_value(self.player.track_percent())
			self.elapsedLabel.set_text(self.player.get_trackposition())
			self.lengthLabel.set_text('/' + self.player.get_tracklength())
		return True

	def update_labels(self, title, artist, album):
		self.titleText.set_text(title)
		self.infoText.set_text("By " + artist + " from " + album)

	def clear_labels(self):
		self.titleText.set_text("Soprano Audio Player")
		self.infoText.set_text("...One Goal, Be Epic")
		self.lengthLabel.set_text("")
		self.elapsedLabel.set_text("")

	def cover_update(self):
		filepath = self.player.get_track()
		if filepath != None:
			data = self.taglookup.getTrackType(filepath)
		try: artist = data[3].replace(' ','%20')
		except: artist = ""
		try: album = data[4].replace(' ','%20')
		except: album = ""

		coverFetch = getCover(artist, album, filepath)
		img = coverFetch.run()
		coverart = self.builder.get_object('img-cover')
		coverart.set_from_pixbuf(img.scale_simple(100,100,GdkPixbuf.InterpType.BILINEAR))

	#Play Handlers
	def on_message(self, bus, message):
		self.play_next()

	def seekevent(self, widget, event):
		self.seekingnow = True

	def seek(self, widget, test):
		self.seekingnow = False
		self.player.seek(widget.get_value())

	def change_volume(self, widget, volume):
		self.player.change_volume(volume)

	def play_prev(self, widget=None):
		for x in range(1,len(self.iconoListView.return_model())):
			if self.iconoListView.return_model()[x][0] == 'media-playback-start':
				GObject.idle_add(self.playitem, self.iconoListView.return_model()[x-1][7])
				self.iconoListView.set_playmark(x-1)
				break

	def play_next(self, widget=None):
		listlength = len(self.iconoListView.return_model())
		if self.shuffle:
			import random
			arand = random.randrange(0, listlength)
			self.iconoListView.set_playmark(arand)
			self.iconoListView.get_sw().get_child().scroll_to_cell(arand)
			GObject.idle_add(self.playitem, self.iconoListView.return_model()[arand][7])
			return
		for x in range(0, listlength):
			#if there on the last track, and they press next without repeat enabled, do nothing
			if x == listlength-1 and not(self.repeat):# and widget == self.toolnext:
				if self.menuautopop.get_active() == True:
					self.SopranoDB.cursor.execute("SELECT Url FROM Songs ORDER BY RANDOM() LIMIT 2;")
					rows = self.SopranoDB.cursor.fetchall()
					if len(rows) != 0:
						for item in rows:
							self.iconoListView.add_row(item[0],self.iconoListView.return_model(),False)
					else:
						break
				else:
					break
			#if the last track finished without repeat enabled, stop playing
			elif x == listlength-1 and not(self.repeat) and widget != self.toolnext:
				GObject.idle_add(self.stop_play)
				break
			#if there on the last track and repeat is enabled go back to the first track
			elif x == listlength-1 and self.repeat:
				self.iconoListView.set_playmark(0)
				self.iconoListView.get_sw().get_child().scroll_to_cell(0)
				GObject.idle_add(self.playitem, self.iconoListView.return_model()[0][7])
				break
			#if not the last track, just find the playmark and play the track below
			if self.iconoListView.return_model()[x][0] == 'media-playback-start':
				self.iconoListView.set_playmark(x+1)
				self.iconoListView.get_sw().get_child().scroll_to_cell(x+1)
				GObject.idle_add(self.playitem, self.iconoListView.return_model()[x+1][7])
				break

	def playitem(self, filepath):
		self.player.stop_play()
		self.player.set_track(filepath)
		self.player.play_item()
		data = self.taglookup.getTrackType(filepath)
		#print(data)
		if data != False:
			self.update_labels(str(data[2]), str(data[3]), str(data[4]))

			#Notifications
			self.notification.update (str(data[2]), str(data[3]), "media-playback-start")
			self.notification.show()
			#set Sound Menu Data
			self.sopranompris.set_metadata(str(data[2]), str(data[3]), str(data[4]), "file://" + sopranoGlobals.CACHEFILE)
			self.sopranompris.signal_playing()

			self.toolSeekBar.set_sensitive(True)
			toolplayimg = self.builder.get_object('image3')
			toolplayimg.set_from_icon_name('media-playback-pause', Gtk.IconSize.LARGE_TOOLBAR)
			GObject.idle_add(self.cover_update)
		else:
			self.clear_labels()
			self.play_next()

	def stop_play(self, *args):
		self.player.stop_play()
		self.iconoListView.clear_playmark()
		self.clear_labels()
		self.toolSeekBar.set_sensitive(False)
		self.toolSeekBar.set_value(0)
		toolplayimg = self.builder.get_object('image3')
		toolplayimg.set_from_icon_name('media-playback-start', Gtk.IconSize.LARGE_TOOLBAR)
		GObject.idle_add(self.cover_update)

	def play_pause(self, filepath=None):
		#print(self.player.get_state())
		toolplayimg = self.builder.get_object('image3')
		if (self.player.get_state() == Gst.State.PLAYING):
			if self.player.get_track()[:7] == 'http://' or self.player.get_track()[:6] == 'mms://':
				self.player.stop_play()
				print("Radio Stop")
			else:
				self.player.pause_item()
			toolplayimg.set_from_icon_name('media-playback-start', Gtk.IconSize.LARGE_TOOLBAR)
			#self.trayplaypause.set_label("Play")			
		elif (self.player.get_state() == Gst.State.PAUSED):
			self.player.play_item()
			toolplayimg.set_from_icon_name('media-playback-pause', Gtk.IconSize.LARGE_TOOLBAR)
			#self.trayplaypause.set_label("Pause")			
		else:#if os.path.isfile(filepath):
			selected = self.iconoListView.get_sw().get_child().get_selection()
			if selected.get_selected_rows()[1] != []:
				modeliter = self.iconoListView.return_model().get_iter(selected.get_selected_rows()[1][0])
			elif self.player.get_state() == Gst.State.NULL and self.iconoListView.get_playmark() != None:
				modelrow = self.iconoListView.get_playmark()
				modeliter = self.iconoListView.return_model().get_iter(modelrow)
			elif self.iconoListView.return_model().get_iter_first() != None:
				modeliter = self.iconoListView.return_model().get_iter_first()

			try: filepath = self.iconoListView.return_model().get_value(modeliter, 7)
			except: return
			#self.trayplaypause.set_label("Pause")			
			GObject.idle_add(self.playitem, filepath)
			self.iconoListView.set_playmark(modeliter)
			toolplayimg.set_from_icon_name('media-playback-pause', Gtk.IconSize.LARGE_TOOLBAR)
			GObject.idle_add(self.cover_update)
Exemplo n.º 7
0
class IconoListView():
	def __init__(self):
		self.sw = Gtk.ScrolledWindow()
		self.trackparser = TrackMetaData()

		builder = Gtk.Builder()
		filename = os.path.join('data', 'treeview.ui')
		builder.add_from_file(filename)
		self.abox = builder.get_object('treeview1')
		self.abox.set_fixed_height_mode(False)

		self.abox.set_search_column(1)
		self.abox.get_selection().set_mode(Gtk.SelectionMode.MULTIPLE)
		trackCol = builder.get_object('trackCol')
		titleCol = builder.get_object('titleCol')
		artistCol = builder.get_object('artistCol')
		albumCol = builder.get_object('albumCol')
		lengthCol = builder.get_object('lengthCol')
		genreCol = builder.get_object('genreCol')
		pathCol = builder.get_object('pathCol')

		#need to figure a working sorting function
		#self.abox.get_model().set_sort_func(1, self.tracknumsortfunc, None)

		trackCol.set_sort_column_id(1)
		titleCol.set_sort_column_id(2)
		artistCol.set_sort_column_id(3)
		albumCol.set_sort_column_id(4)
		lengthCol.set_sort_column_id(5)
		genreCol.set_sort_column_id(6)

		#anEntry = Gtk.TargetEntry.new("abox",Gtk.TargetFlags.SAME_WIDGET, 10)
		self.abox.enable_model_drag_source(Gdk.ModifierType.BUTTON1_MASK, [('TREE_MODEL_ROW', Gtk.TargetFlags.SAME_WIDGET, 0),], Gdk.DragAction.COPY|Gdk.DragAction.MOVE)
		#self.abox.drag_source_set(Gdk.ModifierType.BUTTON1_MASK, [anEntry], 0)
		self.abox.enable_model_drag_dest([], Gdk.DragAction.COPY|Gdk.DragAction.DEFAULT)
		#self.abox.drag_dest_set(0, [], 0)
		self.abox.connect('drag_motion', self.drag_motion_cb)
		self.abox.connect('drag_drop', self.drop_cb)
		self.abox.connect('drag_data_received', self.got_data_cb)

		self.abox.connect("drag_data_get", self.drag_data_get_data)

		self.abox.connect('button_press_event', self.on_button_press)
		self.abox.connect('button_release_event', self.on_button_release)
		self.defer_select=False
		self.sw.add(self.abox)

	def tracknumsortfunc(self,model, row1, row2, user_data):
		if (model.get_value(row1, 3) == model.get_value(row2, 3)) and (model.get_value(row1, 4) == model.get_value(row2, 4)):
			#print("Same Band! and Same Album!")
			#print(model.get_value(row1, 3), model.get_value(row1, 4))
			#print cmp(model[row1][3], model[row2][3])
			if (model.get_value(row1, 1) <= model.get_value(row2, 1)):
				print("0")
				return 0
				#print(model.get_value(row1, 1))
				#model.swap(row1, row2)
			else:
				print("-1")
				return -1
				#model.swap(row2, row1)
		#else:
			#print cmp(model[row1][3], model[row2][3])

	def drag_data_get_data(self, treeview, context, selection, target_id, etime):
		treeselection = treeview.get_selection()
		model, paths = treeselection.get_selected_rows()
		Gtk.tree_set_row_drag_data(selection, treeview.get_model(), paths[0])		

	def drag_motion_cb(self, senderID, context, x, y, time):
		Gdk.drag_status(context, Gdk.DragAction.COPY, time)
		if self.abox.get_dest_row_at_pos(x, y) == None:
			return True
		path, pos = self.abox.get_dest_row_at_pos(x, y)
		self.abox.set_drag_dest_row(path, pos)
		return True

	def got_data_cb(self, windowid, context, x, y, data, info, time):
		treeselection = windowid.get_selection()
		model, paths = treeselection.get_selected_rows()
		refs = []
		for path in paths:
    			refs.append(Gtk.TreeRowReference.new(model, path))
		#refs = [path.append(Gtk.TreeRowReference.new(model, path)) for path in paths# different way of wording the above
		destpath = windowid.get_dest_row_at_pos(x, y)
		if destpath:
			destpath, position = destpath
			destiter = model.get_iter(destpath)
		else:
			#print "outside the rows"
			try: destiter = model.get_iter(len(model))
			except: destiter = False
		#handle internal drag/drops here
		sourceWidget = Gtk.drag_get_source_widget(context)		
		if sourceWidget == windowid:
			#print "internals"			
			if not destpath in paths:
				if (position == Gtk.TreeViewDropPosition.BEFORE):# or position == Gtk.TreeViewDropPosition.INTO_OR_BEFORE):
					print("into or before")
					for currentref in refs:
						model.move_before(model.get_iter(currentref.get_path()), destiter)
				else:
					print("else")
					for currentref in reversed(refs):
						model.move_after(model.get_iter(currentref.get_path()), destiter)
		else:

			##detach model improves performance but causes flicker # MAKES MIKE A SAD PANDA
			windowid.set_model(None)
			#f****n file managers handling differently :( nautilus sends plaintext, but pcman sends uris
			tempArray = []
			if data.get_text():
				for i in data.get_text().splitlines():
					tempArray.append(i)
			else:
				for i in data.get_uris():
					tempArray.append(i)
			from time import time as systime
			systime1 = systime()
			#got the data now split it up
			for i in tempArray:
				i = i.replace('file://','').replace('%20',' ') #simple but is way too slow
				if os.path.isdir(i):
					for root, dirs, files in os.walk(i):
						while Gtk.events_pending():
	    						Gtk.main_iteration()
						for name in files:
							#print(name)
							self.add_row(os.path.join(root, name), model, destiter)
				else:
					self.add_row(i, model, destiter)
			##reattach model
			print("%s%f%s%i" % ("Add Operation took ",systime() - systime1," Items:", len(model)))
			del(systime)
			windowid.set_model(model)

		context.finish(True, False, time)

	def drop_cb(self, windowid, context, x, y, time):
		# Some data was dropped, get the data
		windowid.drag_get_data(context, context.list_targets()[-1], time)
		return True

	def add_row(self, action, widget, destiter):
		x = self.trackparser.getTrackType(action)
		#x = [None, 1,"Title","Artist","Album","400","Genre","/aidscake"]
		#x.insert(0, None)
		if destiter == False and x != False:
			widget.append(x)
		elif x != False:
			widget.insert_after(destiter, x)

	def load_shelf(self, path):
		model = self.return_model()
		self.abox.set_model(None)
		db = pickle.load(open(path, "rb"))
		for i in range(0, len(db), 8):
			templist = []
			for j in range(0, 8):
				templist.append(db[i+j])
			while Gtk.events_pending():
				Gtk.main_iteration()
			model.append(templist)
		self.abox.set_model(model)

	def save_shelf(self, path):
		count = 0
		settings = []
		def writeouttree(model, path, iter, data):
			for i in range(0, 8):
				settings.append(model.get_value(iter, i))

		self.return_model().foreach(writeouttree, None)
		db = pickle.dump(settings, open(path, "wb" ),2)

	def on_button_press(self, widget, event):
		# Here we intercept mouse clicks on selected items so that we can
		# drag multiple items without the click selecting only one
		target = widget.get_path_at_pos(int(event.x), int(event.y))
		if (target 
		   and event.type == Gdk.EventType.BUTTON_PRESS
		   and not (event.get_state() & (Gdk.ModifierType.CONTROL_MASK|Gdk.ModifierType.SHIFT_MASK))
		   and widget.get_selection().path_is_selected(target[0])):
			   # disable selection
			   widget.get_selection().set_select_function(lambda *ignore: False, None)
			   self.defer_select = target[0]
		if event.button == 3:
			self.menu = Gtk.Menu()
			aMenuitem = Gtk.MenuItem()
			aMenuitem.set_label("Remove")
			aMenuitem.connect("activate", self.remove_rows, widget)

			self.menu.append(aMenuitem)
			self.menu.show_all()
			self.menu.popup( None, None, None, None, event.button, event.time)
			return True

	def on_button_release(self, widget, event):
		# re-enable selection
		widget.get_selection().set_select_function(lambda *ignore: True, None)

		target = widget.get_path_at_pos(int(event.x), int(event.y))	
		if (self.defer_select and target and self.defer_select == target[0] and not (event.x==0 and event.y==0)): # certain drag and drop
   				widget.set_cursor(target[0], target[1], False)

	def clear_playmark(self):
		for i in range(0, len(self.return_model())):
			self.return_model().set_value(self.return_model().get_iter(i), 0, '')

	def set_playmark(self, row):
		self.clear_playmark()		
		try: self.return_model().set_value(row, 0, 'media-playback-start')
		except: self.return_model().set_value(self.return_model().get_iter(row), 0, 'media-playback-start')

	def get_playmark(self):
		for i in range(0, len(self.return_model())):
			tempiter = self.return_model().get_iter(i)
			if self.return_model().get_value(tempiter, 0) == 'media-playback-start':
				return i
				break
		return None

	def get_sw(self):
		return self.sw

	def return_model(self):
		return self.abox.get_model()

	def remove_rows(self, widget, treeview):
		model, selected = self.abox.get_selection().get_selected_rows()
		treeview.set_model(None)
		for i in reversed(selected):
			tempiter = model.get_iter(i)
			"""if model.get_value(tempiter, 0) == 'media-playback-start':
				GObject.idle_add(self.stop_play)"""
			model.remove(tempiter)
		treeview.set_model(model)
Exemplo n.º 8
0
class IconoListView():
    def __init__(self):
        self.sw = Gtk.ScrolledWindow()
        self.trackparser = TrackMetaData()

        builder = Gtk.Builder()
        filename = os.path.join('data', 'treeview.ui')
        builder.add_from_file(filename)
        self.abox = builder.get_object('treeview1')
        self.abox.set_fixed_height_mode(False)

        self.abox.set_search_column(1)
        self.abox.get_selection().set_mode(Gtk.SelectionMode.MULTIPLE)
        trackCol = builder.get_object('trackCol')
        titleCol = builder.get_object('titleCol')
        artistCol = builder.get_object('artistCol')
        albumCol = builder.get_object('albumCol')
        lengthCol = builder.get_object('lengthCol')
        genreCol = builder.get_object('genreCol')
        pathCol = builder.get_object('pathCol')

        #need to figure a working sorting function
        #self.abox.get_model().set_sort_func(1, self.tracknumsortfunc, None)

        trackCol.set_sort_column_id(1)
        titleCol.set_sort_column_id(2)
        artistCol.set_sort_column_id(3)
        albumCol.set_sort_column_id(4)
        lengthCol.set_sort_column_id(5)
        genreCol.set_sort_column_id(6)

        #anEntry = Gtk.TargetEntry.new("abox",Gtk.TargetFlags.SAME_WIDGET, 10)
        self.abox.enable_model_drag_source(
            Gdk.ModifierType.BUTTON1_MASK, [
                ('TREE_MODEL_ROW', Gtk.TargetFlags.SAME_WIDGET, 0),
            ], Gdk.DragAction.COPY | Gdk.DragAction.MOVE)
        #self.abox.drag_source_set(Gdk.ModifierType.BUTTON1_MASK, [anEntry], 0)
        self.abox.enable_model_drag_dest([], Gdk.DragAction.COPY
                                         | Gdk.DragAction.DEFAULT)
        #self.abox.drag_dest_set(0, [], 0)
        self.abox.connect('drag_motion', self.drag_motion_cb)
        self.abox.connect('drag_drop', self.drop_cb)
        self.abox.connect('drag_data_received', self.got_data_cb)

        self.abox.connect("drag_data_get", self.drag_data_get_data)

        self.abox.connect('button_press_event', self.on_button_press)
        self.abox.connect('button_release_event', self.on_button_release)
        self.defer_select = False
        self.sw.add(self.abox)

    def tracknumsortfunc(self, model, row1, row2, user_data):
        if (model.get_value(row1, 3) == model.get_value(
                row2, 3)) and (model.get_value(row1, 4) == model.get_value(
                    row2, 4)):
            #print("Same Band! and Same Album!")
            #print(model.get_value(row1, 3), model.get_value(row1, 4))
            #print cmp(model[row1][3], model[row2][3])
            if (model.get_value(row1, 1) <= model.get_value(row2, 1)):
                print("0")
                return 0
                #print(model.get_value(row1, 1))
                #model.swap(row1, row2)
            else:
                print("-1")
                return -1
                #model.swap(row2, row1)
        #else:
        #print cmp(model[row1][3], model[row2][3])

    def drag_data_get_data(self, treeview, context, selection, target_id,
                           etime):
        treeselection = treeview.get_selection()
        model, paths = treeselection.get_selected_rows()
        Gtk.tree_set_row_drag_data(selection, treeview.get_model(), paths[0])

    def drag_motion_cb(self, senderID, context, x, y, time):
        Gdk.drag_status(context, Gdk.DragAction.COPY, time)
        if self.abox.get_dest_row_at_pos(x, y) == None:
            return True
        path, pos = self.abox.get_dest_row_at_pos(x, y)
        self.abox.set_drag_dest_row(path, pos)
        return True

    def got_data_cb(self, windowid, context, x, y, data, info, time):
        treeselection = windowid.get_selection()
        model, paths = treeselection.get_selected_rows()
        refs = []
        for path in paths:
            refs.append(Gtk.TreeRowReference.new(model, path))
        #refs = [path.append(Gtk.TreeRowReference.new(model, path)) for path in paths# different way of wording the above
        destpath = windowid.get_dest_row_at_pos(x, y)
        if destpath:
            destpath, position = destpath
            destiter = model.get_iter(destpath)
        else:
            #print "outside the rows"
            try:
                destiter = model.get_iter(len(model))
            except:
                destiter = False
        #handle internal drag/drops here
        sourceWidget = Gtk.drag_get_source_widget(context)
        if sourceWidget == windowid:
            #print "internals"
            if not destpath in paths:
                if (
                        position == Gtk.TreeViewDropPosition.BEFORE
                ):  # or position == Gtk.TreeViewDropPosition.INTO_OR_BEFORE):
                    print("into or before")
                    for currentref in refs:
                        model.move_before(
                            model.get_iter(currentref.get_path()), destiter)
                else:
                    print("else")
                    for currentref in reversed(refs):
                        model.move_after(model.get_iter(currentref.get_path()),
                                         destiter)
        else:

            ##detach model improves performance but causes flicker # MAKES MIKE A SAD PANDA
            windowid.set_model(None)
            #f****n file managers handling differently :( nautilus sends plaintext, but pcman sends uris
            tempArray = []
            if data.get_text():
                for i in data.get_text().splitlines():
                    tempArray.append(i)
            else:
                for i in data.get_uris():
                    tempArray.append(i)
            from time import time as systime
            systime1 = systime()
            #got the data now split it up
            for i in tempArray:
                i = i.replace('file://',
                              '').replace('%20',
                                          ' ')  #simple but is way too slow
                if os.path.isdir(i):
                    for root, dirs, files in os.walk(i):
                        while Gtk.events_pending():
                            Gtk.main_iteration()
                        for name in files:
                            #print(name)
                            self.add_row(os.path.join(root, name), model,
                                         destiter)
                else:
                    self.add_row(i, model, destiter)
            ##reattach model
            print("%s%f%s%i" % ("Add Operation took ", systime() - systime1,
                                " Items:", len(model)))
            del (systime)
            windowid.set_model(model)

        context.finish(True, False, time)

    def drop_cb(self, windowid, context, x, y, time):
        # Some data was dropped, get the data
        windowid.drag_get_data(context, context.list_targets()[-1], time)
        return True

    def add_row(self, action, widget, destiter):
        x = self.trackparser.getTrackType(action)
        #x = [None, 1,"Title","Artist","Album","400","Genre","/aidscake"]
        #x.insert(0, None)
        if destiter == False and x != False:
            widget.append(x)
        elif x != False:
            widget.insert_after(destiter, x)

    def load_shelf(self, path):
        model = self.return_model()
        self.abox.set_model(None)
        db = pickle.load(open(path, "rb"))
        for i in range(0, len(db), 8):
            templist = []
            for j in range(0, 8):
                templist.append(db[i + j])
            while Gtk.events_pending():
                Gtk.main_iteration()
            model.append(templist)
        self.abox.set_model(model)

    def save_shelf(self, path):
        count = 0
        settings = []

        def writeouttree(model, path, iter, data):
            for i in range(0, 8):
                settings.append(model.get_value(iter, i))

        self.return_model().foreach(writeouttree, None)
        db = pickle.dump(settings, open(path, "wb"), 2)

    def on_button_press(self, widget, event):
        # Here we intercept mouse clicks on selected items so that we can
        # drag multiple items without the click selecting only one
        target = widget.get_path_at_pos(int(event.x), int(event.y))
        if (target and event.type == Gdk.EventType.BUTTON_PRESS and not (
                event.get_state() &
            (Gdk.ModifierType.CONTROL_MASK | Gdk.ModifierType.SHIFT_MASK))
                and widget.get_selection().path_is_selected(target[0])):
            # disable selection
            widget.get_selection().set_select_function(lambda *ignore: False,
                                                       None)
            self.defer_select = target[0]
        if event.button == 3:
            self.menu = Gtk.Menu()
            aMenuitem = Gtk.MenuItem()
            aMenuitem.set_label("Remove")
            aMenuitem.connect("activate", self.remove_rows, widget)

            self.menu.append(aMenuitem)
            self.menu.show_all()
            self.menu.popup(None, None, None, None, event.button, event.time)
            return True

    def on_button_release(self, widget, event):
        # re-enable selection
        widget.get_selection().set_select_function(lambda *ignore: True, None)

        target = widget.get_path_at_pos(int(event.x), int(event.y))
        if (self.defer_select and target and self.defer_select == target[0] and
                not (event.x == 0 and event.y == 0)):  # certain drag and drop
            widget.set_cursor(target[0], target[1], False)

    def clear_playmark(self):
        for i in range(0, len(self.return_model())):
            self.return_model().set_value(self.return_model().get_iter(i), 0,
                                          '')

    def set_playmark(self, row):
        self.clear_playmark()
        try:
            self.return_model().set_value(row, 0, 'media-playback-start')
        except:
            self.return_model().set_value(self.return_model().get_iter(row), 0,
                                          'media-playback-start')

    def get_playmark(self):
        for i in range(0, len(self.return_model())):
            tempiter = self.return_model().get_iter(i)
            if self.return_model().get_value(tempiter,
                                             0) == 'media-playback-start':
                return i
                break
        return None

    def get_sw(self):
        return self.sw

    def return_model(self):
        return self.abox.get_model()

    def remove_rows(self, widget, treeview):
        model, selected = self.abox.get_selection().get_selected_rows()
        treeview.set_model(None)
        for i in reversed(selected):
            tempiter = model.get_iter(i)
            """if model.get_value(tempiter, 0) == 'media-playback-start':
				GObject.idle_add(self.stop_play)"""
            model.remove(tempiter)
        treeview.set_model(model)