diff --git a/invest-applet/invest/preferences.py b/invest-applet/invest/preferences.py
index 5eb1aeb..4372509 100644
--- a/invest-applet/invest/preferences.py
+++ b/invest-applet/invest/preferences.py
@@ -5,6 +5,7 @@ import gtk, gobject, gconf
 import invest
 import currencies
 import cPickle
+from quotes import NameRetriever
 
 class PrefsDialog:
 	def __init__(self, applet):
@@ -26,10 +27,11 @@ class PrefsDialog:
 		self.currency.connect('activate', self.on_activate_entry)
 		self.currency.connect('focus-out-event', self.on_focus_out_entry)
 
-		self.typs = (str, str, float, float, float, float)
+		self.SYMBOL, self.LABEL, self.AMOUNT, self.PRICE, self.COMMISSION, self.EXCHANGE, self.NAMERETRIVER = range(7)
+		self.typs = (str, str, float, float, float, float, NameRetriever)
 		self.names = (_("Symbol"), _("Label"), _("Amount"), _("Price"), _("Commission"), _("Currency Rate"))
 		store = gtk.ListStore(*self.typs)
-		store.set_sort_column_id(0, gtk.SORT_ASCENDING)
+		store.set_sort_column_id(self.SYMBOL, gtk.SORT_ASCENDING)
 		self.treeview.set_model(store)
 		self.model = store
 
@@ -65,29 +67,65 @@ class PrefsDialog:
 					exchange =  purchase["exchange"]
 				else:
 					exchange = 0.0
-				store.append([key, label, purchase["amount"], purchase["bought"], purchase["comission"], exchange])
+				store.append([key, label, purchase["amount"], purchase["bought"], purchase["comission"], exchange, None])
 
 		try:
 			pixbuf = gtk.gdk.pixbuf_new_from_file_at_size(join(invest.ART_DATA_DIR, "invest-16.png"), -1,-1)
 			self.dialog.set_icon(pixbuf)
 		except Exception, msg:
 			invest.debug("Could not load 'invest-16.png' file: %s" % msg)
-			pass
 
 		self.sync_ui()
 
 	def on_cell_edited(self, cell, path, new_text, col, typ):
 		try:
-			if col == 0:    # stock symbols must be uppercase
+			if col == self.SYMBOL:
+				# stock symbols must be uppercase
 				new_text = str.upper(new_text)
-			if col < 2:
-				self.model[path][col] = new_text
-			else:
+				# did the symbol actually change?
+				if new_text == self.model[path][col]:
+					return
+
+				# start a name retriever to get the name of this stock
+				self.new_name_retriever(self.model[path], new_text)
+			if col == self.LABEL:
+				# disable name retriever for this stock if existing
+				self.drop_name_retriever(self.model[path])
+			if typ == float:
 				value = locale.atof(new_text)
 				self.model[path][col] = value
+			else:
+				self.model[path][col] = new_text
 		except Exception, msg:
 			invest.error('Exception while processing cell change: %s' % msg)
-			pass
+
+	# updates the label of a stock, retrieved by a name retriever
+	def update_label(self, nr, store_path):
+		# set label only if NameRetriever has not been cancelled
+		# TODO: only access the store_path if it is still valid,
+		#       the underlying liststore may have been changed in the meanwhile
+		if nr.cancelled == False:
+			store_path[self.LABEL] = nr.name
+		# in any case, drop the name retriever for this stock
+		self.drop_name_retriever(store_path)
+
+	# creates a new name retriever for the given stock
+	def new_name_retriever(self, store_path, symbol):
+		# first drop possibly existing name retriever for this stock
+		self.drop_name_retriever(store_path)
+		# create a new one
+		nr = NameRetriever(symbol)
+		nr.connect('completed', self.update_label, store_path)
+		store_path[self.NAMERETRIVER] = nr
+		nr.start()
+
+	# drops a possibly existing name retriever for this stock by canceling and dropping
+	def drop_name_retriever(self, store_path):
+		nr = store_path[self.NAMERETRIVER]
+		if nr != None:
+			nr.cancel()
+			store_path[self.NAMERETRIVER] = None
+
 
 	def format(self, fmt, value):
 		return locale.format(fmt, value, True)
@@ -177,7 +215,7 @@ class PrefsDialog:
 		pass
 
 	def on_add_stock(self, w):
-		iter = self.model.append(["GOOG", "Google Inc.", 0, 0, 0, 0])
+		iter = self.model.append(["GOOG", "Google Inc.", 0, 0, 0, 0, None])
 		path = self.model.get_path(iter)
 		self.treeview.set_cursor(path, self.treeview.get_column(0), True)
 
diff --git a/invest-applet/invest/quotes.py b/invest-applet/invest/quotes.py
index 93b8b68..3fd4eda 100644
--- a/invest-applet/invest/quotes.py
+++ b/invest-applet/invest/quotes.py
@@ -64,6 +64,53 @@ class QuotesRetriever(Thread, _IdleObject):
 			self.retrieved = True
 		self.emit("completed")
 
+class NameRetriever(Thread, _IdleObject):
+	"""
+	Thread which uses gobject signals to return the name
+	of a stock symbol.
+	"""
+	__gsignals__ =  {
+			"completed": (
+				gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE, []),
+			# FIXME: We don't monitor progress, yet ...
+			#"progress": (
+			#	gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE, [
+			#	gobject.TYPE_FLOAT])        #percent complete
+			}
+
+	def __init__(self, ticker):
+		Thread.__init__(self)
+		_IdleObject.__init__(self)
+		self.ticker = ticker
+		self.retrieved = False
+		self.cancelled = False
+		self.name = []
+
+	def cancel(self):
+		"""
+		Threads in python are not cancellable, so we implement our own
+		cancellation logic
+		"""
+		invest.debug("Retriving name for ticker %s has been cancelled" % self.ticker)
+		self.cancelled = True
+
+	def run(self):
+		invest.debug('Retriving name for ticker: %s' % self.ticker)
+		quotes_url = "http://finance.yahoo.com/d/quotes.csv?s=%s&f=snc4l1&e=.csv" % (self.ticker)
+		try:
+			data_file = urlopen(quotes_url, proxies = invest.PROXY)
+			data = data_file.read()
+			invest.debug('Retrieved data: %s' % data)
+			self.name = data.split(',')[1].replace('"', '')
+			data_file.close()
+		except Exception, msg:
+			invest.debug("Error while retrieving quotes data (url = %s): %s" % (quotes_url, msg))
+		else:
+			# set retrieved = True only if thread has not been cancelled
+			if self.cancelled == False:
+				self.retrieved = True
+				invest.debug('Retrieved name: %s' % self.name)
+		self.emit("completed")
 
 class QuoteUpdater(gtk.ListStore):
 	updated = False
